block contexts

This commit is contained in:
Simon Martens
2026-02-20 13:39:34 +01:00
parent 1fa5f52eef
commit 8f5338c0b8
4 changed files with 69 additions and 60 deletions

View File

@@ -3,37 +3,36 @@ address
tabs tabs
BASE: BASE:
aq aq --- Sans-Serif
b // im Druck b --- bold
del del --- deletion, can be bascaded for double deletion del del
dul dul - double underline
tul tul - triple underline
er er - erased text
gr gr -- greek -- no style changes
hb hb -- hebrew -- no style changes
ink // wechsel der Tinte ref="2" ink // wechsel der Tinte ref="2" -- different color (bleu?)
it // im Druck it -- italic
pe pe -- different color (blue-grey)
ru ru -- russioan -- nos style changes
tl // Textverlust tl -- text loss
ul ul -- underline
note note -- smaller, bold and sans-serif in grey
fn[@index='1'] & anchor // keine ref? irgendwie nur die anchors in den footnotes? fn[@index='1'] & anchor // keine ref? irgendwie nur die anchors in den footnotes? -- no style change for now
INLINE-SONDERFÄLLE: INLINE-SONDERFÄLLE:
nr[@extent='1-4|8|30'] oder ohne default = 1 nr[@extent='1-4|8|30'] oder ohne default = 1 one mioddot before, one after. content = extent emount of spaces
subst (+kinder) = Überschreibungen subst (+kinder) = Überschreibungen -- subst no style for now
insertion insertion -- no style for now
del in subst hand no style for now
hand
INLINE-BLOCK: INLINE-BLOCK:
align center|right align pos= center|right align context fivides the line in 3: normal text right aligned center text center and left text left (can be inside the same line)
tab 2|12|8 tab value= 2|12|8 opens a tab context: value="1-2" means divide this context into two and place the content of this into the first compartment, value="4-8" means divide this context into 8 and place the content of this into the fourth compartment.
BLOCK: BLOCK:
letterText (wie line type="break" falls kein line) letterText (wie line type="break" falls kein line)
line (Fälle: empty, tab 1-2|4-8, break) line (Fälle: empty, tab 1-2|4-8, break) tab is number of indents
page[@index='1-14'] page[@index='1-14']
sidenote[@pos='left|right|(bottom|top [left|right])' and @page='1-14' and @annotation='[.*]' sidenote[@pos='left|right|(bottom|top [left|right])' and @page='1-14' and @annotation='[.*]'

View File

@@ -3,6 +3,7 @@ package xmlmodels
import ( import (
"encoding/xml" "encoding/xml"
"strconv" "strconv"
"strings"
) )
func isASCIISpaceByte(b byte) bool { func isASCIISpaceByte(b byte) bool {
@@ -41,14 +42,6 @@ func isOnlyASCIISpace(s string) bool {
return true return true
} }
func hasLeadingASCIISpace(s string) bool {
return len(s) > 0 && isASCIISpaceByte(s[0])
}
func hasTrailingASCIISpace(s string) bool {
return len(s) > 0 && isASCIISpaceByte(s[len(s)-1])
}
func attrsToMap(attrs []xml.Attr) map[string]string { func attrsToMap(attrs []xml.Attr) map[string]string {
if len(attrs) == 0 { if len(attrs) == 0 {
return nil return nil
@@ -60,21 +53,8 @@ func attrsToMap(attrs []xml.Attr) map[string]string {
return m return m
} }
func isInline(name string) bool { // INFO: list of tags ignored
switch name {
// BASE + note + specials + inline-block things treated as inline for stack correctness
case "aq", "b", "del", "dul", "tul", "er", "gr", "hb", "ink", "it", "pe", "ru", "tl", "ul",
"note",
"fn", "nr", "subst", "insertion", "hand",
"align", "tab":
return true
default:
return false
}
}
func isTransparentWrapper(name string) bool { func isTransparentWrapper(name string) bool {
// IMPORTANT: address subtree is NOT skipped; wrapper tokens are ignored only.
return name == "tabs" || name == "address" return name == "tabs" || name == "address"
} }
@@ -90,7 +70,7 @@ func parseLineMarker(se xml.StartElement) (LineType, int, bool) {
indent = n indent = n
} }
case "type": case "type":
typ = trimASCIISpace(a.Value) typ = strings.ToLower(trimASCIISpace(a.Value))
} }
} }
if typ == "empty" { if typ == "empty" {
@@ -99,8 +79,7 @@ func parseLineMarker(se xml.StartElement) (LineType, int, bool) {
if indent > 0 { if indent > 0 {
return Indent, indent, false return Indent, indent, false
} }
if typ == "break" {
return Semantic, 0, false // INFO: we don't check for break here, it's the default
} return Semantic, 0, false
return Continuation, 0, false
} }

View File

@@ -276,3 +276,11 @@ func linePairHasValidSyntheticCarry(prev, next Line) bool {
} }
return true return true
} }
func hasLeadingASCIISpace(s string) bool {
return len(s) > 0 && isASCIISpaceByte(s[0])
}
func hasTrailingASCIISpace(s string) bool {
return len(s) > 0 && isASCIISpaceByte(s[len(s)-1])
}

