diff --git a/src/resolve.rs b/src/resolve.rs index 3ee91eb..1492c8f 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -13,7 +13,7 @@ pub fn schemes() -> Vec<(&'static str, Vec<(String, String)>)> { let decimal = (0..6) .map(|i| { let lvl = (1..=i + 1).map(|j| format!("%{j}")).collect::>().join("."); - (lvl, "decimal".to_string()) + (format!("{lvl}."), "decimal".to_string()) // trailing dot ("1.", "1.1."): the caption form every corpus contract uses }) .collect(); let legal = [("%1.", "decimal"), ("(%2)", "lowerLetter"), ("(%3)", "lowerRoman"), ("(%4)", "upperLetter"), ("(%5)", "upperRoman"), ("(%6)", "decimal")] @@ -238,7 +238,8 @@ impl Resolver { let Some((display, full)) = self.headnums.get(tgt) else { return Err(format!("cross-reference #{tgt} needs a number its target does not have; pass number_headings or use {{ref=text}}")); }; - Ok(if variant == "leaf" { display.clone() } else { full.clone() }) + let num = if variant == "leaf" { display.clone() } else { full.clone() }; + Ok(num.strip_suffix('.').map_or(num.clone(), str::to_string)) // caption "1.2." cites as "Section 1.2": mid-sentence references drop the trailing dot } /// Prefix text before a reference: `override` text, the type's prefix diff --git a/tests/test_export.py b/tests/test_export.py index 255ef93..e0527ac 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -17,29 +17,29 @@ def test_refs_and_heading_numbering(): h = mdhtml2html(md2mdhtml(REFS_MD), number_headings='legal') assert '1. Payment' in h assert '(a) Late fees' in h - assert 'Section 1.' in h + assert 'Section 1' in h assert '1.(a)' in h # bare: no prefix word assert 'Clause 1.(a)' in h # override text - assert 'Sections 1. and 1.(a)' in h + assert 'Sections 1 and 1.(a)' in h assert 'Section (a)' in h # leaf assert 'Late fees' in h # text assert 'page 1.(a)' in h # page degrades to full assert 'data-ref' not in h assert h.warnings == [] d = mdhtml2html(md2mdhtml('# One {#sec-a}\n\n## Two {#sec-b}\n\nSee [@sec-b].'), number_headings='decimal') - assert '1.1 Two' in d + assert '1.1. Two' in d assert 'Section 1.1' in d def test_ref_errors(): with pytest.raises(ValueError, match='not found'): mdhtml2html(md2mdhtml('See [@sec-x].')) auto = mdhtml2html(md2mdhtml('# A {#sec-a}\n\nSee [@sec-a].')) # refs trigger auto decimal numbering - assert '1 A' in auto and 'Section 1' in auto + assert '1. A' in auto and 'Section 1' in auto assert 'heading-number' not in mdhtml2html(md2mdhtml('# A {#sec-a}\n\nText.')) # no numeric ref: no numbering md = '# A {#exh-a}\n\nSee [@exh-a].' with pytest.raises(ValueError, match='reftypes'): mdhtml2html(md2mdhtml(md), number_headings='legal') h = mdhtml2html(md2mdhtml(md), number_headings='legal', reftypes=dict(exh=('Exhibit', 'Exhibits'))) - assert 'Exhibit 1.' in h + assert 'Exhibit 1' in h with pytest.raises(ValueError, match='data-ref'): mdhtml2html('

t

') @@ -239,10 +239,10 @@ def test_md2gfm_refs_and_numbering(): out = md2gfm(REFS_MD, number_headings='legal') assert '# 1. Payment\n' in out and '## (a) Late fees\n' in out assert '{#sec-pay}' not in out - assert ('See Section 1., 1.(a), Clause 1.(a), Sections 1. and 1.(a), Section (a),\n' + assert ('See Section 1, 1.(a), Clause 1.(a), Sections 1 and 1.(a), Section (a),\n' 'Late fees, and page 1.(a).') in out auto = md2gfm('# A {#sec-a}\n\nSee [@sec-a].') - assert '# 1 A\n' in auto and 'See Section 1.' in auto + assert '# 1. A\n' in auto and 'See Section 1.' in auto dl = md2gfm('# A {#sec-a}\n\nT\n: see [@sec-a].\n') assert ': see Section 1.' in dl # definition bodies are rewrite regions too assert md2gfm('# A {#sec-a}\n\nText only.\n') == '# A\n\nText only.\n' # strip only; rest byte-identical @@ -253,7 +253,7 @@ def test_md2gfm_nested_containers(): md = ('# Top {#sec-top}\n\n::: box\n\n## Inner {#sec-in}\n\nBody.\n\n:::\n\n' '> ## Quoted {#sec-q}\n\nSee [@sec-top], [@sec-in], and [-@sec-q]{ref=text}.\n') out = md2gfm(md) - assert '# 1 Top\n' in out and '## 1.1 Inner\n' in out + assert '# 1. Top\n' in out and '## 1.1. Inner\n' in out assert '{#sec-in}' not in out assert 'See Section 1, Section 1.1, and Quoted.' in out assert '{#sec-q}' in out # marker containers pass through unrewritten