From 391e24410ac394102c0e83907ee01b50e39c2403 Mon Sep 17 00:00:00 2001 From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com> Date: Sun, 12 Feb 2023 13:55:52 +0100 Subject: [PATCH] first work on container blocks --- src/nimib.nim | 14 ++++++++++++++ src/nimib/blocks.nim | 11 +++++++---- src/nimib/capture.nim | 12 +++++++++++- src/nimib/renders.nim | 9 +++++++++ src/nimib/types.nim | 4 +++- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/nimib.nim b/src/nimib.nim index 8b7af490..fff45464 100644 --- a/src/nimib.nim +++ b/src/nimib.nim @@ -52,6 +52,9 @@ template nbInit*(theme = themes.useDefault, backend = renders.useHtmlBackend, th nb.partials = initTable[string, string]() nb.context = newContext(searchDirs = @[]) # templateDirs and partials added during nbSave + nb.currentStdout = stdout.getFileHandle() + nb.originalStdout = dup(nb.currentStdout) + # apply render backend (default backend can be overriden by theme) backend nb @@ -68,6 +71,17 @@ template newNbSlimBlock*(cmd: string, blockImpl: untyped) = # a slim block is a block with no body newNbBlock(cmd, false, nb, nb.blk, "", blockImpl) +template nbUseCurrentBlockAsContainer*(body: untyped) = + let currentBlk = nb.blk + let currentBlocks = nb.blocks + nb.blocks = @[] + + body + + nb.blk = currentBlk + nb.blk.blocks = nb.blocks + nb.blocks = currentBlocks + # block templates template nbCode*(body: untyped) = newNbCodeBlock("nbCode", body): diff --git a/src/nimib/blocks.nim b/src/nimib/blocks.nim index 7ba56656..5f71028e 100644 --- a/src/nimib/blocks.nim +++ b/src/nimib/blocks.nim @@ -1,5 +1,5 @@ import std / [macros, strutils, sugar] -import types, sources +import types, sources, capture macro toStr*(body: untyped): string = (body.toStrLit) @@ -17,7 +17,8 @@ func nbNormalize*(text: string): string = # note that: '\c' == '\r' and '\l' == '\n' template newNbBlock*(cmd: string, readCode: static[bool], nbDoc, nbBlock, body, blockImpl: untyped) = - stdout.write "[nimib] ", nbDoc.blocks.len, " ", cmd, ": " + disableCaptureStdout: + stdout.write "[nimib] ", nbDoc.blocks.len, " ", cmd, ": " nbBlock = NbBlock(command: cmd, context: newContext(searchDirs = @[], partials = nbDoc.partials)) when readCode: nbBlock.code = nbNormalize: @@ -25,9 +26,11 @@ template newNbBlock*(cmd: string, readCode: static[bool], nbDoc, nbBlock, body, toStr(body) else: getCodeAsInSource(nbDoc.source, cmd, body) - echo peekFirstLineOf(nbBlock.code) + disableCaptureStdout: + echo peekFirstLineOf(nbBlock.code) blockImpl - if len(nbBlock.output) > 0: echo " -> ", peekFirstLineOf(nbBlock.output) + disableCaptureStdout: + if len(nbBlock.output) > 0: echo " -> ", peekFirstLineOf(nbBlock.output) nbBlock.context["code"] = nbBlock.code nbBlock.context["output"] = nbBlock.output.dup(removeSuffix) nbDoc.blocks.add nbBlock diff --git a/src/nimib/capture.nim b/src/nimib/capture.nim index f82a2978..54f1dbb9 100644 --- a/src/nimib/capture.nim +++ b/src/nimib/capture.nim @@ -5,9 +5,19 @@ import tempfile # Thanks, Clonk! # low level, should be Posix only but they happen to work on (my) Windows, too! -proc dup(oldfd: FileHandle): FileHandle {.importc, header: "unistd.h".} +proc dup*(oldfd: FileHandle): FileHandle {.importc, header: "unistd.h".} proc dup2(oldfd: FileHandle, newfd: FileHandle): cint {.importc, header: "unistd.h".} +template disableCaptureStdout*(body: untyped) = + # want to write to stdout but not to our custom file. + let currentStdout = dup(nb.currentStdout) + discard dup2(nb.originalStdout, nb.currentStdout) + flushFile stdout + body + flushFile stdout + + discard dup2(currentStdout, nb.currentStdout) + template captureStdout*(ident: untyped, body: untyped) = ## redirect stdout to a temporary file and captures output of body in ident let diff --git a/src/nimib/renders.nim b/src/nimib/renders.nim index b233e9d6..ef5876d6 100644 --- a/src/nimib/renders.nim +++ b/src/nimib/renders.nim @@ -4,12 +4,20 @@ export escapeTag # where is this used? why do I export? a better solution is to import highlight import mustachepkg/values +proc render*(nb: var NbDoc, blk: var NbBlock): string + proc mdOutputToHtml(doc: var NbDoc, blk: var NbBlock) = blk.context["outputToHtml"] = markdown(blk.output, config=initGfmConfig()).dup(removeSuffix) proc highlightCode(doc: var NbDoc, blk: var NbBlock) = blk.context["codeHighlighted"] = highlightNim(blk.code) +proc renderContainer(doc: var NbDoc, blk: var NbBlock) = + var children: seq[string] + for child in blk.blocks.mitems: + children.add doc.render(child) + blk.context["blocks"] = children + proc useHtmlBackend*(doc: var NbDoc) = doc.partials["nbText"] = "{{&outputToHtml}}" @@ -52,6 +60,7 @@ proc useHtmlBackend*(doc: var NbDoc) = doc.renderProcs["mdOutputToHtml"] = mdOutputToHtml doc.renderProcs["highlightCode"] = highlightCode doc.renderProcs["compileNimToJs"] = compileNimToJs + doc.renderProcs["renderContainer"] = renderContainer proc useMdBackend*(doc: var NbDoc) = doc.partials["document"] = """ diff --git a/src/nimib/types.nim b/src/nimib/types.nim index a3c31928..432f5739 100644 --- a/src/nimib/types.nim +++ b/src/nimib/types.nim @@ -8,6 +8,7 @@ type code*: string output*: string context*: Context + blocks*: seq[NbBlock] NbOptions* = object skipCfg*: bool cfgName*, srcDir*, homeDir*, filename*: string @@ -34,7 +35,8 @@ type renderPlans*: Table[string, seq[string]] renderProcs*: Table[string, NbRenderProc] id: int - nbJsCounter*: int + nbJsCounter*: int + currentStdout*, originalStdout*: FileHandle proc thisDir*(doc: NbDoc): AbsoluteDir = doc.thisFile.splitFile.dir proc srcDir*(doc: NbDoc): AbsoluteDir =