Reputation: 1194
The Pandoc documentation says that cross references can be made to section headers in a number of ways. For example, you can create your own ID and reference that ID. For example:
# This is my header {#header}
Will create an ID with value '#header' that can be refenced in the text, as such:
[Link to header](#header)
Which will display the text 'Link to header' with a link to the header.
I couldn't find anywhere how to make the text of the link be the section number when compiled as a LaTeX document.
For example, if my header is compiled to '1.2.3 Section Header', I want my cross-reference to text to display as '1.2.3'.
Upvotes: 10
Views: 6508
Reputation: 10853
Since pandoc
version 2.8 the function pandoc.utils.hierarchicalize
has been replaced with make_sections
. Here is an updated version of the @tarleb's answer which works with newer ´pandoc´ versions.
local make_sections = (require 'pandoc.utils').make_sections
local section_numbers = {}
function populate_section_numbers (doc)
function populate (elements)
for _, el in pairs(elements) do
if el.t == 'Div' and el.attributes.number then
section_numbers['#' .. el.attr.identifier] = el.attributes.number
populate(el.content)
end
end
end
populate(make_sections(true, nil, doc.blocks))
end
function resolve_section_ref (link)
if #link.content > 0 or link.target:sub(1, 1) ~= '#' then
return nil
end
local section_number = pandoc.Str(section_numbers[link.target])
return pandoc.Link({section_number}, link.target, link.title, link.attr)
end
return {
{Pandoc = populate_section_numbers},
{Link = resolve_section_ref}
}
Upvotes: 4
Reputation: 780
You can use the pandoc-secnos filter, which is part of the pandoc-xnos filter suite.
The header
# This is my header {#sec:header}
is referenced using @sec:header
. Alternatively, you can reference
# This is my header
using @sec:this-is-my-header
.
Markdown documents coded in this way can be processed by adding --filter pandoc-secnos
to the pandoc
call. The --number-sections
option should be used as well. The output uses LaTeX's native commands (i.e., \label
and \ref
or \cref
).
The benefit to this approach is that output in other formats (html, epub, docx, ...) is also possible.
Upvotes: 4
Reputation: 22709
A general solution which works with all supported output formats can be build by leveraging pandoc Lua filters: The function pandoc.utils.hierarchicalize
can be used to get the document hierarchy. We can use this to associate section IDs with section numbers, which can later be used to add these numbers to links with no link description (e.g., [](#myheader)
).
local hierarchicalize = (require 'pandoc.utils').hierarchicalize
local section_numbers = {}
function populate_section_numbers (doc)
function populate (elements)
for _, el in pairs(elements) do
if el.t == 'Sec' then
section_numbers['#' .. el.attr.identifier] = table.concat(el.numbering, '.')
populate(el.contents)
end
end
end
populate(hierarchicalize(doc.blocks))
end
function resolve_section_ref (link)
if #link.content > 0 or link.target:sub(1, 1) ~= '#' then
return nil
end
local section_number = pandoc.Str(section_numbers[link.target])
return pandoc.Link({section_number}, link.target, link.title, link.attr)
end
return {
{Pandoc = populate_section_numbers},
{Link = resolve_section_ref}
}
The above should be saved to a file and then passed to pandoc via the --lua-filter
option.
Using the example from the question
# This is my header {#header}
## Some subsection
See section [](#header), especially [](#some-subsection)
Using the above filter, the last line will render as "See section 1, especially 1.1".
Don't forget to call pandoc with option --number-sections
, or headers will not be numbered.
Upvotes: 3
Reputation: 1194
This can be achieved by defining the ID as done previously. eg:
# This is my header {#header}
Then in the text, the cross reference can be written as:
\ref{header}
When this compiles to LaTeX, the cross-reference text will be the section number of the referenced heading.
Upvotes: 9