import nimib, std/strutils, os, strformat, sugar
import nimislides, nimibook
nbInit()
nb.darkMode()
import /requiredForEmbeddedSlides/embeddedReveal
initEmbeddedSlides()
nb.context["highlight"] = """
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>"""
template nbTextWithSource*(body: untyped) =
newNbBlock("nbTextWithSource", false, nb, nb.blk, body):
nb.blk.output = body
nb.blk.context["code"] = body
nb.renderPlans["nbTextWithSource"] = @["mdOutputToHtml"]
nb.partials["nbTextWithSource"] = """{{&outputToHtml}}
<pre><code class=\"language-markdown\">{{code}}</code></pre>"""
import nimib / [capture]
template nbCode(body: untyped) {.used.} =
newNbCodeBlock("nbCode", body):
captureStdout(nb.blk.output):
body
nb.partials["nbCode"] = """
{{>nbCodeSource}}
<pre><code class=\"language-markdown\" style = "color:white;background-color: rgba(255, 255, 255, 0);font-size: 12px;">{{>nbCodeOutput}}</code></pre>
"""
nb.renderPlans["nbCode"] = @["highlightCode"]
var
nbToc: NbBlock
template addToc =
newNbBlock("nbText", false, nb, nbToc, ""):
nbToc.output = "## Table of Contents:\n\n"
template nbSection(name:string) =
let anchorName = name.toLower.replace(" ", "-")
nbText "<a name = \"" & anchorName & "\"></a>\n# " & name & "\n\n---"
nbToc.output.add "1. <a href=\"#" & anchorName & "\">" & name & "</a>\n"
template nbSubSection(name:string) {.used.} =
index.subsection.inc
let anchorName = name.toLower.replace(" ", "-")
nbText "<a name = \"" & anchorName & "\"></a>\n## " & " " & $index.section & "." & $index.subsection & ". " & name & "\n\n---"
nbToc.output.add " - " & $index.section & r"\." & $index.subsection & r"\. " & "<a href=\"#" & anchorName & "\">" & name & "</a>\n"
template nbUoSection(name: string) {.used.} =
nbText "\n# " & name & "\n\n---"
template nbUoSubSection(name: string) {.used.} =
nbText "\n## " & name & "\n\n---"
template addButtonBackToTop() =
nbRawHtml: hlHtml"""
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<style>
body {} <!-- This is a comment, this needs to be here body {} -->
#toTop {
display: none;
position: fixed;
bottom: 20px;
right: 30px;
z-index: 99;
font-size: 18px;
border: none;
outline: none;
background-color: #1A222D;
color: white;
cursor: pointer;
padding: 15px;
border-radius: 4px;
}
#toTop:hover {background-color: #555;}
#toTopMobile {
display: none;
position: fixed;
bottom: -5px;
right: -5px;
z-index: 99;
font-size: 18px;
border: none;
outline: none;
background-color: #1A222D;
opacity: .2;
color: white;
cursor: pointer;
padding: 15px;
border-radius: 4px;
}
#toTopMobile:hover {background-color: #555;}
</style>
<body>
<button onclick = "topFunction()" id = "toTop" title = "Go to top">Top</button>
<button onclick = "topFunction()" id = "toTopMobile" title = "Go to top">Top</button>
<script>
// Get the button
let myButton = document.getElementById("toTop");
let myButtonMobile = document.getElementById("toTopMobile");
var currentButton = myButton
var hasTouchScreen = false;
//var contentBody = document.getElementsByTagName("body"); //gives a query object
//myButton.style.color = "red"; //This works
//myButton.textContent = contentBody; //This also works .innerHTML, .innerText
//document.body.scrollTop > 20 || document.documentElement.scrollTop > 20
//Above could be used to position the button relativly ?
// Detecting if the device is a mobile device
if ("maxTouchPoints" in navigator)
{
hasTouchScreen = navigator.maxTouchPoints > 0;
}
else if ("msMaxTouchPoints" in navigator)
{
hasTouchScreen = navigator.msMaxTouchPoints > 0;
}
else
{
var mQ = window.matchMedia && matchMedia("(pointer:coarse)");
if (mQ && mQ.media === "(pointer:coarse)")
{
hasTouchScreen = !!mQ.matches;
}
else if ('orientation' in window)
{
hasTouchScreen = true; // deprecated, but good fallback
}
else
{
// Only as a last resort, fall back to user agent sniffing
var UA = navigator.userAgent;
hasTouchScreen = (
/\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
/\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA)
);
}
}
if (hasTouchScreen)
currentButton = myButtonMobile
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function()
{
scrollFunction()
};
function scrollFunction()
{
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
currentButton.style.display = "block";
} else {currentButton.style.display = "none";}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
"""
addToc()
addButtonBackToTop()
proc findAndOutputTutorials(videoSeries: string): string =
var link: string
var linkSplit: tuple[dir, name, ext: string]
var links: string
var removeUntil: int
let path = getCurrentDir() & r"\" & fmt"{videoSeries}"
for file in walkDirRec(path):
if file.endsWith(".html"):
link = file.replace(r"\", "/")
removeUntil = file.find(videoSeries)
link.delete(0 .. removeUntil-1)
linkSplit = link.splitFile
var improvedName: string
type
CharacterIndex = tuple
character: char
index: int
var index = 0
let length = linkSplit.name.len
while index < length:
var previous: CharacterIndex = if index-1 > linkSplit.name.len: (linkSplit.name[index-1], index-1) else: ('@', -1)
var current: CharacterIndex = (linkSplit.name[index], index)
var next: CharacterIndex = if index+1 < linkSplit.name.len: (linkSplit.name[index+1], index+1) else: ('@', -1)
if current.character.isUpperAscii and next.character.isUpperAscii:
improvedName.add current.character
improvedName.add next.character
index += 2
current = (linkSplit.name[index], index)
if current.character.isUpperAscii:
improvedName.add current.character
improvedName.add ' '
index += 1
else:
improvedName.add ' '
elif current.character.isDigit and next.character.isDigit:
if current.character != '@' or next.character != '@':
improvedName.add ' '
improvedName.add current.character
improvedName.add next.character
index += 2
current = (linkSplit.name[index], index)
if current.character.isDigit:
improvedName.add current.character
improvedName.add ' '
index += 1
else:
improvedName.add ' '
elif current.character.isUpperAscii or current.character.isDigit:
if not previous.character.isUpperAscii or not previous.character.isDigit:
improvedName.add ' '
improvedName.add current.character
index += 1
else:
improvedName.add current.character
index += 1
linkSplit.name = improvedName
links.add " - <a href = " & '"' & fmt"{link}" & '"' & ">" & linkSplit.name & "</a>" & "\n"
result = links
if result.isEmptyOrWhitespace:
result = "No offline tutorials exist for this video series yet(coming soon)"
nbText: hlMdF"""
- This is the index file to list all of my nimib styled offline tutorials of my Nim Tutorial videos,
organized by their respective video series.
(using nbSections for the video series organization)
(Nimib tutorials are listed newest to oldest, with the latest at the top)
"""
nbSection "Nim for Beginners"
let nimForBeginners = findAndOutputTutorials("Nim for Beginners")
nbText: hlMdF"" & nimForBeginners
nbSection "Exploring Nim's Standard Library"
let exploringNimsStandardLibrary = findAndOutputTutorials("Exploring Nim's Standard Library")
nbText: hlMdF"" & exploringNimsStandardLibrary
nbSection "Nim SDL2 Game Development for Beginners"
let nimSDL2GameDevelopmentForBeginners = findAndOutputTutorials("Nim SDL2 Game Development for Beginners")
nbText: hlMdF"" & nimSDL2GameDevelopmentForBeginners
nbSection "Metaprogramming in Nim"
let metaprogrammingInNim = findAndOutputTutorials("Metaprogramming in Nim")
nbText: hlMdF"" & metaprogrammingInNim
nbSection "Work in Progress"
let workInProgress = findAndOutputTutorials("Work in Progress")
nbText: hlMdF"" & workInProgress
nbSection "Extra Content"
let extraContent = findAndOutputTutorials("Extra Content")
nbText: hlMdF"" & extraContent
nbUoSection "My and General Links"
nbText: """
- [Nim's main page](https://nim-lang.org "Nim's main page")
- [Nim's manual/documentation](https://nim-lang.org/docs/manual.html "Nim's manual/documentation")
- [Patreon](https://www.patreon.com/Kiloneie?fan_landing=true "Patreon")
- [Visual Studio Code Shortcuts](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf "Visual Studio Code Shortcuts")
"""
nbSave()