pietroppeter / nimib

nimib 🐳 - nim πŸ‘‘ driven β›΅ publishing ✍
https://pietroppeter.github.io/nimib/
MIT License
183 stars 10 forks source link
markdown mustache nim nimib

nimib 🐳 - nim πŸ‘‘ driven β›΅ publishing ✍

Nimib provides an API to convert your Nim code and its outputs to html documents.

The type of html output that is obtained by default is similar to html notebooks produced by tools like Jupyter or RMarkdown, but nimib provides this starting directly from standard nim files. It currently does not provide any type of interactivity or automatic reloading.

If you have some nim code lying around that echoes stuff you can try how nimib works with following these steps:

See below for an example of this.

Nimib strives for:

The main goal of Nimib is to empower people to explore nim and its ecosystem and share with others.

This document is generated though nimib both as an index.html file and as a README.md, you should be reading one of the two, for the other:

Nimib was presented at NimConf2022, see the slides and click thumbnail to see video. nimib nimconf2022 thumbnail

Nimib was also presented in NimConf2021, see video and slides.

The VS Codium / Code extension nimiboost (Open VSX) provides syntax highlighting of embedded languages in nimib documents (eg. markdown, python, html) and a preview window of nimib documents inside the editor.

πŸ‘‹ 🌍 Example Usage

First have a look at the following html document: hello.html

This was produced with nim r docsrc/hello, where docsrc/hello.nim is:

import strformat, strutils
import nimib

nbInit

nbText: """
## Secret talk with a computer
Let me show you how to talk with the computer like a [real hacker](https://mango.pdf.zone/)
and incidentally you might learn the basics of [nimib](https://github.com/pietroppeter/nimib).
### A secret message
Inside this document is hidden a secret message. I will ask the computer to spit it out:
"""

let secret = [104, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100]

nbCode:
  echo secret

nbText: fmt"""
what does this integer sequence mean?
Am I supposed to [recognize it](https://oeis.org/search?q={secret.join("%2C+")}&language=english&go=Search)?

### A cryptoanalytic weapon
Luckily I happen to have a [nim](https://nim-lang.org/) implementation of
a recently declassified top-secret cryptoanalytic weapon:"""

nbCode:
  func decode(secret: openArray[int]): string =
    ## classified by NSA as <strong>TOP SECRET</strong>
    for c in secret:
      result.add char(c)

nbText: """
  ### The great revelation
  Now I can just apply it to my secret message and
  finally decrypt what the computer wants to tell me:"""

nbCode:
  let msg = decode secret
  echo msg  # what will it say?

nbText:
  fmt"_Hey_, there must be a bug somewhere, the message (`{msg}`) is not even addressed to me!"

nbSave

Other examples of usage

in this repo:

elsewhere:

you are welcome to add here what you have built with nimib!

πŸ›  Features

β€œI try all things, I achieve what I can.” ― Herman Melville, Moby-Dick or, the Whale

The following are the main elements of a default nimib document:

Customization over the default is mostly achieved through nim-mustache or changing NbDoc and NbBlock elements (see below api). Currently most of the documentation on customization is given by the examples.

other blocks

You can find a complete description of the code blocks along with examples in allblocks.

creating custom blocks

See src/nimib.nim for examples on nimib blocks that are built using these two templates.

interactivity using nim js backend

Nimib can incorporate javascript code generated from nim code using template nbJsFromCode. It also provides a template nbKaraxCode to add code based on karax.

See interactivity for an explanation of the api and counter for examples of how to create widgets using it. In caesar we have an example of a karax app that implements Caesar cipher.

highlighting

Code blocks produced by nbCode are statically highlighted, but code in markdown code blocks are dynamically highlighted using highlightjs. The dynamic highlighting can be disabled by running nb.disableHighlightJs(). The supported languages are the ones listed as "common" here plus Nim, Julia and Latex.

Highlight styling classes are the same of highlightjs and you can pick a different styling (atom-one-light is default for light mode, androidstudio is default for dark mode).

latex

See numerical for an example of latex usage.

To add latex support:

Latex is rendered with katex through an autodetection during document loading.

config, command line options and interaction with filesystem

In the default situation a single nimib document that writes or reads from filesystem will behave as a normal nim file: the current directory is the directory from where you launch the executable.

When nimib is used to produce a website or in general a collection of document it is useful to set up a configuration file. A nimib configuration file is a file named nimib.toml and it is a toml file. Every time nbInit is called nimib tries to find a config file in current directory or in any parent directory. Inside a config file you can define two special directory:

nbInit also parses command line options that start with nb or nimib that allow to override the above value, skip the config file or other options.

All the options available can be seen by running any nimib file with option nbHelp (execution will stop after nbInit).

import osproc
withDir nb.srcDir:
  echo execProcess("nim r --verbosity:0 --hints:off --warnings:off hello --nbHelp")
Nimib options:

  --nbHelp,     --nimibHelp                 print this help
  --nbSkipCfg,  --nimibSkipCfg              skip nimib config file
  --nbCfgName,  --nimibCfgName              change name of config file (default "nimib.toml")
  --nbSrcDir,   --nimibSrcDir               set srcDir as relative (to CfgDir) or absolute; overrides config 
  --nbHomeDir,  --nimibHomeDir              set homeDir as relative (to CfgDir) or absolute; overrides config 
  --nbFilename, --nimibFilename             overrides name of output file (e.g. somefile --nbFilename:othername.html)
  --nbShow,     --nimibShow                 open in browser at the end of nbSave

The value of options are available in nb.options field which also tracks further options in nb.options.other: seq[tuple[kind: CmdLineKind; name, value: string]].

define flags

nimib's behavior can be further turned via Nim's define flags:

Code capture

The code capture of a block like nbCode (or other custom blocks) can happen in two different ways:

🐝 API

Here are two examples that show how to hijack the api:

Rendering

Changelog and πŸ™ Thanks

In the changelog you find all recent changes, some early history of nimib, pointers to relevant examples of usage of nimib and heartfelt thanks to some of the fine folks that made this development possible.

πŸŒ… Roadmap

completed in 0.3:

❓ ❗ Q & A

why the name?

corruption of ninib:

a solar deity; firstborn of Bel and consort was Gula; god of war and the chase and agriculture; sometimes identified with biblical Nimrod

also:

He explains that the seven directions were interpreted by the Babylonian theologians as a reference to the seven great celestial bodies, the sun and moon, Ishtar, Marduk, Ninib, Nergal and Nabu.

This process, which reached its culmination in the post-Khammurabic period, led to identifying the planet Jupiter with Marduk, Venus with Ishtar, Mars with Nergal, Mercury with Nebo, and Saturn with Ninib.

and I should not need to tell you what Marduk is and why Saturn is the best planet.

why the whale 🐳?

why do you need a logo when you have emojis?

no particular meaning about the whale apart the fact that I like the emoji and this project is something I have been chasing for a while (and I expect to be chasing it indefinitely).

also googling nimib whale you might discover the existence of a cool place: Skeleton Coast.

why the emojis?

because I made a package for that and someone has to use it

why the Q & A?

because someone made it into an art form and they tell me imitation is the sincerest form of flattery