Literate is a command line tool which you can use to generate either html, code, or both from a .lit
file.
Once installed, you can use it by typing lit file.lit
. There many extra options you can provide:
--tangle -t Only compile code files --weave -w Only compile HTML files --no-output -no Do not generate any output files --out-dir -odir DIR Put the generated files in DIR --compiler -c Report compiler errors (needs @compiler to be defined) (see reporting compiler errors to the correct line) --linenums -l STR Write line numbers prepended with STR to the output file (see Writing line directives) --md-compiler COMPILER Use COMPILER as the markdown compiler instead of the built-in one (see Using markdown) --version -v Show the version number and compiler information
wc.lit
which is a literate implementation of the word count program
found on Unix systems. You can find the woven html here.@title Hello world in C @s Introduction This is an example hello world C program. We can define codeblocks with `---` --- hello.c @{Includes} int main() { @{Print a string} return 0; } --- Now we can define the `Includes` codeblock: --- Includes #include <stdio.h> --- Finally, our program needs to print "hello world" --- Print a string printf("hello world\n"); ---You can read the explanation that follows, or run it on your own machine and understand it on your own. This program is the hello.lit program in the examples directory.
A Literate program will generally begin with 3 statements, although they are all optional. First you should set the code and comment type.
To set the code type use
@code_type type .extension
. This tells Literate what language you will be using. I use c
and .c
in the example, but for javascript it would be javascript
and .js
.
Next we want to define the comment type using // %s
. For a multiline comment we could use /* %s */
.
Now we give our program a title. To do that use the @title
command.
A Literate program consists of multiple sections, each beginning with the @s title?
command. Sections may have a title, but it is not required.
A section consists of explanation and code. Generally you provide some prose, followed by a piece of code, but really, you can do it in any order you like,
with any amounts of prose and code blocks.
When writing prose, you may use Markdown and it will be converted to HTML on compilation. So using **word**
will make word bold etc...
You can read a nice description of basic markdown here (note that ```
for
denoting large code blocks will not work, just use a Literate code block).
The markdown used by Literate is slightly different than normal markdown: underscores do not do anything, and you can directly inline
html. If you have to write <
and <
, you can use \<
or &lt;
and the
equivalent for greater than.
If you'd like, you can use a custom markdown compiler by using the --md-compiler
flag. For example if you want to use
pandoc for markdown compilation, you can run literate like so:
$ lit --md-compiler pandoc file.litJust make sure that the pandoc command line tool is installed on your machine. Literate just runs the command with the markdown as stdin and captures the stdout. This means that if you want to use a certain pandoc option you can:
$ lit --md-compiler 'pandoc -f markdown_strict' file.lit
Another possible command you can use while writing prose is the @{codeblock name}
command. If you write this in
prose, Literate will replace this with a reference to the code block name and a link to the section the code block is in.
Literate supports rendering math equations. It uses the KaTeX library to render LaTeX
equations. Just put the equation between $
. If you want the equation to be block level (take up an entire row), use
$$
. If you are using inline equations, make sure that there are no newlines in your equation
Note that if you are viewing the html files offline, the math will still render, but the fonts won't be as nice. If you wish to save the html file with good fonts, you can make a pdf.
To create a code block, you use three dashes, followed by the code block name, and another three dashes to signal the end of the code block. For example:
--- Code block some code here ---
A code block may have any name but it must not have any trailing whitespace. In addition, if you name a code block a filename (e.g. file.c
),
this code block will be top-level, and when compiling the Literate file, all the code from this code block will be put in that file.
If you add a +=
after the code block name, the code will be added to that block (the block must already be defined somewhere else).
This is useful because sometimes you want to add a piece of code a code block, but it only makes sense to add it later after the definition.
For example, if you have a code block for all the constants in your program, you can add them as you use them instead of adding them all at once
at the top of the program as you would in a standard programming setting.
The most useful command in a code block is the @{codeblock name}
. Just like it does in prose, it will reference and link the code block
name that you use. However, when generating code from the Literate file, the code that is contained in codeblock name
will be inserted at this position
in the generated source.
+=
modifier, but there are a few others. Here is a short list of the codeblock modifiers and what they do:
+=
: Adds code to an already defined block
:=
: Redefines a codeblock
noWeave
: Specifies that the codeblock should not be included in the HTML output (for an example, see the end of weave.lit
in the source code for Literate)
---
followed by the codeblock name:
--- Some code block name --- noWeaveWith
+=
and :=
you do not have to include the ---
but you can.
You may not like what the HTML output from Literate looks like by default. In that case, fear not, you can customize every bit of the page with CSS (after all, it is just HTML). There are three different kinds of customizations you can make:
You can make each of these customizations with a separate command, and each takes the CSS file which contains your changes:
@overwrite_css file.css
@add_css file.css
@colorscheme file.css
You can find some nice colorschemes here. The default colorscheme is Tomorrow Light.
file -> print
. Change the destination to "Save as PDF", and under "More settings" make sure you have
"Background graphics" selected.
First, note that @include <file.lit>
will include another literate file, as if you had written
the contents of the included file in the current file.
The @change
command is very similar, except that some changes are performed on the other file when it is included.
Here is an example of the syntax:
@change examples/wc.lit This is an example of using the @change command to recreate change files. We are going to change the title in wc.lit from WC to Word Count. @replace @title WC @with @title Word Count @end Let's also change the comment_type from // %s to /* %s */. @replace @comment_type // %s @with @comment_type /* %s */ @end @change_end
You can make as many changes as you want between the @change
and @change_end
commands.
You should see that the title was changed to Word Count and if you view the code, It should be commented mostly with /* ... */.
It would be nice if when compiling the generated code file, if the program has errors, for the compiler to report the error to the correct line in the lit file. To do this, you will tell which command Literate should use to run the compiler, and Literate will check with the compiler when generating the code file.
To use this feature, you should use the@compiler <sh-command>
command.
In addition you must compile with the --compiler
flag (otherwise Literate
will ignore the command).
The sh-command
should invoke literate itself because using --compiler
turns off output generation. This is because on larger projects you probably have your own build
mechanism and don't want little code and html files being generated whenever you lint.
As an example, to check for errors in the hello_world.c file, you could put the following in the file:
@compiler lit hello_world.lit && clang hello_world.cOn a larger project you might just have
@compiler makewhich will build using Literate and then compile the resulting files. You can see this in the source code for literate.
When the lit file is compiled, this command will be run, and the error output (if any) will be parsed
and changed to report the corresponding line numbers in the lit file. Literate can parse clang, because clang
is a common compiler. If the compiler you are using is not supported, you can provide an error_format
that will be used to parse the compiler output. The supported compilers are:
For example, the to define the error_format for clang
you would add this line to your file:
@error_format %s:%l:%s:%s: %mThere are several special characters here:
%s
means any string of characters that should be ignored%l
means the line number%m
means the error message@compiler
option and are using a language
that supports line directives, you can use the --linenums
(or -l
) option which will make
Literate output line directives.
Here is an example for a C program:
$ lit -l '#line' hello.litThe output of this (using the
hello.lit
program from above) will be:
#line 20 #include <stdio.h> #line 11 int main() { #line 26 printf("hello world\n"); #line 13 return 0; #line 14 }
Literate also lets you write Literate "books". These are a collection of lit files that are strung
together as chapters. They can use each others' codeblocks. To create a book, you need a book
file which specifies which files are included as a sort of table of contents. Here is an example
book file for the hangman, hello, and word count programs (The example lit files here can be found
in the Examples/
directory in the github repository).
@book @title Example Book This is an example book which puts hangman.lit as chapter 1, hello.lit as chapter 2, and wc.lit as chapter 3. This section is a short introduction you can include which will be added to the table of contents file. [Hangman](hangman.lit) [Hello World](hello.lit) [Word Count Program](wc.lit)
When you run lit on this file ($ lit book.lit
) a _book
directory will
be generated containing the html files for each chapter, plus a file named Example Book_contents.html
(in this case).
This file will contain an overview of the book, including the explanation you put in the book file.
Literate also comes with a Vim plugin to make writing Lit files much easier. You can download it here. The plugin provides all sorts of niceties like syntax highlighting (it correctly syntax highlights the language embedded in code blocks using information from the @code_type), and keybindings to let you jump between code blocks.
When you first open a .lit
file, vim will syntax highlight commands like @code_type, and @title... correctly, but it will
not syntax highlight the embedded code blocks right away. This is because when you opened the empty file, there was no @code_type, so
vim was unable to know what language you are using. You can execute :e
to reload the syntax highlighting (make sure the file is saved).
You can use <C-]>
to jump to a code block definition from a code block use. If your cursor is on @{block name}
and you press <C-]>
,
your cursor will jump to the next use/definition.
@code_type lang-name .lang-ext
lang-name
: The name of the language you are usinglang-ext
: The extension of the language you are using. For Python this would be py
.code_type
command is used for knowing which language you are using. This information is used when creating an index,
and for syntax highlighting with the Vim plugin.@comment_type /* %s */
@title title
@s title?
title
argument is optional.$equation$
equation
as TeX by using MathJax. Use $$equation$$
to make the equation a block element (takes up an entire line).@{code block name}
code block name
.Code blocks
--- Block name code... ---Creates a code block named Block name. If you add
+=
to the end of the name, Literate will append the code in the code block to an existing
block named Block name.@include <file>
@change
@change <file> Comments here @replace Some code @with Some other code @end More comments ... @change_endThis is the syntax for a change command. This will include
<file>
, but will the changes given. The
code between @replace
and @with
will be replaced with @with
and @end
.@replace ... @with .. @end
statements in a change statement as you want.@add_css file.css
file.css
and add it to the
default css that Literate uses.@overwrite_css file.css
file.css
.@colorscheme file.css
file.css
.
You can find some nice colorschemes
here.
@compiler <sh-command>
Defines the command that will be run to check for errors from the language compiler.
See this section.
@error_format format
If your compiler is not supported, you can provide an error format string to
define how Literate should parse the compiler command's output.
@book
Mark the file as a book file.