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,6 +3,7 @@ package xmlmodels
import (
"encoding/xml"
"strconv"
"strings"
)
func isASCIISpaceByte(b byte) bool {
@@ -41,14 +42,6 @@ func isOnlyASCIISpace(s string) bool {
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 {
if len(attrs) == 0 {
return nil
@@ -60,21 +53,8 @@ func attrsToMap(attrs []xml.Attr) map[string]string {
return m
}
func isInline(name string) bool {
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
}
}
// INFO: list of tags ignored
func isTransparentWrapper(name string) bool {
// IMPORTANT: address subtree is NOT skipped; wrapper tokens are ignored only.
return name == "tabs" || name == "address"
}
@@ -90,7 +70,7 @@ func parseLineMarker(se xml.StartElement) (LineType, int, bool) {
indent = n
}
case "type":
typ = trimASCIISpace(a.Value)
typ = strings.ToLower(trimASCIISpace(a.Value))
}
}
if typ == "empty" {
@@ -99,8 +79,7 @@ func parseLineMarker(se xml.StartElement) (LineType, int, bool) {
if indent > 0 {
return Indent, indent, false
}
if typ == "break" {
return Semantic, 0, false
}
return Continuation, 0, false
// INFO: we don't check for break here, it's the default
return Semantic, 0, false
}

View File

@@ -276,3 +276,11 @@ func linePairHasValidSyntheticCarry(prev, next Line) bool {
}
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 LineType
Indent int
Text string
Tokens []Token
Type LineType
Indent int
AlignCtx bool
TabCtx bool
Text string
Tokens []Token
}
type Page struct {
@@ -90,8 +92,8 @@ func (a *lineAccumulator) ensureLine() {
return
}
a.startLine(a.implicitType, 0)
if a.implicitType == First {
a.implicitType = Continuation
if a.implicitType == First || a.implicitType == Continuation {
a.implicitType = Semantic
}
}
@@ -107,6 +109,7 @@ func (a *lineAccumulator) closeLine() {
Synth: true,
})
}
a.applyContextFlags()
a.curLine.Text = lineTextFromTokens(a.curLine.Tokens)
a.appendLine(*a.curLine)
a.hasAnyLine = true
@@ -121,11 +124,11 @@ func (a *lineAccumulator) handleLineMarker(se xml.StartElement) {
if emitEmpty {
a.startLine(Empty, 0)
a.closeLine()
a.implicitType = Continuation
a.implicitType = Semantic
return
}
a.startLine(lt, indent)
a.implicitType = Continuation
a.implicitType = Semantic
}
func (a *lineAccumulator) appendStart(name string, attrs map[string]string) {
@@ -228,6 +231,26 @@ func lineTextFromTokens(tokens []Token) 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) {
lines := make([]Line, 0, 8)
acc := newLineAccumulator(First, func(line Line) {