View File

@@ -34,10 +34,12 @@ type Token struct {
} }
type Line struct { type Line struct {
Type LineType Type LineType
Indent int Indent int
Text string AlignCtx bool
Tokens []Token TabCtx bool
Text string
Tokens []Token
} }
type Page struct { type Page struct {
@@ -90,8 +92,8 @@ func (a *lineAccumulator) ensureLine() {
return return
} }
a.startLine(a.implicitType, 0) a.startLine(a.implicitType, 0)
if a.implicitType == First { if a.implicitType == First || a.implicitType == Continuation {
a.implicitType = Continuation a.implicitType = Semantic
} }
} }
@@ -107,6 +109,7 @@ func (a *lineAccumulator) closeLine() {
Synth: true, Synth: true,
}) })
} }
a.applyContextFlags()
a.curLine.Text = lineTextFromTokens(a.curLine.Tokens) a.curLine.Text = lineTextFromTokens(a.curLine.Tokens)
a.appendLine(*a.curLine) a.appendLine(*a.curLine)
a.hasAnyLine = true a.hasAnyLine = true
@@ -121,11 +124,11 @@ func (a *lineAccumulator) handleLineMarker(se xml.StartElement) {
if emitEmpty { if emitEmpty {
a.startLine(Empty, 0) a.startLine(Empty, 0)
a.closeLine() a.closeLine()
a.implicitType = Continuation a.implicitType = Semantic
return return
} }
a.startLine(lt, indent) a.startLine(lt, indent)
a.implicitType = Continuation a.implicitType = Semantic
} }
func (a *lineAccumulator) appendStart(name string, attrs map[string]string) { func (a *lineAccumulator) appendStart(name string, attrs map[string]string) {
@@ -228,6 +231,26 @@ func lineTextFromTokens(tokens []Token) string {
return b.String() return b.String()
} }
func (a *lineAccumulator) applyContextFlags() {
if a.curLine == nil {
return
}
for _, tok := range a.curLine.Tokens {
if tok.Type != StartElement {
continue
}
switch tok.Name {
case "align":
a.curLine.AlignCtx = true
case "tab":
a.curLine.TabCtx = true
}
if a.curLine.AlignCtx && a.curLine.TabCtx {
return
}
}
}
func parseBlockLines(dec *xml.Decoder, endLocalName string) ([]Line, error) { func parseBlockLines(dec *xml.Decoder, endLocalName string) ([]Line, error) {
lines := make([]Line, 0, 8) lines := make([]Line, 0, 8)
acc := newLineAccumulator(First, func(line Line) { acc := newLineAccumulator(First, func(line Line) {