From 0d30b8cc94936f40750bfd04ffc91f22fca3944a Mon Sep 17 00:00:00 2001 From: Bastien Dumont Date: Wed, 19 Oct 2022 20:36:49 +0200 Subject: [PATCH] Code refactoring and proper handling of labels on footnotes in ConTeXt --- text-crossrefs.lua | 647 +++++++++++++++++++++++---------------------- 1 file changed, 329 insertions(+), 318 deletions(-) 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 } }