// GEDPARA.SR Paragraph editing
get "BRAVO.DF"
get "CHAR.DF"
get "GINN.DF"
// Incoming procedures
external
[
getint
binsearcha
getvch
putvch
mapscrcp
errhlt
stcopy
stnum
stappend
stsize
insertstring
deletea
inserta
move
movec
enww
cpmin
cpmax
readsel
stcompare
cpadjust2
cppara
parabounds
cpparabounds
paracp
paraspec
gotparaspec
specstate
nextspecstate
gcspecs
freespec
ckspecs
cpadjustlist
parsespec
unparsespec
putscrwd
getscrwd
finishchanges
codechange
changeformata
receivechange
setparaspec
setparacp
invalidateband
invalidatedisplay
compatible
subspec
deletesubspec
insertsubspec
mergespecs
discardspecs
acquirespecs
replacespec
forgetspec
uadjust
paradetails
specdetails
dupspec
selectsel
macpara
compactspec
makeroominspec
bubblesegs
wholeparas
lastparacp
discardpages
wholepages
inheap // ** take out calls when thoroughly debugged
cpc
]
// Incoming statics
external
[
rgdlfirst
rgdllast
rgmaxdl
macww
rgdoc
vdoc
vcp
vchremain
rgmaccp
rgcpfdispl
rgcplast
vxleftmarg
vxrightmarg
cpscrt
vdlhint
vpara
rgpara
currentspec
rgdirty
vdeltacp
selarg
rgprogram
fdebug
otherspec
]
// Outgoing procedures
external
[
fdeletea
finserta
finsertk
finsertstring
finsertparastring
splitpara
mergeparas
copyparas
deleteparas
insertparas
]
// Outgoing statics
external
[
vcpfinsert
]
// Local statics
static [
vgrew
vcpfinsert
]
let fdeletea(doc, cp1, cp2) = valof
[
if cpc(cp1, cp2) gr 0 then resultis cp1
let page1, page2 = nil, nil
if wholepages(doc, cp1, cp2, lv page1, lv page2) then
discardpages(doc, page1, page2)
let para1 = cppara(doc, cp1)
let para2 = cppara(doc, cp2)
if wholeparas(doc, cp1, cp2) then
[ // delete an integral number of paragraphs
cp1 = deleteparas(doc, para1, para2)
if fdebug then ckspecs() // **
resultis cp1
]
if para1 ne para2 then errhlt("XXD")
deletesubspec(doc, para1, cp1, cp2) // delete a subparagraph
deletea(doc, cp1, cp2)
if fdebug then ckspecs() // **
resultis cp1
]
and finserta(docdest, cpdest, doc, cp1, cp2) = valof
[
vgrew = false
if cpc(cp1, cp2) gr 0 then
[
vcpfinsert = cpdest ;
resultis cpdest;
]
let para1 = cppara(doc, cp1)
let para2 = cppara(doc, cp2)
if wholeparas(doc, cp1, cp2) then
[ // paste an integral number of paragraphs
if rgprogram ! docdest then errhlt("PIP")
let para = splitpara(docdest, cpdest, false)
if vgrew & doc eq docdest & cpc(cp1+1, cpdest) gr 0 then
[
para1 = para1 + 1
para2 = para2 + 1
]
resultis insertparas(docdest, para, doc, para1, para2)
]
if para1 ne para2 then errhlt("XXI")
if cpc(cpdest,lastparacp(docdest)) ge 0 do splitpara(docdest,cpdest,true)
insertsubspec(docdest, cpdest, doc, cp1, cp2)
inserta(docdest, cpdest, doc, cp1, cp2)
vcpfinsert = cpdest + cp2 + 1 - cp1
if fdebug then ckspecs() // **
resultis cpdest
]
and finsertk(doc, cp, nchars) = valof
[
// Note -- setpcsiz may call this with nchars ls 0????
let para = cppara(doc, cp)
if para eq macpara(doc)-2 then splitpara(doc, cp, true)
unless nchars do resultis cp
let spec, siz, looks, changes, rcp, r = nil, nil, nil, nil, nil, nil
paradetails(doc, para, lv spec, cp-1)
spec >> SPEC.dirty = true
if r ge siz-2 & siz ge 3 then r = siz-3 // keep hdr ptr same
for i = r+1 to siz-1 do changes!i = changes!i + nchars
if rcp eq -1 & siz eq 2 then // special case -- empty paragraph
[
makeroominspec(doc, para, spec, 2)
paradetails(doc, para, lv spec)
spec >> SPEC.siz = bubblesegs(siz, 1, 1, changes, looks)
changes ! 1 = nchars
]
resultis cp
]
and finsertstring(doc, cp, string) = valof
[
let siz = stsize(string)
cp = finsertk(doc, cp, siz)
insertstring(doc, cp, string)
vcpfinsert = cp + siz
if fdebug then ckspecs()
resultis cp
]
and finsertparastring(doc, para, trailerstring, textstring) = valof
[
insertparas(doc, para, doc, macpara(doc)-2, macpara(doc)-2) // dummy
let cp = paracp(doc, para)
insertstring(doc, cp+1, trailerstring) // after chtrailer
insertstring(doc, cp, textstring)
forgetspec(doc, para)
compactspec(parsespec(doc, para, 0))
vcpfinsert = paracp(doc, para+1)
if fdebug then ckspecs()
resultis cp
]
and splitpara(doc, cp, always) = valof
[
// Make two paragraphs where there is now one
// But if not "always", don't split at the front
// Force cp out of the trailer
// If at beginning or end of a paragraph, insert an empty paragraph
// Else...
// Insert empty trailer at split point
// Make room in tables for the new paragraph
// Make a spec for it out of the tail of the old paragraph
// Replace the spec of the old paragraph by its head
// Return the number of the new paragraph
let tex, b, e = nil, nil, nil
let para = cpparabounds(doc, cp, lv tex, lv b, lv e)
if rgprogram ! doc then resultis para
cp = cpmin(cp, b)
let newpara = para + 1
test cp eq tex
ifso [
if not always then resultis para
insertparas(doc, para, doc, macpara(doc)-2, macpara(doc)-2)
]
ifnot [
finsertstring(doc, cp, "*032*N")
b = b + 2
e = e + 2
acquirespecs(doc, para, 1)
setparacp(doc, newpara, cp+2)
otherspec = subspec(doc, para, cp+2, b-1)
setparaspec(doc, para, subspec(doc, para, tex, cp-1))
replacespec(doc, newpara, otherspec)
otherspec = 0
]
vgrew = true
resultis newpara
]
and mergeparas(doc, para1, para2) = valof
[
// Make one paragraph where there are now many
// Merge successive paragraphs into the last
// The trailer of each absorbed paragraph is deleted
// Finally, remove the extinct paragraphs from tables
// Return the cp that former para2+1 now begins at
if para1 ge para2 then resultis 0 // result irrelevant
let tex, b, e = nil, nil, nil
for para = para2-1 to para1 by -1 do
[
parabounds(doc, para, lv tex, lv b, lv e)
deletea(doc, b, e)
setparacp(doc, para2, b)
paraspec(doc, para) >> SPEC.trailerlength = 0
replacespec(doc, para2, mergespecs(doc,para, doc,para2))
forgetspec(doc, para)
]
discardspecs(doc, para1, para2-1)
setparacp(doc, para1, tex)
resultis b
]
and insertparas(docdest, paradest, doc, para1, para2) = valof
[
// Makes no changes to any document other than a straight text copy
// Returns the number of characters inserted into docdest
let nparas = para2 + 1 - para1
unless nparas gr 0 do resultis 0
let cpdest = paracp(docdest, paradest)
let tex1, b1, e1 = nil, nil, nil
let tex2, b2, e2 = nil, nil, nil
parabounds(doc, para1, lv tex1, lv b1, lv e1)
parabounds(doc, para2, lv tex2, lv b2, lv e2)
let cp1, cp2 = tex1, e2
let nchars = cp2+1-cp1
inserta(docdest, cpdest, doc, cp1, cp2)
if doc eq docdest & cpc(para1+1, paradest) gr 0 then
[
para1 = para1 + nparas
cp1 = cp1 + nchars
]
acquirespecs(docdest, paradest, nparas)
let cpd = cpdest - cp1
for p = 0 to nparas-1 do
[
setparacp(docdest, paradest+p, paracp(doc, para1+p) + cpd)
setparaspec(docdest, paradest+p, dupspec(doc, para1+p))
]
setparacp(docdest, paradest, cpdest) // attempt to paste before self
setparacp(docdest, paradest + nparas, cpdest + nchars)
vgrew = true
vcpfinsert = cpdest + nchars
if fdebug then ckspecs() // **
resultis cpdest
]
and deleteparas(doc, para1, para2) = valof
[
let cp1 = paracp(doc, para1)
let cp2 = paracp(doc, para2+1)-1
for para = para1 to para2 do forgetspec(doc, para)
discardspecs(doc, para1, para2)
deletea(doc, cp1, cp2)
if paracp(doc, para1) ne cp1 then errhlt("DPA") // ** para 0 bug?
resultis cp1
]
and uadjust(u, delta,
pv1, pv2, pv3, pv4, pv5, pv6, pv7, pv8, pv9, pv10, pv11 ;
numargs N) be
for i = 0 to N-3 do
[
let locn = ((lv pv1) ! i)
if cpc(@locn, u) ge 0 then
@locn = @locn + delta
]