@@ -118,14 +96,95 @@ const main = """
"""
-const revealCSS = """
+func revealMainToHtml*(doc: NbDoc, nb: Nb): string =
+ let docJson = %[] # it's unused
+ let renderedBlocks = nbContainerToHtml(doc, nb)
+ result = withNewlines:
+ hlHtmlF"""
+
+ """
+ nb.renderPartial("revealJS", docJson)
+ ""
+
+#[ const document = """
+
+
+ {{> head}}
+
+ {{> main}}
+
+
+""" ]#
+
+func revealNbDocToHtml*(blk: NbBlock, nb: Nb): string =
+ let doc = blk.NbDoc
+ let docJson = %[] # it's unused
+ result = withNewlines:
+ ""
+ """"""
+ nb.renderPartial("head", docJson)
+ ""
+ revealMainToHtml(doc, nb)
+ ""
+ ""
+
+func revealHeadToHtml*(blk: JsonNode, nb: Nb): string =
+ let nbStyle = nb.doc.context{"nb_style"}
+ result = withNewLines:
+ ""
+ """
"""
+ nb.renderPartial("revealCSS", blk)
+ if nbStyle.len > 0:
+ fmt"""
+
+ """
+ ""
+
+#[ const head = """
+
+
+ {{> revealCSS }}
+ {{#nb_style}}
+
+ {{/nb_style}}
+
+""" ]#
+
+const revealCSS = hlHtml"""
"""
-const revealJS = """
+func revealCSSToHtml*(blk: JsonNode, nb: Nb): string =
+ let revealVersion = nb.doc.context{"reveal_version"}.getStr
+ let slidesTheme = nb.doc.context{"slidesTheme"}.getStr
+ result = hlHtmlF"""
+
+
+
+"""
+
+const revealJS = hlHtml"""
@@ -134,25 +193,82 @@ const revealJS = """
{{/latex}}
"""
-proc useLocalReveal*(nb: var NbDoc, path: string) =
- let path = nb.homeDir.string / path
- let themeString = "{{{slidesTheme}}}"
- nb.partials["revealCSS"] = fmt"""
+func revealJSToHtml*(blk: JsonNode, nb: Nb): string =
+ let revealVersion = nb.doc.context{"reveal_version"}.getStr
+ result = withNewLines:
+ hlHtmlF"""
+
+
+
+ """
+ if nb.doc.context{"latex"}.getBool:
+ hlHtmlF""""""
+
+proc localRevealCss*(blk: JsonNode, nb: Nb): string =
+ let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
+ result = fmt"""
-
+
"""
-
- let latexStart = "{{#latex}}"
- let latexEnd = "{{/latex}}"
- nb.partials["revealJS"] = fmt"""
+
+proc localRevealJs*(blk: JsonNode, nb: Nb): string =
+ let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
+ result = withNewlines:
+ fmt"""
-{latexStart}
-
-{latexEnd}
- """
+ """
+ if nb.doc.context{"latex"}.getBool(true):
+ fmt""""""
+
+func nimiSlidesNbCodeSourcePartial*(blk: JsonNode, nb: Nb): string =
+ let code = blk{"code"}.getStr
+ if code.len > 0:
+ &"
{code.highlightNim}"
+ else:
+ ""
+
+func nimiSlidesNbCodeOutputPartial*(blk: JsonNode, nb: Nb): string =
+ let output = blk{"output"}.getStr
+ if output.len > 0:
+ #&"
{output} "
+ &"
{output} "
+ else:
+ ""
+
+
+
+newNbBlock(NbAnimateCode of NbCode):
+ highlightedLines: seq[seq[int]]
+ toHtml:
+ withNewLines:
+ nb.renderPartial("animateCodeSource", jsonutils.toJson(blk))
+ nbContainerToHtml(blk, nb)
+ nb.renderPartial("nbCodeOutput", jsonutils.toJson(blk))
+
+# "
{{&codeHighlighted}}\n" & nb.backend.partials["nbCodeOutput"]
+func highlightedLinesToString*(lines: seq[seq[int]]): string =
+ var linesString: string
+ if lines.len > 0:
+ linesString &= "|"
+ for lineBundle in lines:
+ for line in lineBundle:
+ linesString &= $line & ","
+ linesString &= "|"
+ if lines.len > 0:
+ linesString = linesString[0 .. ^3]
+ return linesString
+
+func nimiSlidesAnimateCodeSourcePartial*(blk: JsonNode, nb: Nb): string =
+ let highlightedLinesString = blk{"highlightedLines"}.to(seq[seq[int]]).highlightedLinesToString()
+ result = nimiSlidesNbCodeSourcePartial(blk, nb).replace("data-line-numbers", &"data-line-numbers=\"{highlightedLinesString}\"")
+
+proc useLocalReveal*(nb: var Nb, path: string) =
+ nb.doc.context["local_reveal_path"] = %path
+ nb.backend.partials["revealCSS"] = localRevealCss
+ nb.backend.partials["revealJS"] = localRevealJs
template setSlidesTheme*(theme: SlidesTheme) =
nb.context["slidesTheme"] = ($theme).toLower
@@ -170,46 +286,50 @@ template disableVerticalCentering*() =
template useScrollView*() =
nb.context["useScrollView"] = true
-proc addStyle*(doc: NbDoc, style: string) =
- doc.context["nb_style"] = doc.context["nb_style"].vString & "\n" & style
+proc addStyle*(nb: var Nb, style: string) =
+ nb.doc.context["nb_style"] = %(nb.doc.context{"nb_style"}.getStr & "\n" & style)
+
+proc revealTheme*(nb: var Nb) =
+ #nb.backend.partials["document"] = document
+ nb.backend.funcs["NbDoc"] = revealNbDocToHtml
+ nb.backend.partials["head"] = revealHeadToHtml
+ #nb.backend.partials["main"] = main
+
+ nb.backend.partials["nbCodeSource"] = nimiSlidesNbCodeSourcePartial
+ nb.backend.partials["nbCodeOutput"] = nimiSlidesNbCodeOutputPartial
-proc revealTheme*(doc: var NbDoc) =
- doc.partials["document"] = document
- doc.partials["head"] = head
- doc.partials["main"] = main
- doc.partials["nbCodeSource"] = "
{{&codeHighlighted}}"
- doc.partials["nbCodeOutput"] = "{{#output}}
{{output}} {{/output}}"
+ nb.backend.partials["animateCodeSource"] = nimiSlidesAnimateCodeSourcePartial
- doc.partials["revealCSS"] = revealCSS
- doc.partials["revealJS"] = revealJS
+ nb.backend.partials["revealCSS"] = revealCSSToHtml
+ nb.backend.partials["revealJS"] = revealJSToHtml
- doc.partials["animateCode"] = "
{{&codeHighlighted}}\n" & doc.partials["nbCodeOutput"]
- doc.renderPlans["animateCode"] = doc.renderPlans["nbCode"]
+ #[ nb.backend.partials["animateCode"] = "
{{&codeHighlighted}}\n" & nb.backend.partials["nbCodeOutput"]
+ #doc.renderPlans["animateCode"] = doc.renderPlans["nbCode"]
- doc.partials["fragmentStart"] = """
+ nb.backend.partials["fragmentStart"] = """
{{#fragments}}
{{/fragments}}
"""
- doc.partials["fragmentEnd"] = """
+ nb.backend.partials["fragmentEnd"] = """
{{#fragments}}
{{/fragments}}
"""
- doc.partials["bigText"] = """
{{&outputToHtml}} """
- doc.renderPlans["bigText"] = doc.renderPlans["nbText"]
+ nb.backend.partials["bigText"] = """
{{&outputToHtml}} """ ]#
+ #doc.renderPlans["bigText"] = doc.renderPlans["nbText"]
- doc.context["slidesTheme"] = "black"
- doc.context["nb_style"] = ""
- doc.context["reveal_version"] = reveal_version
+ nb.doc.context["slidesTheme"] = %"black"
+ nb.doc.context["nb_style"] = %""
+ nb.doc.context["reveal_version"] = %reveal_version
try:
- let slidesConfig = loadTomlSection(doc.rawCfg, "nimislides", NimiSlidesConfig)
+ let slidesConfig = loadTomlSection(nb.doc.rawCfg, "nimislides", NimiSlidesConfig)
if slidesConfig.localReveal != "":
echo "Using local Reveal.js installation specified in nimib.toml "
- doc.useLocalReveal(slidesConfig.localReveal)
+ nb.useLocalReveal(slidesConfig.localReveal)
except CatchableError:
discard # if it doesn't exists, just let it be
@@ -400,12 +520,6 @@ template listItem*(animation: FragmentAnimation, body: untyped) =
template listItem*(body: untyped) =
listItem(fadeInThenSemiOut, body)
-template animateCode*(lines: string, body: untyped) =
- newNbCodeBlock("animateCode", body):
- nb.blk.context["highlightLines"] = lines
- captureStdout(nb.blk.output):
- body
-
template animateCode*(lines: varargs[set[range[0..65535]], toSet], body: untyped) =
## Shows code and its output just like nbCode, but highlights different lines of the code in the order specified in `lines`.
## lines: Specify which lines to highlight and in which order. The lines can be specified using either:
@@ -417,19 +531,18 @@ template animateCode*(lines: varargs[set[range[0..65535]], toSet], body: untyped
## animateCode(1, 2..3, {4, 6}): body
## ```
## This will first highlight line 1, then lines 2 and 3, and lastly line 4 and 6.
- newNbCodeBlock("animateCode", body):
- var linesString: string
- if lines.len > 0:
- linesString &= "|"
- for lineBundle in lines:
- for line in lineBundle:
- linesString &= $line & ","
- linesString &= "|"
- if lines.len > 0:
- linesString = linesString[0 .. ^3]
- nb.blk.context["highlightLines"] = linesString
- captureStdout(nb.blk.output):
+ var highlightedLines: seq[seq[int]]
+ for line in lines:
+ var lineSeq: seq[int]
+ for l in line:
+ lineSeq.add l
+ highlightedLines.add lineSeq
+ let blk = newNbAnimateCode(highlightedLines=highlightedLines)
+ blk.code = getCode(body)
+ nb.withContainer(blk):
+ captureStdout(blk.output):
body
+ nb.add blk
template newAnimateCodeBlock*(cmd: untyped, impl: untyped) =
const cmdStr = astToStr(cmd)
From b79ee1ea5fd4c46a5f37781491417faff4e495fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Fri, 16 May 2025 14:34:59 +0200
Subject: [PATCH 02/22] slide is ported!
---
src/nimiSlides.nim | 72 ++++++++++++++++++++++++++++------------------
1 file changed, 44 insertions(+), 28 deletions(-)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index bd68eb2..5a09132 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -238,8 +238,6 @@ func nimiSlidesNbCodeOutputPartial*(blk: JsonNode, nb: Nb): string =
else:
""
-
-
newNbBlock(NbAnimateCode of NbCode):
highlightedLines: seq[seq[int]]
toHtml:
@@ -265,6 +263,39 @@ func nimiSlidesAnimateCodeSourcePartial*(blk: JsonNode, nb: Nb): string =
let highlightedLinesString = blk{"highlightedLines"}.to(seq[seq[int]]).highlightedLinesToString()
result = nimiSlidesNbCodeSourcePartial(blk, nb).replace("data-line-numbers", &"data-line-numbers=\"{highlightedLinesString}\"")
+newNbBlock(NbSlide of NbContainer):
+ options: SlideOptions
+ slideNumber: int
+ toHtml:
+ withNewLines:
+ nb.renderPartial("slideStart", jsonutils.toJson(blk))
+ nbContainerToHtml(blk, nb)
+ nb.renderPartial("slideEnd", jsonutils.toJson(blk))
+
+proc slideOptionsToAttributes*(options: SlideOptions, slideNumber: int): string =
+ result.add """data-nimib-slide-number="$1" """ % [$slideNumber]
+ if options.autoAnimate:
+ result.add "data-auto-animate "
+ if options.colorBackground.len > 0:
+ result.add """data-background-color="$1" """ % [options.colorBackground]
+ elif options.imageBackground.len > 0:
+ result.add """data-background-image="$1" """ % [options.imageBackground]
+ elif options.videoBackground.len > 0:
+ result.add """data-background-video="$1" """ % [options.videoBackground]
+ elif options.iframeBackground.len > 0:
+ result.add """data-background-iframe="$1" """ % [options.iframeBackground]
+ if options.iframeInteractive:
+ result.add "data-background-interactive "
+ elif options.gradientBackground.len > 0:
+ result.add """data-background-gradient="$1" """ % [options.gradientBackground]
+
+func nimiSlidesSlideStartPartial*(blk: JsonNode, nb: Nb): string =
+ let optionsStr = blk{"options"}.to(SlideOptions).slideOptionsToAttributes(blk{"slideNumber"}.getInt)
+ result = &"
"
+
+func nimiSlidesSlideEndPartial*(blk: JsonNode, nb: Nb): string =
+ " "
+
proc useLocalReveal*(nb: var Nb, path: string) =
nb.doc.context["local_reveal_path"] = %path
nb.backend.partials["revealCSS"] = localRevealCss
@@ -303,9 +334,9 @@ proc revealTheme*(nb: var Nb) =
nb.backend.partials["revealCSS"] = revealCSSToHtml
nb.backend.partials["revealJS"] = revealJSToHtml
- #[ nb.backend.partials["animateCode"] = "
{{&codeHighlighted}}\n" & nb.backend.partials["nbCodeOutput"]
- #doc.renderPlans["animateCode"] = doc.renderPlans["nbCode"]
-
+ nb.backend.partials["slideStart"] = nimiSlidesSlideStartPartial
+ nb.backend.partials["slideEnd"] = nimiSlidesSlideEndPartial
+ #[
nb.backend.partials["fragmentStart"] = """
{{#fragments}}
@@ -335,39 +366,24 @@ proc revealTheme*(nb: var Nb) =
var currentFragment*, currentSlideNumber*: int
-proc slideOptionsToAttributes*(options: SlideOptions): string =
- result.add """data-nimib-slide-number="$1" """ % [$currentSlideNumber]
- if options.autoAnimate:
- result.add "data-auto-animate "
- if options.colorBackground.len > 0:
- result.add """data-background-color="$1" """ % [options.colorBackground]
- elif options.imageBackground.len > 0:
- result.add """data-background-image="$1" """ % [options.imageBackground]
- elif options.videoBackground.len > 0:
- result.add """data-background-video="$1" """ % [options.videoBackground]
- elif options.iframeBackground.len > 0:
- result.add """data-background-iframe="$1" """ % [options.iframeBackground]
- if options.iframeInteractive:
- result.add "data-background-interactive "
- elif options.gradientBackground.len > 0:
- result.add """data-background-gradient="$1" """ % [options.gradientBackground]
-
-template slide*(options: untyped, body: untyped): untyped =
+template slide*(toptions: untyped, body: untyped): untyped =
currentSlideNumber += 1
-
- nbRawHtml: "
" % [slideOptionsToAttributes(options)]
+ let blk = newNbSlide(slideNumber=currentSlideNumber, options=toptions)
+
when declaredInScope(CountVarNimiSlide):
when CountVarNimiSlide < 2:
static: inc CountVarNimiSlide
- body
+ nb.withContainer(blk):
+ body
static: dec CountVarNimiSlide
else:
{.error: "You can only nest slides once!".}
else:
var CountVarNimiSlide {.inject, compileTime.} = 1 # we just entered the first level
- body
+ nb.withContainer(blk):
+ body
static: dec CountVarNimiSlide
- nbRawHtml: " "
+ nb.add blk
template slide*(body: untyped) =
slide(slideOptions()):
From 6e8a63521b5f3043838dd68054e9c1d1936be6b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Fri, 16 May 2025 16:04:28 +0200
Subject: [PATCH 03/22] fragments are working!!!
---
src/nimiSlides.nim | 80 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 63 insertions(+), 17 deletions(-)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index 5a09132..2a34d5f 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -28,6 +28,10 @@ type
highlightCurrentGreen = "highlight-current-green"
highlightCurrentBlue = "highlight-current-blue"
+ FragmentItem* = object
+ classStr: string
+ fragIndex: int
+
SlidesTheme* = enum
Black, Beige, Blood, Dracula, League, Moon, Night, Serif, Simple, Sky, Solarized, White
@@ -296,6 +300,30 @@ func nimiSlidesSlideStartPartial*(blk: JsonNode, nb: Nb): string =
func nimiSlidesSlideEndPartial*(blk: JsonNode, nb: Nb): string =
""
+newNbBlock(NbFragment of NbContainer):
+ fragments: seq[FragmentItem]
+ toHtml:
+ withNewLines:
+ nb.renderPartial("fragmentStart", jsonutils.toJson(blk))
+ nbContainerToHtml(blk, nb)
+ nb.renderPartial("fragmentEnd", jsonutils.toJson(blk))
+
+func nimiSlidesFragmentStartPartial*(blk: JsonNode, nb: Nb): string =
+ if blk{"fragments"}.len > 0:
+ result = ""
+ for fragment in blk{"fragments"}:
+ let classStr = fragment{"classStr"}.getStr
+ let fragIndex = fragment{"fragIndex"}.getInt
+ result &= hlHtmlF"""
+
+ """
+ result &= "\n"
+ else:
+ result = ""
+
+func nimiSlidesFragmentEndPartial*(blk: JsonNode, nb: Nb): string =
+ "
\n".repeat(blk{"fragments"}.len)
+
proc useLocalReveal*(nb: var Nb, path: string) =
nb.doc.context["local_reveal_path"] = %path
nb.backend.partials["revealCSS"] = localRevealCss
@@ -336,19 +364,10 @@ proc revealTheme*(nb: var Nb) =
nb.backend.partials["slideStart"] = nimiSlidesSlideStartPartial
nb.backend.partials["slideEnd"] = nimiSlidesSlideEndPartial
- #[
- nb.backend.partials["fragmentStart"] = """
-{{#fragments}}
-
-{{/fragments}}
- """
-
- nb.backend.partials["fragmentEnd"] = """
-{{#fragments}}
-
-{{/fragments}}
- """
+ nb.backend.partials["fragmentStart"] = nimiSlidesFragmentStartPartial
+ nb.backend.partials["fragmentEnd"] = nimiSlidesFragmentEndPartial
+ #[
nb.backend.partials["bigText"] = """
{{&outputToHtml}} """ ]#
#doc.renderPlans["bigText"] = doc.renderPlans["nbText"]
@@ -393,6 +412,23 @@ template slideAutoAnimate*(body: untyped) =
slide(slideOptions(autoAnimate=true)):
body
+template fragmentCoreOld*(animations: openArray[seq[FragmentAnimation]], endAnimations: openArray[seq[FragmentAnimation]], indexOffset: untyped, incrementCounter: untyped, body: untyped) =
+ ## Creates a fragment of the content of body. Nesting works.
+ ## animations: each seq in animations are animations that are to be applied at the same time. The first seq's animations
+ ## are applied on the first button click, and the second seq's animations on the second click etc.
+ ## endAnimations: animations that should be applied AT THE END of block.
+ ## Example:
+ ## `fragment(@[@[fadeIn, highlightBlue], @[shrinks, semiFadeOut]]): block` will at the first click of a button fadeIn and highlightBlue
+ ## the content of the block. At the second click the same content will shrink and semiFadeOut. This code is also equivilent with
+ ## `fragment(@[@[fadeIn, highlightBlue]]): fragment(@[@[shrinks, semiFadeOut]]): block`.
+ ## `fragment(@[@[fadeIn]], @[@[fadeOut]]): block` will first fadeIn the entire block and perform eventual animations in nested fragments. Once
+ ## all of those are finished, it will run fadeOut on the entire block and its subfragments.
+ var fragments: seq[Table[string, string]]
+ fragmentStartBlock(fragments, animations, endAnimations, indexOffset, incrementCounter)
+ var startBlock = nb.blk # this *should* be the block created by fragmentStartBlock
+ body
+ fragmentEndBlock(fragments, animations, endAnimations, startBlock)
+
template fragmentStartBlock(fragments: seq[Table[string, string]], animations: openArray[seq[FragmentAnimation]], endAnimations: openArray[seq[FragmentAnimation]], indexOffset: int, incrementCounter: bool) =
newNbSlimBlock("fragmentStart"):
for level in animations:
@@ -432,11 +468,21 @@ template fragmentCore*(animations: openArray[seq[FragmentAnimation]], endAnimati
## `fragment(@[@[fadeIn, highlightBlue]]): fragment(@[@[shrinks, semiFadeOut]]): block`.
## `fragment(@[@[fadeIn]], @[@[fadeOut]]): block` will first fadeIn the entire block and perform eventual animations in nested fragments. Once
## all of those are finished, it will run fadeOut on the entire block and its subfragments.
- var fragments: seq[Table[string, string]]
- fragmentStartBlock(fragments, animations, endAnimations, indexOffset, incrementCounter)
- var startBlock = nb.blk # this *should* be the block created by fragmentStartBlock
- body
- fragmentEndBlock(fragments, animations, endAnimations, startBlock)
+ let blk = newNbFragment()
+ for level in animations:
+ if level.len > 1 and fadeIn in level:
+ # Add a fadeIn fragment at the same frame
+ blk.fragments.add FragmentItem(classStr: "", fragIndex: currentFragment + indexOffset)
+ blk.fragments.add FragmentItem(classStr: level.join(" "), fragIndex: currentFragment + indexOffset)
+ if incrementCounter:
+ currentFragment += 1
+
+ withContainer(nb, blk):
+ body
+
+ for level in endAnimations:
+ blk.fragments.add FragmentItem(classStr: level.join(" "), fragIndex: currentFragment)
+ nb.add blk
template fragmentCore*(animations: openArray[seq[FragmentAnimation]], endAnimations: openArray[seq[FragmentAnimation]], body: untyped) =
fragmentCore(animations, endAnimations, 0, true, body)
From 7bce18b5436e90f7eb1f159667f61a4f75b07154 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Fri, 16 May 2025 16:11:01 +0200
Subject: [PATCH 04/22] bigText works
---
src/nimiSlides.nim | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index 2a34d5f..fddc58a 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -324,6 +324,13 @@ func nimiSlidesFragmentStartPartial*(blk: JsonNode, nb: Nb): string =
func nimiSlidesFragmentEndPartial*(blk: JsonNode, nb: Nb): string =
"
\n".repeat(blk{"fragments"}.len)
+newNbBlock(NbBigText of NbText):
+ toHtml:
+ withNewlines:
+ "
"
+ nb.renderPartial("nbText", jsonutils.toJson(blk))
+ " "
+
proc useLocalReveal*(nb: var Nb, path: string) =
nb.doc.context["local_reveal_path"] = %path
nb.backend.partials["revealCSS"] = localRevealCss
@@ -367,9 +374,6 @@ proc revealTheme*(nb: var Nb) =
nb.backend.partials["fragmentStart"] = nimiSlidesFragmentStartPartial
nb.backend.partials["fragmentEnd"] = nimiSlidesFragmentEndPartial
- #[
- nb.backend.partials["bigText"] = """
{{&outputToHtml}} """ ]#
- #doc.renderPlans["bigText"] = doc.renderPlans["nbText"]
nb.doc.context["slidesTheme"] = %"black"
nb.doc.context["nb_style"] = %""
@@ -679,9 +683,9 @@ template typewriter*(textMessage: string, typeSpeed = 50, alignment = "center")
discard
))
-template bigText*(text: string) =
- newNbSlimBlock("bigText"):
- nb.blk.output = text
+template bigText*(ttext: string) =
+ let blk = newNbBigText(text=ttext)
+ nb.add blk
template fitImage*(src: string) =
nbRawHtml: hlHtml"""
""" % [src]
From 17c2faee224caab317e93ffcb65978f5a0f17292 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Sun, 18 May 2025 10:56:52 +0200
Subject: [PATCH 05/22] implement Pietors brilliant idea of a NbDiv block for
column blocks
---
src/nimiSlides.nim | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index fddc58a..2f26868 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -698,39 +698,32 @@ template speakerNote*(text: string) =
""" % [markdown(text)]
template align*(text: string, body: untyped) =
- nbRawHtml: """
-
-""" % text
- body
- nbRawHtml: "
"
+ nbDiv(styles="text-align: $1;" % text, classes=""):
+ body
#templates can't have default args and untyped args at the same time
#so we use overloading to get the same effect
template columns*(columnGap: float, body: untyped) =
#tempted to use fmt"", but strformat doesn't support template args in the format string
- nbRawHtml: """
- """ % $columnGap
- body
- nbRawHtml: "
"
+ nbDiv(styles="display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); overflow-wrap: break-word; column-gap: $1 em;" % $columnGap, classes=""):
+ body
template columns*(body: untyped) =
columns(1.0,body)
template adaptiveColumns*(columnGap: float, body: untyped) =
- nbRawHtml: """
- """ % $columnGap
- body
- nbRawHtml: "
"
+ nbDiv(styles="display: grid; grid-auto-flow: column; overflow-wrap: break-word; column-gap: $1 em;" % $columnGap, classes=""):
+ body
+
template adaptiveColumns*(body: untyped) =
adaptiveColumns(1.0,body)
template column*(bodyInner: untyped) =
## column should always be used inside a `columns` block
- nbRawHtml: "
"
- bodyInner
- nbRawHtml: "
"
+ nbDiv:
+ bodyInner
template footer*(text: string, fontSize: int = 20, opacity: range[0.0 .. 1.0] = 0.6, rawHtml = false) =
nb.context["footerFontSize"] = fontSize
From c75a6c886c6b81712f0dd3e9edef840b840fd99f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Fri, 29 May 2026 14:12:25 +0200
Subject: [PATCH 06/22] update deps to use nimib 0.4.0
---
nimiSlides.nimble | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/nimiSlides.nimble b/nimiSlides.nimble
index f528715..619bc99 100644
--- a/nimiSlides.nimble
+++ b/nimiSlides.nimble
@@ -1,6 +1,6 @@
# Package
-version = "0.2.6"
+version = "0.4.0"
author = "Hugo Granström"
description = "Reveal.js theme for nimib"
license = "MIT"
@@ -9,7 +9,7 @@ srcDir = "src"
# Dependencies
requires "nim >= 1.4.0"
-requires "nimib >= 0.3.9"
+requires "nimib >= 0.4.0"
import os
From 1202ac1baeba6b92955f07f9cd95b7fa58aaa191 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Fri, 29 May 2026 14:15:14 +0200
Subject: [PATCH 07/22] remove Nim 1.6 from CI
---
.github/workflows/valid.yml | 1 -
nimiSlides.nimble | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/valid.yml b/.github/workflows/valid.yml
index d7e5c2c..ddc1c74 100644
--- a/.github/workflows/valid.yml
+++ b/.github/workflows/valid.yml
@@ -11,7 +11,6 @@ jobs:
strategy:
matrix:
nim:
- - '1.6.x'
- 'stable'
- 'devel'
fail-fast: false
diff --git a/nimiSlides.nimble b/nimiSlides.nimble
index 619bc99..c127b2b 100644
--- a/nimiSlides.nimble
+++ b/nimiSlides.nimble
@@ -8,7 +8,7 @@ srcDir = "src"
# Dependencies
-requires "nim >= 1.4.0"
+requires "nim >= 2.0.0"
requires "nimib >= 0.4.0"
import os
From 21e730d8194c967f11459f4ac1814cebd4932d70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Sun, 31 May 2026 20:32:00 +0200
Subject: [PATCH 08/22] make all presntations run
---
docsrc/nimconf2022.nim | 99 ++++++++----------------------------------
docsrc/showcase.nim | 2 +-
src/nimiSlides.nim | 73 ++++++++++++++++---------------
3 files changed, 56 insertions(+), 118 deletions(-)
diff --git a/docsrc/nimconf2022.nim b/docsrc/nimconf2022.nim
index 63092ac..a704c59 100644
--- a/docsrc/nimconf2022.nim
+++ b/docsrc/nimconf2022.nim
@@ -6,71 +6,6 @@ import nimiSlides
nbInit(theme = revealTheme)
nb.useLatex
-template nbCodeDontRun*(body: untyped) =
- newNbCodeBlock("nbCodeDontRun", body):
- discard
-
-template nimibCode*(body: untyped) =
- #nbText: "Nimib code:"
- newNbCodeBlock("nimibCode", body):
- discard
- fragmentFadeIn:
- nbRawHtml: "
"
- #nbText: "Output:"
- body
-
-template nimibCodeAnimate*(lines: varargs[seq[HSlice[int, int]]], body: untyped) =
- ## Shows code and its output just like nbCode, but highlights different lines of the code in the order specified in `lines`.
- ## lines: Specify which lines to highlight and in which order. (Must be specified as a seq[HSlice])
- ## Ex:
- ## ```nim
- ## animateCode(@[1..1], @[3..4, 6..6]): body
- ## ```
- ## This will first highlight line 1, then lines 3, 4 and 6.
- newNbCodeBlock("nimibCodeAnimate", body):
- var linesString: string
- if lines.len > 0:
- linesString &= "|"
- for lineBundle in lines:
- for line in lineBundle:
- linesString &= $line.a & "-" & $line.b & ","
- linesString &= "|"
- if lines.len > 0:
- linesString = linesString[0 .. ^3]
- nb.blk.context["highlightLines"] = linesString
- fragmentFadeIn:
- nbRawHtml: "
"
- body
-
-template nimibCodeAnimate*(lines: varargs[HSlice[int, int], toHSlice], body: untyped) =
- ## Shows code and its output just like nbCode, but highlights different lines of the code in the order specified in `lines`.
- ## lines: Specify which lines to highlight and in which order. (Must be specified as a HSlice)
- ## Ex:
- ## ```nim
- ## animateCode(1..1, 2..3, 5..5, 4..4): body
- ## ```
- ## This will first highlight line 1, then lines 2 and 3, then line 5 and last line 4.
- var s: seq[seq[HSlice[int, int]]]
- for line in lines:
- s.add @[line]
- nimibCodeAnimate(s):
- body
-
-nb.partials["nimibCode"] = nb.partials["nbCode"]
-nb.renderPlans["nimibCode"] = nb.renderPlans["nbCode"]
-nb.partials["nimibCodeAnimate"] = nb.partials["animateCode"]
-nb.renderPlans["nimibCodeAnimate"] = nb.renderPlans["animateCode"]
-
-template nbCodeDontRunAnimateImpl(body: untyped) =
- discard
-
-newAnimateCodeBlock(nbCodeDontRunAnimate, nbCodeDontRunAnimateImpl)
-
-nb.partials["nbCodeDontRun"] = nb.partials["nbCode"]
-nb.renderPlans["nbCodeDontRun"] = nb.renderPlans["nbCode"]
-nb.partials["nimibCode"] = nb.partials["nbCode"]
-nb.renderPlans["nimibCode"] = nb.renderPlans["nbCode"]
-
template nimConfSlide(body: untyped) =
slide:
cornerImage("https://github.com/nim-lang/assets/raw/master/Art/logo-crown.png", UpperRight, size=100, animate=false)
@@ -252,12 +187,12 @@ Text can be *italic*, **bold** or ~~crossed over~~.
nimConfSlide:
nbText: """### Installation"""
- nbCodeDontRun:
+ nbCodeSkip:
nimble install nimiSlides
nimConfSlide:
nbText: "### Setting up"
- nbCodeDontRun:
+ nbCodeSkip:
import nimib, nimiSlides
nbInit(theme = revealTheme)
@@ -273,7 +208,7 @@ Text can be *italic*, **bold** or ~~crossed over~~.
columns:
column:
fragmentFadeIn:
- nbCodeDontRunAnimate(1..4, 1..2, 3..4, 6..12, 6, 7..8, 9..10, 11..12):
+ animateCodeSkip(1..4, 1..2, 3..4, 6..12, 6, 7..8, 9..10, 11..12):
slide:
nbText: "1"
slide:
@@ -431,7 +366,7 @@ slide:
listItem: nbText: "Back again"
nimConfSlide:
- nimibCodeAnimate(1, 2..3, 4, 5..6, 7, 9):
+ animateCode(1, 2..3, 4, 5..6, 7, 9):
unorderedList:
listItem:
nbText: "First item"
@@ -460,7 +395,7 @@ slide:
nimConfAutoSlide:
nbText: "## Columns"
- nimibCodeAnimate(1, 2..3, 4..5, 6..7):
+ animateCode(1, 2..3, 4..5, 6..7):
columns:
column:
nbText: "Left"
@@ -509,7 +444,7 @@ slide:
slide(slideOptions(colorBackground = "darkviolet")):
nbText: "## Color Background"
- nbCodeDontRun:
+ nbCodeSkip:
slide(slideOptions(colorBackground = "darkviolet")):
nbText: "## Color Background"
@@ -518,7 +453,7 @@ slide:
nimConfSlide:
nbText: "## Image Background"
- nbCodeDontRun:
+ nbCodeSkip:
slide(slideOptions(imageBackground = "https://github.com/nim-lang/assets/raw/master/Art/logo-crown.png")):
discard
@@ -527,13 +462,13 @@ slide:
nimConfSlide:
nbText: "## Iframe Background"
- nbCodeDontRun:
+ nbCodeSkip:
slide(slideOptions(iframeBackground = "https://nim-lang.org/")):
discard
nimConfSlide:
nbText: "## Video Background"
- nbCodeDontRun:
+ nbCodeSkip:
slide(slideOptions(videoBackground = "link/to/videofile.mp4")):
discard
fragmentFadeIn:
@@ -575,7 +510,7 @@ slide:
"""
nimConfSlide:
- nbCodeDontRunAnimate(1..4, 6..10, 12..17):
+ animateCodeSkip(1..4, 6..10, 12..17):
slide(slideOptions(autoAnimate=true)):
nbText: """
- First
@@ -639,7 +574,7 @@ slide:
nbText: "## Using Templates"
nimConfAutoSlide:
nbText: "## Using Templates"
- nbCodeDontRunAnimate({1, 3, 6}):
+ animateCodeSkip({1, 3, 6}):
slide(slideOptions(autoAnimate=true)):
nbText: "## Animate header"
slide(slideOptions(autoAnimate=true)):
@@ -654,7 +589,7 @@ slide:
nimConfAutoSlide:
nbText: "## Using Templates"
- nbCodeDontRunAnimate(1, 2..3, 3, 5..6):
+ animateCodeSkip(1, 2..3, 3, 5..6):
template slideAutoAnimate(body: untyped) =
slide(slideOptions(autoAnimate=true)):
body
@@ -667,7 +602,7 @@ slide:
stackElements:
fragment(fadeInThenOut):
nbText: "#### Without template"
- nbCodeDontRun:
+ nbCodeSkip:
slide(slideOptions(autoAnimate=true)):
nbText: "## Animate header"
slide(slideOptions(autoAnimate=true)):
@@ -679,7 +614,7 @@ slide:
nbText: "And this"
fragmentFadeIn:
nbText: "#### With template"
- nbCodeDontRun:
+ nbCodeSkip:
slideAutoAnimate:
nbText: "## Animate header"
slideAutoAnimate:
@@ -698,10 +633,10 @@ slide:
nbText: "Example: Histogram of Gaussian for different N"
nimConfAutoSlide:
nbText: "## Loops ♻️ + Generate images 🖼️"
- nbCodeDontRunAnimate(1, 2, 3, 4..7, 9, 10, 11):
+ animateCodeSkip(1, 2, 3, 4..7, 9, 10, 11):
for n in [50, 100, 1000, 10000]:
let filename = &"images/gauss-{n}.png"
- let samples = newSeqWith[float](n, gauss(0.0, 1.0))
+ let samples = newSeqWith(n, gauss(0.0, 1.0))
let df = toDf(samples)
ggplot(df, aes("samples")) +
geom_histogram(fillColor="green") +
@@ -714,7 +649,7 @@ slide:
slide:
for n in [50, 100, 1000, 10000]:
let filename = &"images/gauss-{n}.png"
- let samples = newSeqWith[float](n, gauss(0.0, 1.0))
+ let samples = newSeqWith(n, gauss(0.0, 1.0))
let df = toDf(samples)
ggplot(df, aes("samples")) +
geom_histogram(fillColor="green") +
diff --git a/docsrc/showcase.nim b/docsrc/showcase.nim
index 0fdaa5a..5315751 100644
--- a/docsrc/showcase.nim
+++ b/docsrc/showcase.nim
@@ -5,7 +5,7 @@ nbInit(theme = revealTheme)
nb.useLatex()
when defined(themeWhite):
- nb.filename = "./showcase_white.html"
+ nb.doc.filename = "./showcase_white.html"
setSlidesTheme(White)
else:
setSlidesTheme(Moon)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index 2f26868..646a4b3 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -208,16 +208,18 @@ func revealJSToHtml*(blk: JsonNode, nb: Nb): string =
if nb.doc.context{"latex"}.getBool:
hlHtmlF""""""
-proc localRevealCss*(blk: JsonNode, nb: Nb): string =
- let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
+func localRevealCss*(blk: JsonNode, nb: Nb): string =
+ {.cast(noSideEffect).}:
+ let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
result = fmt"""
"""
-proc localRevealJs*(blk: JsonNode, nb: Nb): string =
- let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
+func localRevealJs*(blk: JsonNode, nb: Nb): string =
+ {.cast(noSideEffect).}:
+ let path = nb.doc.homeDir.string / nb.doc.context{"local_reveal_path"}.getStr
result = withNewlines:
fmt"""
@@ -331,26 +333,26 @@ newNbBlock(NbBigText of NbText):
nb.renderPartial("nbText", jsonutils.toJson(blk))
""
-proc useLocalReveal*(nb: var Nb, path: string) =
+func useLocalReveal*(nb: var Nb, path: string) =
nb.doc.context["local_reveal_path"] = %path
nb.backend.partials["revealCSS"] = localRevealCss
nb.backend.partials["revealJS"] = localRevealJs
template setSlidesTheme*(theme: SlidesTheme) =
- nb.context["slidesTheme"] = ($theme).toLower
+ nb.doc.context["slidesTheme"] = %($theme).toLower
template useScrollWheel*() =
## Enable using the scroll-wheel to step forward in slides.
- nb.context["useScrollWheel"] = true
+ nb.doc.context["useScrollWheel"] = %true
template showSlideNumber*() =
- nb.context["showSlideNumber"] = true
+ nb.doc.context["showSlideNumber"] = %true
template disableVerticalCentering*() =
- nb.context["disableCentering"] = true
+ nb.doc.context["disableCentering"] = %true
template useScrollView*() =
- nb.context["useScrollView"] = true
+ nb.doc.context["useScrollView"] = %true
proc addStyle*(nb: var Nb, style: string) =
nb.doc.context["nb_style"] = %(nb.doc.context{"nb_style"}.getStr & "\n" & style)
@@ -610,25 +612,26 @@ template animateCode*(lines: varargs[set[range[0..65535]], toSet], body: untyped
body
nb.add blk
-template newAnimateCodeBlock*(cmd: untyped, impl: untyped) =
- const cmdStr = astToStr(cmd)
-
- template `cmd`*(lines: varargs[set[range[0..65535]], toSet], body: untyped) =
- newNbCodeBlock(cmdStr, body):
- var linesString: string
- if lines.len > 0:
- linesString &= "|"
- for lineBundle in lines:
- for line in lineBundle:
- linesString &= $line & ","
- linesString &= "|"
- if lines.len > 0:
- linesString = linesString[0 .. ^3]
- nb.blk.context["highlightLines"] = linesString
- impl(body)
-
- nb.partials[cmdStr] = nb.partials["animateCode"]
- nb.renderPlans[cmdStr] = nb.renderPlans["animateCode"]
+template animateCodeSkip*(lines: varargs[set[range[0..65535]], toSet], body: untyped) =
+ ## Shows code and its output just like nbCode, but highlights different lines of the code in the order specified in `lines`.
+ ## lines: Specify which lines to highlight and in which order. The lines can be specified using either:
+ ## - An `int` (highlight single line)
+ ## - A slice `x..y` (highlight a range of consequative lines)
+ ## - A set {x, y..z} (highlight any combination of lines)
+ ## Ex:
+ ## ```nim
+ ## animateCode(1, 2..3, {4, 6}): body
+ ## ```
+ ## This will first highlight line 1, then lines 2 and 3, and lastly line 4 and 6.
+ var highlightedLines: seq[seq[int]]
+ for line in lines:
+ var lineSeq: seq[int]
+ for l in line:
+ lineSeq.add l
+ highlightedLines.add lineSeq
+ let blk = newNbAnimateCode(highlightedLines=highlightedLines)
+ blk.code = getCode(body)
+ nb.add blk
template typewriter*(textMessage: string, typeSpeed = 50, alignment = "center") =
let localText = textMessage
@@ -637,7 +640,7 @@ template typewriter*(textMessage: string, typeSpeed = 50, alignment = "center")
# HTML and add eventlistener
# check what we get back from reveal's event
let fragIndex = currentFragment # important it is before fragmentFadeIn!
- let id = "typewriter" & $nb.newId()
+ let id = "typewriter" & $nb.doc.newId()
fragmentFadeIn:
nbKaraxCode(id, localText, fragIndex, speed, align):
import nimiSlides/revealFFI
@@ -726,12 +729,12 @@ template column*(bodyInner: untyped) =
bodyInner
template footer*(text: string, fontSize: int = 20, opacity: range[0.0 .. 1.0] = 0.6, rawHtml = false) =
- nb.context["footerFontSize"] = fontSize
- nb.context["footerOpacity"] = opacity
+ nb.doc.context["footerFontSize"] = %fontSize
+ nb.doc.context["footerOpacity"] = %opacity
if rawHtml:
- nb.context["revealFooter"] = text
+ nb.doc.context["revealFooter"] = %text
else:
- nb.context["revealFooter"] = markdown(text, config=initGfmConfig()).dup(removeSuffix)
+ nb.doc.context["revealFooter"] = %markdown(text, config=initGfmConfig()).dup(removeSuffix)
nbJsFromCodeGlobal:
import nimiSlides/revealFFI
@@ -774,7 +777,7 @@ template cornerImage*(image: string, corner: Corner, size: int = 100, animate =
"transition: all 0.2s ease-out;"
else:
""
- let id = "cornerImage-" & $nb.newId()
+ let id = "cornerImage-" & $nb.doc.newId()
let html = &"""
""" % [image, id, $size, vertical, horizontal, animateString]
let currentSlideNr = currentSlideNumber
From 84033e3ede3b69eb17e5899189b60f67592abf95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Sun, 31 May 2026 20:38:59 +0200
Subject: [PATCH 09/22] update ci to newer versions
---
.github/workflows/docs.yml | 4 +++-
.github/workflows/valid.yml | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index a2c20d9..cc0d9f1 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -12,7 +12,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- - uses: iffy/install-nim@v4
+ - name: apt install
+ run: sudo apt install -y libpcre3 libblas-dev liblapack-dev
+ - uses: iffy/install-nim@v5
- name: Generate
run: |
nimble install -y
diff --git a/.github/workflows/valid.yml b/.github/workflows/valid.yml
index ddc1c74..fcb04f6 100644
--- a/.github/workflows/valid.yml
+++ b/.github/workflows/valid.yml
@@ -17,10 +17,11 @@ jobs:
name: Nim ${{ matrix.nim }}
steps:
- uses: actions/checkout@v2
- - uses: jiro4989/setup-nim-action@v1
+ - uses: jiro4989/setup-nim-action@v2.2.2
with:
nim-version: ${{ matrix.nim }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
+ - run: sudo apt install libpcre3 libpcre3-dev
- name: Install deps
run: |
nimble install -y
From 4d45aec774f2732cc9d1562627c6b29434bd6415 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Sun, 31 May 2026 20:52:19 +0200
Subject: [PATCH 10/22] install lapack
---
.github/workflows/valid.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/valid.yml b/.github/workflows/valid.yml
index fcb04f6..970bb66 100644
--- a/.github/workflows/valid.yml
+++ b/.github/workflows/valid.yml
@@ -21,7 +21,7 @@ jobs:
with:
nim-version: ${{ matrix.nim }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
- - run: sudo apt install libpcre3 libpcre3-dev
+ - run: sudo apt install libpcre3 libpcre3-dev liblapack-dev
- name: Install deps
run: |
nimble install -y
From 191b3678c06bd252750bdce4adb58beefe9706ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Mon, 1 Jun 2026 20:35:01 +0200
Subject: [PATCH 11/22] add autoAnimateSlidesCustom which accepts a custom
slide template
---
src/nimiSlides/autoAnimation.nim | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/nimiSlides/autoAnimation.nim b/src/nimiSlides/autoAnimation.nim
index e866205..1f0b438 100644
--- a/src/nimiSlides/autoAnimation.nim
+++ b/src/nimiSlides/autoAnimation.nim
@@ -2,11 +2,14 @@ import std/[strutils]
import nimib
import ./[conversions]
-template autoAnimateSlides*(nSlides: int, body: untyped) =
+template autoAnimateSlidesCustom*(nSlides: int, slideTemplate: untyped, body: untyped) =
for autoAnimateCounter {.inject.} in 1 .. nSlides:
- slide(slideOptions(autoAnimate=true)):
+ slideTemplate(slideOptions(autoAnimate=true)):
body
+template autoAnimateSlides*(nSlides: int, body: untyped) =
+ autoAnimateSlidesCustom(nSlides, slide, body)
+
template showAt*(slideNrs: varargs[set[range[0..65535]], toSet], body: untyped) = # how to auto convert to set like in varargs?
# use vararg and union all results!
# This way you don't need to use the set syntax but can pass in `showOn(1, 2, 3)` instead.
From fa9a73a8fa53646a34011b6840442456b8cd3c32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Mon, 1 Jun 2026 20:35:31 +0200
Subject: [PATCH 12/22] start working on nimconf2026 (if you see this, congrats
on finding out first ;))
---
docsrc/nimconf2026.nim | 113 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 docsrc/nimconf2026.nim
diff --git a/docsrc/nimconf2026.nim b/docsrc/nimconf2026.nim
new file mode 100644
index 0000000..66b4c6d
--- /dev/null
+++ b/docsrc/nimconf2026.nim
@@ -0,0 +1,113 @@
+import std / [strutils, random, sequtils, math, strformat, json]
+import nimib, nimib / [capture]
+import nimiSlides
+
+nbInit(theme = revealTheme)
+nb.useLatex
+
+template nimSlide(body: untyped) =
+ slide:
+ cornerImage("https://github.com/nim-lang/assets/raw/master/Art/logo-crown.png", UpperRight, size=100, animate=false)
+ body
+
+template nimSlide(options: SlideOptions, body: untyped) =
+ slide(options):
+ cornerImage("https://github.com/nim-lang/assets/raw/master/Art/logo-crown.png", UpperRight, size=100, animate=false)
+ body
+
+template nimConfTheme*() =
+ setSlidesTheme(Black)
+ let nimYellow = "#FFE953"
+ nb.addStyle: """
+:root {
+ --r-background-color: #181922;
+ --r-heading-color: $1;
+ --r-link-color: $1;
+ --r-selection-color: $1;
+ --r-link-color-dark: darken($1 , 15%)
+}
+
+.reveal ul, .reveal ol {
+ display: block;
+ text-align: left;
+}
+
+li::marker {
+ color: $1;
+ content: "»";
+}
+
+li {
+ padding-left: 12px;
+}
+""" % [nimYellow]
+
+nimConfTheme()
+
+newNbBlock(FieldSet of NbContainer):
+ title: string
+ toHtml:
+ let renderedBlocks = nbContainerToHtml(blk, nb)
+ hlHtmlF"""
+
+ {blk.title}
+ {renderedBlocks}
+
+ """
+
+template fieldSet(ttitle: string, body: untyped) =
+ let blk = newFieldSet(title=ttitle)
+ nb.withContainer(blk):
+ body
+ nb.add blk
+
+newNbBlock(JsonShow of NbContainer):
+ toHtml:
+ let blocksSerialized = blk.blocks.toJson().fromJson().pretty()
+ preCodeTag("json", blocksSerialized)
+
+template jsonShow(body: untyped) =
+ let blk = newJsonShow()
+ nb.withContainer(blk):
+ body
+ nb.add blk
+
+template showJsonSerialized(body: untyped) =
+ let code = getCode(body)
+ autoAnimateSlidesCustom(3, nimSlide):
+ fieldSet("Nim"):
+ nbRawHtml: preCodeTag("nim", code)
+ showAt(2):
+ fieldSet("Rendered"):
+ body
+ showAt(3):
+ fieldSet("JSON"):
+ jsonShow:
+ body
+
+template intro =
+ slide:
+ nimSlide:
+ nbText: "Nimib v0.4: internals ref-actoring"
+ nbText: "Hugo Granström"
+
+template jsonShowcase =
+ nimSlide:
+ nbText: "## JSON serialization"
+ nimSlide:
+ showJsonSerialized:
+ nbText: "*Hello* **there**"
+ nimSlide:
+ showJsonSerialized:
+ nbCode:
+ echo "General Kenobi"
+ nimSlide:
+ showJsonSerialized:
+ nbDiv(classes="cool", styles="color: green"):
+ nbText: "This is nested"
+
+#intro
+
+jsonShowcase
+
+nbSave
From da9d79d24eae35fe103504b7e2704b6ef909d160 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20Granstr=C3=B6m?=
<5092565+HugoGranstrom@users.noreply.github.com>
Date: Mon, 1 Jun 2026 20:39:02 +0200
Subject: [PATCH 13/22] fix bug where the nb_Style wasn't set
---
src/nimiSlides.nim | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim
index 646a4b3..9ea7eb9 100644
--- a/src/nimiSlides.nim
+++ b/src/nimiSlides.nim
@@ -147,7 +147,7 @@ func revealNbDocToHtml*(blk: NbBlock, nb: Nb): string =
"