Full Code of pietroppeter/nimib for AI

main b8a20221e58e cached
47 files
77.8 KB
23.2k tokens
1 requests
Download .txt
Repository: pietroppeter/nimib
Branch: main
Commit: b8a20221e58e
Files: 47
Total size: 77.8 KB

Directory structure:
gitextract_n9678sdq/

├── .git/
│   ├── HEAD
│   ├── config
│   ├── description
│   ├── hooks/
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── fsmonitor-watchman.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── pre-merge-commit.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   ├── pre-receive.sample
│   │   ├── prepare-commit-msg.sample
│   │   ├── push-to-checkout.sample
│   │   ├── sendemail-validate.sample
│   │   └── update.sample
│   ├── index
│   ├── info/
│   │   └── exclude
│   ├── logs/
│   │   ├── HEAD
│   │   └── refs/
│   │       ├── heads/
│   │       │   └── main
│   │       └── remotes/
│   │           └── origin/
│   │               └── HEAD
│   ├── objects/
│   │   └── pack/
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.idx
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.pack
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.promisor
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.rev
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.idx
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.pack
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.promisor
│   │       └── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.rev
│   ├── packed-refs
│   ├── refs/
│   │   ├── heads/
│   │   │   └── main
│   │   └── remotes/
│   │       └── origin/
│   │           └── HEAD
│   └── shallow
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── docs.yml
│       ├── netlify_build_docs.yml
│       ├── netlify_deploy_preview.yml
│       ├── netlify_pr_task.yml
│       └── test.yml
├── .gitignore
├── CONTRIBUTING.md
├── README.md
├── changelog.md
├── config.nims
├── nimib.nimble
└── nimib.toml

================================================
FILE CONTENTS
================================================

================================================
FILE: .git/HEAD
================================================
ref: refs/heads/main


================================================
FILE: .git/config
================================================
[core]
	repositoryformatversion = 1
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = https://github.com/pietroppeter/nimib
	tagOpt = --no-tags
	fetch = +refs/heads/main:refs/remotes/origin/main
	promisor = true
	partialclonefilter = blob:limit=1048576
[branch "main"]
	remote = origin
	merge = refs/heads/main


================================================
FILE: .git/description
================================================
Unnamed repository; edit this file 'description' to name the repository.


================================================
FILE: .git/hooks/applypatch-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:


================================================
FILE: .git/hooks/commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}


================================================
FILE: .git/hooks/fsmonitor-watchman.sample
================================================
#!/usr/bin/perl

use strict;
use warnings;
use IPC::Open2;

# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 2) and last update token
# formatted as a string and outputs to stdout a new update token and
# all files that have been modified since the update token. Paths must
# be relative to the root of the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $last_update_token) = @ARGV;

# Uncomment for debugging
# print STDERR "$0 $version $last_update_token\n";

# Check the hook interface version
if ($version ne 2) {
	die "Unsupported query-fsmonitor hook version '$version'.\n" .
	    "Falling back to scanning...\n";
}

my $git_work_tree = get_working_dir();

my $retry = 1;

my $json_pkg;
eval {
	require JSON::XS;
	$json_pkg = "JSON::XS";
	1;
} or do {
	require JSON::PP;
	$json_pkg = "JSON::PP";
};

launch_watchman();

sub launch_watchman {
	my $o = watchman_query();
	if (is_work_tree_watched($o)) {
		output_result($o->{clock}, @{$o->{files}});
	}
}

sub output_result {
	my ($clockid, @files) = @_;

	# Uncomment for debugging watchman output
	# open (my $fh, ">", ".git/watchman-output.out");
	# binmode $fh, ":utf8";
	# print $fh "$clockid\n@files\n";
	# close $fh;

	binmode STDOUT, ":utf8";
	print $clockid;
	print "\0";
	local $, = "\0";
	print @files;
}

sub watchman_clock {
	my $response = qx/watchman clock "$git_work_tree"/;
	die "Failed to get clock id on '$git_work_tree'.\n" .
		"Falling back to scanning...\n" if $? != 0;

	return $json_pkg->new->utf8->decode($response);
}

sub watchman_query {
	my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
	or die "open2() failed: $!\n" .
	"Falling back to scanning...\n";

	# In the query expression below we're asking for names of files that
	# changed since $last_update_token but not from the .git folder.
	#
	# To accomplish this, we're using the "since" generator to use the
	# recency index to select candidate nodes and "fields" to limit the
	# output to file names only. Then we're using the "expression" term to
	# further constrain the results.
	my $last_update_line = "";
	if (substr($last_update_token, 0, 1) eq "c") {
		$last_update_token = "\"$last_update_token\"";
		$last_update_line = qq[\n"since": $last_update_token,];
	}
	my $query = <<"	END";
		["query", "$git_work_tree", {$last_update_line
			"fields": ["name"],
			"expression": ["not", ["dirname", ".git"]]
		}]
	END

	# Uncomment for debugging the watchman query
	# open (my $fh, ">", ".git/watchman-query.json");
	# print $fh $query;
	# close $fh;

	print CHLD_IN $query;
	close CHLD_IN;
	my $response = do {local $/; <CHLD_OUT>};

	# Uncomment for debugging the watch response
	# open ($fh, ">", ".git/watchman-response.json");
	# print $fh $response;
	# close $fh;

	die "Watchman: command returned no output.\n" .
	"Falling back to scanning...\n" if $response eq "";
	die "Watchman: command returned invalid output: $response\n" .
	"Falling back to scanning...\n" unless $response =~ /^\{/;

	return $json_pkg->new->utf8->decode($response);
}

sub is_work_tree_watched {
	my ($output) = @_;
	my $error = $output->{error};
	if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {
		$retry--;
		my $response = qx/watchman watch "$git_work_tree"/;
		die "Failed to make watchman watch '$git_work_tree'.\n" .
		    "Falling back to scanning...\n" if $? != 0;
		$output = $json_pkg->new->utf8->decode($response);
		$error = $output->{error};
		die "Watchman: $error.\n" .
		"Falling back to scanning...\n" if $error;

		# Uncomment for debugging watchman output
		# open (my $fh, ">", ".git/watchman-output.out");
		# close $fh;

		# Watchman will always return all files on the first query so
		# return the fast "everything is dirty" flag to git and do the
		# Watchman query just to get it over with now so we won't pay
		# the cost in git to look up each individual file.
		my $o = watchman_clock();
		$error = $output->{error};

		die "Watchman: $error.\n" .
		"Falling back to scanning...\n" if $error;

		output_result($o->{clock}, ("/"));
		$last_update_token = $o->{clock};

		eval { launch_watchman() };
		return 0;
	}

	die "Watchman: $error.\n" .
	"Falling back to scanning...\n" if $error;

	return 1;
}

sub get_working_dir {
	my $working_dir;
	if ($^O =~ 'msys' || $^O =~ 'cygwin') {
		$working_dir = Win32::GetCwd();
		$working_dir =~ tr/\\/\//;
	} else {
		require Cwd;
		$working_dir = Cwd::cwd();
	}

	return $working_dir;
}


================================================
FILE: .git/hooks/post-update.sample
================================================
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info


================================================
FILE: .git/hooks/pre-applypatch.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:


================================================
FILE: .git/hooks/pre-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff-index --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --


================================================
FILE: .git/hooks/pre-merge-commit.sample
================================================
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git merge" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message to
# stderr if it wants to stop the merge commit.
#
# To enable this hook, rename this file to "pre-merge-commit".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
        exec "$GIT_DIR/hooks/pre-commit"
:


================================================
FILE: .git/hooks/pre-push.sample
================================================
#!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local oid> <remote ref> <remote oid>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')

while read local_ref local_oid remote_ref remote_oid
do
	if test "$local_oid" = "$zero"
	then
		# Handle delete
		:
	else
		if test "$remote_oid" = "$zero"
		then
			# New branch, examine all commits
			range="$local_oid"
		else
			# Update to existing branch, examine new commits
			range="$remote_oid..$local_oid"
		fi

		# Check for WIP commit
		commit=$(git rev-list -n 1 --grep '^WIP' "$range")
		if test -n "$commit"
		then
			echo >&2 "Found WIP commit in $local_ref, not pushing"
			exit 1
		fi
	fi
done

exit 0


================================================
FILE: .git/hooks/pre-rebase.sample
================================================
#!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up to date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

<<\DOC_END

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".

DOC_END


================================================
FILE: .git/hooks/pre-receive.sample
================================================
#!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".

if test -n "$GIT_PUSH_OPTION_COUNT"
then
	i=0
	while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
	do
		eval "value=\$GIT_PUSH_OPTION_$i"
		case "$value" in
		echoback=*)
			echo "echo from the pre-receive-hook: ${value#*=}" >&2
			;;
		reject)
			exit 1
		esac
		i=$((i + 1))
	done
