From d1c63d8ac5b5d9adefc407f251c9e74471d1251b 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:07:01 +0200 Subject: [PATCH 1/5] some progress --- src/nimiSlides.nim | 267 ++++++++++++++++++++++++++++++++------------- 1 file changed, 190 insertions(+), 77 deletions(-) diff --git a/src/nimiSlides.nim b/src/nimiSlides.nim index a0e8802..bd68eb2 100644 --- a/src/nimiSlides.nim +++ b/src/nimiSlides.nim @@ -1,4 +1,4 @@ -import std/[strutils, strformat, sequtils, os] +import std/[strutils, strformat, sequtils, os, json] export os import nimib import nimib/[capture, config] @@ -56,28 +56,6 @@ proc slideOptions*(autoAnimate = false, iframeInteractive = true, colorBackgroun const reveal_version* = "5.0.4" -const document = """ - - - {{> head}} - - {{> main}} - - -""" - -const head = """ - - - {{> revealCSS }} - {{#nb_style}} - - {{/nb_style}} - -""" - const main = """
@@ -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""" +
+
+ {renderedBlocks} +
+
+ """ + 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 2/5] 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 3/5] 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 4/5] 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 5/5] 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