(package vx/data/textblock
:libs
(lib collection :path vx/collection)
(lib type :path vx/type)
:doc "Text parser")
(type delim : struct
:properties
[name : string
starttext : string
endtext : string
pos : int
delimlist : delimlist]
:doc "A delimiter type supporting start and end delimiters and positions.")
(type delimlist : list
:allowtypes [delim]
:test (test
(new : delimlist
delimcomma
delimwhitespace)
(delimlist
delimcomma
delimwhitespace))
:doc "A list of delim.")
(type textblock : struct
:properties
[name : string
text : string
startpos : int
endpos : int
curpos : int
line : int
column : int
delim : delim
close : delim
parent : textblock
children : textblocklist]
:doc "A textblock is a tree of text used for parsing by delimter.")
(type textblocklist : list
:allowtypes [textblock]
:doc "A list of textblock.")
(const delimbracketangle : delim
(delim
:name "delimbracketangle"
:starttext "<"
:endtext ">")
:doc "Angle Bracket Delimiter")
(const delimbracketcurly : delim
(delim
:name "delimbracketcurly"
:starttext "{"
:endtext "}")
:doc "Curly Bracket Delimiter")
(const delimbracketsquare : delim
(delim
:name "delimbracketsquare"
:starttext "["
:endtext "]")
:doc "Square Bracket Delimiter")
(const delimclose : delim
(delim
:name "delimclose")
:doc "A placeholder delimiter used to mark the close of whatever is the current delimiter.")
(const delimclosing : delim
(delim
:name "delimclosing")
:doc "A placeholder delimiter used to mark the closing of whatever is the current delimiter.")
(const delimcomma : delim
(delim
:name "delimcomma"
:starttext ",")
:doc "Comma Delimiter")
(const delimcomment : delim
(delim
:name "delimcomment"
:starttext "//"
:endtext "\n")
:doc "Comment Delimiter")
(const delimcommentblock : delim
(delim
:name "delimcommentblock"
:starttext "/*"
:endtext "*/")
:doc "Block Comment Delimiter")
(const delimline : delim
(delim
:name "delimline"
:starttext "\n")
:doc "New Line Delimiter")
(const delimnonwhitespace : delim
(delim
:name "delimnonwhitespace"
:starttext ":nonwhitespace"
:endtext ":whitespace")
:doc "Placeholder for delimited non-whitespace")
(const delimparen : delim
(delim
:name "delimparen"
:starttext "("
:endtext ")")
:doc "Parenthesis Delimiter")
(const delimquote : delim
(delim
:name "delimquote"
:starttext quote
:endtext quote)
:doc "Quote Delimiter")
(const delimquoteblock : delim
(delim
:name "delimquoteblock"
:starttext "`"
:endtext "`")
:doc "Block Quote Delimiter")
(const delimspace : delim
(delim
:name "delimspace"
:starttext " "
:endtext " ")
:doc "Space Delimiter")
(const delimtest1 : delim
(delim
:delimlist delimlisttest1)
:doc "A delimiter used for test suite")
(const delimlisttest1 : delimlist
(delimlist
delimtest2)
:doc "A delimiter used for test suite")
(const delimtest2 : delim
(copy delimbracketangle
:delimlist delimlisttest2)
:doc "A delimiter used for test suite")
(const delimlisttest2 : delimlist
(delimlist
delimcomma
delimtest3)
:doc "A delimiter used for test suite")
(const delimtest3 : delim
(copy delimbracketcurly
:delimlist delimlisttest3)
:doc "A delimiter used for test suite")
(const delimlisttest3 : delimlist
(delimlist
delimcomma
delimwhitespace)
:doc "A delimiter used for test suite")
(const delimtext : delim
(delim
:name "delimtext")
:doc "Placeholder for delimited text")
(const delimwhitespace : delim
(delim
:name "delimwhitespace"
:starttext ":whitespace")
:doc "Placeholder for delimited whitespace")
(func children<-textblock : textblocklist
[textblock : textblock]
(:children textblock)
:doc "Returns the child textblocks from a given textblock.")
(func delim-first<-delim-delim : delim
[delim1 : delim
delim2 : delim]
(let : delim
[pos1 : int := (:pos delim1)
pos2 : int := (:pos delim2)]
(if : delim
(then (= 0 pos2) delim1)
(then (= 0 pos1) delim2)
(then (is-empty delim2) delim1)
(then (is-empty delim1) delim2)
(then (< pos2 pos1) delim2)
(else delim1)))
:test (test
(copy delimcomma
:pos 1)
(delim-first<-delim-delim
(copy delimspace
:pos 2)
(copy delimcomma
:pos 1)))
(test
(empty delim)
(delim-first<-delim-delim
(delim
:pos 0)
(empty delim)))
:doc "Returns non-empty delim with lowest, non-negative startpos found in string.")
(func delim-first<-string-delimlist : delim
[text : string
delimlist : delimlist]
(if : delim
(then
(is-empty delimlist)
(empty delim))
(else
(let : delim
[resolvedlist : delimlist :=
(delimlist-pos<-string-delimlist
text
delimlist)]
(any<-list-start-reduce : delim
resolvedlist
(empty delim)
delim-first<-delim-delim))))
:test (test
(copy delimcomma
:pos 2)
(delim-first<-string-delimlist
"a, b"
(delimlist
delimspace
delimcomma)))
:doc "Returns delim with lowest startpos found in string.")
(func delim-pos<-string-delim : delim
[text : string
delim : delim]
(let : delim
[find : string := (:starttext delim)
pos : int := (typ/int<-string-findkeyword
text
find)]
(if : delim
(then
(= pos 0)
delim)
(else
(copy delim
:pos pos))))
:test (test
(copy delimcomma
:pos 2)
(delim-pos<-string-delim
"a,b"
delimcomma))
:doc "Return a delim with istart updated to position of first starttext.")
(func delimlist-pos<-string-delimlist : delimlist
[text : string
delimlist : delimlist]
(list<-list : delimlist
delimlist
(fn : delim
[delim : delim]
(delim-pos<-string-delim
text
delim)))
:test (test
(delimlist
(copy delimspace
:pos 3)
(copy delimcomma
:pos 2))
(delimlist-pos<-string-delimlist
"a, b"
(delimlist
delimspace
delimcomma)))
:doc "Returns a delimlist with each delim updated to position of first starttext.")
(func is-close : boolean
[delimarg : delim]
(=
(:name delimarg)
(:name delimclose))
:doc "Return true if the given delim is a close delim.")
(func is-single : boolean
[delimarg : delim]
(and
(!= "" (:starttext delimarg))
(= "" (:endtext delimarg)))
:doc "Return true if the given delim is a single text delim.")
(func stringlist<-textblocklist : stringlist
[textblocklist : textblocklist]
(list<-list : stringlist
textblocklist
text<-textblock)
:test (test
(stringlist
"a" "b")
(stringlist<-textblocklist
(textblocklist
(textblock
:text "a")
(textblock
:text "b"))))
:doc "Returns a stringlist from each (:text textblock).")
(func text<-textblock : string
[block : textblock]
(:text block)
:test (test
"a"
(text<-textblock
(textblock
:text "a")))
:doc "Returns the text from a given textblock.")
(func textblock<-close-textblock : textblock
[close : delim
textblockarg : textblock]
(let : textblock
[text : string := (:text textblockarg)
parent : textblock := (:parent textblockarg)
startpos : int := (:startpos textblockarg)
endpos : int := (:endpos textblockarg)
pos : int := (:pos close)
textclose : string := (:starttext close)
lenclose : int := (length textclose)
posminus : int := (-1 pos)
startleft : int := startpos
startclose : int := (+
startpos
posminus)
endclose : int := (switch : int
textclose
(case :whitespace
(int<-string-findkeyword
text
:nonwhitespace))
(else
(+
(-1 startclose)
lenclose)))
endleft : int := (if : int
(= 1 pos)
startclose
(-1 startclose))
startright : int := (+1 endclose)
endright : int := (if : int
(< endpos startright)
startright
endpos)
textleft : string := (typ/string<-string-end
text
posminus)
textright : string := (typ/string<-string-start
text
(+
pos
lenclose))
find : textblock := (textblock-findparent<-textblock
parent)
closefind : delim := (:close find)
textfind : string := (:text find)
startfind : int := (:startpos find)
delimfind : delim := (:delim find)
delimright : delim := (delim
:delimlist
(:delimlist delimfind))
lenfind : int := (-
(+1 endclose)
startfind)
textreplace : string := (string<-string-end
textfind
lenfind)
replace : textblock := (copy find
:text textreplace
:endpos endclose
:delim
(copy delimfind
:delimlist
(empty delimlist))
:close delimclosing)
parentchg : textblock := (textblock-replace<-textblock-find-replace
parent
find
replace)]
(textblock
:text textleft
:startpos startleft
:endpos endleft
:parent
(copy textblockarg
:text textright
:startpos startright
:endpos endright
:delim delimright
:close closefind
:parent parentchg)))
:test (test
(textblock
:text "b"
:startpos 5
:endpos 5
:parent
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))))))
(textblock<-close-textblock
(copy delimclose
:starttext "}"
:pos 2)
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)))))))
(test
(textblock
:startpos 13
:endpos 13
:parent
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))
(textblock<-close-textblock
(copy delimclose
:starttext ">"
:pos 1)
(textblock
:text ">"
:startpos 13
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))))
:doc "Returns a textblock after a close delim found.")
(func textblock<-empty-textblock : textblock
[empty : delim
textblockarg : textblock]
:doc "Returns a textblock after an empty delim found.")
(func textblock<-open-textblock : textblock
[open : delim
textblockarg : textblock]
(let : textblock
[text : string := (:text textblockarg)
parent : textblock := (:parent textblockarg)
startpos : int := (:startpos textblockarg)
endpos : int := (:endpos textblockarg)
delima : delim := (:delim textblockarg)
pos : int := (:pos open)
textopen : string := (:starttext open)
textclose : string := (:endtext open)
delimlistl : delimlist := (:delimlist open)
lenopen : int := (length textopen)
posminus : int := (-1 pos)
startleft : int := (if : int
(= pos 1)
(-1 startpos)
startpos)
endleft : int := (if : int
(= pos 1)
(-1 startpos)
(+
(-1 startleft)
posminus))
startright : int := (+
startpos
posminus
lenopen)
startopen : int := (+
startpos
posminus)
textleft : string := (typ/string<-string-end
text
posminus)
textpar : string := (typ/string<-string-start
text
pos)
textright : string := (typ/string<-string-start
text
(+
pos
lenopen))
close : delim := (copy delimclose
:starttext textclose)
tbleft : textblock := (if : textblock
(then
(= "" textleft)
(empty textblock))
(else
(textblock
:text textleft
:startpos startleft
:endpos endleft)))
tbpar1 : textblock := (copy textblockarg
:text textpar
:startpos startopen
:delim
(copy open
:pos 0
:delimlist
(:delimlist delima))
:parent parent)
tbfind : textblock := (if : textblock
(then
(= "" textleft)
(empty textblock))
(else
(textblock-findparent<-textblock
parent)))
tbparent : textblock := (if : textblock
(then
(is-empty tbfind)
tbpar1)
(else
(textblock-addchild<-textblock-find-child
tbpar1
tbfind
tbleft)))]
(textblock
:text textright
:startpos startright
:endpos endpos
:delim
(delim
:delimlist delimlistl)
:close close
:parent tbparent))
:test (test
(textblock
:text "c}"
:startpos 4
:endpos 5
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c}"
:startpos 3
:endpos 5
:delim
(copy delimbracketcurly
:pos 0)
:parent
(textblock
:text "ab{c}"
:startpos 1
:endpos 5
:children
(textblocklist
(textblock
:text "ab"
:startpos 1
:endpos 2)))))
(textblock<-open-textblock
(copy delimbracketcurly
:pos 3)
(textblock
:text "ab{c}"
:startpos 1
:endpos 5
:delim delimbracketcurly
:parent
(textblock
:text "ab{c}"
:startpos 1
:endpos 5))))
(test
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)))
(textblock<-open-textblock
(copy delimtest2
:pos 1)
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim delimtest1
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))
(test
(textblock
:text "a,b},{c d}>"
:startpos 3
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))
(textblock<-open-textblock
(copy delimtest3
:pos 1)
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)))))
:doc "Returns a textblock after a close delim found.")
(func textblock<-single-textblock : textblock
[single : delim
textblockarg : textblock]
(let : textblock
[text : string := (:text textblockarg)
parent : textblock := (:parent textblockarg)
startpos : int := (:startpos textblockarg)
endpos : int := (:endpos textblockarg)
pos : int := (:pos single)
origsingle : string := (:starttext single)
textsingle : string := (switch : string
origsingle
(case :whitespace
(let : string
[text2 : string := (typ/string<-string-start
text pos)
pos2 : int := (typ/int<-string-findkeyword
text2
:nonwhitespace)
pos3 : int := (if : int
(then
(= 0 pos2)
(length text2))
(then
(= pos2 pos)
pos2)
(else
(-1 pos2)))]
(typ/string<-string-start-end
text
pos
pos3)))
(else origsingle))
delimlistl : delimlist := (:delimlist single)
lensingle : int := (length textsingle)
posminus : int := (-1 pos)
startleft : int := startpos
startsingle : int := (+
startpos
posminus)
endsingle : int := (switch : int
textsingle
(case :whitespace
(int<-string-findkeyword
text
:nonwhitespace))
(else
(+
(-1 startsingle)
lensingle)))
endleft : int := (if : int
(= startsingle startpos)
startsingle
(-1 startsingle))
startright : int := (+1 endsingle)
textleft : string := (typ/string<-string-end
text
posminus)
textpar : string := (typ/string<-string-start
text
pos)
textright : string := (typ/string<-string-start
text
(+
pos
lensingle))]
(textblock
:text textleft
:startpos startleft
:endpos endleft
:delim
(delim
:delimlist delimlistl)
:parent
(textblock
:text textsingle
:startpos startsingle
:endpos endsingle
:delim
(copy single
:pos 0
:delimlist
(empty delimlist))
:parent
(copy textblockarg
:text textright
:startpos startright
:endpos endpos))))
:test (test
(textblock
:text "a"
:startpos 3
:endpos 3
:parent
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:pos 0)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))
(textblock<-single-textblock
(copy delimcomma
:pos 2)
(textblock
:text "a,b},{c d}>"
:startpos 3
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:pos 0)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))
(test
(textblock
:startpos 7
:endpos 7
:parent
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))))
(textblock<-single-textblock
(copy delimcomma
:pos 1)
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))))
(test
(textblock
:text "c"
:startpos 9
:endpos 9
:parent
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)
:parent
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))))
(textblock<-single-textblock
(copy delimwhitespace
:pos 2)
(textblock
:text "c d}>"
:startpos 9
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))))
:doc "Returns a textblock after a single value delim found.")
(func textblock<-string-delim : textblock
[text : string
delim : delim]
(textblock
:text text
:delim delim
:startpos 0
:endpos (length text))
:test (test
(textblock
:text "a"
:startpos 0
:endpos 1
:delim delimcomma)
(textblock<-string-delim
"a"
delimcomma))
:doc "Returns a textblock from a string and delim.")
(func textblock<-textblock-delim : textblock
[textblock : textblock
delim : delim]
:doc "Returns a parsed textblock from an unparsed one.")
(func textblock-addchild<-textblock-find-child : textblock
[textblockarg : textblock
find : textblock
child : textblock]
(if : textblock
(then // empty
(is-empty textblockarg)
(empty textblock))
(then // found
(and (== find textblockarg))
(copy textblockarg
:children
(copy
(:children textblockarg)
child)))
(else // recursion
(copy textblockarg
:parent
(textblock-addchild<-textblock-find-child
(:parent textblockarg)
find
child))))
:doc "Add the child to the given parent textblock.")
(func textblock-delimnotfound : textblock
[textblockarg : textblock]
(let : textblock
[text : string := (:text textblockarg)
delima : delim := (:delim textblockarg)
close : delim := (:close textblockarg)
parent : textblock := (:parent textblockarg)
childp : textblocklist := (:children parent)
delimp : delim := (:delim parent)
delims : delimlist := (:delimlist delimp)]
(if : textblock
(then // if delim not closed then error
(! (is-empty close))
(let : textblock
[msgerr : msg := (msg<-error
"closedelimmissing"
close)
child : textblock := (copy textblockarg
:delim (empty delim)
:close (empty delim)
:parent (empty textblock))
find : textblock := (textblock-findparent<-textblock
parent)
childrenf : textblocklist := (:children find)
childrenr : textblocklist := (copy childrenf
child)
replace : textblock := (copy find
msgerr
:children childrenr)
parent2 : textblock := (textblock-replace<-textblock-find-replace
parent
find
replace)
gparent : textblock := (:parent parent2)
parent3 : textblock := (copy parent2
:parent (empty textblock))
childreng : textblocklist := (:children gparent)
childrenc : textblocklist := (copy childreng
parent3)]
(copy gparent
:children childrenc
msgerr)))
(then // if empty parent then textblockarg
(is-empty parent)
textblockarg)
(else // else add textblockarg to parent and return parent
(let : textblock
[delimchg : delim := (if : delim
(is-empty (:delimlist delima))
delima
(copy delima
:delimlist (empty delimlist)))
child : textblock := (if : textblock
(= "" text)
(empty textblock)
(copy textblockarg
:delim delimchg
:parent (empty textblock)))
find : textblock := (textblock-findparent<-textblock
parent)
closef : delim := (:close find)
closing : boolean := (if : boolean
(== closef delimclosing) true)]
(if : textblock
(then
closing
(let : textblock
[parent2 : textblock := (:parent find)
find2 : textblock := (textblock-findparent<-textblock
parent2)
children1 : textblocklist := (if : textblocklist
(is-empty child)
(:children find)
(copy (:children find)
child))
replace1 : textblock := (copy find
:close (empty delim)
:parent (empty textblock)
:children children1)]
(if : textblock
(then
(is-empty find2)
(copy parent
:parent
(copy parent2
:children
(textblocklist
replace1))))
(else
(let : textblock
[children2 : textblocklist := (copy (:children find2)
replace1)
replace2 : textblock := (copy find2
:close (empty delim)
:children children2)
replace : textblock := (textblock-replace<-textblock-find-replace
parent2
find2
replace2)]
(textblock-replace<-textblock-find-replace
parent
find
replace))))))
(then
(is-empty child)
parent)
(else
(textblock-addchild<-textblock-find-child
parent
find
child)))))))
:test (test
(textblock
:text "<a"
:startpos 1
:endpos 2
:children
(textblocklist
(textblock
:text "<a"
:startpos 1
:endpos 2
:delim
(copy delimbracketangle
:delimlist vx/data/textblock/delimlisttest1)
:children
(textblocklist
(textblock
:text "a"
:startpos 2
:endpos 2))
(msg
:code "closedelimmissing"
:detail
(delim
:name "delimclose"
:starttext ">")
:severity msg-error))))
(textblock-delimnotfound
(textblock
:text "a"
:startpos 2
:endpos 2
:delim
(delim
:delimlist vx/data/textblock/delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<a"
:startpos 1
:endpos 2
:delim
(copy delimbracketangle
:delimlist vx/data/textblock/delimlisttest1)
:parent
(textblock
:text "<a"
:startpos 1
:endpos 2)))))
(test
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:pos 0)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)))))
(textblock-delimnotfound
(textblock
:text "a"
:startpos 3
:endpos 3
:parent
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:pos 0)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))))
(test
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))
(textblock-delimnotfound
(textblock
:text "b"
:startpos 5
:endpos 5
:parent
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))))))))
(test
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))))
(textblock-delimnotfound
(textblock
:startpos 13
:endpos 13
:parent
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))))
(test
(textblock
:text
"\"b\"
1,\"2\""
:startpos 5
:endpos 13
:delim
(delim
:delimlist
(delimlist
vx/data/textblock/delimline
vx/data/textblock/delimquote
vx/data/textblock/delimcomma))
:parent
(textblock
:text
"\"a\",\"b\"
1,\"2\""
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "\"a\""
:startpos 1
:endpos 3
:delim
(delim
:name "delimquote"
:starttext "\""
:endtext "\"")
:children
(textblocklist
(textblock
:text "a"
:startpos 2
:endpos 2)))
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(delim
:name "delimcomma"
:starttext ",")))))
(textblock-delimnotfound
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(delim
:name "delimcomma"
:starttext ",")
:parent
(textblock
:text
"\"b\"
1,\"2\""
:startpos 5
:endpos 13
:delim
(delim
:delimlist
(delimlist
vx/data/textblock/delimline
vx/data/textblock/delimquote
vx/data/textblock/delimcomma))
:parent
(textblock
:text
"\"a\",\"b\"
1,\"2\""
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "\"a\""
:startpos 1
:endpos 3
:delim
(delim
:name "delimquote"
:starttext "\""
:endtext "\"")
:children
(textblocklist
(textblock
:text "a"
:startpos 2
:endpos 2)))))))))
:doc "Returns a textblock when a delim is not found.")
(func textblock-findparent<-textblock : textblock
[textblockarg : textblock]
(let : textblock
[delimcurr : delim := (:delim textblockarg)
parent : textblock := (:parent textblockarg)
children : textblocklist := (:children textblockarg)
starttext : string := (:starttext delimcurr)
endtext : string := (:endtext delimcurr)]
(if : textblock
(then // empty
(is-empty textblockarg) (empty textblock))
(then // allows children
(or
(is-empty parent)
(and
(!= "" starttext)
(!= "" endtext)))
textblockarg)
(else // recursion
(textblock-findparent<-textblock
parent))))
:doc "Find a parent that accepts a child.")
(func textblock-init : textblock
[textblockarg : textblock]
(let : textblock
[text : string := (:text textblockarg)
startpos : int := (if : int
(= "" text)
0
1)
endpos : int := (if : int
(= "" text)
0
(length text))]
(copy textblockarg
:startpos startpos
:endpos endpos
:parent
(copy textblockarg
:startpos startpos
:endpos endpos
:delim (empty delim))))
:test (test
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim delimtest1
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
(textblock-init
(textblock
:text "<{a,b},{c d}>"
:delim delimtest1)))
:doc "Returns a textblock ready for parsing.")
(func textblock-parse : textblock
[textblock : textblock]
(collection/any<-for-until-loop-max : textblock
textblock
(fn : boolean
[current : textblock]
(is-empty
(:parent current)))
(fn : textblock
[current : textblock]
(textblock-parse-one
current))
100000)
:bigospace :n^n
:bigotime :n^n
:test (test
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))
(textblock-parse
(textblock
:text "<{a,b},{c d}>"
:delim delimtest1)))
:doc "Returns a fully parsed textblock from an initialized textblock.")
(func textblock-parse<-string-delim : textblock
[text : string
delim : delim]
(let : textblock
[textblockinit : textblock := (textblock<-string-delim
text delim)]
(textblock-parse textblockinit))
:doc "Returns a fully parsed textblock from a string and delim.")
(func textblock-parse-one : textblock
[textblockarg : textblock]
(let : textblock
[delimarg : delim := (:delim textblockarg)
close : delim := (:close textblockarg)
startpos : int := (:startpos textblockarg)
textarg : string := (:text textblockarg)
parent : textblock := (:parent textblockarg)
is-init : boolean :=
(and
(is-empty parent)
(= startpos 0))
starttext : string := (:starttext delimarg)
endtext : string := (:endtext delimarg)
delimlistarg : delimlist := (:delimlist delimarg)
startposchg : int :=
(if : int
(then
(= "" textarg)
startpos)
(then
(= 0 startpos)
1)
(else startpos))
delimlistcl : delimlist :=
(if : delimlist
(is-empty close)
delimlistarg
(copy
delimlistarg
close))
delimfirst : delim :=
(delim-first<-string-delimlist
textarg
delimlistcl)]
(if : textblock
(then // init
is-init
(textblock-init
textblockarg))
(then // empty parent
(is-empty parent)
textblockarg)
(then // no delim found
(is-empty delimfirst)
(textblock-delimnotfound
textblockarg))
(then // close delim
(is-close delimfirst)
(textblock<-close-textblock
delimfirst
textblockarg))
(then // single delim
(is-single delimfirst)
(textblock<-single-textblock
delimfirst
textblockarg))
(else // open delim
(textblock<-open-textblock
delimfirst
textblockarg))))
:test (test
(textblock
:text "<a"
:startpos 1
:endpos 2
:children
(textblocklist
(textblock
:text "<a"
:startpos 1
:endpos 2
:delim
(copy delimbracketangle
:delimlist vx/data/textblock/delimlisttest1)
:children
(textblocklist
(textblock
:text "a"
:startpos 2
:endpos 2))
(msg
:code "closedelimmissing"
:detail
(delim
:name "delimclose"
:starttext ">")
:severity msg-error))))
(textblock-parse-one
(textblock
:text "a"
:startpos 2
:endpos 2
:delim
(delim
:delimlist vx/data/textblock/delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<a"
:startpos 1
:endpos 2
:delim
(copy delimbracketangle
:delimlist vx/data/textblock/delimlisttest1)
:parent
(textblock
:text "<a"
:startpos 1
:endpos 2)))))
(test
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim delimtest1
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
(textblock-parse-one
(textblock
:text "<{a,b},{c d}>"
:delim delimtest1)))
(test
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)))
(textblock-parse-one
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim delimtest1
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))
(test
(textblock
:text "a,b},{c d}>"
:startpos 3
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))
(textblock-parse-one
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)))))
(test
(textblock
:text "a"
:startpos 3
:endpos 3
:parent
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))
(textblock-parse-one
(textblock
:text "a,b},{c d}>"
:startpos 3
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))
(test
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)))))
(textblock-parse-one
(textblock
:text "a"
:startpos 3
:endpos 3
:parent
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))))))))
(test
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)))))
(textblock-parse-one
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)))))))
(test
(textblock
:text "b"
:startpos 5
:endpos 5
:parent
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))))))
(textblock-parse-one
(textblock
:text "b},{c d}>"
:startpos 5
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{a,b},{c d}>"
:startpos 2
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0)))))))
(test
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))
(textblock-parse-one
(textblock
:text "b"
:startpos 5
:endpos 5
:parent
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13))
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))))))))
(test
(textblock
:startpos 7
:endpos 7
:parent
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))))
(textblock-parse-one
(textblock
:text ",{c d}>"
:startpos 7
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))))
(test
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))))))
(textblock-parse-one
(textblock
:startpos 7
:endpos 7
:parent
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5))))))))))
(test
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)))))
(textblock-parse-one
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))))))))
(test
(textblock
:text "c d}>"
:startpos 9
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))
(textblock-parse-one
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0)))))))
(test
(textblock
:text "c"
:startpos 9
:endpos 9
:parent
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)
:parent
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))))
(textblock-parse-one
(textblock
:text "c d}>"
:startpos 9
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))))
(test
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)
:parent
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)))))
(textblock-parse-one
(textblock
:text "c"
:startpos 9
:endpos 9
:parent
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)
:parent
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))))))))
(test
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(delim
:name "delimbracketangle"
:starttext "<"
:endtext ">"
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)))))
(textblock-parse-one
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)
:parent
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)))))))
(test
(textblock
:text "d"
:startpos 11
:endpos 11
:parent
(textblock
:text ">"
:startpos 13
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))))))
(textblock-parse-one
(textblock
:text "d}>"
:startpos 11
:endpos 13
:delim
(delim
:delimlist delimlisttest3)
:close
(copy delimclose
:starttext "}")
:parent
(textblock
:text "{c d}>"
:startpos 8
:endpos 13
:delim
(copy delimbracketcurly
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(delim
:name "delimbracketangle"
:starttext "<"
:endtext ">"
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0)))))))
(test
(textblock
:text ">"
:startpos 13
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))
(textblock-parse-one
(textblock
:text "d"
:startpos 11
:endpos 11
:parent
(textblock
:text ">"
:startpos 13
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))))
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))))))))
(test
(textblock
:startpos 13
:endpos 13
:parent
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))
(textblock-parse-one
(textblock
:text ">"
:startpos 13
:endpos 13
:delim
(delim
:delimlist delimlisttest2)
:close
(copy delimclose
:starttext ">")
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))))
(test
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))))
(textblock-parse-one
(textblock
:startpos 13
:endpos 13
:parent
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:close delimclosing
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))))
(test
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))
(textblock-parse-one
(textblock
:startpos 14
:endpos 14
:delim
(delim
:delimlist delimlisttest1)
:parent
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11))))))))))
(test
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))
(textblock-parse-one
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:children
(textblocklist
(textblock
:text "<{a,b},{c d}>"
:startpos 1
:endpos 13
:delim
(copy delimbracketangle
:pos 0)
:children
(textblocklist
(textblock
:text "{a,b}"
:startpos 2
:endpos 6
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "a"
:startpos 3
:endpos 3)
(textblock
:text ","
:startpos 4
:endpos 4
:delim
(copy delimcomma
:pos 0))
(textblock
:text "b"
:startpos 5
:endpos 5)))
(textblock
:text ","
:startpos 7
:endpos 7
:delim
(copy delimcomma
:pos 0))
(textblock
:text "{c d}"
:startpos 8
:endpos 12
:delim
(copy delimbracketcurly
:pos 0)
:children
(textblocklist
(textblock
:text "c"
:startpos 9
:endpos 9)
(textblock
:text " "
:startpos 10
:endpos 10
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "d"
:startpos 11
:endpos 11)))))))))
:doc "Returns a textblock that has been parse a single level.")
(func textblock-replace<-textblock-find-replace : textblock
[textblockarg : textblock
find : textblock
replace : textblock]
(if : textblock
(then // empty
(is-empty textblockarg)
(empty textblock))
(then // found
(and (== find textblockarg))
replace)
(else // recursion
(copy textblockarg
:parent
(textblock-replace<-textblock-find-replace
(:parent textblockarg)
find
replace))))
:doc "Replace the given parent textblock.")
(func textblock-startleft<-string-delim-offset : textblock
[text : string
delim : delim
offset : int]
(let
[pos : int := (:pos delim)
start : int := 1
end : int := (- pos 1)]
(if
(then
(= "" text)
(empty textblock))
(then
(= 0 pos)
(empty textblock))
(else
(textblock
:text
(string<-string-start-end
text start end)
:startpos (+ offset start)
:endpos (+ offset end)
:curpos 0))))
:test (test
(textblock
:text "a"
:startpos 1
:endpos 1)
(textblock-startleft<-string-delim-offset
"a,b"
(delim
:pos 2)
0))
:doc "Returns a textblock constructed from the text before the current delimiter start.")
(func textblock-startright<-string-delim-offset : textblock
[text : string
delimin : delim
offset : int]
(let
[startpos : int := (:pos delimin)
starttext : string := (:starttext delimin)
endtext : string := (:endtext delimin)
delimlist : delimlist := (:delimlist delimin)
close : delim := (if : delim
(then (= endtext "") (empty delim))
(else
(copy delimclose
:starttext endtext)))
delimlen : int := (switch : int
starttext
(case :nonwhitespace 0)
(case :whitespace 0)
(else (length starttext)))
curpos : int := 0]
(if
(then (= text "") (empty textblock))
(then (< startpos 0) (empty textblock))
(else
(textblock
:text
(string<-string-start text startpos)
:startpos
(+ offset startpos)
:curpos curpos
:delim delimin
:close close))))
:test (test
(textblock
:text ",b"
:startpos 2
:delim
(copy delimcomma
:pos 2))
(textblock-startright<-string-delim-offset
"a,b"
(copy delimcomma
:pos 2)
0))
(test
(textblock
:text "<b>c"
:startpos 2
:delim
(copy delimbracketangle
:pos 2
:delimlist
(delimlist
delimbracketcurly))
:close
(copy delimclose
:starttext ">"))
(textblock-startright<-string-delim-offset
"a<b>c"
(copy delimbracketangle
:pos 2
:delimlist
(delimlist
delimbracketcurly))
0))
:doc "Returns a textblock constructed from the text after the current delimiter start.")
(func textblocklist<-textblocklist-remove : textblocklist
[tblist : textblocklist
remove : delim]
(list<-list-filter : textblocklist
tblist
(fn : textblock
[textblock : textblock]
(let : textblock
[delimcurr : delim := (:delim textblock)
namecurr : string := (:name delimcurr)
nameremove : string := (:name remove)]
(if
(!= namecurr nameremove)
textblock))))
:test (test
(textblocklist
(textblock
:text "+")
(textblock
:text "2")
(textblock
:text "3"))
(textblocklist<-textblocklist-remove
(textblocklist
(textblock
:text "+")
(textblock
:text " "
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "2")
(textblock
:text " "
:delim
(copy delimwhitespace
:pos 0))
(textblock
:text "3"))
delimwhitespace))
:doc "Return a textblocklist with all removedelims removed.")