Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement container blocks #177

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/nimib.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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):
Expand Down
11 changes: 7 additions & 4 deletions src/nimib/blocks.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import std / [macros, strutils, sugar]
import types, sources
import types, sources, capture

macro toStr*(body: untyped): string =
(body.toStrLit)
Expand All @@ -17,17 +17,20 @@ 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:
when defined(nimibCodeFromAst):
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
Expand Down
12 changes: 11 additions & 1 deletion src/nimib/capture.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions src/nimib/renders.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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}}"
Expand Down Expand Up @@ -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"] = """
Expand Down
4 changes: 3 additions & 1 deletion src/nimib/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type
code*: string
output*: string
context*: Context
blocks*: seq[NbBlock]
NbOptions* = object
skipCfg*: bool
cfgName*, srcDir*, homeDir*, filename*: string
Expand All @@ -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 =
Expand Down