fi


================================================
FILE: .git/hooks/prepare-commit-msg.sample
================================================
#!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples. The first one removes the
# "# Please enter the commit message..." help message.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3

/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"

# case "$COMMIT_SOURCE,$SHA1" in
#  ,|template,)
#    /usr/bin/perl -i.bak -pe '
#       print "\n" . `git diff --cached --name-status -r`
# 	 if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
#  *) ;;
# esac

# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
# if test -z "$COMMIT_SOURCE"
# then
#   /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
# fi


================================================
FILE: .git/hooks/push-to-checkout.sample
================================================
#!/bin/sh

# An example hook script to update a checked-out tree on a git push.
#
# This hook is invoked by git-receive-pack(1) when it reacts to git
# push and updates reference(s) in its repository, and when the push
# tries to update the branch that is currently checked out and the
# receive.denyCurrentBranch configuration variable is set to
# updateInstead.
#
# By default, such a push is refused if the working tree and the index
# of the remote repository has any difference from the currently
# checked out commit; when both the working tree and the index match
# the current commit, they are updated to match the newly pushed tip
# of the branch. This hook is to be used to override the default
# behaviour; however the code below reimplements the default behaviour
# as a starting point for convenient modification.
#
# The hook receives the commit with which the tip of the current
# branch is going to be updated:
commit=$1

# It can exit with a non-zero status to refuse the push (when it does
# so, it must not modify the index or the working tree).
die () {
	echo >&2 "$*"
	exit 1
}

# Or it can make any necessary changes to the working tree and to the
# index to bring them to the desired state when the tip of the current
# branch is updated to the new commit, and exit with a zero status.
#
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
# in order to emulate git fetch that is run in the reverse direction
# with git push, as the two-tree form of git read-tree -u -m is
# essentially the same as git switch or git checkout that switches
# branches while keeping the local changes in the working tree that do
# not interfere with the difference between the branches.

# The below is a more-or-less exact translation to shell of the C code
# for the default behaviour for git's push-to-checkout hook defined in
# the push_to_deploy() function in builtin/receive-pack.c.
#
# Note that the hook will be executed from the repository directory,
# not from the working tree, so if you want to perform operations on
# the working tree, you will have to adapt your code accordingly, e.g.
# by adding "cd .." or using relative paths.

if ! git update-index -q --ignore-submodules --refresh
then
	die "Up-to-date check failed"
fi

if ! git diff-files --quiet --ignore-submodules --
then
	die "Working directory has unstaged changes"
fi

# This is a rough translation of:
#
#   head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
if git cat-file -e HEAD 2>/dev/null
then
	head=HEAD
else
	head=$(git hash-object -t tree --stdin </dev/null)
fi

if ! git diff-index --quiet --cached --ignore-submodules $head --
then
	die "Working directory has staged changes"
fi

if ! git read-tree -u -m "$commit"
then
	die "Could not update working tree to new HEAD"
fi


================================================
FILE: .git/hooks/sendemail-validate.sample
================================================
#!/bin/sh

# An example hook script to validate a patch (and/or patch series) before
# sending it via email.
#
# The hook should exit with non-zero status after issuing an appropriate
# message if it wants to prevent the email(s) from being sent.
#
# To enable this hook, rename this file to "sendemail-validate".
#
# By default, it will only check that the patch(es) can be applied on top of
# the default upstream branch without conflicts in a secondary worktree. After
# validation (successful or not) of the last patch of a series, the worktree
# will be deleted.
#
# The following config variables can be set to change the default remote and
# remote ref that are used to apply the patches against:
#
#   sendemail.validateRemote (default: origin)
#   sendemail.validateRemoteRef (default: HEAD)
#
# Replace the TODO placeholders with appropriate checks according to your
# needs.

validate_cover_letter () {
	file="$1"
	# TODO: Replace with appropriate checks (e.g. spell checking).
	true
}

validate_patch () {
	file="$1"
	# Ensure that the patch applies without conflicts.
	git am -3 "$file" || return
	# TODO: Replace with appropriate checks for this patch
	# (e.g. checkpatch.pl).
	true
}

validate_series () {
	# TODO: Replace with appropriate checks for the whole series
	# (e.g. quick build, coding style checks, etc.).
	true
}

# main -------------------------------------------------------------------------

if test "$GIT_SENDEMAIL_FILE_COUNTER" = 1
then
	remote=$(git config --default origin --get sendemail.validateRemote) &&
	ref=$(git config --default HEAD --get sendemail.validateRemoteRef) &&
	worktree=$(mktemp --tmpdir -d sendemail-validate.XXXXXXX) &&
	git worktree add -fd --checkout "$worktree" "refs/remotes/$remote/$ref" &&
	git config --replace-all sendemail.validateWorktree "$worktree"
else
	worktree=$(git config --get sendemail.validateWorktree)
fi || {
	echo "sendemail-validate: error: failed to prepare worktree" >&2
	exit 1
}

unset GIT_DIR GIT_WORK_TREE
cd "$worktree" &&

if grep -q "^diff --git " "$1"
then
	validate_patch "$1"
else
	validate_cover_letter "$1"
fi &&

if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL"
then
	git config --unset-all sendemail.validateWorktree &&
	trap 'git worktree remove -ff "$worktree"' EXIT &&
	validate_series
fi


