From dd5d345cd6645b3da050194a1d820c37e3ee5e6d Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:14:49 +0200
Subject: [PATCH 01/30] basics are working
---
src/nimib.nim | 33 ++++++++++++++++++++++++++++----
src/nimib/jsutils.nim | 44 +++++++++++++++++++++++++------------------
src/nimib/types.nim | 1 +
3 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/src/nimib.nim b/src/nimib.nim
index 92f4a052..b83a5438 100644
--- a/src/nimib.nim
+++ b/src/nimib.nim
@@ -135,7 +135,7 @@ template nbJsFromStringInit*(body: string): NbBlock =
result
template nbJsFromCodeInit*(args: varargs[untyped]): NbBlock =
- let (code, originalCode) = nimToJsString(true, args)
+ let (code, originalCode) = nimToJsString(false, args)
var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
result.context["transformedCode"] = code
result
@@ -161,8 +161,21 @@ template nbJsFromString*(body: string) =
script.addToDocAsJs
template nbJsFromCode*(args: varargs[untyped]) =
- let script = nbJsFromCodeInit(args)
- script.addToDocAsJs
+ let (code, originalCode) = nimToJsString(compileToOwnFile=false, putCodeInBlock=true, args)
+ nb.nbJsScript.add "\n" & code
+ #var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
+ #result.context["transformedCode"] = code
+ #result.addToDocAsJs
+
+template nbJsFromCodeGlobal*(args: varargs[untyped]) =
+ let (code, originalCode) = nimToJsString(compileToOwnFile=false, putCodeInBlock=false, args)
+ nb.nbJsGlobalScript.add "\n" & code
+
+template nbJsFromCodeOwnFile*(args: varargs[untyped]) =
+ let (code, originalCode) = nimToJsString(compileToOwnFile=true, putCodeInBlock=false, args)
+ var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
+ result.context["transformedCode"] = "import std / json\n" & code
+ result.addToDocAsJs
template nbCodeToJs*(args: varargs[untyped]) {.deprecated: "Use nbJsFromCode or nbJsFromString instead".} =
nbJsFromCode(args)
@@ -192,7 +205,19 @@ template nbSave* =
# order if searchDirs/searchTable is relevant: directories have higher priority. rationale:
# - in memory partial contains default mustache assets
# - to override/customize (for a bunch of documents) the best way is to modify a version on file
- # - in case you need to manage additional exceptions for a specific document add a new set of partials before calling nbSave
+ # - in case you need to manage additional exceptions for a specific document add a new set of partials before calling
+ nb.nbJsGlobalScript = "import std / json\n" & nb.nbJsGlobalScript
+ let completeJsCode = nb.nbJsGlobalScript & "\n" & nb.nbJsScript
+ echo "Complete Js Code: \n", completeJsCode
+ var jsBlock = NbBlock(
+ command: "nbCodeToJs",
+ code: completeJsCode,
+ context: newContext(searchDirs = @[], partials = nb.partials),
+ output: ""
+ )
+ jsBlock.context["transformedCode"] = completeJsCode
+ jsBlock.addToDocAsJs
+
nb.context.searchDirs(nb.templateDirs)
nb.context.searchTable(nb.partials)
diff --git a/src/nimib/jsutils.nim b/src/nimib/jsutils.nim
index 930b21b0..6af16d97 100644
--- a/src/nimib/jsutils.nim
+++ b/src/nimib/jsutils.nim
@@ -97,7 +97,7 @@ proc gensymProcIterConverter(n: NimNode, replaceProcs: bool) =
else:
gensymProcIterConverter(n[i], replaceProcs)
-proc degensymAst(n: NimNode, removeGensym = false) =
+proc degensymAst(n: NimNode, removeGensym: bool) =
for i in 0 ..< n.len:
case n[i].kind
of nnkIdent, nnkSym:
@@ -126,16 +126,20 @@ proc degensymAst(n: NimNode, removeGensym = false) =
else:
degensymAst(n[i], removeGenSym)
-proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode]): tuple[code: NimNode, placeholders: seq[NimNode]] =
+proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode], removeGensym: bool): tuple[code: NimNode, placeholders: seq[NimNode]] =
result.code = newStmtList()
# generate fromJSON loading and then add entire body afterwards
if capturedVariables.len > 0:
- result.code.add quote do:
- import std/json
+ #result.code.add quote do:
+ # import std/json
for (cap, capType) in zip(capturedVariables, capturedTypes):
let placeholder = gensym(ident="placeholder")
var newSym: NimNode
- if "`gensym" notin cap.strVal:
+ if "`gensym" in cap.strVal and removeGensym:
+ let newStr = cap.strVal.split("`gensym")[0]
+ newSym = ident(newStr)
+ elif "`gensym" notin cap.strVal and (not removeGensym):
+ # as it's not gensym'd and we don't want to remove gensym, we want to generate a unique variable name for this
newSym = gensym(NimSymKind.nskLet, ident=cap.strVal)
# add to tab[cap] = cap.gensym?
tabMapIdents[cap.strVal.nimIdentNormalize] = newSym.repr.ident
@@ -146,15 +150,14 @@ proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode]): tupl
let `newSym` = parseJson(`placeholder`).to(`capType`) # we must gensym `cap` as well!
-macro nimToJsStringSecondStage*(key: static string, captureVars: varargs[typed]): untyped =
+macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
let captureVars = toSeq(captureVars)
let captureTypes = collect:
for cap in captureVars:
cap.getTypeInst
- # dispatch either to string based if the body has type string
- # or to typed version otherwise.
+ # Get the untyped body from CacheTable
var body: NimNode
if key in bodyCache:
body = bodyCache[key]
@@ -163,11 +166,18 @@ macro nimToJsStringSecondStage*(key: static string, captureVars: varargs[typed])
# Now we have the body!
body = body.copyNimTree()
# 1. Generate the captured variable assignments and return placeholders
- let (capAssignments, placeholders) = genCapturedAssignment(captureVars, captureTypes)
+ let (capAssignments, placeholders) = genCapturedAssignment(captureVars, captureTypes, removeGensym = not compileToOwnFile)
# 2. Stringify code
- let code = newStmtList(capAssignments, body).copyNimTree()
- code.gensymProcIterConverter(replaceProcs=true)
- code.degensymAst()
+ var code = newStmtList(capAssignments, body).copyNimTree()
+ # Only do this if compiling to its own file, blocks will cover this for us in the other case.
+ if compileToOwnFile:
+ code.gensymProcIterConverter(replaceProcs=true)
+ # If we want to compile the script to its own file, then we want to re-gensym it.
+ # If not, then we want to degensym it entirely and instead but it inside a block
+ code.degensymAst(removeGenSym = not compileToOwnFile)
+ # Put the code inside a block if not compileToOwnFile
+ if putCodeInBlock:
+ code = newBlockStmt(code)
var codeText = code.toStrLit
# 3. Generate code which does the serialization and replacement of placeholders
let codeTextIdent = genSym(NimSymKind.nskVar ,ident="codeText")
@@ -184,13 +194,11 @@ macro nimToJsStringSecondStage*(key: static string, captureVars: varargs[typed])
body.degensymAst(removeGenSym=true) # remove `gensym if code was written in a template
result.add nnkTupleConstr.newTree(codeTextIdent, body.toStrLit)
-macro nimToJsString*(isNewScript: static bool, args: varargs[untyped]): untyped =
+macro nimToJsString*(compileToOwnFile: static bool, putCodeInBlock: static bool, args: varargs[untyped]): untyped =
if args.len == 0:
error("nbJsFromCode needs a code block to be passed", args)
- # If new script, clear the table.
- if isNewScript:
- tabMapIdents.clear()
+ tabMapIdents.clear()
let body = args[^1]
let captureVars =
@@ -207,7 +215,7 @@ macro nimToJsString*(isNewScript: static bool, args: varargs[untyped]): untyped
result = newStmtList()
result.add quote do:
addBody(`key`, `body`)
- var nextArgs = @[newLit(key)]
+ var nextArgs = @[newLit(key), newLit(compileToOwnFile), newLit(putCodeInBlock)]
nextArgs.add captureVars
result.add newCall("nimToJsStringSecondStage", nextArgs)
@@ -245,6 +253,6 @@ macro nbKaraxCodeBackend*(rootId: untyped, args: varargs[untyped]) =
callArgs.add captureVars
callArgs.add newBody
- let call = newCall(ident"nbJsFromCode", callArgs)
+ let call = newCall(ident"nbJsFromCodeOwnFile", callArgs)
result = call
\ No newline at end of file
diff --git a/src/nimib/types.nim b/src/nimib/types.nim
index 1d1a482e..f80d0c5a 100644
--- a/src/nimib/types.nim
+++ b/src/nimib/types.nim
@@ -33,6 +33,7 @@ type
renderPlans*: Table[string, seq[string]]
renderProcs*: Table[string, NbRenderProc]
id: int
+ nbJsGlobalScript*, nbJsScript*: string
proc thisDir*(doc: NbDoc): AbsoluteDir = doc.thisFile.splitFile.dir
proc srcDir*(doc: NbDoc): AbsoluteDir =
From 5842306429d593411b2a9cd1d648c1558bc1ffae Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:09:55 +0200
Subject: [PATCH 02/30] fix tests
---
tests/tnimib.nim | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tests/tnimib.nim b/tests/tnimib.nim
index 44a99117..b6b161e4 100644
--- a/tests/tnimib.nim
+++ b/tests/tnimib.nim
@@ -176,7 +176,7 @@ when moduleAvailable(karax/kbase):
echo a
check nb.blk.code.len > 0
check nb.blk.context["transformedCode"].vString.len > 0
-
+ #[
test "nbJsFromCodeInit + addCodeToJs":
let script = nbJsFromCodeInit:
let a = 1
@@ -185,12 +185,11 @@ when moduleAvailable(karax/kbase):
script.addToDocAsJs
check nb.blk.code.len > 0
check nb.blk.context["transformedCode"].vString.len > 0
-
+ ]#
test "nbJsFromCode + exportc":
- let script = nbJsFromCodeInit:
+ nbJsFromCodeOwnFile:
proc setup() {.exportc.} =
echo 1
- script.addToDocAsJs
check "setup()" in nb.blk.context["transformedCode"].vString
test "nbKaraxCode":
From 68bb641b53cdb6fd812e9de13a3807f0ce2f401a Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:10:06 +0200
Subject: [PATCH 03/30] update counters.nim
---
docsrc/counters.nim | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docsrc/counters.nim b/docsrc/counters.nim
index 26772cdc..e8c5e97b 100644
--- a/docsrc/counters.nim
+++ b/docsrc/counters.nim
@@ -13,6 +13,8 @@ A button which increases a counter each time you click it. We will do this in tw
The first method is to use Nim like you would have used Javascript using `getElementById` and `addEventListener`:
"""
nbCode:
+ nbJsFromCodeGlobal:
+ import std/dom
## 1:
template counterButton(id: string) =
let labelId = "label-" & id
@@ -24,7 +26,6 @@ nbCode:
""" % [labelId, buttonId]
## 3:
nbJsFromCode(labelId, buttonId):
- import std/dom
## 4:
var label = getElementById(labelId.cstring)
var button = getElementById(buttonId.cstring)
From 4a15a898c96f296ea54b01b7010f250129fcc4f5 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:11:13 +0200
Subject: [PATCH 04/30] exclude interactivity.nim from docs until rewritten
---
nimib.nimble | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nimib.nimble b/nimib.nimble
index 113d946f..8e813361 100644
--- a/nimib.nimble
+++ b/nimib.nimble
@@ -38,7 +38,7 @@ task docs, "Build documentation":
exec "nim r docsrc/cheatsheet.nim"
exec "nim r docsrc/files.nim"
exec "nim r docsrc/index.nim"
- exec "nim r docsrc/interactivity.nim"
+ #exec "nim r docsrc/interactivity.nim"
exec "nim r docsrc/counters.nim"
exec "nim r docsrc/caesar.nim"
when not defined(nimibDocsSkipPenguins):
From 582e632bba581875e309166c5d4b924b3f95970f Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 19:11:50 +0200
Subject: [PATCH 05/30] bye bye old gensym
---
src/nimib.nim | 4 ++
src/nimib/jsutils.nim | 88 ++++++++++++++++++++++++++++++++++++++-----
src/nimib/renders.nim | 14 ++++++-
3 files changed, 96 insertions(+), 10 deletions(-)
diff --git a/src/nimib.nim b/src/nimib.nim
index b83a5438..46a03e6c 100644
--- a/src/nimib.nim
+++ b/src/nimib.nim
@@ -134,6 +134,7 @@ template nbJsFromStringInit*(body: string): NbBlock =
result.context["transformedCode"] = body
result
+#[
template nbJsFromCodeInit*(args: varargs[untyped]): NbBlock =
let (code, originalCode) = nimToJsString(false, args)
var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
@@ -147,6 +148,7 @@ template addCodeToJs*(script: NbBlock, args: varargs[untyped]) =
let (code, originalCode) = nimToJsString(false, args)
script.code &= "\n" & originalCode
script.context["transformedCode"] = script.context["transformedCode"].vString & "\n" & code
+]#
template addStringToJs*(script: NbBlock, body: string) =
script.code &= "\n" & body
@@ -175,6 +177,7 @@ template nbJsFromCodeOwnFile*(args: varargs[untyped]) =
let (code, originalCode) = nimToJsString(compileToOwnFile=true, putCodeInBlock=false, args)
var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
result.context["transformedCode"] = "import std / json\n" & code
+ result.context["isOwnFile"] = true
result.addToDocAsJs
template nbCodeToJs*(args: varargs[untyped]) {.deprecated: "Use nbJsFromCode or nbJsFromString instead".} =
@@ -216,6 +219,7 @@ template nbSave* =
output: ""
)
jsBlock.context["transformedCode"] = completeJsCode
+ jsBlock.context["isOwnFile"] = false
jsBlock.addToDocAsJs
nb.context.searchDirs(nb.templateDirs)
diff --git a/src/nimib/jsutils.nim b/src/nimib/jsutils.nim
index 6af16d97..b81a8c64 100644
--- a/src/nimib/jsutils.nim
+++ b/src/nimib/jsutils.nim
@@ -97,7 +97,7 @@ proc gensymProcIterConverter(n: NimNode, replaceProcs: bool) =
else:
gensymProcIterConverter(n[i], replaceProcs)
-proc degensymAst(n: NimNode, removeGensym: bool) =
+proc degensymAstOld(n: NimNode, removeGensym: bool) =
for i in 0 ..< n.len:
case n[i].kind
of nnkIdent, nnkSym:
@@ -121,12 +121,24 @@ proc degensymAst(n: NimNode, removeGensym: bool) =
if pragmas.isPragmaExportc: # varName {.exportc.}
n[i][0] = identifier.strVal.split("`gensym")[0].ident
else:
- degensymAst(identifier, removeGensym)
- degensymAst(pragmas, removeGensym)
+ degensymAstOld(identifier, removeGensym)
+ degensymAstOld(pragmas, removeGensym)
else:
- degensymAst(n[i], removeGenSym)
+ degensymAstOld(n[i], removeGenSym)
-proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode], removeGensym: bool): tuple[code: NimNode, placeholders: seq[NimNode]] =
+proc degensymAst(n: NimNode) =
+ for i in 0 ..< n.len:
+ case n[i].kind
+ of nnkIdent, nnkSym:
+ let str = n[i].strVal
+ if "`gensym" in str:
+ let newStr = str.split("`gensym")[0]
+ let newSym = ident(newStr)
+ n[i] = newSym
+ else:
+ degensymAst(n[i])
+
+proc genCapturedAssignmentOld(capturedVariables, capturedTypes: seq[NimNode], removeGensym: bool): tuple[code: NimNode, placeholders: seq[NimNode]] =
result.code = newStmtList()
# generate fromJSON loading and then add entire body afterwards
if capturedVariables.len > 0:
@@ -148,9 +160,23 @@ proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode], remov
result.placeholders.add placeholder
result.code.add quote do:
let `newSym` = parseJson(`placeholder`).to(`capType`) # we must gensym `cap` as well!
+
+proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode]): tuple[code: NimNode, placeholders: seq[NimNode]] =
+ result.code = newStmtList()
+ # generate fromJSON loading and then add entire body afterwards
+ if capturedVariables.len > 0:
+ #result.code.add quote do:
+ # import std/json
+ for (cap, capType) in zip(capturedVariables, capturedTypes):
+ let placeholder = gensym(ident="placeholder")
+
+ let newSym = cap
+ result.placeholders.add placeholder
+ result.code.add quote do:
+ let `newSym` = parseJson(`placeholder`).to(`capType`) # we must gensym `cap` as well!
-macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
+macro nimToJsStringSecondStageOld*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
let captureVars = toSeq(captureVars)
let captureTypes = collect:
@@ -166,7 +192,7 @@ macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static boo
# Now we have the body!
body = body.copyNimTree()
# 1. Generate the captured variable assignments and return placeholders
- let (capAssignments, placeholders) = genCapturedAssignment(captureVars, captureTypes, removeGensym = not compileToOwnFile)
+ let (capAssignments, placeholders) = genCapturedAssignmentOld(captureVars, captureTypes, removeGensym = not compileToOwnFile)
# 2. Stringify code
var code = newStmtList(capAssignments, body).copyNimTree()
# Only do this if compiling to its own file, blocks will cover this for us in the other case.
@@ -174,7 +200,51 @@ macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static boo
code.gensymProcIterConverter(replaceProcs=true)
# If we want to compile the script to its own file, then we want to re-gensym it.
# If not, then we want to degensym it entirely and instead but it inside a block
- code.degensymAst(removeGenSym = not compileToOwnFile)
+ code.degensymAstOld(removeGenSym = not compileToOwnFile)
+ # Put the code inside a block if not compileToOwnFile
+ if putCodeInBlock:
+ code = newBlockStmt(code)
+ var codeText = code.toStrLit
+ # 3. Generate code which does the serialization and replacement of placeholders
+ let codeTextIdent = genSym(NimSymKind.nskVar ,ident="codeText")
+ result = newStmtList()
+ result.add newVarStmt(codeTextIdent, codeText)
+ for i in 0 .. captureVars.high:
+ let placeholder = placeholders[i].repr.newLit
+ let varIdent = captureVars[i]
+ let serializedValue = quote do:
+ $(toJson(`varIdent`))
+ result.add quote do:
+ `codeTextIdent` = `codeTextIdent`.replace(`placeholder`, "\"\"\"" & `serializedValue` & "\"\"\"")
+ # return tuple of the transformed code to be compiled and the prettified code for visualization
+ body.degensymAstOld(removeGenSym=true) # remove `gensym if code was written in a template
+ result.add nnkTupleConstr.newTree(codeTextIdent, body.toStrLit)
+
+macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
+ let captureVars = toSeq(captureVars)
+
+ let captureTypes = collect:
+ for cap in captureVars:
+ cap.getTypeInst
+
+ # Get the untyped body from CacheTable
+ var body: NimNode
+ if key in bodyCache:
+ body = bodyCache[key]
+ else:
+ error(&"Nimib error: key {key} not in any of the tables. Please open an issue on Github with a minimal reproducible example")
+ # Now we have the body!
+ body = body.copyNimTree()
+ # 1. Generate the captured variable assignments and return placeholders
+ let (capAssignments, placeholders) = genCapturedAssignment(captureVars, captureTypes)
+ # 2. Stringify code
+ var code = newStmtList(capAssignments, body).copyNimTree()
+ # Only do this if compiling to its own file, blocks will cover this for us in the other case.
+ #if compileToOwnFile:
+ # code.gensymProcIterConverter(replaceProcs=true)
+ # If we want to compile the script to its own file, then we want to re-gensym it.
+ # If not, then we want to degensym it entirely and instead but it inside a block
+ code.degensymAst()
# Put the code inside a block if not compileToOwnFile
if putCodeInBlock:
code = newBlockStmt(code)
@@ -191,7 +261,7 @@ macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static boo
result.add quote do:
`codeTextIdent` = `codeTextIdent`.replace(`placeholder`, "\"\"\"" & `serializedValue` & "\"\"\"")
# return tuple of the transformed code to be compiled and the prettified code for visualization
- body.degensymAst(removeGenSym=true) # remove `gensym if code was written in a template
+ body.degensymAst() # remove `gensym if code was written in a template
result.add nnkTupleConstr.newTree(codeTextIdent, body.toStrLit)
macro nimToJsString*(compileToOwnFile: static bool, putCodeInBlock: static bool, args: varargs[untyped]): untyped =
diff --git a/src/nimib/renders.nim b/src/nimib/renders.nim
index 3846724a..bc7822b7 100644
--- a/src/nimib/renders.nim
+++ b/src/nimib/renders.nim
@@ -16,7 +16,19 @@ proc compileNimToJs(doc: var NbDoc, blk: var NbBlock) =
let (dir, filename, ext) = doc.thisFile.splitFile()
let nimfile = dir / (filename & "_nbCodeToJs_" & $doc.newId() & ext).RelativeFile
let jsfile = tempdir / "out.js"
- writeFile(nimfile, blk.context["transformedCode"].vString)
+ var codeText = blk.context["transformedCode"].vString
+ if blk.context["isOwnFile"].vBool:
+ var bumpGensymString = """
+import macros
+
+macro bumpGensym() =
+ let _ = gensym()
+
+"""
+ for i in 0 .. doc.newId():
+ bumpGensymString.add "bumpGensym()\n"
+ codeText = bumpGensymString & codeText
+ writeFile(nimfile, codeText)
let kxiname = "nimib_kxi_" & $doc.newId()
let errorCode = execShellCmd(&"nim js -d:danger -d:kxiname=\"{kxiname}\" -o:{jsfile} {nimfile}")
if errorCode != 0:
From d0f14a463d7d87237cc7e01df45e01196e6854f3 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Wed, 26 Oct 2022 19:48:17 +0200
Subject: [PATCH 06/30] remove old code. So little code left :o
---
src/nimib/jsutils.nim | 194 +-----------------------------------------
1 file changed, 2 insertions(+), 192 deletions(-)
diff --git a/src/nimib/jsutils.nim b/src/nimib/jsutils.nim
index b81a8c64..c54a879a 100644
--- a/src/nimib/jsutils.nim
+++ b/src/nimib/jsutils.nim
@@ -7,125 +7,12 @@ proc contains(tab: CacheTable, keyToCheck: string): bool =
return true
return false
-#const validCodeTable = CacheTable"validCodeTable"
const bodyCache = CacheTable"bodyCache"
-var tabMapIdents {.compiletime.}: Table[string, NimNode]
-
-#[ macro typedChecker(n: typed): untyped = discard
-macro checkIsValidCode(n: untyped): untyped =
- result = quote do:
- when compiles(typedChecker(`n`)):
- true
- else:
- false ]#
-
-# remove this
-#[ macro addValid(key: string, s: typed): untyped =
- # If it is valid we want it typed
- if key.strVal notin validCodeTable:
- validCodeTable[key.strVal] = s ]#
macro addBody(key: string, s: untyped): untyped =
if key.strVal notin bodyCache:
bodyCache[key.strVal] = s
-proc isPragmaExportc(n: NimNode): bool =
- ## Returns whether pragma contains exportc
- n.expectKind(nnkPragma)
- for child in n:
- if child.kind == nnkExprColonExpr: # {.exportc: "newName".}
- if child[0].eqIdent("exportc"):
- result = true
- elif child.kind == nnkIdent:
- if child.eqIdent("exportc"): # {.exportc.}
- result = true
-
-proc gensymProcIterConverter(n: NimNode, replaceProcs: bool) =
- ## By default procs, iterators and converters are injected and will share the same name in the resulting javascript.
- ## Therefore we gensym them here to give them unique names. Also replace the references to it.
- ## replaceProcs: whether to replace procs names or not. It will replace existing names regardless.
- for i in 0 ..< n.len:
- case n[i].kind
- of nnkProcDef, nnkIteratorDef, nnkConverterDef:
- if replaceProcs:
- # add check for {.exportc.} here
- var isExportc: bool
- let pragmas = n[i][4]
- if pragmas.kind == nnkPragma:
- isExportc = isPragmaExportc(pragmas)
- # Do not gensym if proc is exportc'ed
- if not isExportc:
- if n[i][0].kind == nnkPostfix: # foo*
- let oldIdent = n[i][0][1].strVal.nimIdentNormalize
- let newIdent = gensym(ident=oldIdent).repr.ident
- n[i][0][1] = newIdent
- tabMapIdents[oldIdent] = newIdent
- else:
- let oldIdent = n[i][0].strVal.nimIdentNormalize
- let newIdent = gensym(ident=oldIdent).repr.ident
- n[i][0] = newIdent
- tabMapIdents[oldIdent] = newIdent
- # Function might be recursive or contain other procs, loop through it's body as well
- for child in n[i][6]:
- gensymProcIterConverter(child, replaceProcs)
- of nnkLambda:
- # rewrite from:
- # proc () = discard
- # to
- # block:
- # proc lambda_gensym() = discard
- # lambda_gensym
- let p = nnkProcDef.newTree()
- n[i].copyChildrenTo p
- let newIdent = gensym(ident="lambda")
- p[0] = newIdent
- # loop through proc body as well
- for child in p[6]:
- gensymProcIterConverter(child, replaceProcs)
- n[i] = newStmtList(p, newIdent)
- of nnkSym, nnkIdent:
- let oldIdent = n[i].strVal.nimIdentNormalize
- if oldIdent in tabMapIdents:
- n[i] = tabMapIdents[oldIdent]
- of nnkCall:
- # Check if it is karaxHtml:
- # if so set replaceProcs = false for the children
- if n[i][0].eqIdent("karaxHtml"):
- gensymProcIterConverter(n[i][1], false)
- else:
- gensymProcIterConverter(n[i], replaceProcs)
- else:
- gensymProcIterConverter(n[i], replaceProcs)
-
-proc degensymAstOld(n: NimNode, removeGensym: bool) =
- for i in 0 ..< n.len:
- case n[i].kind
- of nnkIdent, nnkSym:
- let str = n[i].strVal
- if "`gensym" in str:
- let newStr = str.split("`gensym")[0].nimIdentNormalize
- var newSym: NimNode
- if removeGensym: # remove gensym all together, useful for removing gensym noise when showing code
- newSym = ident(newStr)
- else: # replace gensym with one that is accepted by the parser
- # If this symbol is already used in this script, use the gensym'd symbol from tabMapIdents
- if newStr in tabMapIdents:
- newSym = tabMapIdents[newStr]
- else: # else create a gensym'd symbol and add it to the table
- newSym = gensym(ident=newStr).repr.ident
- tabMapIdents[newStr] = newSym
- n[i] = newSym
- of nnkPragmaExpr:
- let identifier = n[i][0]
- let pragmas = n[i][1]
- if pragmas.isPragmaExportc: # varName {.exportc.}
- n[i][0] = identifier.strVal.split("`gensym")[0].ident
- else:
- degensymAstOld(identifier, removeGensym)
- degensymAstOld(pragmas, removeGensym)
- else:
- degensymAstOld(n[i], removeGenSym)
-
proc degensymAst(n: NimNode) =
for i in 0 ..< n.len:
case n[i].kind
@@ -138,35 +25,10 @@ proc degensymAst(n: NimNode) =
else:
degensymAst(n[i])
-proc genCapturedAssignmentOld(capturedVariables, capturedTypes: seq[NimNode], removeGensym: bool): tuple[code: NimNode, placeholders: seq[NimNode]] =
- result.code = newStmtList()
- # generate fromJSON loading and then add entire body afterwards
- if capturedVariables.len > 0:
- #result.code.add quote do:
- # import std/json
- for (cap, capType) in zip(capturedVariables, capturedTypes):
- let placeholder = gensym(ident="placeholder")
- var newSym: NimNode
- if "`gensym" in cap.strVal and removeGensym:
- let newStr = cap.strVal.split("`gensym")[0]
- newSym = ident(newStr)
- elif "`gensym" notin cap.strVal and (not removeGensym):
- # as it's not gensym'd and we don't want to remove gensym, we want to generate a unique variable name for this
- newSym = gensym(NimSymKind.nskLet, ident=cap.strVal)
- # add to tab[cap] = cap.gensym?
- tabMapIdents[cap.strVal.nimIdentNormalize] = newSym.repr.ident
- else:
- newSym = cap
- result.placeholders.add placeholder
- result.code.add quote do:
- let `newSym` = parseJson(`placeholder`).to(`capType`) # we must gensym `cap` as well!
-
proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode]): tuple[code: NimNode, placeholders: seq[NimNode]] =
result.code = newStmtList()
# generate fromJSON loading and then add entire body afterwards
if capturedVariables.len > 0:
- #result.code.add quote do:
- # import std/json
for (cap, capType) in zip(capturedVariables, capturedTypes):
let placeholder = gensym(ident="placeholder")
@@ -174,51 +36,6 @@ proc genCapturedAssignment(capturedVariables, capturedTypes: seq[NimNode]): tupl
result.placeholders.add placeholder
result.code.add quote do:
let `newSym` = parseJson(`placeholder`).to(`capType`) # we must gensym `cap` as well!
-
-
-macro nimToJsStringSecondStageOld*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
- let captureVars = toSeq(captureVars)
-
- let captureTypes = collect:
- for cap in captureVars:
- cap.getTypeInst
-
- # Get the untyped body from CacheTable
- var body: NimNode
- if key in bodyCache:
- body = bodyCache[key]
- else:
- error(&"Nimib error: key {key} not in any of the tables. Please open an issue on Github with a minimal reproducible example")
- # Now we have the body!
- body = body.copyNimTree()
- # 1. Generate the captured variable assignments and return placeholders
- let (capAssignments, placeholders) = genCapturedAssignmentOld(captureVars, captureTypes, removeGensym = not compileToOwnFile)
- # 2. Stringify code
- var code = newStmtList(capAssignments, body).copyNimTree()
- # Only do this if compiling to its own file, blocks will cover this for us in the other case.
- if compileToOwnFile:
- code.gensymProcIterConverter(replaceProcs=true)
- # If we want to compile the script to its own file, then we want to re-gensym it.
- # If not, then we want to degensym it entirely and instead but it inside a block
- code.degensymAstOld(removeGenSym = not compileToOwnFile)
- # Put the code inside a block if not compileToOwnFile
- if putCodeInBlock:
- code = newBlockStmt(code)
- var codeText = code.toStrLit
- # 3. Generate code which does the serialization and replacement of placeholders
- let codeTextIdent = genSym(NimSymKind.nskVar ,ident="codeText")
- result = newStmtList()
- result.add newVarStmt(codeTextIdent, codeText)
- for i in 0 .. captureVars.high:
- let placeholder = placeholders[i].repr.newLit
- let varIdent = captureVars[i]
- let serializedValue = quote do:
- $(toJson(`varIdent`))
- result.add quote do:
- `codeTextIdent` = `codeTextIdent`.replace(`placeholder`, "\"\"\"" & `serializedValue` & "\"\"\"")
- # return tuple of the transformed code to be compiled and the prettified code for visualization
- body.degensymAstOld(removeGenSym=true) # remove `gensym if code was written in a template
- result.add nnkTupleConstr.newTree(codeTextIdent, body.toStrLit)
macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static bool, putCodeInBlock: static bool, captureVars: varargs[typed]): untyped =
let captureVars = toSeq(captureVars)
@@ -239,18 +56,13 @@ macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static boo
let (capAssignments, placeholders) = genCapturedAssignment(captureVars, captureTypes)
# 2. Stringify code
var code = newStmtList(capAssignments, body).copyNimTree()
- # Only do this if compiling to its own file, blocks will cover this for us in the other case.
- #if compileToOwnFile:
- # code.gensymProcIterConverter(replaceProcs=true)
- # If we want to compile the script to its own file, then we want to re-gensym it.
- # If not, then we want to degensym it entirely and instead but it inside a block
code.degensymAst()
- # Put the code inside a block if not compileToOwnFile
+
if putCodeInBlock:
code = newBlockStmt(code)
var codeText = code.toStrLit
# 3. Generate code which does the serialization and replacement of placeholders
- let codeTextIdent = genSym(NimSymKind.nskVar ,ident="codeText")
+ let codeTextIdent = genSym(NimSymKind.nskVar, ident="codeText")
result = newStmtList()
result.add newVarStmt(codeTextIdent, codeText)
for i in 0 .. captureVars.high:
@@ -267,8 +79,6 @@ macro nimToJsStringSecondStage*(key: static string, compileToOwnFile: static boo
macro nimToJsString*(compileToOwnFile: static bool, putCodeInBlock: static bool, args: varargs[untyped]): untyped =
if args.len == 0:
error("nbJsFromCode needs a code block to be passed", args)
-
- tabMapIdents.clear()
let body = args[^1]
let captureVars =
From de6ff1183c39d3d73963538de2757fd4402585b2 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Thu, 27 Oct 2022 10:41:18 +0200
Subject: [PATCH 07/30] update interactivity.nim
---
docsrc/interactivity.nim | 73 ++++++++++++++++++++++++++--------------
nimib.nimble | 2 +-
2 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/docsrc/interactivity.nim b/docsrc/interactivity.nim
index 1e9798eb..c2aa3a69 100644
--- a/docsrc/interactivity.nim
+++ b/docsrc/interactivity.nim
@@ -3,48 +3,48 @@ import nimib
nbInit
nbText: hlMd"""
-# Creating interactive components in Nimib
+# Creating interactive components in nimib
Nimib can easily be used to create static content with `nbText` and `nbCode`, but did you know that you can create interactive
content as well? And that you can do it all in Nim even! This can be achieved using either the `nbJsFromCode`-API or `nbKaraxCode`.
They work by compiling Nim code into javascript and adding it to the resulting HTML file.
This means that arbitrary Javascript can be written but also that Karax, which compiles to javascript, also can be used.
-## nbJsFromCodeInit
-This is the fundamental API used for compiling Nim-snippets to javascript. It consists of three templates:
-- `nbJsFromCodeInit` - Creates a new code script that further code can be added to later.
-- `addCodeToJs` - Adds to an existing code script
-- `addToDocAsJs` - Takes the Nim code in a script and compiles it to javascript.
+## nbJsFromCode
+This is the fundamental API used for compiling Nim-snippets to javascript.
Here is a basic example:
"""
nbCode:
- let script = nbJsFromCodeInit:
- echo "Hello world!"
let x = 3.14
- script.addCodeToJs(x):
+ nbJsFromCode(x):
+ echo "Hello world!"
echo "Pi is roughly ", x
- ## Uncomment this line:
- ##script.addToDocAsJs()
-script.addToDocAsJs()
-nbJsShowSource("This is the complete script:")
-
nbText: hlMd"""
-The reason `script.addToDocAsJs()` is commented out is just a limitation of nimib not handling nested blocks well.
If you now go to your browser's javascript console you should see `Hello world` and `Pi is roughly 3.14` printed there.
-What is up with `script.addCodeToJs(x)` though? Why is `(x)` needed? It is because we have to capture the value of `x`
+What is up with `nbJsFromCode(x)` though? Why is `(x)` needed? It is because we have to capture the value of `x`
to be able to use it in the javascript. The code block will basically be copy-pasted into a separate file and
compiled into javascript. And `x` isn't defined there so we have to capture it. This is true for any variable that
-we want to use that is defined outside the script blocks.
+we want to use that is defined outside the script blocks.
-## nbJsFromCode
-This is basically a shorthand for running `nbJsFromCodeInit` and `addToDocAsJs` in a single call:
-```nim
-let x = 3.14
-nbJsCode(x):
- echo "Pi is roughly ", x
-```
+The code that you pass to `nbJsFromCode` will internally be put inside a `block`, so things like `import`s which need to be top-level statements
+will need to be done using `nbJsFromCodeGlobal`. Code defined using `nbJsFromCodeGlobal` will be visible to all `nbJsFromCode` blocks. So if you want
+to have communication between different code blocks, you have to set it up using a global variable here. An example if how this would work is this:
+"""
+
+nbCode:
+ nbJsFromCodeGlobal:
+ import std / dom # this will be imported for all your nbJs blocks
+ var globalVar = 1
+ nbJsFromCode:
+ echo "First block: ", globalVar
+ globalVar += 1
+ nbJsFromCode:
+ echo "Second block: ", globalVar
+
+nbText: hlMd"""
+If you look in the console you should see that it prints out `1` in the first block and `2` in the second block.
## nbKaraxCode
@@ -52,7 +52,7 @@ If you want to write a component using karax this is the template for you!
A normal karax program has the following structure:
```nim
nbJsFromCode(rootId):
- import karax / [kbase, karax, karaxdsl, vdom, compact, jstrutils, kdom]
+ include karax / prelude
karaxCode # some code, set up global variables for example
@@ -86,8 +86,29 @@ nbCode:
proc onClick() =
message = "Poof! Gone!"
-nbText: "This is the output this code produces:"
+nbText: "This is the output this code produces when called:"
karaxExample()
+nbText: hlMd"""
+## Internal workings
+### nbJsFromCode
+The way this works is that each `nbJsFromCode` is put inside a separate `block` inside a common file. So if we have 10 `nbJsFromCode` blocks in
+our code, we will have 10 `block`s in the final code that will be compiled. Any code passed to `nbJsFromCodeGlobal` will be put at the top of the file
+without any blocks. Here's a simple schematic:
+```nim
+global code here (imports and global variables)
+block:
+ first nbJsFromCode
+block:
+ second nbJsFromCode
+block:
+ third nbJsFromCode
+```
+
+### nbKaraxCode
+`nbKaraxCode` works a bit differently, there each code block will be compiled in its own file so there is no global scope.
+So (`nbJsFromCode` + `nbJsFromCodeGlobal`) and `nbKaraxCode` are totally isolated from each other.
+"""
+
nbSave
\ No newline at end of file
diff --git a/nimib.nimble b/nimib.nimble
index 8e813361..113d946f 100644
--- a/nimib.nimble
+++ b/nimib.nimble
@@ -38,7 +38,7 @@ task docs, "Build documentation":
exec "nim r docsrc/cheatsheet.nim"
exec "nim r docsrc/files.nim"
exec "nim r docsrc/index.nim"
- #exec "nim r docsrc/interactivity.nim"
+ exec "nim r docsrc/interactivity.nim"
exec "nim r docsrc/counters.nim"
exec "nim r docsrc/caesar.nim"
when not defined(nimibDocsSkipPenguins):
From 19083837939929611a954efd9e98ea8e6e6baee1 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Thu, 27 Oct 2022 10:49:47 +0200
Subject: [PATCH 08/30] update lots of small things
---
README.md | 2 +-
docsrc/counters.nim | 2 +-
docsrc/index.nim | 2 +-
src/nimib.nim | 33 ++++++++++++++++-----------------
4 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/README.md b/README.md
index 80096960..d93519a6 100644
--- a/README.md
+++ b/README.md
@@ -153,7 +153,7 @@ Currently most of the documentation on customization is given by the examples.
* `nbImage`: image command to show images (see `penguins.nim` example linked above)
* `nbFile`: content (string or untyped) is saved to file (see example document [files](https://pietroppeter.github.io/nimib/files.html))
-* `nbRawOutput`: called with string content, it will add the raw content to document (html backend)
+* `nbRawHtml`: called with string content, it will add the raw content to document (html backend)
* `nbTextWithCode`: a variant of `nbText` that also reads nim source. See example of usage
at the end of the source in `numerical.nim` linked above.
* `nbPython`: can be used after calling `nbInitPython()` and it runs and capture output of python code;
diff --git a/docsrc/counters.nim b/docsrc/counters.nim
index e8c5e97b..ab0b2d1a 100644
--- a/docsrc/counters.nim
+++ b/docsrc/counters.nim
@@ -20,7 +20,7 @@ nbCode:
let labelId = "label-" & id
let buttonId = "button-" & id
## 2:
- nbRawOutput: """
+ nbRawHtml: """
""" % [labelId, buttonId]
diff --git a/docsrc/index.nim b/docsrc/index.nim
index 7649263f..d30ab05c 100644
--- a/docsrc/index.nim
+++ b/docsrc/index.nim
@@ -131,7 +131,7 @@ Currently most of the documentation on customization is given by the examples.
* `nbImage`: image command to show images (see `penguins.nim` example linked above)
* `nbFile`: content (string or untyped) is saved to file (see example document [files]({docs}/files.html))
-* `nbRawOutput`: called with string content, it will add the raw content to document (html backend)
+* `nbRawHtml`: called with string content, it will add the raw content to document (html backend)
* `nbTextWithCode`: a variant of `nbText` that also reads nim source. See example of usage
at the end of the source in `numerical.nim` linked above.
* `nbPython`: can be used after calling `nbInitPython()` and it runs and capture output of python code;
diff --git a/src/nimib.nim b/src/nimib.nim
index 46a03e6c..04f7c515 100644
--- a/src/nimib.nim
+++ b/src/nimib.nim
@@ -132,6 +132,7 @@ template nbRawHtml*(content: string) =
template nbJsFromStringInit*(body: string): NbBlock =
var result = NbBlock(command: "nbCodeToJs", code: body, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
result.context["transformedCode"] = body
+ result.context["isOwnFile"] = true
result
#[
@@ -165,9 +166,6 @@ template nbJsFromString*(body: string) =
template nbJsFromCode*(args: varargs[untyped]) =
let (code, originalCode) = nimToJsString(compileToOwnFile=false, putCodeInBlock=true, args)
nb.nbJsScript.add "\n" & code
- #var result = NbBlock(command: "nbCodeToJs", code: originalCode, context: newContext(searchDirs = @[], partials = nb.partials), output: "")
- #result.context["transformedCode"] = code
- #result.addToDocAsJs
template nbJsFromCodeGlobal*(args: varargs[untyped]) =
let (code, originalCode) = nimToJsString(compileToOwnFile=false, putCodeInBlock=false, args)
@@ -187,7 +185,7 @@ template nbCodeToJs*(args: varargs[untyped]) {.deprecated: "Use nbJsFromCode or
when moduleAvailable(karax/kbase):
template nbKaraxCode*(args: varargs[untyped]) =
let rootId = "karax-" & $nb.newId()
- nbRawOutput: "
"
+ nbRawHtml: ""
nbKaraxCodeBackend(rootId, args)
template nbJsShowSource*(message: string = "") =
@@ -208,19 +206,20 @@ template nbSave* =
# order if searchDirs/searchTable is relevant: directories have higher priority. rationale:
# - in memory partial contains default mustache assets
# - to override/customize (for a bunch of documents) the best way is to modify a version on file
- # - in case you need to manage additional exceptions for a specific document add a new set of partials before calling
- nb.nbJsGlobalScript = "import std / json\n" & nb.nbJsGlobalScript
- let completeJsCode = nb.nbJsGlobalScript & "\n" & nb.nbJsScript
- echo "Complete Js Code: \n", completeJsCode
- var jsBlock = NbBlock(
- command: "nbCodeToJs",
- code: completeJsCode,
- context: newContext(searchDirs = @[], partials = nb.partials),
- output: ""
- )
- jsBlock.context["transformedCode"] = completeJsCode
- jsBlock.context["isOwnFile"] = false
- jsBlock.addToDocAsJs
+ # - in case you need to manage additional exceptions for a specific document add a new set of partials before calling
+ if nb.nbJsGlobalScript.len > 0 or nb.nbJsScript.len > 0:
+ nb.nbJsGlobalScript = "import std / json\n" & nb.nbJsGlobalScript
+ let completeJsCode = nb.nbJsGlobalScript & "\n" & nb.nbJsScript
+ echo "Complete Js Code: \n", completeJsCode
+ var jsBlock = NbBlock(
+ command: "nbCodeToJs",
+ code: completeJsCode,
+ context: newContext(searchDirs = @[], partials = nb.partials),
+ output: ""
+ )
+ jsBlock.context["transformedCode"] = completeJsCode
+ jsBlock.context["isOwnFile"] = false
+ jsBlock.addToDocAsJs
nb.context.searchDirs(nb.templateDirs)
nb.context.searchTable(nb.partials)
From 977aad5a83aa7b98e071605cb3c886ffc59ce489 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Thu, 27 Oct 2022 10:56:42 +0200
Subject: [PATCH 09/30] update nbJs tests
---
tests/tnimib.nim | 47 +++++++++++++----------------------------------
1 file changed, 13 insertions(+), 34 deletions(-)
diff --git a/tests/tnimib.nim b/tests/tnimib.nim
index b6b161e4..0b6ab273 100644
--- a/tests/tnimib.nim
+++ b/tests/tnimib.nim
@@ -164,29 +164,27 @@ when moduleAvailable(karax/kbase):
check nb.blk.context["transformedCode"].vString.len > 0
test "nbJsFromCode":
+ let startLen = nb.nbJsScript.len
nbJsFromCode:
let a = 1
echo a
- check nb.blk.code.len > 0
- check nb.blk.context["transformedCode"].vString.len > 0
+ check nb.nbJsScript.len > startLen
test "nbJsFromCode, capture variable":
+ let startLen = nb.nbJsScript.len
let a = 1
nbJsFromCode(a):
echo a
- check nb.blk.code.len > 0
- check nb.blk.context["transformedCode"].vString.len > 0
- #[
- test "nbJsFromCodeInit + addCodeToJs":
- let script = nbJsFromCodeInit:
- let a = 1
- script.addCodeToJs:
- echo a
- script.addToDocAsJs
- check nb.blk.code.len > 0
- check nb.blk.context["transformedCode"].vString.len > 0
- ]#
- test "nbJsFromCode + exportc":
+ check nb.nbJsScript.len > startLen
+
+ test "nbJsFromCodeGlobal":
+ let startLen = nb.nbJsGlobalScript.len
+ nbJsFromCodeGlobal:
+ import std / dom
+ var x = 1
+ check nb.nbJsGlobalScript.len > startLen
+
+ test "nbJsFromCodeOwnFile + exportc":
nbJsFromCodeOwnFile:
proc setup() {.exportc.} =
echo 1
@@ -201,22 +199,3 @@ when moduleAvailable(karax/kbase):
text message
check nb.blk.code.len > 0
check nb.blk.context["transformedCode"].vString.len > 0
-
- #[ test "Interlaced nbJsFromCode": # failing because of #118
- template foo() =
- let script1 = nbJsFromCodeInit:
- let a = 1
- let script2 = nbJsFromCodeInit:
- let b = 2
- script1.addCodeToJs:
- echo a
- script2.addCodeToJs:
- echo b
-
- echo script1.context["transformedCode"]
- echo script2.context["transformedCode"]
- for script in [script1, script2]:
- let code = script.context["transformedCode"].vString # eg. "\nlet a_469764253 = 1\n\necho a_469764292"
- let splits = code.splitWhitespace() # @["let", "a_469764257", "=", "1", "echo", "a_469764296"]
- check splits[1] == splits[5]
- foo() ]#
From dc4919c6bc5372007e35c6eeeab1727039df18f2 Mon Sep 17 00:00:00 2001
From: HugoGranstrom <5092565+HugoGranstrom@users.noreply.github.com>
Date: Thu, 27 Oct 2022 11:09:28 +0200
Subject: [PATCH 10/30] update text of counters.nim
---
docsrc/counters.nim | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docsrc/counters.nim b/docsrc/counters.nim
index ab0b2d1a..faf68c85 100644
--- a/docsrc/counters.nim
+++ b/docsrc/counters.nim
@@ -13,6 +13,7 @@ A button which increases a counter each time you click it. We will do this in tw
The first method is to use Nim like you would have used Javascript using `getElementById` and `addEventListener`:
"""
nbCode:
+ ## 0:
nbJsFromCodeGlobal:
import std/dom
## 1:
@@ -39,10 +40,11 @@ nbCode:
nbText: hlMd"""
Let's explain each part of the code:
+0. We import `std/dom` in a `nbJsFromCodeGlobal` block. `std/dom` is where many dom-manipulation functions are located.
1. We define a template called `counterButton` which will create a new counter button. So if you call it somewhere it will
place the widget there, that's the reusable part done. But it also takes an input `id: string`. This is to solve the problem of each widget needing unique ids. It can also be done with `nb.newId` as will be used in the Karax example.
2. Here we emit the `