Add 'text-crossrefs/' from commit '7e09b67aeda54b4f098e8576c203c809572a85bb'
git-subtree-dir: text-crossrefs git-subtree-mainline:02e7a6fef1
git-subtree-split:7e09b67aed
This commit is contained in:
commit
6f5b110c9e
23
text-crossrefs/Makefile
Normal file
23
text-crossrefs/Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
.PHONY: test-all test-internal
|
||||
|
||||
SHELL=/bin/bash
|
||||
return_statement_line_number := $(shell grep -nE '^return' text-crossrefs.lua | cut -d ':' -f 1)
|
||||
line_before_return := $(shell echo $$(($(return_statement_line_number) - 1)))
|
||||
|
||||
test-all: test-internal test-context test-latex test-opendocument
|
||||
|
||||
test-internal: text-crossrefs.lua
|
||||
-rm --interactive=never test/tmp.lua
|
||||
sed -n 1,$(line_before_return)p text-crossrefs.lua > test/tmp.lua
|
||||
cat test/test-functions.lua >> test/tmp.lua
|
||||
chmod -w test/tmp.lua
|
||||
pandoc -L test/tmp.lua <<< ''
|
||||
@echo -e '==========================\nAll internal tests passed.\n==========================\n'
|
||||
rm --interactive=never test/tmp.lua
|
||||
|
||||
test-%: text-crossrefs.lua sample.md
|
||||
TESTED_FORMAT=$* pandoc -t native -L text-crossrefs.lua sample.md > test/tmp-$*.native
|
||||
diff test/tmp-$*.native test/sample-$*.native
|
||||
@echo -e '\n===============\ntest passed.\n===============\n'
|
||||
rm test/tmp-$*.native
|
||||
|
323
text-crossrefs/README.md
Normal file
323
text-crossrefs/README.md
Normal file
|
@ -0,0 +1,323 @@
|
|||
# text-crossrefs: cross-references to arbitrary portions of text in Pandoc
|
||||
|
||||
This filter extends Pandoc's cross-referencing abilities
|
||||
with references to any portion of text
|
||||
by its page number, its note number (when applicable)
|
||||
or an arbitrary reference type (with ConTeXt or LaTeX output).
|
||||
It currently supports the following output formats:
|
||||
|
||||
* context
|
||||
* docx
|
||||
* latex
|
||||
* odt
|
||||
* opendocument
|
||||
|
||||
## Format-specific preliminary notices
|
||||
|
||||
### DOCX and ODT/Opendocument
|
||||
|
||||
When opening for the first time a file produced by Pandoc with _text-crossrefs_,
|
||||
you should have to refresh the fields in order to get the correct values.
|
||||
In LibreOffice, press `F9`; in Word, a dialog box should appear when the file opens.
|
||||
|
||||
### ConTeXt specifically
|
||||
|
||||
Your template should include the following directive before `\starttext`
|
||||
(as in the default template for ConTeXt):
|
||||
|
||||
```
|
||||
$for(header-includes)$
|
||||
$header-includes$
|
||||
$endfor$
|
||||
```
|
||||
|
||||
### All TeX-based formats
|
||||
|
||||
All references are wrapped in a macro named `\crossrefenum`.
|
||||
It has two optional arguments:
|
||||
the first one is the reference type,
|
||||
the second indicates whether the prefix (e.g. “p. ”) should be printed or not
|
||||
(can be set to `withprefix`, `noprefix`, `yes` or `no`).
|
||||
The default values for these arguments should match
|
||||
those of `tcrf-default-reftype` and `tcrf-default-prefixref`
|
||||
(resp. `page` and `yes`, i.e. `withprefix`).
|
||||
The mandatory argument of `\crossrefenum` is a group enclosing one or more groups.
|
||||
Each of them contain a reference (either a single reference or a range).
|
||||
|
||||
Here are some valid invocations:
|
||||
|
||||
* `\crossrefenum[note][withprefix]{{lblone}{lbltwo}{lblthree}}`
|
||||
* `\crossrefenum[page][noprefix]{{lblone}{lbltwo}{lblthree}}`
|
||||
* `\crossrefenum[noprefix]{{lblone}{lbltwo}{lblthree}}` (the first argument defaults to `page`)
|
||||
* `\crossrefenum{{lblone}{lbltwo}{lblthree}}` (the second argument defaults to `withprefix`)
|
||||
* `\crossrefenum{{only-one}}` (even if the enumeration is limited to one item, it must be in a group)
|
||||
* `\crossrefenum{{lblone to lbltwo}{lblthree}}` (the first reference points to a range)
|
||||
|
||||
It is up to you to define `\crossrefenum` 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 currently supports ConTeXt and LaTeX.
|
||||
Here are some hints about the implementation of the `\crossrefenum` macro:
|
||||
|
||||
* [The `\crossrefenum` macro is supposed to output non only the numbers,
|
||||
but also 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 one would from a `\label` in LaTeX.
|
||||
To work around this, footnotes are labelled automatically with `note:`
|
||||
followed by the first identifier attached to a span in the note.
|
||||
Contrary to the ConTeXt syntax, this label is placed _after_ the footnote content,
|
||||
so the `\footnote` macro has to be redefined.
|
||||
If your template includes the `header-includes` metadata variable like the default one does,
|
||||
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\crfnm@secondArg{#2}%
|
||||
\ifx\crfnm@secondArg\crfnm@bracket
|
||||
\def\crfnm@todo{\crfnm@footnote@withlabel{#1}#2} %
|
||||
\else
|
||||
\def\crfnm@todo{\origfootnote{#1}#2}%
|
||||
\fi
|
||||
\crfnm@todo
|
||||
}
|
||||
\def\crfnm@bracket{[}
|
||||
\def\crfnm@footnote@withlabel#1[#2]{\origfootnote[#2]{#1}}
|
||||
\catcode`\@=13
|
||||
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basics
|
||||
|
||||
Mark the span of text you want to refer to later
|
||||
with an identifier composed of alphanumeric characters, periods, colons, underscores or hyphens:
|
||||
|
||||
``` markdown
|
||||
Émile Gaboriau published [_L'Affaire Lerouge_ in
|
||||
1866]{#publication}.[^1]
|
||||
|
||||
[^1]: It is a very [fine piece of literature]{#my-evaluation}.
|
||||
|
||||
[It was very popular.]{#reception}
|
||||
```
|
||||
|
||||
To refer to it, write another span with class `tcrf` containing the target's identifier.
|
||||
If the span you are referring to is part of a footnote,
|
||||
you can refer to it either by page or note number
|
||||
according to the value of the `reftype` attribute (defaults to `page`).
|
||||
For instance, this:
|
||||
|
||||
``` markdown
|
||||
See [publication]{.tcrf} for the publication date. I gave my
|
||||
opinion in [my-evaluation]{.tcrf reftype=note}, [my-evaluation]{.tcrf}.
|
||||
```
|
||||
|
||||
will render in ConTeXt or LaTeX output:
|
||||
|
||||
``` tex
|
||||
See \crossrefenum{{publication}} for the publication date. I expressed
|
||||
my thoughts about it in \crossrefenum[note]{{my-evaluation}},
|
||||
\crossrefenum{{my-evaluation}}.
|
||||
```
|
||||
|
||||
If you want to give a reference by note _and_ page number like in the example above,
|
||||
you can also use the following shorthand:
|
||||
|
||||
```md
|
||||
[my-evaluation]{.tcrf reftype=pagenote}
|
||||
```
|
||||
|
||||
In fact, you can use any identifier, including those automatically set by Pandoc.
|
||||
|
||||
To suppress the prefixes (e.g. “p. ”), you can set the `prefixref` attribute to `no` (defaults to `yes`).
|
||||
It can be useful, for instance, for small manually formatted indexes[^comma-syntax]:
|
||||
|
||||
``` markdown
|
||||
Gaboriau: [publication, my-evaluation, reception]{.tcrf prefixref=no}
|
||||
```
|
||||
|
||||
[^comma-syntax]: About the comma-delimited syntax used in this example, see [the section on enumerations below](#enums).
|
||||
|
||||
### Controlling where the label is placed
|
||||
|
||||
By default, labels are placed at the beginning of the spans.
|
||||
You can change this via the attribute `refanchor`, which can be set to:
|
||||
|
||||
* `beg` (default);
|
||||
* `end`;
|
||||
* `both`.
|
||||
|
||||
When the value is `both`, _text-crossrefs_ creates two labels
|
||||
by suffixing `-beg` and `-end` to the identifier.
|
||||
A typical use case is:
|
||||
|
||||
```
|
||||
[A portion of text that may cross a page break.]{#mylbl refanchor=both}
|
||||
|
||||
See [mylbl-beg>mylbl-end]{.tcrf}.
|
||||
```
|
||||
|
||||
### Page ranges
|
||||
|
||||
You can refer to a page range like this:
|
||||
|
||||
``` markdown
|
||||
If you want to know more about _L'Affaire Lerouge_, see [publication>reception]{.tcrf}.
|
||||
```
|
||||
|
||||
The separator (here `>`) can be set to any string of characters
|
||||
other than alphanumeric, period, colon, underscore, hyphen and space
|
||||
(see the [customization options](#common-opts)).
|
||||
|
||||
In LaTeX and ConTeXt output, the above-mentionned `\crossrefenum` macro
|
||||
should be defined so that the range is printed as a simple page reference if the page numbers are identical.
|
||||
The syntax of a range is[^customize-range-tex]:
|
||||
|
||||
``` tex
|
||||
\crossrefenum{{publication to reception}}
|
||||
```
|
||||
|
||||
[^customize-range-tex]: Note that [it can be customized](#tex-options).
|
||||
|
||||
In DOCX and ODT/Opendocument output,
|
||||
a range will be printed as a range even if the numbers are identical.
|
||||
|
||||
### Enumerations {#enums}
|
||||
|
||||
You can enumerate several references as a comma-delimited list, for instance:
|
||||
|
||||
``` markdown
|
||||
[ref-one, ref-two>ref-three, ref-four]{.tcrf}
|
||||
```
|
||||
|
||||
In DOCX and ODT/Opendocument output, all these references will be printed,
|
||||
potentially resulting in unnecessary repetitions.
|
||||
In TeX-based output formats, they will be wrapped in `\crossrefenum` like this
|
||||
and should be collapsed by the macro when it is desirable:
|
||||
|
||||
``` tex
|
||||
\crossrefenum{{ref-one}{ref-two to ref-three}{ref-four}}
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Common options {#common-opts}
|
||||
|
||||
The following metadata fields can be set as strings:
|
||||
|
||||
* `tcrf-references-enum-separator`:
|
||||
* the string between two references in an enumeration in a reference span;
|
||||
* defaults to a comma followed by a space.
|
||||
* `tcrf-references-range-separator`:
|
||||
* the string used to separate two references in a reference span;
|
||||
* defaults to `>`.
|
||||
* `tcrf-only-explicit-labels`:
|
||||
* set it to `true` if you want _crossrefenum_ to refer to spans with class `label` only;
|
||||
* defaults to `false`.
|
||||
* `tcrf-default-prefixref`:
|
||||
* default value for the `prefixref` attribute;
|
||||
* defaults to `yes`.
|
||||
* `tcrf-default-reftype`:
|
||||
* default value for the `reftype` attribute;
|
||||
* defaults to `page`.
|
||||
|
||||
### Options specific to DOCX and ODT/Opendocument
|
||||
|
||||
Here are some metadata fields for the `docx`, `odt` and `opendocument` formats only
|
||||
(see [above](#prefixes-tex) why they are ignored in ConTeXt and LaTeX output):
|
||||
|
||||
* `tcrf-page-prefix`:
|
||||
* “page” prefix;
|
||||
* defaults to `p. `.
|
||||
* `tcrf-pages-prefix`:
|
||||
* “pages” prefix;
|
||||
* defaults to `pp. `.
|
||||
* `tcrf-note-prefix`:
|
||||
* “note” prefix;
|
||||
* defaults to `n. `.
|
||||
* `tcrf-notes-prefix`:
|
||||
* “notes” prefix;
|
||||
* defaults to `nn. `.
|
||||
* `tcrf-pagenote-separator`:
|
||||
* the separator between the enumerated references in the output file
|
||||
when `reftype` is set to `pagenote`;
|
||||
* defaults to a comma followed by a space.
|
||||
* `tcrf-pagenote-at-end`:
|
||||
* the string printed at the end of a `pagenote` reference in the output file;
|
||||
* defaults to the empty string, but it can be used to achieve something like *n. 3 (p. 5)*
|
||||
(see the sample file).
|
||||
* `tcrf-pagenote-factorize-first-prefix-in-enum`:
|
||||
* defines if the prefixes of the type printed first in a reference to page and note
|
||||
should be repeated (like in “p. 6, n. 1 and p. 9, n. 3”)
|
||||
or set globally at the beginning of the enumeration (like in “pp. 6, n. 1 and 9, n. 3”);
|
||||
* defaults to `no`, can be set to `yes`.
|
||||
* `tcrf-pagenote-first-type`:
|
||||
* the type of the reference number that is printed first in references to page and note;
|
||||
* defaults to `page`, can be set to `note`.
|
||||
* `tcrf-range-separator`:
|
||||
* the string separating the page numbers in a range;
|
||||
* defaults to `–`.
|
||||
* `tcrf-references-enum-separator`:
|
||||
* the string separating the elements of an enumeration in a reference span;
|
||||
* defaults to a comma followed by a space.
|
||||
* `tcrf-multiple-delimiter`:
|
||||
* the string between two elements (but the two last ones) in an enumeration;
|
||||
* defaults to a comma followed by a space.
|
||||
* `tcrf-multiple-before-last`:
|
||||
* the string inserted between the two last elements in an enumeration;
|
||||
* defaults to `and` surrounded with spaces.
|
||||
|
||||
### Options specific to the formats based on TeX {#tex-options}
|
||||
|
||||
Since TeX is extensible, you may wish to support types
|
||||
other than `page`, `note` and `pagenote` for ConTeXt and LaTeX output.
|
||||
`tcrf-additional-types` can be provided with a list of supplementary accepted types, e.g.:
|
||||
|
||||
``` yaml
|
||||
tcrf-additional-types:
|
||||
- line
|
||||
- figure
|
||||
```
|
||||
|
||||
Once declared, these types can be used as the value of `reftype`
|
||||
in the same way as `page`, `note` and `pagenote`.
|
||||
|
||||
In addition, the following metadata field can be used to control the rendering of ranges of labels in `\crossrefenum`:
|
||||
|
||||
* `tcrf-range-delim-crossrefenum`:
|
||||
* the delimiter between the labels of a range in the TeX output file;
|
||||
* defaults to `to` surrounded with spaces.
|
||||
|
||||
## Compatibility with other filters
|
||||
|
||||
_text-crossrefs_ must be run after all filters that may create, delete or move footnotes, such as citeproc.
|
||||
|
||||
In a citation inside square brackets, the span bearing an identifier should not include
|
||||
a citation key, a locator or a `;` delimiter.
|
||||
When it follows immediatly the locator,
|
||||
you should protect the locator with curly brackets.
|
||||
For example, this should work:
|
||||
|
||||
``` markdown
|
||||
[@Jones1973, p. 5-70; @Doe2004[]{#jones-doe}]
|
||||
|
||||
[@Jones1973, p. 5-70; [it was elaborated upon]{#further-elaboration} by @Doe2004]
|
||||
|
||||
[@Jones1973, {p. 5-70}[]{#ref-to-jones}; @Doe2004]
|
||||
```
|
||||
|
||||
not that:
|
||||
|
||||
``` markdown
|
||||
[[@Jones1973, p. 5-70]{#ref-to-jones}; @Doe2004]
|
||||
|
||||
[[@Jones1973, p. 5-70; @Doe2004]{#jones-doe}]
|
||||
|
||||
[@Jones1973, p. 5-70[]{#ref-to-jones}; @Doe2004]
|
||||
```
|
41
text-crossrefs/sample.md
Normal file
41
text-crossrefs/sample.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
tcrf-pagenote-separator: '\ ('
|
||||
tcrf-pagenote-at-end: ')'
|
||||
header-includes: |
|
||||
\input{crossrefenum}
|
||||
---
|
||||
|
||||
(About the notes, see [toc-notes-begin>toc-notes-end]{.tcrf}.)
|
||||
|
||||
Émile Gaboriau published [_L'Affaire Lerouge_ in
|
||||
1866]{#publication}.[^1]
|
||||
|
||||
[^1]: It is a very [fine piece of literature]{#my-evaluation}.
|
||||
|
||||
[It was very popular.]{#reception}
|
||||
|
||||
See [publication]{.tcrf} for the publication date. I expressed
|
||||
my thoughts about it in [my-evaluation]{.tcrf reftype=pagenote}.
|
||||
|
||||
If you want to know more about _L'Affaire Lerouge_, see [publication>reception]{.tcrf}.
|
||||
|
||||
Here are some precisions.[^2]
|
||||
|
||||
[^2]: [Whatever format]{#format} you choose, you can [refer to a note]{#refer-to-note} by the identifier of [any of its spans. You can even [nest spans]{#nested-spans}!]{#which-identifier}
|
||||
|
||||
[I want to refer to a note]{#toc-notes-begin}:
|
||||
|
||||
* How can I refer to a note by its number? → See [refer-to-note]{.tcrf}.
|
||||
* What formats are supported? → See [format]{.tcrf}.
|
||||
* What if the note contains multiple spans with identifiers? → See [which-identifier]{.tcrf}.
|
||||
* What happens if a span in contained in a span? → See [nested-spans]{.tcrf}.
|
||||
* What are the notes? → [my-evaluation, format, refer-to-note]{.tcrf reftype=note}
|
||||
* Where are the notes? → [my-evaluation, format]{.tcrf}
|
||||
|
||||
[]{#toc-notes-end}
|
||||
|
||||
[A portion of text that may cross a page break.]{#doubledlbl refanchor=both}
|
||||
|
||||
[And this one is labelized at the end.]{#lblatend refanchor=end}
|
||||
|
||||
See [doubledlbl-beg>doubledlbl-end]{.tcrf}.
|
456
text-crossrefs/test/sample-context.native
Normal file
456
text-crossrefs/test/sample-context.native
Normal file
|
@ -0,0 +1,456 @@
|
|||
[ Para
|
||||
[ Str "(About"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes,"
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum{{toc-notes-begin to toc-notes-end}}"
|
||||
]
|
||||
, Str ".)"
|
||||
]
|
||||
, Para
|
||||
[ Str "\201mile"
|
||||
, Space
|
||||
, Str "Gaboriau"
|
||||
, Space
|
||||
, Str "published"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "publication" , [] , [] )
|
||||
[ Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Space
|
||||
, Str "in"
|
||||
, SoftBreak
|
||||
, Str "1866"
|
||||
]
|
||||
, Str "."
|
||||
, RawInline
|
||||
(Format "context") "\\withfirstopt[note:my-evaluation]"
|
||||
, Note
|
||||
[ Para
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "my-evaluation" , [] , [] )
|
||||
[ Str "fine"
|
||||
, Space
|
||||
, Str "piece"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "literature"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, RawInline (Format "context") ""
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "reception" , [] , [] )
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "was"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, Str "popular."
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context") "\\crossrefenum{{publication}}"
|
||||
]
|
||||
, Space
|
||||
, Str "for"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "publication"
|
||||
, Space
|
||||
, Str "date."
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "expressed"
|
||||
, SoftBreak
|
||||
, Str "my"
|
||||
, Space
|
||||
, Str "thoughts"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Str "it"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "pagenote" ) ] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum[pagenote]{{my-evaluation}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "If"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "know"
|
||||
, Space
|
||||
, Str "more"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Str ","
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum{{publication to reception}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "Here"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "some"
|
||||
, Space
|
||||
, Str "precisions."
|
||||
, RawInline (Format "context") "\\withfirstopt[note:format]"
|
||||
, Note
|
||||
[ Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "format" , [] , [] )
|
||||
[ Str "Whatever" , Space , Str "format" ]
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "choose,"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "refer-to-note" , [] , [] )
|
||||
[ Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "identifier"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "which-identifier" , [] , [] )
|
||||
[ Str "any"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "spans."
|
||||
, Space
|
||||
, Str "You"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "even"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "nested-spans" , [] , [] )
|
||||
[ Str "nest" , Space , Str "spans" ]
|
||||
, Str "!"
|
||||
]
|
||||
]
|
||||
]
|
||||
, RawInline (Format "context") ""
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "toc-notes-begin" , [] , [] )
|
||||
[ Str "I"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Str ":"
|
||||
]
|
||||
, BulletList
|
||||
[ [ Plain
|
||||
[ Str "How"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "number?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context") "\\crossrefenum{{refer-to-note}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "formats"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "supported?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline (Format "context") "\\crossrefenum{{format}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "contains"
|
||||
, Space
|
||||
, Str "multiple"
|
||||
, Space
|
||||
, Str "spans"
|
||||
, Space
|
||||
, Str "with"
|
||||
, Space
|
||||
, Str "identifiers?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum{{which-identifier}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "happens"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "contained"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context") "\\crossrefenum{{nested-spans}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "note" ) ] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum[note]{{my-evaluation}{format}{refer-to-note}}"
|
||||
]
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "Where"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum{{my-evaluation}{format}}"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
, Para [ Str "" , Span ( "toc-notes-end" , [] , [] ) [] ]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "doubledlbl" , [] , [ ( "refanchor" , "both" ) ] )
|
||||
[ Str ""
|
||||
, Span ( "doubledlbl-beg" , [] , [] ) []
|
||||
, Str "A"
|
||||
, Space
|
||||
, Str "portion"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "text"
|
||||
, Space
|
||||
, Str "that"
|
||||
, Space
|
||||
, Str "may"
|
||||
, Space
|
||||
, Str "cross"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "page"
|
||||
, Space
|
||||
, Str "break."
|
||||
, Str ""
|
||||
, Span ( "doubledlbl-end" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "lblatend" , [] , [ ( "refanchor" , "end" ) ] )
|
||||
[ Str "And"
|
||||
, Space
|
||||
, Str "this"
|
||||
, Space
|
||||
, Str "one"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "labelized"
|
||||
, Space
|
||||
, Str "at"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "end."
|
||||
, Str ""
|
||||
, Span ( "lblatend" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "context")
|
||||
"\\crossrefenum{{doubledlbl-beg to doubledlbl-end}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
454
text-crossrefs/test/sample-latex.native
Normal file
454
text-crossrefs/test/sample-latex.native
Normal file
|
@ -0,0 +1,454 @@
|
|||
[ Para
|
||||
[ Str "(About"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes,"
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex")
|
||||
"\\crossrefenum{{toc-notes-begin to toc-notes-end}}"
|
||||
]
|
||||
, Str ".)"
|
||||
]
|
||||
, Para
|
||||
[ Str "\201mile"
|
||||
, Space
|
||||
, Str "Gaboriau"
|
||||
, Space
|
||||
, Str "published"
|
||||
, Space
|
||||
, RawInline (Format "latex") "\\label{publication}"
|
||||
, Span
|
||||
( "publication" , [] , [] )
|
||||
[ Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Space
|
||||
, Str "in"
|
||||
, SoftBreak
|
||||
, Str "1866"
|
||||
]
|
||||
, Str "."
|
||||
, RawInline (Format "latex") ""
|
||||
, Note
|
||||
[ Para
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, RawInline (Format "latex") "\\label{my-evaluation}"
|
||||
, Span
|
||||
( "my-evaluation" , [] , [] )
|
||||
[ Str "fine"
|
||||
, Space
|
||||
, Str "piece"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "literature"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, RawInline (Format "latex") ""
|
||||
]
|
||||
, Para
|
||||
[ RawInline (Format "latex") "\\label{reception}"
|
||||
, Span
|
||||
( "reception" , [] , [] )
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "was"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, Str "popular."
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline (Format "latex") "\\crossrefenum{{publication}}"
|
||||
]
|
||||
, Space
|
||||
, Str "for"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "publication"
|
||||
, Space
|
||||
, Str "date."
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "expressed"
|
||||
, SoftBreak
|
||||
, Str "my"
|
||||
, Space
|
||||
, Str "thoughts"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Str "it"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "pagenote" ) ] )
|
||||
[ RawInline
|
||||
(Format "latex") "\\crossrefenum[pagenote]{{my-evaluation}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "If"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "know"
|
||||
, Space
|
||||
, Str "more"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Str ","
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex")
|
||||
"\\crossrefenum{{publication to reception}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "Here"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "some"
|
||||
, Space
|
||||
, Str "precisions."
|
||||
, RawInline (Format "latex") ""
|
||||
, Note
|
||||
[ Para
|
||||
[ RawInline (Format "latex") "\\label{format}"
|
||||
, Span
|
||||
( "format" , [] , [] )
|
||||
[ Str "Whatever" , Space , Str "format" ]
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "choose,"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, RawInline (Format "latex") "\\label{refer-to-note}"
|
||||
, Span
|
||||
( "refer-to-note" , [] , [] )
|
||||
[ Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "identifier"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, RawInline (Format "latex") "\\label{which-identifier}"
|
||||
, Span
|
||||
( "which-identifier" , [] , [] )
|
||||
[ Str "any"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "spans."
|
||||
, Space
|
||||
, Str "You"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "even"
|
||||
, Space
|
||||
, RawInline (Format "latex") "\\label{nested-spans}"
|
||||
, Span
|
||||
( "nested-spans" , [] , [] )
|
||||
[ Str "nest" , Space , Str "spans" ]
|
||||
, Str "!"
|
||||
]
|
||||
]
|
||||
]
|
||||
, RawInline (Format "latex") ""
|
||||
]
|
||||
, Para
|
||||
[ RawInline (Format "latex") "\\label{toc-notes-begin}"
|
||||
, Span
|
||||
( "toc-notes-begin" , [] , [] )
|
||||
[ Str "I"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Str ":"
|
||||
]
|
||||
, BulletList
|
||||
[ [ Plain
|
||||
[ Str "How"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "number?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex") "\\crossrefenum{{refer-to-note}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "formats"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "supported?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline (Format "latex") "\\crossrefenum{{format}}" ]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "contains"
|
||||
, Space
|
||||
, Str "multiple"
|
||||
, Space
|
||||
, Str "spans"
|
||||
, Space
|
||||
, Str "with"
|
||||
, Space
|
||||
, Str "identifiers?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex") "\\crossrefenum{{which-identifier}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "happens"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "contained"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex") "\\crossrefenum{{nested-spans}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "note" ) ] )
|
||||
[ RawInline
|
||||
(Format "latex")
|
||||
"\\crossrefenum[note]{{my-evaluation}{format}{refer-to-note}}"
|
||||
]
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "Where"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex")
|
||||
"\\crossrefenum{{my-evaluation}{format}}"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ RawInline (Format "latex") "\\label{toc-notes-end}"
|
||||
, Span ( "toc-notes-end" , [] , [] ) []
|
||||
]
|
||||
, Para
|
||||
[ RawInline (Format "latex") "\\label{doubledlbl}"
|
||||
, Span
|
||||
( "doubledlbl" , [] , [ ( "refanchor" , "both" ) ] )
|
||||
[ RawInline (Format "latex") "\\label{doubledlbl-beg}"
|
||||
, Span ( "doubledlbl-beg" , [] , [] ) []
|
||||
, Str "A"
|
||||
, Space
|
||||
, Str "portion"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "text"
|
||||
, Space
|
||||
, Str "that"
|
||||
, Space
|
||||
, Str "may"
|
||||
, Space
|
||||
, Str "cross"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "page"
|
||||
, Space
|
||||
, Str "break."
|
||||
, RawInline (Format "latex") "\\label{doubledlbl-end}"
|
||||
, Span ( "doubledlbl-end" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ RawInline (Format "latex") "\\label{lblatend}"
|
||||
, Span
|
||||
( "lblatend" , [] , [ ( "refanchor" , "end" ) ] )
|
||||
[ Str "And"
|
||||
, Space
|
||||
, Str "this"
|
||||
, Space
|
||||
, Str "one"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "labelized"
|
||||
, Space
|
||||
, Str "at"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "end."
|
||||
, RawInline (Format "latex") "\\label{lblatend}"
|
||||
, Span ( "lblatend" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "latex")
|
||||
"\\crossrefenum{{doubledlbl-beg to doubledlbl-end}}"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
460
text-crossrefs/test/sample-opendocument.native
Normal file
460
text-crossrefs/test/sample-opendocument.native
Normal file
|
@ -0,0 +1,460 @@
|
|||
[ Para
|
||||
[ Str "(About"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes,"
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"pp.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"toc-notes-begin\">000</text:bookmark-ref>\8211<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"toc-notes-end\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str ".)"
|
||||
]
|
||||
, Para
|
||||
[ Str "\201mile"
|
||||
, Space
|
||||
, Str "Gaboriau"
|
||||
, Space
|
||||
, Str "published"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "publication" , [] , [] )
|
||||
[ Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Space
|
||||
, Str "in"
|
||||
, SoftBreak
|
||||
, Str "1866"
|
||||
]
|
||||
, Str "."
|
||||
, RawInline (Format "opendocument") ""
|
||||
, Note
|
||||
[ Para
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "my-evaluation" , [] , [] )
|
||||
[ Str "fine"
|
||||
, Space
|
||||
, Str "piece"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "literature"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, RawInline (Format "opendocument") ""
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "reception" , [] , [] )
|
||||
[ Str "It"
|
||||
, Space
|
||||
, Str "was"
|
||||
, Space
|
||||
, Str "very"
|
||||
, Space
|
||||
, Str "popular."
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"publication\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Space
|
||||
, Str "for"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "publication"
|
||||
, Space
|
||||
, Str "date."
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "expressed"
|
||||
, SoftBreak
|
||||
, Str "my"
|
||||
, Space
|
||||
, Str "thoughts"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Str "it"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "pagenote" ) ] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"my-evaluation\">000</text:bookmark-ref>\160(n.\160<text:note-ref text:note-class=\"footnote\" text:reference-format=\"text\" text:ref-name=\"ftn0\">000</text:note-ref>)"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "If"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "know"
|
||||
, Space
|
||||
, Str "more"
|
||||
, Space
|
||||
, Str "about"
|
||||
, Space
|
||||
, Emph [ Str "L\8217Affaire" , Space , Str "Lerouge" ]
|
||||
, Str ","
|
||||
, Space
|
||||
, Str "see"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"pp.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"publication\">000</text:bookmark-ref>\8211<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"reception\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
, Para
|
||||
[ Str "Here"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "some"
|
||||
, Space
|
||||
, Str "precisions."
|
||||
, RawInline (Format "opendocument") ""
|
||||
, Note
|
||||
[ Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "format" , [] , [] )
|
||||
[ Str "Whatever" , Space , Str "format" ]
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "choose,"
|
||||
, Space
|
||||
, Str "you"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "refer-to-note" , [] , [] )
|
||||
[ Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "identifier"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "which-identifier" , [] , [] )
|
||||
[ Str "any"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "spans."
|
||||
, Space
|
||||
, Str "You"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "even"
|
||||
, Space
|
||||
, Str ""
|
||||
, Span
|
||||
( "nested-spans" , [] , [] )
|
||||
[ Str "nest" , Space , Str "spans" ]
|
||||
, Str "!"
|
||||
]
|
||||
]
|
||||
]
|
||||
, RawInline (Format "opendocument") ""
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "toc-notes-begin" , [] , [] )
|
||||
[ Str "I"
|
||||
, Space
|
||||
, Str "want"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
]
|
||||
, Str ":"
|
||||
]
|
||||
, BulletList
|
||||
[ [ Plain
|
||||
[ Str "How"
|
||||
, Space
|
||||
, Str "can"
|
||||
, Space
|
||||
, Str "I"
|
||||
, Space
|
||||
, Str "refer"
|
||||
, Space
|
||||
, Str "to"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "by"
|
||||
, Space
|
||||
, Str "its"
|
||||
, Space
|
||||
, Str "number?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"refer-to-note\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "formats"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "supported?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"format\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "note"
|
||||
, Space
|
||||
, Str "contains"
|
||||
, Space
|
||||
, Str "multiple"
|
||||
, Space
|
||||
, Str "spans"
|
||||
, Space
|
||||
, Str "with"
|
||||
, Space
|
||||
, Str "identifiers?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"which-identifier\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "happens"
|
||||
, Space
|
||||
, Str "if"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "contained"
|
||||
, Space
|
||||
, Str "in"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "span?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"p.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"nested-spans\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "What"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [ ( "reftype" , "note" ) ] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"nn.\160<text:note-ref text:note-class=\"footnote\" text:reference-format=\"text\" text:ref-name=\"ftn0\">000</text:note-ref>, <text:note-ref text:note-class=\"footnote\" text:reference-format=\"text\" text:ref-name=\"ftn1\">000</text:note-ref> and <text:note-ref text:note-class=\"footnote\" text:reference-format=\"text\" text:ref-name=\"ftn1\">000</text:note-ref>"
|
||||
]
|
||||
]
|
||||
]
|
||||
, [ Plain
|
||||
[ Str "Where"
|
||||
, Space
|
||||
, Str "are"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "notes?"
|
||||
, Space
|
||||
, Str "\8594"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"pp.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"my-evaluation\">000</text:bookmark-ref> and <text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"format\">000</text:bookmark-ref>"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
, Para [ Str "" , Span ( "toc-notes-end" , [] , [] ) [] ]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "doubledlbl" , [] , [ ( "refanchor" , "both" ) ] )
|
||||
[ Str ""
|
||||
, Span ( "doubledlbl-beg" , [] , [] ) []
|
||||
, Str "A"
|
||||
, Space
|
||||
, Str "portion"
|
||||
, Space
|
||||
, Str "of"
|
||||
, Space
|
||||
, Str "text"
|
||||
, Space
|
||||
, Str "that"
|
||||
, Space
|
||||
, Str "may"
|
||||
, Space
|
||||
, Str "cross"
|
||||
, Space
|
||||
, Str "a"
|
||||
, Space
|
||||
, Str "page"
|
||||
, Space
|
||||
, Str "break."
|
||||
, Str ""
|
||||
, Span ( "doubledlbl-end" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str ""
|
||||
, Span
|
||||
( "lblatend" , [] , [ ( "refanchor" , "end" ) ] )
|
||||
[ Str "And"
|
||||
, Space
|
||||
, Str "this"
|
||||
, Space
|
||||
, Str "one"
|
||||
, Space
|
||||
, Str "is"
|
||||
, Space
|
||||
, Str "labelized"
|
||||
, Space
|
||||
, Str "at"
|
||||
, Space
|
||||
, Str "the"
|
||||
, Space
|
||||
, Str "end."
|
||||
, Str ""
|
||||
, Span ( "lblatend" , [] , [] ) []
|
||||
]
|
||||
]
|
||||
, Para
|
||||
[ Str "See"
|
||||
, Space
|
||||
, Span
|
||||
( "" , [ "tcrf" ] , [] )
|
||||
[ RawInline
|
||||
(Format "opendocument")
|
||||
"pp.\160<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"doubledlbl-beg\">000</text:bookmark-ref>\8211<text:bookmark-ref text:reference-format=\"page\" text:ref-name=\"doubledlbl-end\">000</text:bookmark-ref>"
|
||||
]
|
||||
, Str "."
|
||||
]
|
||||
]
|
36
text-crossrefs/test/test-functions.lua
Normal file
36
text-crossrefs/test/test-functions.lua
Normal file
|
@ -0,0 +1,36 @@
|
|||
local refs
|
||||
|
||||
refs = parse_references_enum('mylabel')
|
||||
assert(#refs == 1)
|
||||
assert(refs[1].anchor == 'mylabel')
|
||||
assert(not refs[1].end_of_range)
|
||||
assert(make_raw_content_tex(refs, 'page', true)
|
||||
== '\\crossrefenum{{mylabel}}')
|
||||
assert(make_raw_content_tex(refs, 'page', false)
|
||||
== '\\crossrefenum[noprefix]{{mylabel}}')
|
||||
assert(make_raw_content_tex(refs, 'note', true)
|
||||
== '\\crossrefenum[note]{{mylabel}}')
|
||||
assert(make_raw_content_tex(refs, 'note', false)
|
||||
== '\\crossrefenum[note][noprefix]{{mylabel}}')
|
||||
|
||||
refs = parse_references_enum('rangebeg>rangeend')
|
||||
assert(#refs == 1)
|
||||
assert(refs[1].anchor == 'rangebeg')
|
||||
assert(refs[1].end_of_range == 'rangeend')
|
||||
assert(make_raw_content_tex(refs, 'page', true)
|
||||
== '\\crossrefenum{{rangebeg to rangeend}}')
|
||||
|
||||
refs = parse_references_enum('first, second')
|
||||
assert(#refs == 2)
|
||||
assert(refs[1].anchor == 'first')
|
||||
assert(refs[2].anchor == 'second')
|
||||
assert(make_raw_content_tex(refs, 'page', true)
|
||||
== '\\crossrefenum{{first}{second}}')
|
||||
|
||||
refs = parse_references_enum('first, rangebeg>rangeend')
|
||||
assert(#refs == 2)
|
||||
assert(refs[1].anchor == 'first')
|
||||
assert(refs[2].anchor == 'rangebeg')
|
||||
assert(refs[2].end_of_range == 'rangeend')
|
||||
assert(make_raw_content_tex(refs, 'page', true)
|
||||
== '\\crossrefenum{{first}{rangebeg to rangeend}}')
|
611
text-crossrefs/text-crossrefs.lua
Normal file
611
text-crossrefs/text-crossrefs.lua
Normal file
|
@ -0,0 +1,611 @@
|
|||
local stringify = pandoc.utils.stringify
|
||||
|
||||
local TEXT_CROSSREF_CLASS = 'tcrf'
|
||||
local REF_TYPE_ATTR = 'reftype'
|
||||
local PREFIXED_ATTR = 'prefixref'
|
||||
local PLACE_LABEL_ATTR = 'refanchor'
|
||||
local IS_CONFIG_ARRAY = { ['additional_types'] = true }
|
||||
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 support_footnote_label_ConTeXt(metadata)
|
||||
if RAW_ATTRIBUTE == 'context' then
|
||||
local label_macro_def = '\n\\def\\withfirstopt[#1]#2{#2[#1]}\n'
|
||||
if not metadata['header-includes'] then
|
||||
metadata['header-includes'] = pandoc.MetaBlocks(pandoc.RawBlock('context', ''))
|
||||
end
|
||||
metadata['header-includes']:insert(pandoc.RawBlock('context', label_macro_def))
|
||||
end
|
||||
return metadata
|
||||
end
|
||||
|
||||
-- Configuration
|
||||
|
||||
local function define_raw_attribute()
|
||||
if FORMAT == 'native' then
|
||||
RAW_ATTRIBUTE = pandoc.system.environment().TESTED_FORMAT
|
||||
elseif FORMAT == 'docx' then
|
||||
RAW_ATTRIBUTE = 'openxml'
|
||||
elseif FORMAT == 'odt' or FORMAT == 'opendocument' then
|
||||
RAW_ATTRIBUTE = 'opendocument'
|
||||
elseif FORMAT == 'context' or FORMAT == 'latex' then
|
||||
RAW_ATTRIBUTE = FORMAT
|
||||
else
|
||||
error(FORMAT ..
|
||||
' output not supported by text-crossrefs.lua.')
|
||||
end
|
||||
end
|
||||
|
||||
local function define_label_template()
|
||||
if RAW_ATTRIBUTE == 'opendocument' or RAW_ATTRIBUTE == 'openxml' then
|
||||
IS_LABEL_SET_BY_PANDOC = true
|
||||
elseif RAW_ATTRIBUTE == 'context' then
|
||||
if PANDOC_VERSION < pandoc.types.Version('2.14') then
|
||||
LABEL_TEMPLATE = '\\pagereference[{{label}}]'
|
||||
else
|
||||
IS_LABEL_SET_BY_PANDOC = true
|
||||
end
|
||||
elseif RAW_ATTRIBUTE == 'latex' then
|
||||
LABEL_TEMPLATE = '\\label{{{label}}}'
|
||||
end
|
||||
end
|
||||
|
||||
local config = {
|
||||
page_prefix = 'p. ',
|
||||
pages_prefix = 'pp. ',
|
||||
note_prefix = 'n. ',
|
||||
notes_prefix = 'nn. ',
|
||||
pagenote_first_type = 'page',
|
||||
pagenote_separator = ', ',
|
||||
pagenote_at_end = '',
|
||||
pagenote_factorize_first_prefix_in_enum = 'no',
|
||||
multiple_delimiter = ', ',
|
||||
multiple_before_last = ' and ',
|
||||
references_range_separator = '>',
|
||||
range_separator = '–',
|
||||
references_enum_separator = ', ',
|
||||
only_explicit_labels = 'false',
|
||||
default_reftype = 'page',
|
||||
default_prefixref = 'yes',
|
||||
filelabel_ref_separator = '::',
|
||||
range_delim_crossrefenum = ' to ',
|
||||
additional_types = {}
|
||||
}
|
||||
|
||||
local accepted_types = {
|
||||
page = true,
|
||||
note = true,
|
||||
pagenote = true
|
||||
}
|
||||
|
||||
local function format_config_to_openxml()
|
||||
local to_format = { 'page_prefix',
|
||||
'pages_prefix',
|
||||
'note_prefix',
|
||||
'notes_prefix',
|
||||
'pagenote_separator',
|
||||
'pagenote_at_end',
|
||||
'range_separator',
|
||||
'multiple_delimiter',
|
||||
'multiple_before_last' }
|
||||
for i = 1, #to_format do
|
||||
config[to_format[i]] = '<w:r><w:t xml:space="preserve">' ..
|
||||
config[to_format[i]] .. '</w:t></w:r>'
|
||||
end
|
||||
end
|
||||
|
||||
local function set_configuration_item_from_metadata(item, metamap)
|
||||
metakey = 'tcrf-' .. string.gsub(item, '_', '-')
|
||||
if metamap[metakey] then
|
||||
if IS_CONFIG_ARRAY[item] then
|
||||
-- The metadata values is a list of MetaInlines,
|
||||
-- each of them contains a single Str.
|
||||
for _, value_metalist in ipairs(metamap[metakey]) do
|
||||
table.insert(config[item], value_metalist[1].text)
|
||||
end
|
||||
else
|
||||
-- The metadata value is a single Str in a MetaInlines.
|
||||
config[item] = metamap[metakey][1].text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function configure(metadata)
|
||||
define_raw_attribute()
|
||||
define_label_template()
|
||||
for item, _ in pairs(config) do
|
||||
set_configuration_item_from_metadata(item, metadata)
|
||||
end
|
||||
if RAW_ATTRIBUTE == 'openxml' then
|
||||
format_config_to_openxml()
|
||||
end
|
||||
if RAW_ATTRIBUTE == 'context' or RAW_ATTRIBUTE == 'latex' then
|
||||
for _, additional_type in ipairs(config.additional_types) do
|
||||
accepted_types[additional_type] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- End of configuration
|
||||
|
||||
-- Preprocessing of identifiers on notes
|
||||
-- Necessary for those output format where a note can be referred to
|
||||
-- only via an identifier directly attached to it, not to its content
|
||||
|
||||
local spans_to_note_labels = {}
|
||||
local current_odt_note_index = 0
|
||||
local is_first_span_in_note = true
|
||||
local current_note_label
|
||||
local text_to_note_labels = {}
|
||||
|
||||
local function map_span_to_label(span)
|
||||
if RAW_ATTRIBUTE == 'opendocument' then
|
||||
spans_to_note_labels[span.identifier] = 'ftn' .. current_odt_note_index
|
||||
elseif RAW_ATTRIBUTE == 'openxml' or RAW_ATTRIBUTE == 'context' then
|
||||
if is_first_span_in_note then
|
||||
current_note_label = span.identifier
|
||||
is_first_span_in_note = false
|
||||
end
|
||||
spans_to_note_labels[span.identifier] = current_note_label
|
||||
end
|
||||
end
|
||||
|
||||
local function map_spans_to_labels(container)
|
||||
for i = 1, #container.content do
|
||||
-- The tests must be separate in order to support spans inside spans.
|
||||
if container.content[i].t == 'Span'
|
||||
and container.content[i].identifier
|
||||
then
|
||||
map_span_to_label(container.content[i])
|
||||
end
|
||||
if container.content[i].content then
|
||||
map_spans_to_labels(container.content[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function map_spans_to_notelabels(note)
|
||||
if RAW_ATTRIBUTE == 'context'
|
||||
or RAW_ATTRIBUTE == 'opendocument'
|
||||
or RAW_ATTRIBUTE == 'openxml'
|
||||
then
|
||||
is_first_span_in_note = true
|
||||
map_spans_to_labels(note)
|
||||
current_odt_note_index = current_odt_note_index + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function control_label_placement(span)
|
||||
local label_placement = span.attributes[PLACE_LABEL_ATTR]
|
||||
if label_placement then
|
||||
local id = span.identifier
|
||||
if label_placement == 'end' then
|
||||
span.content:insert(pandoc.Span({}, { id = id }))
|
||||
span.identifier = nil
|
||||
elseif label_placement == 'both' then
|
||||
span.content:insert(1, pandoc.Span({}, { id = id .. '-beg' })) -- for DOCX/ODT
|
||||
span.content:insert(pandoc.Span({}, { id = id .. '-end' }))
|
||||
span.identifier = nil
|
||||
elseif label_placement ~= 'beg' then
|
||||
error('Invalid value ' .. label_placement .. ' on attribute ' .. PLACE_LABEL_ATTR .. ': ' ..
|
||||
'shoud be “beg” (default), “end” of “both”.')
|
||||
end
|
||||
end
|
||||
return span
|
||||
end
|
||||
|
||||
local function make_label(label)
|
||||
-- pandoc.Null() cannot be used here because it is a Block element.
|
||||
local label_pandoc_object = pandoc.Str('')
|
||||
if not IS_LABEL_SET_BY_PANDOC then
|
||||
local label_rawcode = string.gsub(LABEL_TEMPLATE, '{{label}}', label)
|
||||
label_pandoc_object = pandoc.RawInline(RAW_ATTRIBUTE, label_rawcode)
|
||||
end
|
||||
return label_pandoc_object
|
||||
end
|
||||
|
||||
local function labelize_span(span)
|
||||
if span.identifier ~= '' then
|
||||
local label = span.identifier
|
||||
local label_begin = make_label(label, 'begin')
|
||||
return { label_begin, span }
|
||||
end
|
||||
end
|
||||
|
||||
local current_note_labels = {}
|
||||
|
||||
local collect_note_labels = {
|
||||
Span = function(span)
|
||||
if span.identifier ~= ''
|
||||
and (config.only_explicit_labels == 'false' or span.classes:includes('label'))
|
||||
then
|
||||
table.insert(current_note_labels, span.identifier)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local function make_notelabel(pos)
|
||||
-- About the strategy followed with ConTeXt,
|
||||
-- see above support_footnote_label_ConTeXt.
|
||||
local raw_code = ''
|
||||
if pos == 'begin' then
|
||||
if RAW_ATTRIBUTE == 'openxml' then
|
||||
raw_code = string.gsub(
|
||||
'<w:bookmarkStart w:id="{{label}}_Note" w:name="{{label}}_Note"/>',
|
||||
'{{label}}', current_note_labels[1])
|
||||
elseif RAW_ATTRIBUTE == 'context' then
|
||||
raw_code = '\\withfirstopt[note:' .. current_note_labels[1] .. ']'
|
||||
end
|
||||
elseif pos == 'end' then
|
||||
if RAW_ATTRIBUTE == 'openxml' then
|
||||
raw_code = string.gsub('<w:bookmarkEnd w:id="{{label}}_Note"/>',
|
||||
'{{label}}', current_note_labels[1])
|
||||
end
|
||||
end
|
||||
return pandoc.RawInline(RAW_ATTRIBUTE, raw_code)
|
||||
end
|
||||
|
||||
local function labelize_note(note)
|
||||
local 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)
|
||||
local note_label = 'note:' .. current_note_labels[1]
|
||||
for _, text_label in ipairs(current_note_labels) do
|
||||
text_to_note_labels[text_label] = note_label
|
||||
end
|
||||
end
|
||||
|
||||
function set_notelabels(note)
|
||||
current_note_labels = {}
|
||||
pandoc.walk_inline(note, collect_note_labels)
|
||||
if #current_note_labels > 0 then
|
||||
map_text_to_note_labels(current_note_labels)
|
||||
return labelize_note(note)
|
||||
end
|
||||
end
|
||||
|
||||
-- End of preprocessing of identifiers on notes
|
||||
|
||||
-- Gathering of data from the references span
|
||||
|
||||
local function new_ref(anchor, end_of_range)
|
||||
-- A ref is a string-indexed table containing an "anchor" field
|
||||
-- and an optionnal "end_of_range" field.
|
||||
-- When "end_of_range" is non-nil, the ref is a range.
|
||||
local ref = {}
|
||||
ref.anchor = anchor
|
||||
ref.end_of_range = end_of_range
|
||||
return ref
|
||||
end
|
||||
|
||||
local function is_ref_external(raw_references)
|
||||
if string.find(raw_references, config.filelabel_ref_separator, 1, true) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local function parse_possible_range(reference)
|
||||
-- If reference is a string representing a range,
|
||||
-- returns the strings representing the boundaries of the range.
|
||||
-- Else, returns the string.
|
||||
local range_first, range_second = nil
|
||||
local delim_beg, delim_end = string.find(reference,
|
||||
config.references_range_separator,
|
||||
1, true)
|
||||
if delim_beg then
|
||||
range_first = string.sub(reference, 1, delim_beg - 1)
|
||||
range_second = string.sub(reference, delim_end + 1)
|
||||
end
|
||||
return (range_first or reference), range_second
|
||||
end
|
||||
|
||||
local function parse_next_reference(raw_references, beg_of_search)
|
||||
-- Returns the ref corresponding to the next reference string
|
||||
-- and the index which the parsing should be resumed at.
|
||||
local current_ref = false
|
||||
local next_ref_beg = nil
|
||||
if beg_of_search < #raw_references then
|
||||
-- The delimiter can be composed of more than one character.
|
||||
local delim_beg, delim_end = string.find(raw_references,
|
||||
config.references_enum_separator,
|
||||
beg_of_search, true)
|
||||
if delim_beg then
|
||||
reference = string.sub(raw_references, beg_of_search, delim_beg - 1)
|
||||
next_ref_beg = delim_end + 1
|
||||
else
|
||||
reference = string.sub(raw_references, beg_of_search)
|
||||
next_ref_beg = #raw_references
|
||||
end
|
||||
current_ref = new_ref(parse_possible_range(reference))
|
||||
end
|
||||
return current_ref, next_ref_beg
|
||||
end
|
||||
|
||||
local function parse_references_enum(raw_references)
|
||||
-- raw_refs is a string consisting of a list of single references or ranges.
|
||||
-- Returns an array of refs produced by "new_ref" above.
|
||||
local parsed_refs = {}
|
||||
local current_ref, next_ref_beg = parse_next_reference(raw_references, 1)
|
||||
while current_ref do
|
||||
table.insert(parsed_refs, current_ref)
|
||||
current_ref, next_ref_beg =
|
||||
parse_next_reference(raw_references, next_ref_beg)
|
||||
end
|
||||
return parsed_refs
|
||||
end
|
||||
|
||||
local function error_on_attr(attr_key, attr_value, span_content)
|
||||
error('Invalid value "' .. attr_value .. '" for attribute "' .. attr_key ..
|
||||
'" in the span with class "' .. TEXT_CROSSREF_CLASS ..
|
||||
'" whose content is "' .. stringify(span_content) .. '".')
|
||||
end
|
||||
|
||||
local function get_ref_type(span)
|
||||
local ref_type = span.attributes[REF_TYPE_ATTR] or config.default_reftype
|
||||
if not accepted_types[ref_type] then
|
||||
error_on_attr(REF_TYPE_ATTR, ref_type, span.content)
|
||||
end
|
||||
return ref_type
|
||||
end
|
||||
|
||||
local function if_prefixed(span)
|
||||
local prefixed_attr_value = span.attributes[PREFIXED_ATTR] or config.default_prefixref
|
||||
if prefixed_attr_value ~= 'yes' and prefixed_attr_value ~= 'no' then
|
||||
error_on_attr(PREFIXED_ATTR, prefixed_attr_value, span.content)
|
||||
end
|
||||
local is_prefixed = true
|
||||
if prefixed_attr_value == 'no' then is_prefixed = false end
|
||||
return is_prefixed
|
||||
end
|
||||
|
||||
-- End of gathering of data from the references span
|
||||
|
||||
-- Formatting references as raw inlines.
|
||||
|
||||
local function make_crossrefenum_first_arg(ref_type)
|
||||
local ref_type_is_explicit = ref_type ~= config.default_reftype
|
||||
local crossrefenum_first_arg = ''
|
||||
if ref_type_is_explicit then
|
||||
crossrefenum_first_arg = '[' .. ref_type .. ']'
|
||||
end
|
||||
return crossrefenum_first_arg
|
||||
end
|
||||
|
||||
local function make_crossrefenum_second_arg(is_prefixed)
|
||||
local is_prefixed_is_explicit = is_prefixed ~= (config.default_prefixref == 'yes')
|
||||
local crossrefenum_second_arg = ''
|
||||
local is_prefixed_string = ''
|
||||
if is_prefixed_is_explicit then
|
||||
if is_prefixed then
|
||||
is_prefixed_string = 'withprefix'
|
||||
else
|
||||
is_prefixed_string = 'noprefix'
|
||||
end
|
||||
crossrefenum_second_arg = '[' .. is_prefixed_string .. ']'
|
||||
end
|
||||
return crossrefenum_second_arg
|
||||
end
|
||||
|
||||
local function make_crossrefenum_references_list(refs, ref_type)
|
||||
local crossrefenum_references_list = ''
|
||||
for i = 1, #refs do
|
||||
local ref = refs[i]
|
||||
local anchor = ref.anchor
|
||||
if FORMAT == 'context'
|
||||
and (ref_type == 'note' or ref_type == 'pagenote')
|
||||
then
|
||||
anchor = text_to_note_labels[anchor]
|
||||
end
|
||||
local texified_ref = '{' .. anchor
|
||||
if ref.end_of_range then
|
||||
texified_ref = texified_ref .. config.range_delim_crossrefenum .. ref.end_of_range
|
||||
end
|
||||
texified_ref = texified_ref .. '}'
|
||||
crossrefenum_references_list = crossrefenum_references_list .. texified_ref
|
||||
end
|
||||
return crossrefenum_references_list
|
||||
end
|
||||
|
||||
local function make_raw_content_tex(refs, ref_type, is_prefixed)
|
||||
local texified_references = ''
|
||||
texified_references = '\\crossrefenum'
|
||||
.. make_crossrefenum_first_arg(ref_type)
|
||||
.. make_crossrefenum_second_arg(is_prefixed)
|
||||
.. '{' .. make_crossrefenum_references_list(refs, ref_type) .. '}'
|
||||
return texified_references
|
||||
end
|
||||
|
||||
local function make_prefix_xml(ref_type, is_plural)
|
||||
local prefix = ''
|
||||
if is_plural then
|
||||
prefix = config[ref_type .. 's_prefix']
|
||||
else
|
||||
prefix = config[ref_type .. '_prefix']
|
||||
end
|
||||
return prefix
|
||||
end
|
||||
|
||||
local function make_page_reference_xml(target, is_prefixed)
|
||||
local xml_page_ref = ''
|
||||
if is_prefixed then
|
||||
xml_page_ref = make_prefix_xml('page', false)
|
||||
end
|
||||
if RAW_ATTRIBUTE == 'opendocument' then
|
||||
xml_page_ref = xml_page_ref ..
|
||||
'<text:bookmark-ref ' ..
|
||||
' text:reference-format="page" text:ref-name="' ..
|
||||
target .. '">000</text:bookmark-ref>'
|
||||
elseif RAW_ATTRIBUTE == 'openxml' then
|
||||
xml_page_ref = xml_page_ref ..
|
||||
'<w:r><w:fldChar w:fldCharType="begin" w:dirty="true"/></w:r>' ..
|
||||
'<w:r><w:instrText xml:space="preserve"> PAGEREF ' ..
|
||||
target .. ' \\h </w:instrText></w:r>' ..
|
||||
'<w:r><w:fldChar w:fldCharType="separate"/></w:r>' ..
|
||||
'<w:r><w:t>000</w:t></w:r>' ..
|
||||
'<w:r><w:fldChar w:fldCharType="end"/></w:r>'
|
||||
end
|
||||
return xml_page_ref
|
||||
end
|
||||
|
||||
local function make_pagerange_reference_xml(first, second, is_prefixed)
|
||||
local prefix = ''
|
||||
if is_prefixed then prefix = make_prefix_xml('page', true) end
|
||||
return prefix .. make_page_reference_xml(first, false) ..
|
||||
config.range_separator .. make_page_reference_xml(second, false)
|
||||
end
|
||||
|
||||
local function make_note_reference_xml(target, is_prefixed)
|
||||
local note_ref_xml = ''
|
||||
if is_prefixed then
|
||||
note_ref_xml = make_prefix_xml('note', false)
|
||||
end
|
||||
if RAW_ATTRIBUTE == 'opendocument' then
|
||||
note_ref_xml = note_ref_xml ..
|
||||
'<text:note-ref text:note-class="footnote"' ..
|
||||
' text:reference-format="text" text:ref-name="' ..
|
||||
(spans_to_note_labels[target] or '') .. '">000</text:note-ref>'
|
||||
elseif RAW_ATTRIBUTE == 'openxml' then
|
||||
note_ref_xml = note_ref_xml ..
|
||||
'<w:r><w:fldChar w:fldCharType="begin" w:dirty="true"/></w:r>' ..
|
||||
'<w:r><w:instrText xml:space="preserve"> NOTEREF ' ..
|
||||
(spans_to_note_labels[target] or '') .. '_Note' .. ' \\h </w:instrText></w:r>' ..
|
||||
'<w:r><w:fldChar w:fldCharType="separate"/></w:r>' ..
|
||||
'<w:r><w:t>000</w:t></w:r>' ..
|
||||
'<w:r><w:fldChar w:fldCharType="end"/></w:r>'
|
||||
end
|
||||
return note_ref_xml
|
||||
end
|
||||
|
||||
local function make_pagenote_reference_xml(target, is_prefixed)
|
||||
local pagenote_ref_xml = ''
|
||||
if is_prefixed then
|
||||
pagenote_ref_xml = make_prefix_xml(config.pagenote_first_type, false)
|
||||
end
|
||||
if config.pagenote_first_type == 'page' then
|
||||
pagenote_ref_xml = pagenote_ref_xml ..
|
||||
make_page_reference_xml(target, false) ..
|
||||
config.pagenote_separator .. make_note_reference_xml(target, true) ..
|
||||
config.pagenote_at_end
|
||||
elseif config.pagenote_first_type == 'note' then
|
||||
pagenote_ref_xml = pagenote_ref_xml ..
|
||||
make_note_reference_xml(target, false) ..
|
||||
config.pagenote_separator .. make_page_reference_xml(target, true) ..
|
||||
config.pagenote_at_end
|
||||
else
|
||||
error('“tcrf-pagenote-first-type” must be set either to “page” or “note”.')
|
||||
end
|
||||
return pagenote_ref_xml
|
||||
end
|
||||
|
||||
local function make_reference_xml(ref, ref_type, is_prefixed)
|
||||
local reference_xml = ''
|
||||
if ref_type == 'page' and ref.end_of_range then
|
||||
reference_xml =
|
||||
make_pagerange_reference_xml(ref.anchor, ref.end_of_range, is_prefixed)
|
||||
elseif ref_type == 'page' then
|
||||
reference_xml = make_page_reference_xml(ref.anchor, is_prefixed)
|
||||
elseif ref_type == 'note' then
|
||||
reference_xml = make_note_reference_xml(ref.anchor, is_prefixed)
|
||||
elseif ref_type == 'pagenote' then
|
||||
reference_xml = make_pagenote_reference_xml(ref.anchor, is_prefixed)
|
||||
end
|
||||
return reference_xml
|
||||
end
|
||||
|
||||
local function make_global_prefix_xml(ref_type)
|
||||
local global_prefix_xml = ''
|
||||
local prefix_type = ref_type
|
||||
if ref_type == 'pagenote' then
|
||||
prefix_type = config.pagenote_first_type
|
||||
end
|
||||
global_prefix_xml = make_prefix_xml(prefix_type, true)
|
||||
return global_prefix_xml
|
||||
end
|
||||
|
||||
local function make_references_xml(refs, ref_type, is_prefixed)
|
||||
local references_xml = ''
|
||||
for i = 1, #refs do
|
||||
references_xml = references_xml ..
|
||||
make_reference_xml(refs[i], ref_type, is_prefixed)
|
||||
if i < #refs then
|
||||
if i < #refs - 1 then
|
||||
references_xml = references_xml .. config.multiple_delimiter
|
||||
else
|
||||
references_xml = references_xml .. config.multiple_before_last
|
||||
end
|
||||
end
|
||||
end
|
||||
return references_xml
|
||||
end
|
||||
|
||||
local function make_raw_content_xml(refs, ref_type, is_prefixed)
|
||||
local is_enumeration = #refs > 1
|
||||
local global_prefix = ''
|
||||
if is_enumeration and is_prefixed
|
||||
and (ref_type ~= 'pagenote'
|
||||
or pagenote_factorize_first_prefix_in_enum == 'yes')
|
||||
then
|
||||
global_prefix = make_global_prefix_xml(ref_type)
|
||||
is_prefixed = false
|
||||
end
|
||||
local references_raw_xml = make_references_xml(refs, ref_type, is_prefixed)
|
||||
return global_prefix .. references_raw_xml
|
||||
end
|
||||
|
||||
local function make_raw_content(refs, ref_type, is_prefixed)
|
||||
local raw_content = ''
|
||||
if RAW_ATTRIBUTE == 'context' or RAW_ATTRIBUTE == 'latex' then
|
||||
raw_content = make_raw_content_tex(refs, ref_type, is_prefixed)
|
||||
else
|
||||
raw_content = make_raw_content_xml(refs, ref_type, is_prefixed)
|
||||
end
|
||||
return raw_content
|
||||
end
|
||||
|
||||
local function format_references(refs, ref_type, is_prefixed)
|
||||
local raw_content = make_raw_content(refs, ref_type, is_prefixed)
|
||||
return pandoc.RawInline(RAW_ATTRIBUTE, raw_content)
|
||||
end
|
||||
|
||||
local function format_enum(span)
|
||||
-- A reference is a Str contained in a span representing a label or a range of labels.
|
||||
-- A ref is a ref object produced by the function "new_ref" defined above.
|
||||
if span.classes:includes(TEXT_CROSSREF_CLASS)
|
||||
and not(is_ref_external(stringify(span.content)))
|
||||
then
|
||||
local refs = parse_references_enum(stringify(span.content))
|
||||
local ref_type = get_ref_type(span)
|
||||
local is_prefixed = if_prefixed(span)
|
||||
span.content = format_references(refs, ref_type, is_prefixed)
|
||||
end
|
||||
return span
|
||||
end
|
||||
|
||||
return {
|
||||
{ Meta = configure },
|
||||
{ Meta = support_footnote_label_ConTeXt },
|
||||
{ Note = set_notelabels },
|
||||
{ Note = map_spans_to_notelabels },
|
||||
{ Span = control_label_placement },
|
||||
{ Span = labelize_span },
|
||||
{ Span = format_enum }
|
||||
}
|
Loading…
Reference in New Issue
Block a user