Markdown syntax
Franklin aims to support most of Common Mark with a few differences and some useful extensions.Experimenting
Beyond directly experimenting in a project folder, you can also explore what HTML is generated with the fd2html
function:
julia> """Set `x` to 1, see [the docs](http://example.com).""" |> fd2html
"<p>Set <code>x</code> to 1, see <a href="http://example.com">the docs</a>.</p>\n"
Basics
If you're already familiar with Markdown, you can skip this section, though it may serve as a useful reminder.
Headers
# Level 1
## Level 2
...
###### Level 6
will generate the various header levels.
\toc
).Text styling
**Bold text**, *italic* or _italic_, **_bold italic_**, `inline code`.
Inserting a horizontal rule can be done with
---
For a blockquote, start the line with >
:
> This is a blockquote
Links
inline links: [plain link](https:://www.wikipedia.org)
reference links: ["reference" link][reflink] and ["reference" link][]
[reflink]: https://www.wikipedia.org
["reference" link]: https://www.wikipedia.org
Footnotes follow a similar syntax
This has a footnote[^1]
[^1]: footnote definition
Note: footnotes are expected to be on a single line, this is due to a limitation of the parser.
For images, just add an exclamation mark !
:
inline: ![alt text](https://juliacon.org/2018/assets/img/julia-logo-dots.png)
reference: ![alt text][ref]
[ref]: https://juliacon.org/2018/assets/img/julia-logo-dots.png
Notes:
(link reference) when using "indirect links" i.e. in the text you use something like
[link name][link A]
and then somewhere else you define[link A]: some/url/
, we recommend you use unambiguous link identifiers (here[link A]
). We recommend you to not use numbers like[link name][1]
, indeed if on the page you have some code where[1]
appears, there is an ambiguity for the parser,(link title) are currently not supported e.g. something like
[link A](some/url/ "link title")
,(suppress links) if, for some reason, you want to have something like
[...]: ...
somewhere on your page that does not define a link, then you need to toggle ref-links off (@def reflinks = false
) and only use inline links[link name](some/url/)
.
Lists
Unordered list (you can also use -
, +
or .
instead of *
)
* item 1
* item 2
* sub-item 1
Ordered list (the proper numbering is done automatically)
1. item 1
1. item 2
1. subitem 1
Comments
You can add comments in your markdown using HTML-style comments: <!-- your comment -->
possibly on multiple lines. Note that comments are not allowed in a math environment.
Symbols and HTML entities
Outside code environments, there are a few quirks in dealing with symbols:
(dollar sign) to introduce a dollar sign, you must escape it with a backslash:
\$
as it is otherwise used to open and close inline math blocks,(HTML entity) you can use HTML entities without issues like
→
for "→" or$
for "$",(backslash) to introduce a backslash, you can just use
\
, while a double backslash\\
can be used to specify a line break in text.
Table of contents
Franklin can insert an automatically generated table of contents simply by using \toc
or \tableofcontents
somewhere appropriate in your markdown. The table of contents will be generated in a franklin-toc
div block, so if you would like to modify the styling, you should modify .franklin-toc ol
, .franklin-toc li
etc in your CSS.
You can specify the minimum and maximum header level to control the table of contents nesting using @def mintoclevel=2
and @def maxtoclevel=3
where, here, it would build a table of contents with the h2
and h3
headers only (this is the setting used here for instance).
Code
Inline code with single and double back-ticks
Single back-ticks: `var = 5`, and
double back-ticks if the code includes ticks: ``var = "`"``.
Blocks of code with triple back-ticks and the language specifier
```julia
a = 5
println(a)
```
You're not obliged to specify the language, if you don't it will assume the language corresponds to the page variable lang
(set to julia
by default). If you want the block to be considered as plaintext, use plaintext
as the language specifier.
Finally, you can also use indented code blocks (which will also take its highlighting hint from lang
) but this is not recommended and you have to explicitly opt in by setting indented_code
on a page that would use them:
@def indented_code = true
Code block:
a = 5
println(a)
Indented code blocks are ambiguous with how other Franklin blocks can be defined such as div blocks and latex blocks. If you really want to use them, you will have to ensure that your div blocks and latex commands on that page do not use indentation as it might cause problems.
Highlighting
Syntax highlighting is done via highlight.js and you can find the relevant script in the /_libs/highlight/
folder. The default one supports highlighting for Bash, CSS, Ini, Julia, Julia-repl, Markdown, plaintext, Python, R, Ruby, Xml and Yaml. Note that if you use pre-rendering, then the full highlight.js
is used with support for over 100 languages.
By default unfenced code blocks (e.g. indented code blocks) will be highlighted as Julia code blocks; to change this, set @def lang = "python"
. If you want a code block to not be highlighted, we recommend you use plaintext
to guarantee this:
```plaintext
this will not be highlighted
```
If you wish to have highlighting for more languages outside of the pre-rendering mode, head to highlight.js, make a selection of languages and place the resulting highlight.pack.js
in the /_libs/highlight/
folder. If you do this, you might want to slightly modify it to ensure that the Julia-repl mode is properly highlighted (e.g. shell>
):
open the
highlight.pack.js
in an editor of your choicelook for
hljs.registerLanguage("julia-repl"
and modify the entry to:
hljs.registerLanguage("julia-repl",function(a){return{c:[{cN:"meta",b:/^julia>/,r:10,starts:{e:/^(?![ ]{6})/,sL:"julia"}},{cN:"metas",b:/^shell>/,r:10,starts:{e:/^(?![ ]{6})/,sL:"bash"}},{cN:"metap",b:/^\(.*\)\spkg>/,r:10,starts:{e:/^(?![ ]{6})/,sL:"julia"}}]}});
(see also the README of FranklinTemplates).
Evaluated code blocks
Julia code blocks can be evaluated and the result of the code is either shown or rendered. To declare a code block for evaluation, use the fenced code block syntax with a name for the code block:
```julia:snippet1
using LinearAlgebra, Random
Random.seed!(555)
a = randn(5)
round(norm(a), sigdigits=4)
```
\show{snippet1}
This will look like
using LinearAlgebra, Random
Random.seed!(555)
a = randn(5)
round(norm(a), sigdigits=4)
3.173
For more information on using evaluated code blocks, please head to the section on code insertion.
Maths
Inline and display maths
Inserting maths is done pretty much like in LaTeX:
Inline: $x=5$ or display:
$$ \mathcal W_\psi[f] = \int_{\mathbb R} f(s)\psi(s)\mathrm{d}s $$
Inline: \(x=5\) or display:
\[ \mathcal W_\psi[f] = \int_{\mathbb R} f(s)\psi(s)\mathrm{d}s \]You can also use \[...\]
for display maths.
One thing to keep in mind when adding maths on your page is that you should be generous in your use of whitespace, particularly around inequality operators to avoid the ambiguity that could confuse KaTeX. So for instance prefer: $0 < C$
to $0<C$
(the latter will not render properly). Also if you have to write double braces, make sure to add a space in between so { {
or } }
and not {{
or }}
since that has a specific meaning in Franklin:
$$ \dfrac{ {101}_{2} } $$
\[\dfrac{1}{ {101}_{2} }\]
Aligned maths
For aligned environment you can use \begin{eqnarray}...\end{eqnarray}
or \begin{align}...\end{align}
\begin{eqnarray}
\exp(i\pi)+1 &=& 0\\
1+1 &=& 2
\end{eqnarray}
\begin{align}
\exp(i\pi)+1 &= 0\\
1+1 &= 2
\end{align}
\[\begin{array}{rcl}
\exp(i\pi)+1 &=& 0\\
1+1 &=& 2
\end{array}\]
\[\begin{aligned}
\exp(i\pi)+1 &= 0\\
1+1 &= 2
\end{aligned}\]
\eqnarray
is discouraged due to possible interference with array column spacing. In Franklin, this does not happen and so the only practical difference is that \eqnarray
will give you a bit more horizontal spacing around the =
signs.Raw HTML
You can inject raw HTML by fencing it with ~~~...~~~
which can be useful for custom formatting.
A simple example is if you want to colour your text; for instance with
~~~
<span style="color:magenta;">coloured</span>
~~~
you get: some coloured text (note that it all can be on a single line.)
You could also use this to locally customise a layout etc.
@@divname...@@
blocks instead of raw HTML since those can have markdown, maths, etc. in them. (See inserting divs.)File insertions
A few commands are defined to help you with insertions of content; you can also define your own commands using custom HTML as was discussed before.
Inserting a figure
The commands
\figalt{alt}{path}
, and\fig{path}
are convenient commands to insert figures. Of course, you're free to use the default markdown way ![alt](full_path)
instead. One difference with these commands though is that they allow the use of relative paths; this can be convenient in order to organise your assets as you organise your pages.
Note: to help with the organisation of assets, Franklin will assume by default that figures are placed in a folder /output/
relative to where the script is, i.e. if the script is in [script_dir]
, the figures will be in [script_dir]/output/
. To help with this, the macro @OUTPUT
can be used which specifies the path to this relative output dir:
```julia:./ex1
using PyPlot
figure()
plot([0, 1], [0, 1])
savefig(joinpath(@OUTPUT, "test.png"))
```
\fig{./output/test}
This gives:
using PyPlot
figure()
plot([0, 1], [0, 1])
savefig(joinpath(@OUTPUT, "test.png"))
In fact the syntax \fig{./test}
is also allowed, Franklin will then first look in the [script_dir]
for a test.*
figure and, if it doesn't find one, will try to look in [script_dir]/output/
for a test.*
figure:
Figure style (for instance, if one wishes to modify figure width) can be further customized in two different ways. The first way is to define custom CSS for the figure. In the markdown, this comes down to writing:
@@im-50
![](/assets/rndimg.jpg)
@@
which puts the image in a div block with a class name im-50
.
While defining the corresponding custom CSS as such:
.im-50 {text-align: center;}
.im-50 img {
padding: 0;
width: 50%;
}
Another solution consists in defining a custom LaTeX command, for example:
\newcommand{\figenv}[3]{
~~~
<figure style="text-align:center;">
<img src="!#2" style="padding:0;#3" alt="#1"/>
<figcaption>#1</figcaption>
</figure>
~~~
}
This creates a command called figenv
which takes 3 arguments and inserts raw HTML (~~~
...~~~
) plugging in each of the arguments in the appropriate location i.e.: (1) the image caption (2) the image source path and (3) specific CSS styling for the image. This command could be used as such (here changing the width and adding a 1px wide red border to the image):
\figenv{the caption}{/assets/rndimg.jpg}{width:50%;border: 1px solid red;}
Inserting markdown
In some situations, you may have some markdown in a file which you might want to include somewhere else. This can be achieved thanks to the \textinput{path}
command. The path specification is as the other commands, and the text will be formatted.
As an example you could have in /assets/ccc/sidefile.md
:
some **markdown** in a side file.
whereas in index.md
:
This is the index then \textinput{ccc/sidefile}
and this will be equivalent to just having in index.md
:
This is the index then some **markdown** in a side file.
Note: if you don't specify a file extension, .md
is appended to the specified path.
Inserting a table
You can insert tables directly from CSV files with the \tableinput{header}{path}
command. If you generate the file on the fly, you should follow this example:
```julia:./tableinput/gen
testcsv = "h1,h2,h3
152,some string, 1.5f0
0,another string,2.87"
write("assets/pages/tableinput/testcsv.csv", testcsv)
```
Then you can insert the table with:
\tableinput{}{./tableinput/testcsv.csv}
This will result in:
h1 | h2 | h3 |
---|---|---|
152 | some string | 1.5f0 |
0 | another string | 2.87 |
In this case, given no header was specified in the call, a header was generated from the first line in the CSV (here: h1, h2, h3
).
If your file doesn't have a header, you can specify it in the call:
```julia:./tableinput/gen
testcsv = "152,some string, 1.5f0
0,another string,2.87"
write("assets/pages/tableinput/testcsv2.csv", testcsv)
```
\tableinput{custom h1,custom h2,custom h3}{./tableinput/testcsv2.csv}
custom h1 | custom h2 | custom h3 |
---|---|---|
152 | some string | 1.5f0 |
0 | another string | 2.87 |
With the above in mind, you can also include existing CSV files.
There are a couple of rules that you have to keep in mind when using the \tableinput{}{}
command:
Columns must be separated by a comma (
,
).If a header is specified, its length must match the number of columns in the file.
The standard way of creating tables in Markdown, namely using:
| Heading 1 | Heading 2 | Heading 3 |
|-----------|-----------|-----------|
| LaTeX | KaTeX | MikTeX |
can also be used. It is also possible to use HTML to create a table with the HTML fenced between ~~~
.