© Thomas Mailund 2019
T. MailundIntroducing Markdown and Pandochttps://doi.org/10.1007/978-1-4842-5149-2_7

7. Cross-referencing

Thomas Mailund1 
(1)
Aarhus N, Denmark
 

Cross-referencing is not directly supported by standard Markdown. Markdown was mainly invented to write hypertext documents for web pages, so referencing section numbers, figures, or tables is not part of it. We can use the link syntax to make hypertext references to sections but not get section numbers and such.

Pandoc itself doesn’t support extensions for other kinds of cross-referencing, but there is a so-called “filter,” pandoc-crossref, that adds this support. Filters (see Chapter 11) are scripts that are run to modify a document after it has been parsed by Pandoc and before the output format is generated. Filters are beyond the scope of this book, but we will use two in this and the next chapter.

The pandoc-crossref filter is not necessarily automatically installed when you install Pandoc, so you might need to install it manually. How you do this will depend on your platform. I work on MacOS and use the Homebrew1 package manager, so I installed it using
brew install pandoc-crossref
The filter is a Haskell package, so you can also install it using the cabal package manager if you have the Haskell system installed.
cabal update
cabal install pandoc-crossref

It might take a little while.

If you installed Pandoc using any of the packages from the Pandoc releases web page,2 the filter should already be included. If all else fails, you can download the source code and compile it at the pandoc-crossref homepage.3

To invoke the filter when processing a document with Pandoc, you use the option --filter (or -F as a shorter option). To enable the pandoc-crossref filter , run Pandoc as
pandoc --filter pandoc-crossref

