diff --git a/text-crossrefs.lua b/text-crossrefs.lua
index 167cdfd..981d129 100644
--- a/text-crossrefs.lua
+++ b/text-crossrefs.lua
@@ -1,16 +1,11 @@
--- TODO : permettre la citation de références multiples avec un seul préfixe
--- [ref-one, ref-two>ref-four, ref-three]{.ref} → pp. 1, 3-6 et 12
--- Compléter README et test une fois que ce sera fait.
--- TODO : créer des commandes latex et context pour les énumérations
--- de notes et de pages sur le modèle de \tcrfpagerangeref
+local stringify = pandoc.utils.stringify
--- Begin of initialization
-
-local IDENTIFIER_PATTERN = '[%w_.:-]+'
+local TEXT_CROSSREF_CLASS = 'tcrf'
+local REF_TYPE_ATTR = 'reftype'
+local PREFIXED_ATTR = 'prefixref'
local RAW_ATTRIBUTE
-local IS_LABEL_SET_BY_PANDOC
-local LABEL_TEMPLATE
-local NOTELABEL_TEMPLATE
+
+-- Configuration
local function define_raw_attribute()
if FORMAT == 'native' then
@@ -41,38 +36,43 @@ local function define_label_template()
end
end
-define_raw_attribute()
-define_label_template()
-
--- End of initialization
-
--- Configuration
-
local config = {
page_prefix = 'p. ',
- pages_prefix = 'p. ',
+ pages_prefix = 'pp. ',
note_prefix = 'n. ',
- notes_prefix = 'n. ',
- pagenote_order = 'pagefirst',
+ 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 = ';',
+ range_separator = '–',
+ references_enum_separator = ', ',
only_explicit_labels = 'false',
- default_info_type = 'page',
- filelabel_ref_separator = '::'
+ default_reftype = 'page',
+ default_prefixref = 'yes',
+ filelabel_ref_separator = '::',
+ range_delim_tcrfenum = ' to '
+}
+
+local accepted_types = {
+ page = true,
+ note = true,
+ pagenote = true
}
local function format_config_to_openxml()
- to_format = { 'page_prefix',
+ local to_format = { 'page_prefix',
'pages_prefix',
'note_prefix',
+ 'notes_prefix',
'pagenote_separator',
'pagenote_at_end',
- 'range_separator' }
+ 'range_separator',
+ 'multiple_delimiter',
+ 'multiple_before_last' }
for i = 1, #to_format do
config[to_format[i]] = '' ..
config[to_format[i]] .. ''
@@ -83,11 +83,13 @@ local function set_configuration_item_from_metadata(item, metamap)
metakey = 'tcrf-' .. string.gsub(item, '_', '-')
if metamap[metakey] then
-- The metadata values are Str in MetaInlines.
- config[item] = metamap[metakey][1].c
+ config[item] = metamap[metakey][1].text
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
@@ -98,65 +100,15 @@ end
-- End of configuration
--- Extensions for the output document's format
-
-local function define_tex_macros(document)
- if RAW_ATTRIBUTE == 'context' then
- local footnote_redefinition = '\\let\\oldfootnote\\footnote\n' ..
- '\\define[2]\\footnote{\\oldfootnote[#2]{#1}%\n' ..
- '\\expandafter\\edef\\csname #2pagenumber\\endcsname{\\userpage}}\n'
- local predefined_strings =
- '\\define\\tcrfpage{' .. config.page_prefix .. '}\n' ..
- '\\define\\tcrfpages{' .. config.pages_prefix .. '}\n' ..
- '\\define\\tcrfrangesep{' .. config.range_separator .. '}\n'
- local range_ref = '\\ifdefined\\tcrfpagerangeref\\else\n' ..
- '\\define[2]\\tcrfpagerangeref{' ..
- '\\if' ..
- '\\csname #1pagenumber\\endcsname' ..
- '\\csname #2pagenumber\\endcsname\n' ..
- '\\tcrfpage\\at[#1]\n' ..
- '\\else\n' ..
- '\\tcrfpages\\at[#1]\\tcrfrangesep\\at[#2]\\fi}\n' ..
- '\\fi\n'
- local macros_block = pandoc.RawBlock('context',
- footnote_redefinition ..
- predefined_strings ..
- range_ref)
- table.insert(document.blocks, 1, macros_block)
- elseif RAW_ATTRIBUTE == 'latex' then
- local predefined_strings =
- '\\newcommand*{\\tcrfpage}{' .. config.page_prefix .. '}\n' ..
- '\\newcommand*{\\tcrfpages}{' .. config.pages_prefix .. '}\n' ..
- '\\newcommand*{\\tcrfrangesep}{' .. config.range_separator .. '}\n'
- local label_redefinition = '\\let\\oldlabel\\label\n' ..
- '\\renewcommand*{\\label}[1]{\\oldlabel{#1}%\n' ..
- '\\expandafter\\xdef\\csname #1pagenumber\\endcsname{\\thepage}}\n'
- local range_ref = '\\ifdefined\\tcrfpagerangeref\\else\n' ..
- '\\newcommand*{\\tcrfpagerangeref}[2]{%\n' ..
- '\\if' ..
- '\\csname #1pagenumber\\endcsname' ..
- '\\csname #2pagenumber\\endcsname\n' ..
- '\\tcrfpage\\pageref{#1}\n' ..
- '\\else\n' ..
- '\\tcrfpages\\pageref{#1}\\tcrfrangesep\\pageref{#2}\\fi}\n' ..
- '\\fi\n'
- local macros_block = pandoc.RawBlock('latex',
- predefined_strings ..
- label_redefinition ..
- range_ref)
- table.insert(document.blocks, 1, macros_block)
- end
- return document
-end
-
--- End of the extensions for the output document's format
-
--- Identifiers
+-- 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
@@ -174,7 +126,7 @@ 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 ~= ''
+ and container.content[i].identifier
then
map_span_to_label(container.content[i])
end
@@ -187,7 +139,8 @@ end
local function map_spans_to_notelabels(note)
if RAW_ATTRIBUTE == 'context'
or RAW_ATTRIBUTE == 'opendocument'
- or RAW_ATTRIBUTE == 'openxml' then
+ 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
@@ -195,12 +148,13 @@ local function map_spans_to_notelabels(note)
end
local function make_label(label)
- if IS_LABEL_SET_BY_PANDOC then
- return pandoc.Str('')
- else
- label_rawcode = string.gsub(LABEL_TEMPLATE, '{{label}}', label)
- return pandoc.RawInline(RAW_ATTRIBUTE, label_rawcode)
+ -- 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)
@@ -211,26 +165,12 @@ local function labelize_span(span)
end
end
-local function has_class(elem, class)
- if elem.classes then
- for i = 1, #elem.classes do
- if elem.classes[i] == class then
- return true
- end
- end
- return false
- else
- error('function has_class used on an element of type ' ..
- elem.t .. ' that cannot have classes.')
- end
-end
-
local current_note_labels = {}
local collect_note_labels = {
Span = function(span)
- if span.identifier ~= '' and
- (config.only_explicit_labels == 'false' or has_class(span, 'label'))
+ if span.identifier ~= ''
+ and (config.only_explicit_labels == 'false' or span.classes:includes('label'))
then
table.insert(current_note_labels, span.identifier)
end
@@ -240,302 +180,373 @@ local collect_note_labels = {
local function make_notelabel(pos)
local raw_code = ''
if pos == 'begin' then
- if RAW_ATTRIBUTE == 'openxml' then
- raw_code = string.gsub(
- '',
- '{{label}}', current_note_labels[#current_note_labels])
- end
+ raw_code = string.gsub(
+ '',
+ '{{label}}', current_note_labels[1])
elseif pos == 'end' then
- if RAW_ATTRIBUTE == 'context' then
- local label = current_note_labels[1] .. '_note'
- raw_code = '{' .. label .. '}'
- elseif RAW_ATTRIBUTE == 'openxml' then
- raw_code = string.gsub('',
- '{{label}}', current_note_labels[1])
- end
+ raw_code = string.gsub('',
+ '{{label}}', current_note_labels[1])
end
return pandoc.RawInline(RAW_ATTRIBUTE, raw_code)
end
local function labelize_note(note)
- local label_begin = make_notelabel('begin')
- local label_end = make_notelabel('end')
- return { label_begin, note, label_end }
+ 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
+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 identifiers-related code
+-- End of preprocessing of identifiers on notes
--- References
+-- Gathering of data from the references span
-local function is_reference_valid(ref)
- if string.find(ref, '^[' .. IDENTIFIER_PATTERN .. ']') then
- error('text-crossrefs.lua: Invalid character in reference: ' .. ref ..
- '\nIdentifier and reference names can only contain' ..
- ' alphanumerical characters, periods, underscores and hyphens.\n')
- else
- return true
- end
+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(rawref)
- if string.find(rawref, config.filelabel_ref_separator, 1, true) then
+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 is_ref_range(rawref)
- if string.find(rawref, config.references_range_separator, 1, true) then
- return true
- else
- return false
+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
-function get_first_reference_end_index(range_separator_index)
- if range_separator_index then
- return range_separator_index - 1
- end
-end
-
-local function get_first_reference(rawref)
- local _, file_ref_separator_index =
- string.find(rawref, config.filelabel_ref_separator, 1, true)
- local range_separator_index, _ =
- string.find(rawref, config.references_range_separator, 1, true)
- local ref = string.sub(rawref,
- (file_ref_separator_index or 0) + 1,
- get_first_reference_end_index(range_separator_index))
- if is_reference_valid(ref) then return ref end
-end
-
-local function get_second_reference(rawref)
- local second_ref_begin_index
- local _, file_ref_separator_index =
- string.find(rawref, config.filelabel_ref_separator, 1, true)
- if file_ref_separator_index then
- _, file_ref_separator_index =
- string.find(rawref,
- config.filelabel_ref_separator,
- config.file_ref_separator_index + 1,
- true)
- second_ref_begin_index = file_ref_separator_index + 1
- else
- local _, range_separator_index, _ =
- string.find(rawref, config.references_range_separator, 1, true)
- second_ref_begin_index = range_separator_index + 1
- end
- local ref = string.sub(rawref, second_ref_begin_index)
- if is_reference_valid(ref) then return ref end
-end
-
-local function is_ref_enumeration(raw_reference)
- if string.match(raw_reference, '%' .. config.references_enum_separator) then
- return true
- else
- return false
- end
-end
-
-local function analyze_reference_span(reference_span)
- if #reference_span.content == 1 and reference_span.content[1].t == 'Str' then
- raw_reference = reference_span.content[1].c
- analyzed_reference = {}
- analyzed_reference.is_external = is_ref_external(raw_reference)
- analyzed_reference.is_range = is_ref_range(raw_reference)
- analyzed_reference.is_enumeration = is_ref_enumeration(raw_reference)
- if analyzed_reference.is_external then
- analyzed_reference.filelabel = get_extfilelabel(raw_reference)
+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
- analyzed_reference.first = get_first_reference(raw_reference)
- if analyzed_reference.is_range then
- analyzed_reference.second = get_second_reference(raw_reference)
- end
- return analyzed_reference
- else
- error('The content of a span with class ref must be a plain string.')
+ current_ref = new_ref(parse_possible_range(reference))
end
+ return current_ref, next_ref_beg
end
-local function insert_page_target_in_xml(target)
+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_attr_value, 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_tcrfenum_first_arg(ref_type)
+ local ref_type_is_explicit = ref_type ~= config.default_reftype
+ local tcrfenum_first_arg = ''
+ if ref_type_is_explicit then
+ tcrfenum_first_arg = '[' .. ref_type .. ']'
+ end
+ return tcrfenum_first_arg
+end
+
+local function make_tcrfenum_second_arg(is_prefixed)
+ local is_prefixed_is_explicit = is_prefixed ~= (config.default_prefixref == 'yes')
+ local tcrfenum_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
+ tcrfenum_second_arg = '[' .. is_prefixed_string .. ']'
+ end
+ return tcrfenum_second_arg
+end
+
+local function make_tcrfenum_references_list(refs, ref_type)
+ local tcrfenum_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_tcrfenum .. ref.end_of_range
+ end
+ texified_ref = texified_ref .. '}'
+ tcrfenum_references_list = tcrfenum_references_list .. texified_ref
+ end
+ return tcrfenum_references_list
+end
+
+local function make_raw_content_tex(refs, ref_type, is_prefixed)
+ local texified_references = ''
+ texified_references = '\\tcrfenum'
+ .. make_tcrfenum_first_arg(ref_type)
+ .. make_tcrfenum_second_arg(is_prefixed)
+ .. '{' .. make_tcrfenum_references_list(refs, ref_type) .. '}'
+ return texified_references
+end
+
+--- TODO : début de section à revoir
+
+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
- return '000'
elseif RAW_ATTRIBUTE == 'openxml' then
- return '' ..
+ xml_page_ref = xml_page_ref ..
+ '' ..
' PAGEREF ' ..
target .. ' \\h ' ..
'' ..
'000' ..
''
end
+ return xml_page_ref
end
-local function format_prefix(info_type, is_enumeration)
- if not is_enumeration then
- return config[info_type .. '_prefix']
- elseif RAW_ATTRIBUTE == 'context' or RAW_ATTRIBUTE == 'latex' then
- return ''
- elseif RAW_ATTRIBUTE == 'opendocument' or RAW_ATTRIBUTE == 'openxml' then
- return config[info_type .. 's_prefix']
+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
-end
-
-local function format_page_reference(target)
- if RAW_ATTRIBUTE == 'context' then
- return '\\at[' .. target .. ']'
- elseif RAW_ATTRIBUTE == 'latex' then
- return '\\pageref{' .. target .. '}'
- elseif RAW_ATTRIBUTE == 'opendocument' then
- return insert_page_target_in_xml(target)
- elseif RAW_ATTRIBUTE == 'openxml' then
- return insert_page_target_in_xml(target)
- end
-end
-
-local function format_pagerange_reference(first, second, is_prefixed)
- if RAW_ATTRIBUTE == 'context' or RAW_ATTRIBUTE == 'latex' then
- local bracketed_arg = ''
- if is_prefixed then bracketed_arg = 'prefixed' end
- -- TODO : implémenter l'argument entre crochets
- return '\\tcrfpagerangeref[' .. bracketed_arg .. ']{' .. first .. '}{' .. second .. '}'
- elseif RAW_ATTRIBUTE == 'opendocument' or RAW_ATTRIBUTE == 'openxml' then
- local to_return = ''
- if is_prefixed then to_return = config.pages_prefix end
- return to_return .. insert_page_target_in_xml(first) ..
- config.range_separator .. insert_page_target_in_xml(second)
- end
-end
-
-local function format_note_reference(target)
- if RAW_ATTRIBUTE == 'context' then
- return '\\in[' .. spans_to_note_labels[target] .. '_note' .. ']'
- elseif RAW_ATTRIBUTE == 'latex' then
- return '\\ref{' .. target .. '}'
- elseif RAW_ATTRIBUTE == 'opendocument' then
- return '000'
+ (spans_to_note_labels[target] or '') .. '">000'
elseif RAW_ATTRIBUTE == 'openxml' then
- return
+ note_ref_xml = note_ref_xml ..
'' ..
' NOTEREF ' ..
- target .. '_Note' .. ' \\h ' ..
+ (spans_to_note_labels[target] or '') .. '_Note' .. ' \\h ' ..
'' ..
'000' ..
''
end
+ return note_ref_xml
end
-local function format_pagenote_reference(target)
- if config.pagenote_order == 'pagefirst' then
- return format_prefix('page', false) .. format_page_reference(target) ..
- config.pagenote_separator .. format_prefix('note', false) ..
- format_note_reference(target) .. config.pagenote_at_end
- elseif config.pagenote_order == 'notefirst' then
- return format_prefix('note', false) .. format_note_reference(target) ..
- config.pagenote_separator .. format_prefix('page', false) ..
- format_page_reference(target) .. config.pagenote_at_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-order must be set either to pagefirst or notefirst.')
+ error('“tcrf-pagenote-first-type” must be set either to “page” or “note”.')
end
+ return pagenote_ref_xml
end
-local function format_reference(target, info_type)
- if info_type == 'page' and target.is_range then
- return format_pagerange_reference(target.first, target.second,
- not target.is_enumeration)
- elseif info_type == 'page' then
- return format_page_reference(target.first)
- elseif info_type == 'note' then
- return format_note_reference(target.first)
- elseif info_type == 'pagenote' then
- return format_pagenote_reference(target.first)
- else
- error('Invalid value for attribute type in span with class ref: ' ..
- info_type)
+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_reference_head(info_type, is_enumeration, is_range)
- if (info_type == 'page' or info_type == 'note') and not is_range then
- return format_prefix(info_type, is_enumeration)
- else
- return ''
+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 format_all_items_in_enumeration(enum, info_type)
- local reference_body = ''
- local enumerated_ref_spans = {}
- for ref in string.gmatch(enum,
- '[^%' .. config.references_enum_separator .. ']+') do
- ref_span = pandoc.Span(ref, {['type'] = info_type})
- table.insert(enumerated_ref_spans, ref_span)
- end
- for i = 1, #enumerated_ref_spans do
- target_in_enum = analyze_reference_span(enumerated_ref_spans[i])
- reference_body = reference_body .. format_reference(target_in_enum, info_type)
- if i < #enumerated_ref_spans then
- if i < #enumerated_ref_spans-1 then
- reference_body = reference_body .. config.multiple_delimiter
+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
- reference_body = reference_body .. config.multiple_before_last
+ references_xml = references_xml .. config.multiple_before_last
end
end
end
- return reference_body
+ return references_xml
end
-local function format_enumeration(target, info_type)
+--- Fin de section à revoir
+
+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
- -- TODO
- return format_enumeration_smart(target.first, info_type)
- elseif RAW_ATTRIBUTE == 'opendocument' or RAW_ATTRIBUTE == 'openxml' then
- return format_all_items_in_enumeration(target.first, info_type)
- end
-end
-
-local function make_reference_body(target, info_type)
- local reference_body
- if target.is_enumeration then
- reference_body = format_enumeration(target, info_type)
+ raw_content = make_raw_content_tex(refs, ref_type, is_prefixed)
else
- reference_body = format_reference(target, info_type)
+ raw_content = make_raw_content_xml(refs, ref_type, is_prefixed)
end
- return reference_body
+ return raw_content
end
-local function make_reference(span)
- if has_class(span, 'ref') then
- local target = analyze_reference_span(span)
- if not target.is_external then
- local info_type = span.attributes.type or config.default_info_type
- local head = make_reference_head(info_type, target.is_enumeration, target.is_range)
- local body = make_reference_body(target, info_type)
- span.content[1] = pandoc.RawInline(RAW_ATTRIBUTE, head .. body)
- return span
- end
- 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
--- End of references-related code
+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 },
- { Pandoc = define_tex_macros },
{ Note = set_notelabels },
{ Note = map_spans_to_notelabels },
{ Span = labelize_span },
- { Span = make_reference }
+ { Span = format_enum }
}