diff options
author | bptato <nincsnevem662@gmail.com> | 2021-11-13 09:51:06 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2021-11-13 09:51:17 +0100 |
commit | c141a3cea17f32f526853cd4085ae4cc80c4fed6 (patch) | |
tree | 248f7d55aefcd7b1c32891f60dffc193df6e51a8 | |
parent | 2e408503f452f0cac8ca2a63eaf59e0bfb332f1d (diff) | |
download | chawan-c141a3cea17f32f526853cd4085ae4cc80c4fed6.tar.gz |
Refactor output formatting code, drop non-ansi support
-rw-r--r-- | src/html/dom.nim | 3 | ||||
-rw-r--r-- | src/io/buffer.nim | 229 | ||||
-rw-r--r-- | src/io/cell.nim | 92 | ||||
-rw-r--r-- | src/types/enums.nim | 3 | ||||
-rw-r--r-- | src/utils/twtstr.nim | 19 |
5 files changed, 164 insertions, 182 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim index ffa0b7c3..96e58ada 100644 --- a/src/html/dom.nim +++ b/src/html/dom.nim @@ -487,9 +487,6 @@ proc applyAuthorRules*(document: Document): seq[tuple[e:Element,d:CSSDeclaration result.add((elem, decl, pseudo)) else: elem.applyProperty(decl, pseudo) - if elem.id == "wrong": - eprint "wrong", elem.cssvalues - eprint decl var i = elem.children.len - 1 while i >= 0: diff --git a/src/io/buffer.nim b/src/io/buffer.nim index 30bea7ad..a0d7839f 100644 --- a/src/io/buffer.nim +++ b/src/io/buffer.nim @@ -16,22 +16,6 @@ import io/lineedit import io/cell type - DrawInstruction = object - case t: DrawInstructionType - of DRAW_TEXT: - text: seq[Rune] - of DRAW_GOTO: - x: int - y: int - of DRAW_FGCOLOR, DRAW_BGCOLOR: - color: CellColor - of DRAW_STYLE: - bold: bool - italic: bool - underline: bool - of DRAW_RESET: - discard - Buffer* = ref BufferObj BufferObj = object title*: string @@ -79,42 +63,7 @@ func generateFullOutput*(buffer: Buffer): seq[string] = x = 0 s = "" - if formatting.bold and not cell.formatting.bold or - formatting.italic and not cell.formatting.italic or - formatting.underline and not cell.formatting.underline or - formatting.strike and not cell.formatting.strike or - formatting.overline and not cell.formatting.overline: - s &= "\e[m" - formatting = newFormatting() - - if cell.formatting.fgcolor != formatting.fgcolor and cell.formatting.fgcolor != defaultColor: - var color = cell.formatting.fgcolor - if color.rgb: - let rgb = color.rgbcolor - s &= "\e[38;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m" - else: - s &= "\e[" & $color.color & "m" - - if cell.formatting.bgcolor != formatting.bgcolor and cell.formatting.bgcolor != defaultColor: - var color = cell.formatting.bgcolor - if color.rgb: - let rgb = color.rgbcolor - s &= "\e[48;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m" - else: - s &= "\e[" & $color.color & "m" - - if not formatting.bold and cell.formatting.bold: - s &= "\e[1m" - if not formatting.italic and cell.formatting.italic: - s &= "\e[3m" - if not formatting.underline and cell.formatting.underline: - s &= "\e[4m" - if not formatting.strike and cell.formatting.strike: - s &= "\e[9m" - if not formatting.overline and cell.formatting.overline: - s &= "\e[53m" - - formatting = cell.formatting + s &= formatting.processFormatting(cell.formatting) s &= $cell.runes inc x @@ -122,86 +71,54 @@ func generateFullOutput*(buffer: Buffer): seq[string] = result.add(s) # generate a sequence of instructions to replace the previous frame with the -# current one. ideally we should have some mechanism in place to determine -# where we should use this and where we should just rewrite the frame, though -# now that I think about it rewriting every frame might be a better option -#func generateSwapOutput*(buffer: Buffer): seq[DrawInstruction] = -# var fgcolor: CellColor -# var bgcolor: CellColor -# var italic = false -# var bold = false -# var underline = false -# -# let max = buffer.width * buffer.height -# let curr = buffer.display -# let prev = buffer.prevdisplay -# var x = 0 -# var y = 0 -# var cx = 0 -# var cy = 0 -# var i = 0 -# var text: seq[Rune] -# while i < max: -# if x >= buffer.width: -# x = 0 -# cx = 0 -# text &= Rune('\n') -# inc y -# inc cy -# -# if curr[i] != prev[i]: -# let currwidth = curr[i].runes.width() -# let prevwidth = prev[i].runes.width() -# if (curr[i].runes.len > 0 or currwidth < prevwidth) and (x != cx or y != cy): -# if text.len > 0: -# result.add(DrawInstruction(t: DRAW_TEXT, text: text)) -# text.setLen(0) -# result.add(DrawInstruction(t: DRAW_GOTO, x: x, y: y)) -# cx = x -# cy = y -# -# let cancont = -# (curr[i].fgcolor == fgcolor and curr[i].bgcolor == bgcolor and -# curr[i].italic == italic and curr[i].bold == bold and curr[i].underline == underline) -# -# if text.len > 0 and not cancont: -# result.add(DrawInstruction(t: DRAW_TEXT, text: text)) -# text.setLen(0) -# -# if curr[i].fgcolor != fgcolor: -# fgcolor = curr[i].fgcolor -# result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor)) -# -# if curr[i].bgcolor != bgcolor: -# bgcolor = curr[i].bgcolor -# result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor)) -# -# if curr[i].italic != italic or curr[i].bold != bold or curr[i].underline != underline: -# if italic and not curr[i].italic or bold and not curr[i].bold or underline and not curr[i].underline: -# result.add(DrawInstruction(t: DRAW_RESET)) -# if fgcolor != defaultColor: -# result.add(DrawInstruction(t: DRAW_FGCOLOR, color: fgcolor)) -# if bgcolor != defaultColor: -# result.add(DrawInstruction(t: DRAW_BGCOLOR, color: bgcolor)) -# italic = curr[i].italic -# bold = curr[i].bold -# underline = curr[i].underline -# result.add(DrawInstruction(t: DRAW_STYLE, italic: italic, bold: bold, underline: underline)) -# -# text &= curr[i].runes -# if currwidth < prevwidth: -# var j = 0 -# while j < prevwidth - currwidth: -# text &= Rune(' ') -# inc j -# if text.len > 0: -# inc cx -# -# inc x -# inc i -# -# if text.len > 0: -# result.add(DrawInstruction(t: DRAW_TEXT, text: text)) +# current one. ideally should be used when small changes are made (e.g. hover +# changes underlining) +func generateSwapOutput*(buffer: Buffer): string = + var formatting = newFormatting() + + let max = buffer.width * buffer.height + let curr = buffer.display + let prev = buffer.prevdisplay + var x = 0 + var y = 0 + var cx = 0 + var cy = 0 + var i = 0 + var text = "" + while i < max: + if x >= buffer.width: + x = 0 + cx = 0 + text &= '\n' + inc y + inc cy + + if curr[i] != prev[i]: + let currwidth = curr[i].runes.width() + let prevwidth = prev[i].runes.width() + if (curr[i].runes.len > 0 or currwidth < prevwidth) and (x != cx or y != cy): + if text.len > 0: + result &= text + text = "" + result &= HVP(y + 1, x + 1) + cx = x + cy = y + + text &= formatting.processFormatting(curr[i].formatting) + + text &= $curr[i].runes + if currwidth < prevwidth: + var j = 0 + while j < prevwidth - currwidth: + text &= ' ' + inc j + if text.len > 0: + inc cx + + inc x + inc i + if text.len > 0: + result &= $text func generateStatusMessage*(buffer: Buffer): string = for cell in buffer.statusmsg: @@ -737,56 +654,16 @@ proc statusMsgForBuffer(buffer: Buffer) = msg &= " " & buffer.hovertext buffer.setStatusMessage(msg) -#proc displayBufferSwapOutput(buffer: Buffer) = -# termGoto(0, 0) -# let instructions = buffer.generateSwapOutput() -# for inst in instructions: -# case inst.t -# of DRAW_TEXT: -# print(inst.text) -# of DRAW_GOTO: -# termGoto(inst.x, inst.y) -# of DRAW_FGCOLOR: -# let color = inst.color -# if inst.color.rgb: -# let rgb = color.rgbcolor -# print("\e[38;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m") -# else: -# print("\e[" & $color.color & "m") -# of DRAW_BGCOLOR: -# let color = inst.color -# if inst.color.rgb: -# let rgb = color.rgbcolor -# print("\e[48;2;" & $rgb.r & ";" & $rgb.g & ";" & $rgb.b & "m") -# else: -# print("\e[" & $color.color & "m") -# of DRAW_STYLE: -# var os = "\e[" -# var p = false -# if inst.italic: -# os &= "3" -# p = true -# if inst.bold: -# if p: -# os &= ";" -# os &= "1" -# p = true -# if inst.underline: -# if p: -# os &= ";" -# os &= "4" -# p = true -# os &= "m" -# print(os) -# of DRAW_RESET: -# print("\e[0m") +proc displayBufferSwapOutput(buffer: Buffer) = + termGoto(0, 0) + print(buffer.generateSwapOutput()) proc displayBuffer(buffer: Buffer) = termGoto(0, 0) let full = buffer.generateFullOutput() for line in full: print(line) - print("\e[K") + print(EL()) print('\n') proc displayStatusMessage(buffer: Buffer) = diff --git a/src/io/cell.nim b/src/io/cell.nim index 983c5b4d..133b88d6 100644 --- a/src/io/cell.nim +++ b/src/io/cell.nim @@ -49,3 +49,95 @@ func width*(line: FlexibleLine): int = func newFormatting*(): Formatting = return Formatting(fgcolor: defaultColor, bgcolor: defaultColor) + +proc processFormatting*(formatting: var Formatting, cellf: Formatting): string = + if formatting.bold and not cellf.bold: + result &= SGR(22) + if formatting.italic and not cellf.italic: + result &= SGR(23) + if formatting.underline and not cellf.underline: + result &= SGR(24) + if formatting.strike and not cellf.strike: + result &= SGR(29) + if formatting.overline and not cellf.overline: + result &= SGR(55) + + if cellf.fgcolor != formatting.fgcolor: + var color = cellf.fgcolor + if color.rgb: + let rgb = color.rgbcolor + result &= SGR(38, 2, rgb.r, rgb.g, rgb.b) + elif color == defaultColor: + result &= SGR() + formatting = newFormatting() + else: + result &= SGR(color.color) + + if cellf.bgcolor != formatting.bgcolor: + var color = cellf.bgcolor + if color.rgb: + let rgb = color.rgbcolor + result &= SGR(48, 2, rgb.r, rgb.g, rgb.b) + elif color == defaultColor: + result &= SGR() + formatting = newFormatting() + else: + result &= SGR(color.color) + + if not formatting.bold and cellf.bold: + result &= SGR(1) + if not formatting.italic and cellf.italic: + result &= SGR(3) + if not formatting.underline and cellf.underline: + result &= SGR(4) + if not formatting.strike and cellf.strike: + result &= SGR(9) + if not formatting.overline and cellf.overline: + result &= SGR(53) + + formatting = cellf + if formatting.bold and not cellf.bold: + result &= SGR(22) + if formatting.italic and not cellf.italic: + result &= SGR(23) + if formatting.underline and not cellf.underline: + result &= SGR(24) + if formatting.strike and not cellf.strike: + result &= SGR(29) + if formatting.overline and not cellf.overline: + result &= SGR(55) + + if cellf.fgcolor != formatting.fgcolor: + var color = cellf.fgcolor + if color.rgb: + let rgb = color.rgbcolor + result &= SGR(38, 2, rgb.r, rgb.g, rgb.b) + elif color == defaultColor: + result &= SGR() + formatting = newFormatting() + else: + result &= SGR(color.color) + + if cellf.bgcolor != formatting.bgcolor: + var color = cellf.bgcolor + if color.rgb: + let rgb = color.rgbcolor + result &= SGR(48, 2, rgb.r, rgb.g, rgb.b) + elif color == defaultColor: + result &= SGR() + formatting = newFormatting() + else: + result &= SGR(color.color) + + if not formatting.bold and cellf.bold: + result &= SGR(1) + if not formatting.italic and cellf.italic: + result &= SGR(3) + if not formatting.underline and cellf.underline: + result &= SGR(4) + if not formatting.strike and cellf.strike: + result &= SGR(9) + if not formatting.overline and cellf.overline: + result &= SGR(53) + + formatting = cellf diff --git a/src/types/enums.nim b/src/types/enums.nim index db7a87e7..d0c34b6e 100644 --- a/src/types/enums.nim +++ b/src/types/enums.nim @@ -88,8 +88,5 @@ type VALUE_NONE, VALUE_LENGTH, VALUE_COLOR, VALUE_CONTENT, VALUE_DISPLAY, VALUE_FONT_STYLE, VALUE_WHITE_SPACE, VALUE_INTEGER, VALUE_TEXT_DECORATION - DrawInstructionType* = enum - DRAW_TEXT, DRAW_GOTO, DRAW_FGCOLOR, DRAW_BGCOLOR, DRAW_STYLE, DRAW_RESET - FormatContextType* = enum CONTEXT_BLOCK, CONTEXT_INLINE diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim index 9cf63d68..db5a1293 100644 --- a/src/utils/twtstr.nim +++ b/src/utils/twtstr.nim @@ -190,6 +190,25 @@ func skipBlanks*(buf: string, at: int): int = while result < buf.len and buf[result].isWhitespace(): inc result +template ESC*(s: varargs[string, `$`]): string = + var r = "\e[" + var first = true + for x in s: + if not first: + r &= ";" + first = false + r &= x + r + +template SGR*(s: varargs[string, `$`]): string = + ESC(s) & "m" + +template HVP*(s: varargs[string, `$`]): string = + ESC(s) & "f" + +template EL*(s: varargs[string, `$`]): string = + ESC(s) & "K" + iterator split*(s: seq[Rune], sep: Rune): seq[Rune] = var i = 0 var prev = 0 |