Cross-referencing using pandoc-crossref uses a syntax similar to hypertext links, but with a twist. You specify labels with curly brackets and insert references to them using square brackets. You need to include cross-referencing type as part of the labels, though. To insert a label, you use the syntax {#type:label}, and to refer to it, you use the syntax [@type:label]. The type, here, specifies whether you are referring to sections, tables, figures, or equations.

Referencing Sections

Using cross-referencing via links works well for HTML or EPUB documents, where you have hypertext, but less well for printed media, where you don’t. There, you would make references to chapters and sections using their numbers instead, but that isn’t supported in standard Markdown.

Using pandoc-crossref , we can refer to sections via section numbers. We need to define labels for the headers we want to refer to, and these labels must start with the prefix sec: (in addition to the hashtag that all header labels must have). We can then insert cross-references to section numbers using [@sec:label] markup. An example could look like this:
# This is a chapter {#sec:chapter}
## This is a section {#sec:section}
See [@sec:chapter] and [@sec:section].
Pandoc doesn’t number sections by default, and while it will number sections in some formats when we use pandoc-crossref, we should use the option --number-sections to make sure. If, for example, you generate PDF output, sections will not be numbered if you leave out this option, and consequently, it makes no sense to refer to sections by their numbers.
pandoc --number-sections
    --filter pandoc-crossref
    -o output.pdf
    input.md

This approach will use the LaTeX section numbering system for PDF output but will also work for other output formats such as HTML.

You can set the section numbering depth with the metavariable secnumdepth. For example, to number chapters and sections (or sections and subsections, depending on the top level section type), you can add the following line to your metadata header:
secnumdepth: 2

This will only affect LaTeX and PDF output, though, and not other output formats.

Alternatively, you can leave the section numbering entirely up to the filter by setting metadata variable
numberSections
to true and set the section depth you want to be numbered with the metadata variable
sectionsDepth
For example, in your header, you can add the following lines to get chapters and sections, but not subsections, numbered (assuming the top level headers are chapters; otherwise you get sections and subsection headers numbered):
numberSections: true
sectionsDepth: 2

This will insert chapter and section numbers at the desired depth and let you cross-reference sections in HTML and EPUB format, but unfortunately the cross-referencing does not work in LaTeX and PDF. Here, you only get the section numbers but not the cross-references inserted.

Neither of the two choices for section numbering is ideal for both PDF and EPUB output. Using
--number-sections
will insert section numbers in both output formats, but you can only control the numbering depth in PDF output. Using
numberSections
will insert section numbers to the desired depth in both output formats, but you can’t insert references to them in PDF output. You can’t use both
--number-sections
and
numberSections

either since both the Pandoc filter and LaTeX will insert section numbers , and you end up with two of them in each header.

One solution I use for this is to call Pandoc with different options when generating EPUB and PDF. For EPUB output, I use
pandoc --metadata numberSections=true
       --filter pandoc-crossref ...
For PDF output, I use
pandoc --number-sections
       --filter pandoc-crossref ...
I set the numbering depth in my YAML header, using both options for controlling that:
sectionsDepth: 2
secnumdepth: 2

Reference Prefixes

When you need to refer to a section, you use the syntax
[@sec:label]
When you reference a section this way, the filter will insert both the section number and a default prefix, which is “sec.” for a single section and “secs.” for multiple sections. You can refer to more than one section but separating the labels by semicolons inside the square brackets:
[@sec:label1; @sec:label2]

For documents where you have both chapters and sections, this might not be what you want. There you might want to use the prefix “Chapter” for chapters and “Section” for sections. Unfortunately, you cannot make prefixes that depend on the header depth, but you can disable the prefixes by overriding them.

You can either change the reference prefix on a per-reference basis or globally through metadata. For referring to chapters as “Chapter” rather than “sec.”—as in this example—the best solution is probably to set the prefix explicitly when referring to a chapter, but we can see how both approaches work.

To use a per-reference specific prefix, you need to insert the prefix you want between the start square bracket and the label. So, to make the prefix for the reference to a chapter be “Chapter,” we would write [Chapter @sec:chapter].

To change the prefixes globally, we need to set a metadata variable. The metadata variable that controls the section references prefix is secPrefix. If we set it to the empty string, we get rid of the prefixes .
secPrefix: ""
You can then manually insert the prefixes you want in the Markdown text:
See Chapter[@sec:chapter]
and Section[@sec:section].

Notice the lack of spaces between prefix and references here. This is needed for PDF output; the LaTeX document that Pandoc generates for the references contain a hard space, so if we put a space between the prefix and reference, the PDF document will have too much space in the generated text. For HMTL and EPUB, it doesn’t matter.

Completely disabling a prefix can be done on a per-reference basis as well. Just add a “-” between the start bracket and the label. If you write [-@sec:chapter], you only get the chapter number and not the prefix. You rarely need to set the default prefix to the empty string explicitly. But using that as an example gave me an excuse to introduce the variable.

You can set the secPrefix metadata to a list. The first element is used for single references and the second for plural. So, to use “Sect.” as the prefix for a reference to a single section, and “Sects.” as the prefix for multiple sections, we could specify this metadata:
secPrefix: ["Sect.", "Sects."]

The prefix list can have any length, and the number of references is used to select a prefix. So, if you want a special prefix when you refer to three sections, you can add a third element to the list. When you have more references than prefixes, you get the last element in the list. Thus, if you specify two elements in the list, the first is used for singular references and the second for multiple references .

You might want to use lowercase “sect.” when you refer to a section in the middle of a sentence but “Sect.” at the beginning of sentences. With pandoc-crossref it is simple to switch between uppercase and lowercase label prefixes. If you insert a label that starts with an uppercase, your prefix will be in uppercase as well. Thus, if you write [@Sec:label], the default prefix will be “Sec.”; if you write [@sec:label], the default prefix will be “sec.”. The same goes for references to figures, tables, equations, and so on.

Referencing Figures, Tables, and Equations

To reference figures, you use the same syntax as for sections, except for where you define figure labels and the prefix of the labels. To define a label for a figure, you must give it the prefix #fig: and place the label right after the markup for inserting the figure, so using the syntax
[Caption](link-to-figure){#fig:label}

You cannot put a space between the figure insertion and the label definition. You refer to figure labels as you would with references to sections.

For tables, your labels must start with #tbl: and placed after the table caption:
 a   b   c
--- --- ---
 1   2   3
 4   5   6
: Caption {#tbl:label}

For tables you must have a space between the caption and the label.

For display-style math , math that stands on a line of its own and is written with two dollar signs, you can add labels if they begin with #eq: and are put on the same line as the math with a space between the label and the terminating double dollar signs:
$$ f(x) = x^2 + a x $$ {#eq:label}

You can change the default prefix for figures, tables, and equations, as you can for sections, with the metadata figPrefix, tblPrefix, and eqnPrefix, respectively.

For more details on how to use the cross-reference filter, I will refer to its online manual.4

Bibliographies

If your text requires citations and a bibliography, you can enable the filter pandoc-citeproc by either running Pandoc with the
--bibliography
option or using
--filter pandoc-citeproc
If you use both pandoc-crossref and pandoc-citeproc filters, you must always use pandoc-crossref first
pandoc --filter pandoc-crossref
       --filter pandoc-citeproc ...

The two filters use similar kinds of citation syntax, and this means that the order in which you run the filters matter. The citeproc filter gets confused if it sees cross-reference labels. The same does not happen if you run the cross-reference filter first; it will leave the citation codes alone so they can be handled by the citation filter.

With the --bibliography option, you need to specify the file that contains your bibliography. Using
--filter pandoc-citeproc
you can specify the bibliography file as metadata in your YAML header instead, for example:
---
    bibliography: citations.bib
---

The pandoc-citeproc filter can read bibliographies in various file formats and will pick the format based on the file suffix. With .bib files it will use BibTeX. For EndNote you would use .enl and for ISI .wos. Check the online documentation5 for a complete list.

To control the format used for citations and the bibliography, you can specify a CSL6 file with the metadata variable csl or the Pandoc option --csl. CSL files for most journal styles can be downloaded from GitHub.7

For example, if “smith12” is a key in your bibliography, you can insert a citation using [@smith12]. You need to include @ even though it isn’t part of the reference key; the filter (and Pandoc) uses this to recognize citations. You can cite more than one reference by separating the references with semicolons: [@smith12; @smith14].

Depending on the citation style, the inserted reference might contain author names. This doesn’t read well if you have already mentioned authors in the text, and you can disable it with a minus before the reference: [-@smith12]. The same effect is achieved by leaving out the square brackets and write @smith12.

More generally, you can insert text in the citations to add, for example, page information or other comments, such as [see @smith12, chap1; also @smith14, chap 12]. If you leave out the square brackets to get an in-text citation, you can add comments to appear inside the parenthesis (again, depending on your citation style) by writing the comments in square brackets after the reference: see @smith12 [chapter 11].

The bibliography will be put at the end of your document. If you want to give the bibliography a section header, you should end your Markdown document with the header for the bibliography.

Exercises

Reference Sections

Write three sections. In two and three, refer back to one and two, respectively.

Figures, Tables, and Equations

Write a document with each of a figure, a table, and an equation. Make references to each.

Bibliographies

If you have a bibliography, then make a document that cites the elements in it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset