ConTeXt: Revert to the strategy of inverting the label and the footnote content

Users will be able to use block content in labelized footnotes again.
This commit is contained in:
Bastien Dumont 2022-10-29 18:56:13 +02:00
parent 0d30b8cc94
commit e9cfad51cd
2 changed files with 76 additions and 16 deletions

View File

@ -33,7 +33,25 @@ All references are wrapped in a macro named `\tcrfenum`. It has two optional arg
It is up to you to define `\tcrfenum` in your preamble. If your target format is LaTeX, it should be possible to define it as a wrapper for the `\zcref` macro provided by [the zref-clever package](https://ctan.org/pkg/zref-clever). Alternatively, you can use [my implementation](TODO), which supports ConTeXt, LaTeX and other formats. Here are some hints about the implementation:
* [The `\tcrfenum` macro is supposed to output the numbers along with the prefixes and delimiters (e.g. “p. ” and “–”)]{#prefixes-tex};
* In ConTeXt, there is no way to retrieve the note number from a `\reference` or a `\pagereference` contained in the note as is customary in LaTeX. to work around this, footnotes are labelled automatically with the first identifier attached to a span in the note suffixed with `_note`.
* In ConTeXt, there is no way to retrieve the note number from a `\reference` or a `\pagereference` contained in the note as is customary in LaTeX. to work around this, footnotes are labelled automatically with the first identifier attached to a span in the note prefixed with `note:`. Contrary to the ConTeXt syntax, this label is placed _after_ the footnote content, which implies redefining the `\footnote` macro. If your template includes the `header-includes` metadata variable like in the default template, this redefinition will happen automatically. Otherwise, you can copy-paste the following code in your preamble:
``` {=tex}
\catcode`\@=11
\let\origfootnote\footnote
\def\footnote#1#2{
\def\tcrf@secondArg{#2}%
\ifx\tcrf@secondArg\tcrf@bracket
\def\tcrf@todo{\tcrf@footnote@withlabel{#1}#2} %
\else
\def\tcrf@todo{\origfootnote{#1}#2}%
\fi
\tcrf@todo
}
\def\tcrf@bracket{[}
\def\tcrf@footnote@withlabel#1[#2]{\origfootnote[#2]{#1}}
\catcode`\@=13
```
## Usage

View File

@ -5,6 +5,46 @@ local REF_TYPE_ATTR = 'reftype'
local PREFIXED_ATTR = 'prefixref'
local RAW_ATTRIBUTE
-- ConTeXt-specific tweak in order to add the label to the footnote
--[[
Placing the label in square brackets immediatly after \footnote
in the regular way would require unpacking the content
of the Note and wrapping them with the RawInlines
'\footnote[note:' .. label .. ']{' and '}'.
However, Notes have the strange property of being Inlines
that contain Blocks, so this would result in Blocks being
brought into the content of the object that contains the Note,
which would be invalid.
That's why we place the label at the end of the \footnote
and redefine the macro so that it takes it into account.
]]--
local function tweak_footnote_if_ConTeXt(metadata)
if RAW_ATTRIBUTE == 'context' then
local footnote_redefinition = [[
\catcode`\@=11
\let\origfootnote\footnote
\def\footnote#1#2{
\def\tcrf@secondArg{#2}%
\def\tcrf@bracket{[}%
\ifx\tcrf@secondArg\tcrf@bracket
\def\tcrf@todo{\tcrf@footnote@withlabel{#1}#2} %
\else
\def\tcrf@todo{\origfootnote{#1}#2}%
\fi
\tcrf@todo
}
\def\tcrf@footnote@withlabel#1[#2]{\origfootnote[#2]{#1}}
\catcode`\@=13
]]
if not metadata['header-includes'] then
metadata['header-includes'] = pandoc.MetaBlocks(pandoc.RawBlock('context', ''))
end
metadata['header-includes']:insert(pandoc.RawBlock('context', footnote_redefinition))
end
return metadata
end
-- Configuration
local function define_raw_attribute()
@ -178,30 +218,31 @@ local collect_note_labels = {
}
local function make_notelabel(pos)
-- About the strategy followed with ConTeXt,
-- see above tweak_footnote_if_ConTeXt.
local raw_code = ''
if pos == 'begin' then
raw_code = string.gsub(
'<w:bookmarkStart w:id="{{label}}_Note" w:name="{{label}}_Note"/>',
'{{label}}', current_note_labels[1])
if RAW_ATTRIBUTE == 'openxml' then
raw_code = string.gsub(
'<w:bookmarkStart w:id="{{label}}_Note" w:name="{{label}}_Note"/>',
'{{label}}', current_note_labels[1])
end
elseif pos == 'end' then
raw_code = string.gsub('<w:bookmarkEnd w:id="{{label}}_Note"/>',
'{{label}}', current_note_labels[1])
if RAW_ATTRIBUTE == 'openxml' then
raw_code = string.gsub('<w:bookmarkEnd w:id="{{label}}_Note"/>',
'{{label}}', current_note_labels[1])
elseif RAW_ATTRIBUTE == 'context' then
raw_code = '[note:' .. current_note_labels[1] .. ']'
end
end
return pandoc.RawInline(RAW_ATTRIBUTE, raw_code)
end
local function labelize_note(note)
local labelized_note
if RAW_ATTRIBUTE == 'openxml' then
local label_begin = make_notelabel('begin')
local label_end = make_notelabel('end')
labelized_note = { label_begin, note, label_end }
elseif RAW_ATTRIBUTE == 'context' then
labelized_note = pandoc.utils.blocks_to_inlines(note.content)
labelized_note:insert(1, pandoc.RawInline('context', '\\footnote[note:' .. current_note_labels[1] .. ']{'))
labelized_note:insert(pandoc.RawInline('context', '}'))
end
return labelized_note
local label_begin = make_notelabel('begin')
local label_end = make_notelabel('end')
return { label_begin, note, label_end }
end
local function map_text_to_note_labels(current_note_labels)
@ -545,6 +586,7 @@ end
return {
{ Meta = configure },
{ Meta = tweak_footnote_if_ConTeXt },
{ Note = set_notelabels },
{ Note = map_spans_to_notelabels },
{ Span = labelize_span },