================================================
FILE: .git/hooks/update.sample
================================================
#!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --type=bool hooks.allowunannotated)
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
allowmodifytag=$(git config --type=bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0


================================================
FILE: .git/info/exclude
================================================
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~


================================================
FILE: .git/logs/HEAD
================================================
0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> 1778238322 +0000	clone: from https://github.com/pietroppeter/nimib


================================================
FILE: .git/logs/refs/heads/main
================================================
0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> 1778238322 +0000	clone: from https://github.com/pietroppeter/nimib


================================================
FILE: .git/logs/refs/remotes/origin/HEAD
================================================
0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> 1778238322 +0000	clone: from https://github.com/pietroppeter/nimib


================================================
FILE: .git/objects/pack/pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.promisor
================================================


================================================
FILE: .git/objects/pack/pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.promisor
================================================
b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 refs/heads/main


================================================
FILE: .git/packed-refs
================================================
# pack-refs with: peeled fully-peeled sorted 
b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 refs/remotes/origin/main


================================================
FILE: .git/refs/heads/main
================================================
b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32


================================================
FILE: .git/refs/remotes/origin/HEAD
================================================
ref: refs/remotes/origin/main


================================================
FILE: .git/shallow
================================================
b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32


================================================
FILE: .gitattributes
================================================
assets/* linguist-vendored


================================================
FILE: .github/workflows/docs.yml
================================================
on:
  push:
    branches:
      - main
jobs:
  gh-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: install nim
        id: install_nim
        uses: iffy/install-nim@v5
      - name: install library dependencies
        run: nimble install -y
      - name: install doc dependencies
        run: nimble docsdeps
      - name: build docs
        run: nimble docs
      - name: deploy on github pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: docs

================================================
FILE: .github/workflows/netlify_build_docs.yml
================================================
# build docs and uploads saves output as artifact for netlify_deploy_preview pipeline to be used
name: netlify_build_docs
on:
  pull_request:
    branches:
      - main
jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - name: apt install
        run: sudo apt install -y libpcre3 libblas-dev liblapack-dev
      - uses: actions/checkout@v2
      - name: install nim
        id: install_nim
        uses: iffy/install-nim@v5
      - name: install library dependencies
        run: nimble install -y
      - name: install doc dependencies
        run: nimble docsdeps
      - name: build docs
        run: nimble docs
      - run: echo Commit hash = ${{ github.event.pull_request.head.sha }}
      - uses: actions/upload-artifact@v4
        with:
          name: build-${{ github.event.pull_request.head.sha }}
          path: docs/
          retention-days: 1
          if-no-files-found: error


================================================
FILE: .github/workflows/netlify_deploy_preview.yml
================================================

# runs when netlify_build_docs is completed
# reason for the split: we do not want to run user code in an environment that has access to netlify secrets
name: netlify_deploy_preview
on:
  workflow_run:
    workflows:
      - netlify_build_docs
    types:
      - completed
jobs:
  deploy:
    name: Deploy Preview
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: potiuk/get-workflow-origin@v1_1
        id: source-run-info
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          sourceRunId: ${{ github.event.workflow_run.id }}
      - run: echo sourceHeadSha = ${{ steps.source-run-info.outputs.sourceHeadSha }}
      - name: Set env
        run: echo "GITHUB_SHA_SHORT=$(echo ${{ steps.source-run-info.outputs.sourceHeadSha }} | cut -c 1-20)" >> $GITHUB_ENV
      - run: echo Short hash = ${{ env.GITHUB_SHA_SHORT }}
      - name: Show pending status check
        uses: Sibz/github-status-action@v1.1.5
        with:
          authToken: ${{ secrets.GITHUB_TOKEN }}
          context: Netlify preview
          sha: ${{ steps.source-run-info.outputs.sourceHeadSha }}
          description: Deploying site to Netlify. Please wait...
          state: pending
      - run: rm -rf docs
      - name: 'Download artifacts'
        uses: dawidd6/action-download-artifact@v2
        with:
          github_token: ${{secrets.GITHUB_TOKEN}}
          workflow: netlify_build_docs.yml  # Name of the workflow that created the artifact
          name: "build-${{ steps.source-run-info.outputs.sourceHeadSha }}" # Name of the artifact
          path: docs/
      - run: echo Deploy Alias = ${{ env.GITHUB_SHA_SHORT }}
      - uses: jsmrcaga/action-netlify-deploy@master
        with:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
          deploy_alias: ${{ env.GITHUB_SHA_SHORT }}
          build_directory: docs/
          install_command: ls
          build_command: ls
      - name: Status check
        uses: Sibz/github-status-action@v1.1.5
        with:
          authToken: ${{ secrets.GITHUB_TOKEN }}
          context: Netlify preview
          description: Click link to preview ⇒
          sha: ${{ steps.source-run-info.outputs.sourceHeadSha }}
          state: success
          # customize with netlify site name
          target_url: https://${{ env.GITHUB_SHA_SHORT }}--nimib.netlify.app


================================================
FILE: .github/workflows/netlify_pr_task.yml
================================================
# creates a task saying that it is waiting for the build to finish, does nothing else
name: netlify PR task
on:
  pull_request_target:  # runs for activity on pr but does not use code from pr and only from pr target
    branches:
      - main
jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: echo Commit hash = ${{ github.event.pull_request.head.sha }} 
      - name: Show pending status check
        uses: Sibz/github-status-action@v1.1.5
        with:
          authToken: ${{ secrets.GITHUB_TOKEN }}
          context: Netlify preview
          sha: ${{ github.event.pull_request.head.sha }}
          description: Waiting for build to finish...
          state: pending

================================================
FILE: .github/workflows/test.yml
================================================
name: Run tests
on: 
  push:
    branches:
      - main
  pull_request:
jobs:
  tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        nim:
          - 'stable'
          - 'devel'
      fail-fast: false
    name: Nim ${{ matrix.nim }}
    steps:
      - uses: actions/checkout@v3
      - uses: jiro4989/setup-nim-action@v2.2.2
        with:
          nim-version: ${{ matrix.nim }}
      - run: sudo apt install libpcre3 libpcre3-dev
      - run: nimble -y install
      - run: nimble docsdeps
      - run: nimble test


================================================
FILE: .gitignore
================================================
*
!/**/
!*.*
.DS_store

*.exe
*.tmp.html
# let's try using this to test around with stuff:
x_*

# ignore build of docs 
docs/*.html
docs/images/*.png

================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to nimib
You are interested in contributing to nimib? The you have come to the right place!
Note that using nimib and sharing more nim code around is **already** contributing to nimib.
But this is the guide for contributing code to nimib!

## What can I help with?
Both small and large contributions are welcomed! If you have an idea, open an issue and discuss it with us. Otherwise,
have a look at the [open issues](https://github.com/pietroppeter/nimib/issues) and see if anything peaks your interest.

There might be some issues marked as [good first issue](https://github.com/pietroppeter/nimib/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22):
those are issues where we have already a clear idea on what needs to be done and sometimes even code for the fix;
they are especially good to familiarize oneself with the codebase and the process of contributing to open source.

You can also use github [discussion forum](https://github.com/pietroppeter/nimib/discussions) if you are not sure about what to ask.

We also organize [Nimib speaking hours](https://github.com/pietroppeter/nimib/discussions/categories/nimib-speaking-hours), a semi regular
meeting of nimib's maintainers (Pietro and Hugo) where we welcome users and contributors (even potential ones).
These are announced on the discussion forum, [look at the special forum category](https://github.com/pietroppeter/nimib/discussions/categories/nimib-speaking-hours) for when we have the next one (or ask if it is not yet planned).

## Project Structure
There are 4 main folders in the project:
- `docsrc/`: Here the source files for the documentation are located.
- `docs/`: Here the built documentation is located. You will only find committed some static files.
- `tests`: All unit-tests are located here.
- `src`: Here the implementation of `nimib` is located
  - `nimib.nim`: This file is the glue that exports the entire library. Most of the exported procs and templates are implemented here.
  - `nimib/`
    - `blocks.nim`: Here the `newNbBlock` template is defined.
    - `boost.nim`: Here functionality related to nimiBoost is defined. For example the string-highlighting templates like `hlMd`.
    - `capture.nim`: The logic of the `captureStdout` template which allows you to capture everything that is `echo`'d in a code block.
    - `config.nim`: Logic related to loading `nimib.toml`. 
    - `docs.nim`: Procs acting on `NbDoc`. For example `write` to write a document to file and `open` to open the written file in a browser.
    - `gits.nim`: Git-related logic.
    - `highlight.nim`: Logic related to static highlighting of Nim code.
    - `jsutils.nim`: Here the underlying logic of the `nbJs` blocks are located.
    - `options.nim`: Logic related to parsing runtime options when building a document.
    - `paths.nim`: Wrapper on top of the compiler's `pathutils`.
    - `renders.nim`: Here all the backends are defined. `partials`, `renderPlans` and `renderProcs` are defined here.
    - `sources.nim`: The logic of `codeAsInSource` is located here.
    - `themes.nim`: Here the default theme is located. If you are making your own theme, this is a good reference to start from.
    - `types.nim`: The core types like `NbDoc`, `NbBlock` are defined.

## How to add a new block

- add the logic in `nimib.nim`
- add the rendering in `nimib\renders.nim`
- add some test in `tests` (if it make sense)
- add an example in `allblocks.nim`
  - ⚠️ currently `README.md` depends on `docsrc\index.nim`, you will have to modify `docsrc\index.nim` and run `nimble readme` to update the readme. we will remove this dependency, see https://github.com/pietroppeter/nimib/issues/141 

## CI and deploy preview

documentation is built in CI and we have **deploy preview** built with netlify. Once all checks have run succesfully the last one will contain a link to the deploy preview. This is very useful to make sure the documents still build so make sure to check it when you work on the internals of nimib.


================================================
FILE: README.md
================================================
# 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](https://nbviewer.jupyter.org/url/norvig.com/ipython/Advent%20of%20Code.ipynb)
or [RMarkdown](https://rmarkdown.rstudio.com/lesson-10.html), 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:
  * run in shell `nimble install nimib`
  * add `import nimib` at the top of your nim file
  * add a `nbInit` command right after that
  * split your code into one or more `nbCode:` blocks
  * add some text commentary in markdown through `nbText:` blocks
  * add a `nbSave` command at the end
  * compile and run
  * open the html file that has been generated next to your nim file (same name)
  * (you can use runtime option `--nbShow` to open the html file automatically in your default browser)

See below for an example of this.

Nimib strives for:
  * a simple API
  * sane defaults
  * easy customization

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:

* [README.md](https://github.com/pietroppeter/nimib)
* [index.html](https://pietroppeter.github.io/nimib)

Nimib was presented at [NimConf2022](https://nim-lang.org/nimconf2022/), see the [slides](https://github.com/pietroppeter/nimconf22-nimib/) and click thumbnail to see video.
[![nimib nimconf2022 thumbnail](https://github.com/pietroppeter/nimib/raw/d4399747aa4c4435d27e0038046ad0311a92f21d/assets/nimib-nimconf-thumbnail.png)](https://www.youtube.com/watch?v=hZ7wX1kgnuc)

Nimib was also presented in [NimConf2021](https://conf.nim-lang.org),
see [video](https://www.youtube.com/watch?v=sWA58Wtk6L8)
and [slides](https://github.com/pietroppeter/nimconf2021).

The VS Codium / Code extension
[nimiboost](https://marketplace.visualstudio.com/items?itemName=hugogranstrom.nimiboost) ([Open VSX](https://open-vsx.org/extension/hugogranstrom/nimiboost))
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](https://pietroppeter.github.io/nimib/hello.html)

This was produced with `nim r docsrc/hello`, where [docsrc/hello.nim](https://github.com/pietroppeter/nimib/blob/main/docsrc/hello.nim) is:
```nim
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:

* [index](https://pietroppeter.github.io/nimib/index.html): generate an HTML and a README.md at the same time (you are reading one of the two).
* [penguins](https://pietroppeter.github.io/nimib/penguins.html): explore palmer penguins dataset using ggplotnim (example of showing images).
* [numerical](https://pietroppeter.github.io/nimib/numerical.html): example usage of NumericalNim (example of custom style, usage of latex).
* [cheatsheet](https://pietroppeter.github.io/nimib/cheatsheet.html): markdown cheatsheet (example of a custom block, custom highlighting and a simple TOC).
* [mostaccio](https://pietroppeter.github.io/nimib/mostaccio.html): examples of usage of nim-mustache and of dark mode.
* [interactivity](https://pietroppeter.github.io/nimib/interactivity.html): shows the basic API of creating interactive elements using `nbJsFromCode`.
* [counter](https://pietroppeter.github.io/nimib/counters.html): shows how to create reusable interactive widgets by creating a counter button.
* [caesar](https://pietroppeter.github.io/nimib/caesar.html): a Caesar cipher implemented using `nbKaraxCode` and `karax`.


elsewhere:

* [adventofnim](https://pietroppeter.github.io/adventofnim/index.html): solutions for advent of code in nim
* [intro to binarylang](https://ajusa.github.io/binarylang-fun/intro.html): a introduction to library [binarylang](https://github.com/sealmove/binarylang) (first public usage of nimib I was aware of)
* [nblog](https://github.com/pietroppeter/nblog): a blog about nimib and its ecosystem
* [nimibook](https://github.com/pietroppeter/nimibook): a port of mdbook to nim(ib)
* [SciNim Getting Started](https://scinim.github.io/getting-started/): tutorials for nim in scientific computing
* [Norm documentation](https://norm.nim.town): documentation of a Nim ORM library.
* [NimiSlides](https://github.com/HugoGranstrom/nimib-reveal): a [reveal.js](https://revealjs.com) theme for nimib.

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:

* `nbInit`: initializes a nimib document, required for all other commands to work.
  In particular it creates and injects into scope a `nb` object used by all other blocks
  (see below section API for internal details).
* `nbCode`: code blocks with automatic stdout capture and capture of code source
* `nbText`: text blocks with automatic conversion from markdown to html (thanks to [nim-markdown](https://github.com/soasme/nim-markdown))
* `nbSave`: save the document (by default to html)
* styling with [water.css](https://watercss.kognise.dev/), light mode is default, dark mode available (`nb.darkMode` after `nbInit`).
* static highlighting of nim code. Highlight styling classes are the same of [highlightjs](https://highlightjs.org/)
  and you can pick a different styling (`atom-one-light` is default for light mode, `androidstudio` is default for dark mode).
* (optional) latex rendering through [katex](https://katex.org/) (see below)
* a header with navigation to a home page, a minimal title and an automatic detection of github repo (with link)
* a footer with a "made with nimib" line and a `Show source` button that shows the full source to create the document.
* (optional) possibility to create a markdown version of the same document (see this document for an example: [docsrc/index.nim](https://github.com/pietroppeter/nimib/blob/main/docsrc/index.nim))

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](https://pietroppeter.github.io/nimib/allblocks.html).

### creating custom blocks

* `newNbCodeBlock(cmd: string, body, blockImpl: untyped)`: template that can be used to create custom
  code block that will need both a `body` and an implementation which might make use of `body`.
  Also, the source code in `body` is read.
  Example blocks created with `newNbCodeBlock` are `nbCode` and `nbTextWithCode`.
* `newNbSlimBlock(cmd: string, blockImpl: untyped)`: template that can be used to create
  a custom block that does not need a separate `body`.
  Example blocks created with `newNbSlimBlock` are `nbText`, `nbImage`.

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

* a `newId` proc is available for `nb: NbDoc` object and provides an incremental integer.
  It can be used in some custom blocks (it is used in `nbJsFromCode` described below).

### 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](https://github.com/karaxnim/karax).

See [interactivity](https://pietroppeter.github.io/nimib/interactivity.html) for an explanation of the api
and [counter](https://pietroppeter.github.io/nimib/counters.html) for examples of how to create widgets using it.
In [caesar](https://pietroppeter.github.io/nimib/caesar.html) we have an example of a karax app
that implements [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher).

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

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

### latex

See [numerical](https://pietroppeter.github.io/nimib/numerical.html) for an example of latex usage.

To add latex support:

  * add a `nb.useLatex` command somewhere between `nbInit` and `nbSave`
  * use delimiters `$` for inline-math or `$$` for display math inside nbText blocks.

Latex is rendered with [katex](https://katex.org/) 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](https://github.com/toml-lang/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:

* `homeDir`: the directory to set as current directory.
  It can be given as an absolute directory or as a relative directory.
  When it is given as a relative directory it is relative with respect
  to the directory of config file.
* `srcDir`: the directory where all the sources resides.
  It is used to create the output filename that includes a relative path.
  In this way the folder structure of nim files can be recreated in the output.
  As `homeDir`, it can be set as absolute or relative (to config).

`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`).
```nim
import osproc
withDir nb.doc.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:

* `-d:nimibQuiet`: Completely disables nimib's logging to stdout
* `-d:nimibCodeFromAst`: Makes nimib capture block code from AST of body (as opposed to from file source; see next section). Available since version 0.3

### Code capture

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

* `CodeAsInSource` (default since version 0.3): code for a single block
  is parsed from file source (available in `nb.source`).
* `CodeFromAst` (default in versions 0.1 and 0.2): code for a single block
  is rendered from AST of body. This means that only documentation comments
  are shown (since normal comments are not part of the AST) and that the source show
  might be different from original source.

## 🐝 API <!-- Api means bees in Italian -->

* `nbInit` template creates and injects a `nb` variable of type `NbDoc`.
* templates like `nbCode` and `nbText` create a new object of type `NbBlock`,
  these objects are added to a sequence of blocks accessible in `nb.blocks`
* the last processed block is available as `nb.blk`
* `nb.blk.output` contains the (non rendered) output of block
* `nb.blk.code` contains the source code of the block (if it was created with `newNbCodeBlock`)
* `NbBlock` is a ref object, so changing `nb.blk`, changes the last block in `nb.blocks`.

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

* [nolan](https://pietroppeter.github.io/nimib/nolan.html): how to mess up the timeline of blocks ⏳
* [pythno](https://pietroppeter.github.io/nimib/pythno.html): a reminder that nim is not python 😜

## Rendering

* rendering is currently based on [nim-mustache](https://github.com/soasme/nim-mustache).
  This will likely be changed in a next release and in fact refactoring the rendering part of nimib
  is the main target for next breaking change, see [#111](https://github.com/pietroppeter/nimib/issues/111)
* there are two rendering backends, a html one and a markdown backend.
  In order to use the markdown backend one must initialize its document with `nbInitMd` instead of `nbInit`
* rendering happens during the call to `nbSave`, and two steps are performed:
  1. rendering all blocks and adding them to a sequence of blocks (added to `nb.context["blocks"]`)
  2. rendering the document starting from `document` partial using
* rendering of a single block depends
  on a number of fields of `nb` object:
  - `partials`: a `Table[string, string]` that contains the templates/partials for every command (e.g. `nb.partials["nbCode"]`);
  - `templateDirs`: a `seq[string]` of folders where to look for `.mustache` templates that can complement/override
    the templates in `partials`.
    A common usage is to add a `head_other.mustache` template that contain additional content added to head section
    of **every** document (in many repositories - including nimib - it is used to add a [plausible analytics](https://plausible.io) script)
  - `renderPlans`: a `Table[string, seq[string]]` that contains the render plan (a `seq[string]`) for every step of render plan
    an associated `renderProc` is called;
  - `renderProcs`: a `Table[string, NbRenderProc]` that contains all available render procs by name.
     (`type NbRenderProc = proc (doc: var NbDoc, blk: var NbBlock) {. nimcall .}`)
* the above fields are initialized during `nbInit` with a call to `render` backend and can
  be customized by a call to `theme` (`render` and `theme` have default values).

## Changelog and 🙏 Thanks

In the [changelog](https://github.com/pietroppeter/nimib/blob/main/changelog.md) 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

- add more themes such as [nimibook](https://github.com/pietroppeter/nimibook).
  In particular themes for blogging and for creating general websites.
- can I use nimib to build a library directly from documentation (like in [nbdev](https://github.com/fastai/nbdev))?
- nimib executable for scaffolding and to support different publishing workflows
- server-side dynamic sites (streamlit style? take advantage of caching instead of hot code reloading)
- possibility of editing document in the browser (similar to jupyter UI, not necessarily taking advantage of hot code reloading)
- ...

completed in 0.3:
- [x] refactor rendering of blocks and simplify api extensions ([#24](https://github.com/pietroppeter/nimib/issues/24))
- [x] client-side dynamic site: interactivity of documents, e.g. a dahsboard (possibly taking advantage of nim js backend)

## ❓ ❗ Q & A

### why the name?

corruption of [ninib](https://www.vocabulary.com/dictionary/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](https://jupyter.org/) is
and why [Saturn is the best planet](https://www.theatlantic.com/science/archive/2016/01/a-major-correction/422514/).

### 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](https://en.wikipedia.org/wiki/Captain_Ahab) 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](https://en.wikipedia.org/wiki/Skeleton_Coast).

### why the emojis?

because I made a [package](https://github.com/pietroppeter/nimoji) for that and someone has to use it

### why the Q & A?

because [someone made it into an art form](https://github.com/oakes/vim_cubed#q--a)
and they tell me [imitation is the sincerest form of flattery](https://www.goodreads.com/quotes/558084-imitation-is-the-sincerest-form-of-flattery-that-mediocrity-can)

================================================
FILE: changelog.md
================================================

# Changelog

The changelog includes a bit of the 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.

For contributors: make sure to have a relevant and clear message for your PR and when merging update the first PR message with relevant notes regarding the PR (these notes will be used by maintainers during release, see below).

Notes for maintainers:

- When a maintainer merges a PR, they should make sure that the squashed commit message is relevant and clear.
- When we tag a new release, we should auto generate the release notes. It does not hurt if we add more context to the release notes (e.g. taking notable elements from PR discussion). We might also want to add a release discussion post.
- finally, after a release, we update this changelog (and bump version) using the same wording from release notes: https://github.com/pietroppeter/nimib/releases

## v 0.4.0

todo after release

## v0.3.12

### What's Changed
* Update changelog.md with 3.11 release notes and bump 3.12 by @pietroppeter in https://github.com/pietroppeter/nimib/pull/239
* Make Nimib logging to stdout optional (`-d:nimibQuiet`) by @neroist in https://github.com/pietroppeter/nimib/pull/242
* Add nbVideo & nbAudio (revive #153) by @neroist in https://github.com/pietroppeter/nimib/pull/244
* Create homeDir if it doesn't exist alredy by @neroist in https://github.com/pietroppeter/nimib/pull/246

**Full Changelog**: https://github.com/pietroppeter/nimib/compare/v0.3.11...v0.3.12

## v0.3.11

### What's Changed
* Update changelog.md and bumping to 3.11 by @pietroppeter in https://github.com/pietroppeter/nimib/pull/231
* paths.nim: Fix import for FreeBSD by @lbartoletti in https://github.com/pietroppeter/nimib/pull/238

### New Contributors
* @lbartoletti made their first contribution in https://github.com/pietroppeter/nimib/pull/238

**Full Changelog**: https://github.com/pietroppeter/nimib/compare/v0.3.10...v0.3.11

## v0.3.10

### What's Changed
* bump 0.3.10 and update changelog with 0.3.9 release notes by @pietroppeter in https://github.com/pietroppeter/nimib/pull/199
* Enlarge figure and center figure captions by @dlesnoff in https://github.com/pietroppeter/nimib/pull/201
* Refactor tests and remove hints to better visualize success/failure by @dlesnoff in https://github.com/pietroppeter/nimib/pull/202
* Complete Allblocks by @dlesnoff in https://github.com/pietroppeter/nimib/pull/203
* Automatically change file ext to `md` when using `nbInitMd` (and add a `thisFileRel` param) by @neroist in https://github.com/pietroppeter/nimib/pull/206
* Allblocks: add nbShow, nbCodeWithText, nbCodeInBlock by @dlesnoff in https://github.com/pietroppeter/nimib/pull/208
* update to numericalnim 0.8.8 by @HugoGranstrom in https://github.com/pietroppeter/nimib/pull/214
* Fix std/random bug (#204) by @sent44 in https://github.com/pietroppeter/nimib/pull/211
* Happyx support by @quimt in https://github.com/pietroppeter/nimib/pull/212
* Add nbFile overload for file embedding by @PhilippMDoerner in https://github.com/pietroppeter/nimib/pull/219
* fix issue#229: skip nimble INFO logs when dumping json by @lost22git in https://github.com/pietroppeter/nimib/pull/230

### New Contributors :heart: 
* @sent44 made their first contribution in https://github.com/pietroppeter/nimib/pull/211
* @quimt made their first contribution in https://github.com/pietroppeter/nimib/pull/212
* @PhilippMDoerner made their first contribution in https://github.com/pietroppeter/nimib/pull/219
* @lost22git made their first contribution in https://github.com/pietroppeter/nimib/pull/230

**Full Changelog**: https://github.com/pietroppeter/nimib/compare/v0.3.9...v0.3.10

## v0.3.9

* Update water.css and fix code output by @dlesnoff in https://github.com/pietroppeter/nimib/pull/185
* Add `nbCodeSkip` and `allblocks.nim` by @neroist in https://github.com/pietroppeter/nimib/pull/187
* fix typo in CONTRIBUTING.md by @neroist in https://github.com/pietroppeter/nimib/pull/188
* Add `nbCapture`, closes #156 by @neroist in https://github.com/pietroppeter/nimib/pull/189
* Add meta tag with generator, closes #170 by @neroist in https://github.com/pietroppeter/nimib/pull/190
* Fix special chars escaped by the markdown renderer, close #159 by @neroist in https://github.com/pietroppeter/nimib/pull/191
* Make "figure:" not show up when using nbImage with no caption by @neroist in https://github.com/pietroppeter/nimib/pull/192
* Add seperate `alt` param to  `nbImage`, close #193 by @neroist in https://github.com/pietroppeter/nimib/pull/195
* Fix `getNimibVersion()` by @neroist in https://github.com/pietroppeter/nimib/pull/196

### New Contributors
* @dlesnoff made their first contribution in https://github.com/pietroppeter/nimib/pull/185
* @neroist made their first contribution in https://github.com/pietroppeter/nimib/pull/187

**Full Changelog**: https://github.com/pietroppeter/nimib/compare/v0.3.8...v0.3.9

## v0.3.8 - Fix nim-markdown not exporting escapeTag anymore

* remove export escapeTag by @HugoGranstrom in https://github.com/pietroppeter/nimib/pull/181
  * [nim-markdown](https://github.com/soasme/nim-markdown) released a new version which doesn't export `escapeTag` anymore, so we remove it. Not sure why we did it to begin with tbh.

## v0.3.7 - All code shall be highlighted
* Implement nbShow and highlight.js support for code in markdown by @HugoGranstrom in https://github.com/pietroppeter/nimib/pull/179
  * `nbShow` can be used to pretty print any type which implements a `toHtml` proc that returns a string of HTML to be rendered.
  * Code blocks in markdown are now highlighted dynamically using [highlight.js](https://highlightjs.org). 
* updated changelog with 0.3.6 release notes + change in changelog workflow by @pietroppeter in https://github.com/pietroppeter/nimib/pull/176

## v0.3.6 - nim 2.0 compatibility!

* Change toml lib + fix macro bug on devel by @HugoGranstrom in https://github.com/pietroppeter/nimib/pull/173
  with this PR nimib is finally compatible with the upcoming 2.0. Two things needed fixing:
  - a nim compiler orc macro bug (reported here: https://github.com/nim-lang/Nim/issues/21326), fixed with a [workaround]
  - there was an issue with toml serialization on orc (reported here: https://github.com/status-im/nim-toml-serialization/issues/62) fixed by removing the dependency from [toml_serialization] and using [parsetoml] instead
    - some custom code in order to support direct to object conversion was needed, see https://github.com/NimParsers/parsetoml/issues/59
    - we also added a dependency to [jsony] to support a loose direct to object conversion from toml
* Adding devel to CI, fix #161, fix #149 by @pietroppeter in https://github.com/pietroppeter/nimib/pull/169
  - added both stable (which will become 2.0) and devel (which is currently the 2.0 rc) to CI, also update the versions of actions we depend on

**Full Changelog**: https://github.com/pietroppeter/nimib/compare/v0.3.5...v0.3.6

**release discussion**: https://github.com/pietroppeter/nimib/discussions/175

[workaround]: https://github.com/pietroppeter/nimib/pull/173/commits/f1966097da91d4ba7b2711dbe44223e871927b42
[toml_serialization]: https://github.com/status-im/nim-toml-serialization
[parsetoml]: https://github.com/NimParsers/parsetoml
[jsony]: https://github.com/treeform/jsony

## 0.3.5
* codeAsInSource has been reworked to work better with templates and uses of `nbCode` in different files.
The cases that still don't work is when code from different places are combined in a single `nbCode`, like here:

```nim
template foo(body: untyped) =
  nbCode:
    body # This code is from line 7
    echo "Hello world" # this code is from line 4

foo:
  echo "Goodbye world"
```
* If you don't use any nbJs, now nimib won't build an empty nim file in those cases.
* The temporary js files generated by nbJs now has unique names to allow parallel builds.

## 0.3.4

* added `nbCodeDisplay` and `nbCodeAnd` (#158).
  They provide an easy way to:
    - display code in `nbJsFromCode` and friends
    - run code both in js and c backend
  They are also generic templates that can be used with other templates
  and do not depend on any specificities of `nbJsFromCode` templates.

## 0.3.3

* Refactored nbJs (#148)
  * **Breaking**: All `nbJsFromCode` blocks are now inserted into the same file (Compared to previously when each block was compiled as its own file).
  So this will break any reusable components as you will get `redefinition of variable` errors. The solution is to use `nbJsFromCodeInBlock` which puts the code inside a `block`. Imports can't be done in there though so you must do them in a separate `nbJsFromCode` or `nbJsFromCodeGlobal` before. 
  * See [https://pietroppeter.github.io/nimib/interactivity.html](https://pietroppeter.github.io/nimib/interactivity.html) for a more detailed guide on how to use the new API.
* Added `nimibCode` template. One problem with using `nbCode` is that you can't show *nimib* code using it because it nests blocks and wrecks havoc.
So `nimibCode` allows you to show *nimib* code but at the cost of not capturing output of the code.

## 0.3.2

* Add `hlHtml` and `hlHtml` to nimiBoost
* fix rarely occuring issue of terminal output not being captured (windows only, see example in https://github.com/pietroppeter/nimib/pull/132)
* compress line height in nbCode output (using class `nb-output`), see #133
* Fixed a case when capturing a global in `nbJsFromCode` didn't gensym the symbols, causing the same variable names in the generated code. #136

## 0.3.1

* fix "Did not parse stylesheet at 'https://unpkg.com/normalize.css/' in strict mode" (#120)
* Split untyped and string versions of `nbCodeToJs` into `nbJsFromCode` and `nbJsFromString`. Same for `nbCodeToJsInit` → `nbJsFromCodeInit`, `nbJsFromStringInit` (#125)
* Add `postRender` template to `nbKaraxCode` (#125)
* `nbJsFromCode` now respects `exportc` pragma (#125)
* rename `rawOutput` (deprecated) to `rawHtml`

## 0.3 "Block Maker" (July 2022)

This release started with the aim of making the construction of custom blocks as easy as the construction of native blocks.
A wide refactoring of the codebase was required for this (#78)
and further adjustments were made along the way (#80, #81).
Some new blocks are introduced taking advantage of this (e.g. `nbRawOutput`, `nbPython`) (#80, #83).

Contributing to the codebase is made easier through introduction of proper testing (#80)
docs are now built in CI (#89, #90, #91) and deploy previews have been added (#92, #93).
Documentation has been updated to include all changes so far
and contextually the changelog has been updated (#103).

A big milestone is reached (#88) by introducing templates to add interactivity to documents
taking advantage of nim js backend (`nbCodeToJs` allows to incorporate javascript scripts in the document derived from nim code).
In particular templates to reduce boilerplate when developing karax based apps or
widgets are introduced (`nbKaraxCode`, `karaxHtml`).
Three new example documents are introduced for documenting this change (`interactivity`, `counters`, `caesar`).

Another major change is setting as default the `CodeAsInSource` introduced in 0.2.4
(a number of fixes are made: #105, #106, #108).

Most of these contributions are due to @HugoGranstrom
(thanks for all the awesome work on this ❤️) which joins @pietroppeter
as maintainer and co-creator of nimib! 🥳

List of detailed changes:

* refactoring of `NbBlock` type and rendering of blocks (#78, fixes #24):
  * `NbBlock` type is completely refactored. Instead of having a `kind` with a fixed
    number of values, a block behaviour is specified by a `command` string
    which is set to the name of the command template used to create a block
    (e.g. `nbCode`, `nbText`, `nbImage`, ...) - 
  * `newNbBlock` is now the main template to create a new block
  * Every block now has a `context` field and the rendering backend (either html or markdown)
    has a mechanism to retrieve a `partial` for every command.
  * as an additional mechanism to be able to perform other computations when rendering,
    a sequence of `renderProc`s can be assigned for every command (for a specific backend).
  * `nimib / renders` module completely refactored to take into account the above changes
  * some other accidental or not so welcome changes that happened during the refactoring:
    - `sugar` is now exported _(accidental)_
    - `nb: NbDoc` is mutated when rendered _(unwelcome, will be changed later)_
    - cannot use both Html and Md backend at the same time _(unwelcome, will be changed later)_
* logging has been improved (see changes in `nimib.blocks.newNbBlock`) (#78)
* new `main` partial introduced (#78)
* fixed cheatsheet document (#78, fixes #52)
* tests are added and ptest document is removed (#78)
* aliases to minimize breaking changes that happened in 0.2 (`nbDoc`, `nbBlock`, `nbHomeDir`) are noew removed (#78)
* added a new `readCode: bool` parameter to `newNbBlock` (with an overload that sets it as true) (#80)
* new template `nbRawOutput` that renders raw html (#80)
* new command `nbClearOutput` that removes output from last block processed (#80)
* new templates for creating code blocks `newNbCodeBlock` and `newNbSlimBlock`
  for creating custom blocks and related changes (#81):
  - `newNbCodeBlock`: captures source code of `body`
  - `newNbSlimBlock`: block without a `body` (and in particular no capture of source)
  - all nimib "native" blocks now use one of the two mechanism above
  - now `nbText` does NOT contain its source
  - new `nbTextWithCode` that does contain code source
* new example document `files.nim`, changed the rendering of `nbFile`
  (no more "writing file ..." only the name of file is added) (#81)
* added `loadNimibCfg` proc that can be used for themes (used by nimibook) (#81)
* added `nbInitPython` and `nbPython` templates to support running python in nimib documents using `nimpy` (#83)
  - `md` and `fmd` from `nimib / boost` now deprecated and replaced by `hlMd` and `hlMdF`
  - new `hlPy` and `hlPyF` in `nimib / boost`
* docs now are built in CI (#89, #90, #91)
  - sources of docs are now in folder `docsrc`
  - outputs are in `docs`
* add deploy preview through netlify (#92, #93)
* new templates to introduce interactivity in documents taking advantage of nim's javascript backend (#88)
  - `nbCodeToJs`: a block of nim code is compiled to javascript and added as a script to html file (and allows capturing of variables)
  - `nbCodeToJsInit`, `addCodeToJs`, `addToDocAsJs`: templates to allow splitting in multiple blocks the code in `nbCodeToJs`
  - `nbCodeToJsShowSource`: template to show the nim source of a `nbCodeToJs` block.
  - `nbKaraxCode` (with `karaxHtml`): template to create a karax app/widget with minimal boilerplate (based on `nbCodeToJs`)
  - new example document `interactivity.nim`: explains the basic of `nbCodeToJs` and related templates
  - new example document `counters.nim`: shows how to create counter widgets using `nbCodeToJs`
  - new example document `caesar.nim`: a caesar cipher app built using `nbKaraxCode`
  - new module `nimib / jsutils` to support the implementation of the above 
* `newId` proc for `NbDoc` that gives a new incremental integer every time it is called (#88)
* `CodeAsInSource` is made default:
  - new `nimibCodeFromAst` flag to revert to old default
  - added a warning to `nimibPreviewCodeAsInSource` (now obsolete)
* various fixes to `CodeAsInSource` (#105, #106, #108)
* changelog updated and separated from documentation (#103)
* updated documentation to include most recent changes (#103)
* turned off warning for unused imports in `nimib.nim` (#103)
* fix markdown backend, it was broken since html theme was overiding render backend (#103):
  - new `nbInitMd` to use markdown backend
  - new `themes.noTheme` for empty theme (used by `nbInitMd`)

Thanks to @metagn for improving our CI/nimble file! Every contribution counts!

Relevant examples of usage:

* [nimislides](https://github.com/HugoGranstrom/nimib-reveal): a new nimib theme that allows to create
  slides using [reveal.js](https://revealjs.com) html presentation framework
* some posts in nblog are relevant example of new blocks and customization of nimib:
  - [Making Diagrams using mermaid.js](https://pietroppeter.github.io/nblog/drafts/mermaid_diagram.html)
  - [Plotly in nimib](https://pietroppeter.github.io/nblog/drafts/show_plotly.html)

## 0.2.x (November 2021)

### 0.2.4 - CodeAsInSource

* Update penguins example which now uses datamancer and shows Simpson's paradaox, by @Vindaar (#70)
* code as in source for nbCode (`-d:nimibPreviewCodeAsInSource`) by @HugoGranstrom (#63): with this option the code shown is not derived from Ast but it is read from source code.
* ptest document is turned off from CI

### 0.2.3

* align version in nimble file and tagged version 

### 0.2.2 - nbFile

* add `nbFile` by @Clonkk (#64)

### 0.2.1

* fix to `path_to_root` (renamed from `home_path`, also `here_path` renamed to `path_to_here`) (#67)

## 0.2 "Theme Maker" (November 2021)

this release aims to simplify creating Nimib themes such as nimibook.

It does this through the following changes:
* instead of creating and injecting multiple variables
  (`nbDoc`, `nbBlock`, `nbHomeDir`, ...), nimib now only injects a `nb` variable
  that is a `NbDoc`. Some aliases are provided to minimize breakage.
* handling of paths (`srcDir` and `homeDir`) is changed and is based on the presence
  of a new config file `nimib.toml`
* command line options are now processed and can be used to skip/override the config process.
  Run any nimib file with option `--nbHelp` to see available options.
* note in particular new `--nbShow` option which will automatically open the file in your default browser.
* `nbPostInit` and `nbPreSave` customization mechanism based on includes are now removed 
* documentation has been updated to reflect the above changes and also to add other Nimib references (NimConf video, nimibook, getting-started, ...)
most of the changes break the api

relevant external example:

* [norm](https://norm.nim.town) starts to use nimibook for its documentation

Special thanks again to to @Vindaar, @Clonkk and @HugoGranstrom for this release.

## 0.1.x (March-June 2021)

a growing ecosystem drives most of the development of the 0.1.x series:

* [intro to binarylang](https://ajusa.github.io/binarylang-fun/intro.html) by @ajusa (March 2021): first public use of nimib by someone other than @pietroppeter 
* [SciNim Getting Started](https://scinim.github.io/getting-started/) decided to use nimib and for that purpose
  [nimibook](https://github.com/pietroppeter/nimibook), a book theme (based of mdbook) developments was started
* [nblog](https://github.com/pietroppeter/nblog), a nimib blog, was started as a way to use nimib to explore nim ecosystem and experiment
  the various features of nimib
* [nimiboost](https://github.com/HugoGranstrom/nimiBoost) is a vs code extension to provide
  markdown highlighting and a preview mechanism.

changes:

*  0.1.1:
  - add nbPostInit mechanism to customize document (#32)
  - fix (breaking): code output is escaped by default
  - fix (breaking): code output is not stripped anymore
  - fix: nbDoc.write will create directories if not existing (#44)
* 0.1.2: release to align tag and nimble version
* 0.1.3: added compile-time switches to override nbHomeDir (#53)
* 0.1.4: fix for `nbImage` path (#56)
* 0.1.5: new template `nbCodeInBlock` (#59)
* 0.1.6: added `nimib / boost` module with `md` and `fmd` helpers to support markdown highlight with nimiboost

Thanks for this release series to @Vindaar, @Clonkk and @HugoGranstrom who decided to adopt
nimib in scinim/getting-started and motivated and directly contributed to nimib and nimibook development
to support this use case.

At the end June 2021, nimib was presented at [NimConf2021](https://conf.nim-lang.org).

## 0.1 (March 2021)

* initial version with essential templates `nbInit`, `nbText`, `nbCode`, `nbImage`, `nbSave`
  - capture of output in `nbCode` based on code by @Clonkk
* html backend based on mustache and markdown by @soasme
* default theme using water.css
  - header with home button, minimal title (filename by default), automatic detection of github repo
  - footer with "made with nimib" and Show Source button
* static highlighting of nim code (by @yardanico)
* latex rendering through katex
* markdown backend
* essential documentation in `index.nim`
  - sections: intro, example usage, features, api, roadmap, thanks, Q&A
  - also generates `README.md` and serves as an example of usage of markdown backend
* possibility to customize theme (dark mode, custom stylesheet, add other scripts, ...)
* example documents:
  - `penguins`: data exploration, adding images
  - `numerical`: latex usage, theme customization
  - `cheatsheet`: toc creation, new text block which shows source, custom highlighting
    - also documents the markdown to html generator
  - `mostaccio`: example of using dark mode
    - also documents the templating system mustache
  - `ptest`: print testing for nimib
* deployed using github pages. html files committed in repo.

relevant external examples:

* adventofnim (2020) by @pietroppeter
  - first appeareance of nimib in public (before 0.1 release), see [commit on Dec 1st, 2020](https://github.com/pietroppeter/adventofnim/commit/973f9a2472d41188bb37650c082f115fc5787687#diff-a21a437c51bd7babb945c8291588853296387c7e1950997e05f1eb62d18b54f7)

Initial commit of nimib was on Nov, 25, 2020.
On the same day the [first milestone](https://github.com/pietroppeter/nimib/commit/b02ec7be4663956167701a81a96246d8e528fff3)
reached was the working hello world example.

For this release, thanks to:

* [soasme](https://github.com/soasme) for the excellent libraries nim-markdown and nim-mustache, which provide the backbone of nimib rendering and customization
* [Clonkk](https://github.com/Clonkk) for help in a critical piece of code early on (see [this Stack Overflow answer](https://stackoverflow.com/a/64032172/4178189))
* [yardanico](https://github.com/yardanico) for being the first contributor and great sponsor of this library, even before an official release


================================================
FILE: config.nims
================================================
switch("d","nimibHomeDir=docs")

================================================
FILE: nimib.nimble
================================================
# Package

version       = "0.4.0"
author        = "Pietro Peterlongo & Hugo Granström"
description   = "nimib 🐳 - nim 👑 driven ⛵ publishing ✍"
license       = "MIT"
srcDir        = "src"

# Dependencies

requires "nim >= 1.4.0"
requires "fusion >= 1.2"
requires "markdown >= 0.8.1"
requires "parsetoml >= 0.7.0"
requires "jsony >= 1.1.5"

task docsdeps, "install dependendencies required for doc building":
  exec "nimble -y install ggplotnim@0.5.9 numericalnim@0.8.8 nimoji nimpy karax@1.3.3 happyx@2.0.0 mustache@0.4.3"

task test, "General tests":
  for file in ["tsources.nim", "tblocks.nim", "tnimib.nim", "trenders.nim"]:
    exec "nim r --hints:off tests/" & file
  for file in ["tblocks.nim", "tnimib.nim", "trenders.nim"]:
    exec "nim r --hints:off -d:nimibCodeFromAst tests/" & file

task readme, "update readme":
  exec "nim -d:mdOutput r docsrc/index.nim"  

task docs, "Build documentation":
  for file in ["allblocks", "hello", "mostaccio", "numerical", "nolan",
    "pythno", "cheatsheet", "files", "index",
    "interactivity", "counters", "caesar"]:
    exec "nim r --hints:off docsrc/" & file & ".nim"
  when not defined(nimibDocsSkipPenguins):
    exec "nim r --hints:off docsrc/penguins.nim"
  exec "nimble readme"  


================================================
FILE: nimib.toml
================================================
[nimib]
srcDir = "docsrc"
homeDir = "docs"
Download .txt
gitextract_n9678sdq/

├── .git/
│   ├── HEAD
│   ├── config
│   ├── description
│   ├── hooks/
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── fsmonitor-watchman.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── pre-merge-commit.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   ├── pre-receive.sample
│   │   ├── prepare-commit-msg.sample
│   │   ├── push-to-checkout.sample
│   │   ├── sendemail-validate.sample
│   │   └── update.sample
│   ├── index
│   ├── info/
│   │   └── exclude
│   ├── logs/
│   │   ├── HEAD
│   │   └── refs/
│   │       ├── heads/
│   │       │   └── main
│   │       └── remotes/
│   │           └── origin/
│   │               └── HEAD
│   ├── objects/
│   │   └── pack/
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.idx
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.pack
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.promisor
│   │       ├── pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.rev
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.idx
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.pack
│   │       ├── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.promisor
│   │       └── pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.rev
│   ├── packed-refs
│   ├── refs/
│   │   ├── heads/
│   │   │   └── main
│   │   └── remotes/
│   │       └── origin/
│   │           └── HEAD
│   └── shallow
├── .gitattributes
├── .github/
│   └── workflows/
│       ├── docs.yml
│       ├── netlify_build_docs.yml
│       ├── netlify_deploy_preview.yml
│       ├── netlify_pr_task.yml
│       └── test.yml
├── .gitignore
├── CONTRIBUTING.md
├── README.md
├── changelog.md
├── config.nims
├── nimib.nimble
└── nimib.toml
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (85K chars).
[
  {
    "path": ".git/HEAD",
    "chars": 21,
    "preview": "ref: refs/heads/main\n"
  },
  {
    "path": ".git/config",
    "chars": 342,
    "preview": "[core]\n\trepositoryformatversion = 1\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n[remote \"origin\"]\n\turl = htt"
  },
  {
    "path": ".git/description",
    "chars": 73,
    "preview": "Unnamed repository; edit this file 'description' to name the repository.\n"
  },
  {
    "path": ".git/hooks/applypatch-msg.sample",
    "chars": 478,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message taken by\n# applypatch from an e-mail message.\n#\n# T"
  },
  {
    "path": ".git/hooks/commit-msg.sample",
    "chars": 896,
    "preview": "#!/bin/sh\n#\n# An example hook script to check the commit log message.\n# Called by \"git commit\" with one argument, the na"
  },
  {
    "path": ".git/hooks/fsmonitor-watchman.sample",
    "chars": 4726,
    "preview": "#!/usr/bin/perl\n\nuse strict;\nuse warnings;\nuse IPC::Open2;\n\n# An example hook script to integrate Watchman\n# (https://fa"
  },
  {
    "path": ".git/hooks/post-update.sample",
    "chars": 189,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare a packed repository for use over\n# dumb transports.\n#\n# To enable this h"
  },
  {
    "path": ".git/hooks/pre-applypatch.sample",
    "chars": 424,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed\n# by applypatch from an e-mail message.\n#\n#"
  },
  {
    "path": ".git/hooks/pre-commit.sample",
    "chars": 1649,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git commit\" with no arguments"
  },
  {
    "path": ".git/hooks/pre-merge-commit.sample",
    "chars": 416,
    "preview": "#!/bin/sh\n#\n# An example hook script to verify what is about to be committed.\n# Called by \"git merge\" with no arguments."
  },
  {
    "path": ".git/hooks/pre-push.sample",
    "chars": 1374,
    "preview": "#!/bin/sh\n\n# An example hook script to verify what is about to be pushed.  Called by \"git\n# push\" after it has checked t"
  },
  {
    "path": ".git/hooks/pre-rebase.sample",
    "chars": 4898,
    "preview": "#!/bin/sh\n#\n# Copyright (c) 2006, 2008 Junio C Hamano\n#\n# The \"pre-rebase\" hook is run just before \"git rebase\" starts d"
  },
  {
    "path": ".git/hooks/pre-receive.sample",
    "chars": 544,
    "preview": "#!/bin/sh\n#\n# An example hook script to make use of push options.\n# The example simply echoes all push options that star"
  },
  {
    "path": ".git/hooks/prepare-commit-msg.sample",
    "chars": 1492,
    "preview": "#!/bin/sh\n#\n# An example hook script to prepare the commit log message.\n# Called by \"git commit\" with the name of the fi"
  },
  {
    "path": ".git/hooks/push-to-checkout.sample",
    "chars": 2783,
    "preview": "#!/bin/sh\n\n# An example hook script to update a checked-out tree on a git push.\n#\n# This hook is invoked by git-receive-"
  },
  {
    "path": ".git/hooks/sendemail-validate.sample",
    "chars": 2308,
    "preview": "#!/bin/sh\n\n# An example hook script to validate a patch (and/or patch series) before\n# sending it via email.\n#\n# The hoo"
  },
  {
    "path": ".git/hooks/update.sample",
    "chars": 3650,
    "preview": "#!/bin/sh\n#\n# An example hook script to block unannotated tags from entering.\n# Called by \"git receive-pack\" with argume"
  },
  {
    "path": ".git/info/exclude",
    "chars": 240,
    "preview": "# git ls-files --others --exclude-from=.git/info/exclude\n# Lines that start with '#' are comments.\n# For a project mostl"
  },
  {
    "path": ".git/logs/HEAD",
    "chars": 187,
    "preview": "0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> "
  },
  {
    "path": ".git/logs/refs/heads/main",
    "chars": 187,
    "preview": "0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> "
  },
  {
    "path": ".git/logs/refs/remotes/origin/HEAD",
    "chars": 187,
    "preview": "0000000000000000000000000000000000000000 b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 appuser <appuser@7c99e0e64a07.(none)> "
  },
  {
    "path": ".git/objects/pack/pack-62e2fb9434711e9a7e8675eb3152bb80cbb84291.promisor",
    "chars": 0,
    "preview": ""
  },
  {
    "path": ".git/objects/pack/pack-bfc15b21f9bdd2385245f680d4c27a0b69cc2673.promisor",
    "chars": 57,
    "preview": "b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 refs/heads/main\n"
  },
  {
    "path": ".git/packed-refs",
    "chars": 112,
    "preview": "# pack-refs with: peeled fully-peeled sorted \nb8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32 refs/remotes/origin/main\n"
  },
  {
    "path": ".git/refs/heads/main",
    "chars": 41,
    "preview": "b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32\n"
  },
  {
    "path": ".git/refs/remotes/origin/HEAD",
    "chars": 30,
    "preview": "ref: refs/remotes/origin/main\n"
  },
  {
    "path": ".git/shallow",
    "chars": 41,
    "preview": "b8a20221e58ea38cd2f7dd75ad9ea7a3408e0f32\n"
  },
  {
    "path": ".gitattributes",
    "chars": 27,
    "preview": "assets/* linguist-vendored\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "chars": 578,
    "preview": "on:\n  push:\n    branches:\n      - main\njobs:\n  gh-docs:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/chec"
  },
  {
    "path": ".github/workflows/netlify_build_docs.yml",
    "chars": 904,
    "preview": "# build docs and uploads saves output as artifact for netlify_deploy_preview pipeline to be used\nname: netlify_build_doc"
  },
  {
    "path": ".github/workflows/netlify_deploy_preview.yml",
    "chars": 2422,
    "preview": "\n# runs when netlify_build_docs is completed\n# reason for the split: we do not want to run user code in an environment t"
  },
  {
    "path": ".github/workflows/netlify_pr_task.yml",
    "chars": 725,
    "preview": "# creates a task saying that it is waiting for the build to finish, does nothing else\nname: netlify PR task\non:\n  pull_r"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 535,
    "preview": "name: Run tests\non: \n  push:\n    branches:\n      - main\n  pull_request:\njobs:\n  tests:\n    runs-on: ubuntu-latest\n    st"
  },
  {
    "path": ".gitignore",
    "chars": 149,
    "preview": "*\n!/**/\n!*.*\n.DS_store\n\n*.exe\n*.tmp.html\n# let's try using this to test around with stuff:\nx_*\n\n# ignore build of docs \n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4005,
    "preview": "# Contributing to nimib\nYou are interested in contributing to nimib? The you have come to the right place!\nNote that usi"
  },
  {
    "path": "README.md",
    "chars": 19346,
    "preview": "# nimib 🐳 - nim 👑 driven ⛵ publishing ✍\n\nNimib provides an API to convert your Nim code and its outputs to html document"
  },
  {
    "path": "changelog.md",
    "chars": 22333,
    "preview": "\n# Changelog\n\nThe changelog includes a bit of the early history of nimib, pointers to relevant\nexamples of usage of nimi"
  },
  {
    "path": "config.nims",
    "chars": 31,
    "preview": "switch(\"d\",\"nimibHomeDir=docs\")"
  },
  {
    "path": "nimib.nimble",
    "chars": 1240,
    "preview": "# Package\n\nversion       = \"0.4.0\"\nauthor        = \"Pietro Peterlongo & Hugo Granström\"\ndescription   = \"nimib 🐳 - nim 👑"
  },
  {
    "path": "nimib.toml",
    "chars": 43,
    "preview": "[nimib]\nsrcDir = \"docsrc\"\nhomeDir = \"docs\"\n"
  }
]

// ... and 7 more files (download for full content)

About this extraction

This page contains the full source code of the pietroppeter/nimib GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (77.8 KB), approximately 23.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!