diff options
author | bptato <nincsnevem662@gmail.com> | 2021-11-15 19:28:46 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-11-15 19:36:15 +0100 |
commit | dc70358d994894ba707e0fb42660036eba603d38 (patch) | |
tree | 96122416a2748ed88240bc500e2633be734e5224 | |
parent | f802b92f0071700e3aacf560d2a90fb47b3baf6b (diff) | |
download | chawan-dc70358d994894ba707e0fb42660036eba603d38.tar.gz |
Fix some whitespace bugs
-rw-r--r-- | src/html/parser.nim | 18 | ||||
-rw-r--r-- | src/io/buffer.nim | 31 | ||||
-rw-r--r-- | src/layout/box.nim | 1 | ||||
-rw-r--r-- | src/layout/engine.nim | 53 |
4 files changed, 53 insertions, 50 deletions
diff --git a/src/html/parser.nim b/src/html/parser.nim index 68295dbe..3f1ca218 100644 --- a/src/html/parser.nim +++ b/src/html/parser.nim @@ -18,6 +18,7 @@ type in_style: bool in_noscript: bool in_body: bool + skip_lf: bool elementNode: Element textNode: Text commentNode: Comment @@ -208,15 +209,6 @@ proc processDocumentAddNode(state: var HTMLParseState, newNode: Node) = else: state.elementNode = state.elementNode.ownerDocument.head - #> If the next token is a U+000A LINE FEED (LF) character token, then ignore - #> that token and move on to the next one. (Newlines at the start of pre - #> blocks are ignored as an authoring convenience.) - elif state.elementNode.tagType == TAG_PRE: - if state.elementNode.childNodes.len == 1 and - state.elementNode.childNodes[0].nodeType == TEXT_NODE and - Text(state.elementNode.childNodes[0]).data == "\n": - discard state.elementNode.childNodes.pop() - insertNode(state.elementNode, newNode) proc processDocumentEndNode(state: var HTMLParseState) = @@ -267,6 +259,8 @@ proc processDocumentStartElement(state: var HTMLParseState, element: Element, ta state.elementNode = state.elementNode.ownerDocument.head of TAG_BODY: add = false + of TAG_PRE: + state.skip_lf = true else: discard if not state.in_body and not (element.tagType in HeadTagTypes): @@ -420,8 +414,10 @@ proc processDocumentPart(state: var HTMLParseState, buf: string) = if state.in_comment: state.commentNode.data &= $r else: - processDocumentText(state) - state.textNode.data &= $r + if not (state.skip_lf and r == Rune('\n')): + processDocumentText(state) + state.textNode.data &= $r + state.skip_lf = false proc parseHtml*(inputStream: Stream): Document = let document = newDocument() diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 05581551..0f83fe99 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -204,14 +204,11 @@ proc clearBuffer*(buffer: Buffer) = buffer.hovertext = "" proc clearDisplay*(buffer: Buffer) = - var i = 0 - while i < buffer.display.len: - buffer.display[i].runes.setLen(0) - inc i + buffer.prevdisplay = buffer.display + buffer.display = newFixedGrid(buffer.width, buffer.height) proc refreshDisplay*(buffer: Buffer) = var y = 0 - buffer.prevdisplay = buffer.display buffer.clearDisplay() for line in buffer.lines[buffer.fromy.. @@ -231,7 +228,7 @@ proc refreshDisplay*(buffer: Buffer) = inc n buffer.display[dls + j - n].runes.add(line[i].rune) buffer.display[dls + j - n].formatting = line[i].formatting - buffer.display[dls + j - n].nodes.add(line[i].nodes) + buffer.display[dls + j - n].nodes = line[i].nodes j += line[i].rune.width() inc i @@ -610,7 +607,8 @@ proc updateCursor(buffer: Buffer) = buffer.cursory = buffer.lastVisibleLine - 1 if buffer.cursorx >= buffer.currentLineWidth() - 1: - buffer.cursorLineEnd() + buffer.cursorx = max(buffer.currentLineWidth() - 1, 0) + buffer.fromx = max(buffer.cursorx - buffer.width + 1, 0) if buffer.lines.len == 0: buffer.cursory = 0 @@ -620,7 +618,7 @@ proc updateCursor(buffer: Buffer) = # practically means we're re-interpreting all style-sheets AND re-applying all # rules way too often #* reshape also calls redraw so the entire window gets re-painted too which -# looks pretty bad +# looks pretty bad (tick) #* and finally it re-arranges all CSS boxes too, which is a rather # resource-intensive operation #overall the second point is the easiest to solve, then the first and finally @@ -696,7 +694,6 @@ proc renderDocument*(buffer: Buffer) = buffer.updateCursor() proc reshapeBuffer*(buffer: Buffer) = - buffer.display = newFixedGrid(buffer.width, buffer.height) #TODO #buffer.statusmsg = newFixedGrid(buffer.width) if buffer.showsource: @@ -710,10 +707,7 @@ proc cursorBufferPos(buffer: Buffer) = termGoto(x, y) proc clearStatusMessage(buffer: Buffer) = - var i = 0 - while i < buffer.statusmsg.len: - buffer.statusmsg[i].runes.setLen(0) - inc i + buffer.statusmsg = newFixedGrid(buffer.width) proc setStatusMessage*(buffer: Buffer, str: string) = buffer.clearStatusMessage() @@ -748,6 +742,7 @@ proc displayBuffer(buffer: Buffer) = proc displayStatusMessage(buffer: Buffer) = termGoto(0, buffer.height) + print(SGR()) print(buffer.generateStatusMessage()) print(EL()) @@ -827,19 +822,25 @@ proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool = buffer.redraw = true else: discard stdout.hideCursor() - buffer.updateHover() if buffer.refreshTermAttrs(): buffer.redraw = true buffer.reshape = true + if buffer.redraw: + buffer.refreshDisplay() + buffer.displayBuffer() + buffer.redraw = false + + #TODO + buffer.updateHover() if buffer.reshape: buffer.reshapeBuffer() buffer.reshape = false buffer.redraw = true #? if buffer.redraw: buffer.refreshDisplay() - buffer.displayBuffer() + buffer.displayBufferSwapOutput() buffer.redraw = false if not nostatus: diff --git a/src/layout/box.nim b/src/layout/box.nim index 271fbd10..bee93363 100644 --- a/src/layout/box.nim +++ b/src/layout/box.nim @@ -30,6 +30,7 @@ type marginy*: int conty*: bool whitespace*: bool + ws_initial*: bool InlineContext* = object cssvalues*: CSSComputedValues diff --git a/src/layout/engine.nim b/src/layout/engine.nim index 52069b6f..7d279b87 100644 --- a/src/layout/engine.nim +++ b/src/layout/engine.nim @@ -10,6 +10,7 @@ func newContext*(box: CSSBox): Context = new(result) result.fromx = box.x result.whitespace = true + result.ws_initial = true func newBlockBox*(parent: CSSBox, vals: CSSComputedValues): CSSBlockBox = new(result) @@ -17,19 +18,18 @@ func newBlockBox*(parent: CSSBox, vals: CSSComputedValues): CSSBlockBox = result.x = parent.x if parent.context.conty: inc parent.height - #eprint "inc n" + #eprint "CONTY N" inc parent.context.fromy parent.context.conty = false result.y = parent.context.fromy let mtop = vals[PROPERTY_MARGIN_TOP].length.cells() if mtop > parent.bcontext.marginy: result.y += mtop - parent.bcontext.marginy - #eprint "my", mtop, parent.bcontext.marginy parent.bcontext.marginy = mtop + #eprint "M-TOP", mtop - parent.bcontext.marginy result.width = parent.width result.context = newContext(parent) - #eprint "inc to", result.y result.context.fromy = result.y result.cssvalues = vals @@ -59,7 +59,8 @@ proc inlineWrap(ibox: var CSSInlineBox, rowi: var int, fromx: var int, rowbox: v inc rowi fromx = ibox.x ibox.context.whitespace = true - ibox.context.conty = true + ibox.context.ws_initial = true + ibox.context.conty = false rowbox = CSSRowBox(x: ibox.x, y: ibox.y + rowi) rowbox.setup(ibox.cssvalues, ibox.bcontext.nodes) @@ -87,25 +88,29 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox = if rowbox.width + r.width() > ibox.width: inlineWrap(ibox, rowi, fromx, rowbox) if r.isWhitespace(): + let wsr = ibox.cssvalues[PROPERTY_WHITESPACE].whitespace if ibox.context.whitespace: - continue - else: - let wsr = ibox.cssvalues[PROPERTY_WHITESPACE].whitespace - - case wsr - of WHITESPACE_NORMAL, WHITESPACE_NOWRAP: - r = Rune(' ') - of WHITESPACE_PRE, WHITESPACE_PRE_LINE, WHITESPACE_PRE_WRAP: - if r == Rune('\n'): - inlineWrap(ibox, rowi, fromx, rowbox) - ibox.context.whitespace = false + if ibox.context.ws_initial: + ibox.context.ws_initial = false + if not (wsr in {WHITESPACE_PRE, WHITESPACE_PRE_LINE, WHITESPACE_PRE_WRAP}): continue - - case wsr - of WHITESPACE_NORMAL, WHITESPACE_NOWRAP, WHITESPACE_PRE_LINE: - ibox.context.whitespace = true else: + continue + case wsr + of WHITESPACE_NORMAL, WHITESPACE_NOWRAP: + r = Rune(' ') + of WHITESPACE_PRE, WHITESPACE_PRE_LINE, WHITESPACE_PRE_WRAP: + if r == Rune('\n'): + inlineWrap(ibox, rowi, fromx, rowbox) ibox.context.whitespace = false + ibox.context.ws_initial = true + continue + r = Rune(' ') + case wsr + of WHITESPACE_NORMAL, WHITESPACE_NOWRAP, WHITESPACE_PRE_LINE: + ibox.context.whitespace = true + else: + ibox.context.whitespace = false else: ibox.context.whitespace = false rowbox.width += r.width() @@ -127,7 +132,7 @@ proc processInlineBox(parent: CSSBox, str: string): CSSBox = proc processElemBox(parent: CSSBox, elem: Element): CSSBox = case elem.cssvalues[PROPERTY_DISPLAY].display of DISPLAY_BLOCK: - #eprint "START", elem.tagType + #eprint "START", elem.tagType, parent.context.fromy result = newBlockBox(parent, elem.cssvalues) CSSBlockBox(result).tag = $elem.tagType of DISPLAY_INLINE: @@ -143,18 +148,18 @@ proc add(parent: var CSSBox, box: CSSBox) = if box of CSSBlockBox: parent.context.fromx = 0 parent.context.whitespace = true + parent.context.ws_initial = true if box.context.conty: + #eprint "CONTY A" inc box.height - #eprint "inc a" inc box.context.fromy box.context.conty = false let mbot = box.cssvalues[PROPERTY_MARGIN_BOTTOM].length.cells() - #eprint "inc b", mbot box.context.fromy += mbot box.bcontext.marginy = mbot - #eprint "END", CSSBlockBox(box).tag + #eprint "M-BOT", mbot + #eprint "END", CSSBlockBox(box).tag, box.context.fromy parent.height += box.height - #eprint "parent to", box.context.fromy parent.context.fromy = box.context.fromy parent.children.add(box) |