diff --git a/README.md b/README.md
index faf89ec..575c5d6 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,25 @@ 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:
diff --git a/sample.md b/sample.md
index de2ec76..a4a0906 100644
--- a/sample.md
+++ b/sample.md
@@ -33,3 +33,9 @@ Here are some precisions.[^2]
* 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}.
diff --git a/test/sample-context.native b/test/sample-context.native
index d71fb71..77aa293 100644
--- a/test/sample-context.native
+++ b/test/sample-context.native
@@ -389,4 +389,67 @@
]
]
, 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 "."
+ ]
]
diff --git a/test/sample-latex.native b/test/sample-latex.native
index 90e1761..7cfcb88 100644
--- a/test/sample-latex.native
+++ b/test/sample-latex.native
@@ -388,4 +388,67 @@
[ 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 "."
+ ]
]
diff --git a/test/sample-opendocument.native b/test/sample-opendocument.native
index d07ef34..fbd1f37 100644
--- a/test/sample-opendocument.native
+++ b/test/sample-opendocument.native
@@ -394,4 +394,67 @@
]
]
, 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.\160000\8211000"
+ ]
+ , Str "."
+ ]
]
diff --git a/text-crossrefs.lua b/text-crossrefs.lua
index 46cd595..ac7201f 100644
--- a/text-crossrefs.lua
+++ b/text-crossrefs.lua
@@ -3,6 +3,7 @@ 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
@@ -202,6 +203,25 @@ local function map_spans_to_notelabels(note)
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('')
@@ -600,6 +620,7 @@ return {
{ Meta = tweak_footnote_if_ConTeXt },
{ Note = set_notelabels },
{ Note = map_spans_to_notelabels },
+ { Span = control_label_placement },
{ Span = labelize_span },
{ Span = format_enum }
}