diff --git a/src/intermediate/footnote_reference.rs b/src/intermediate/footnote_reference.rs index c63966b..aa473d2 100644 --- a/src/intermediate/footnote_reference.rs +++ b/src/intermediate/footnote_reference.rs @@ -10,11 +10,11 @@ pub(crate) struct IFootnoteReference { } intermediate!(IFootnoteReference, FootnoteReference, original, registry, { - let footnote_id = + let (footnote_id, reference_count) = get_footnote_reference_id(registry, original.label, &original.definition).await?; Ok(IFootnoteReference { footnote_id, - duplicate_offset: 0, // TODO + duplicate_offset: reference_count, }) }); @@ -31,7 +31,7 @@ impl IFootnoteReference { format!("fnr.{}", self.get_display_label()) } else { // Org-mode makes all duplicates use "100" but I figure there is no harm in giving each a unique ID. - let append = 100 + self.duplicate_offset; + let append = 100 + self.duplicate_offset - 1; format!("fnr.{}.{}", self.get_display_label(), append) } } diff --git a/src/intermediate/registry.rs b/src/intermediate/registry.rs index 9631268..3ae276e 100644 --- a/src/intermediate/registry.rs +++ b/src/intermediate/registry.rs @@ -13,6 +13,7 @@ pub(crate) struct Registry<'orig, 'parse> { id_counter: IdCounter, targets: HashMap<&'parse str, String>, footnote_ids: Vec<(Option<&'parse str>, Vec)>, + footnote_reference_counts: HashMap<&'parse str, usize>, on_deck_footnote_ids: HashMap<&'parse str, &'orig Vec>>, } @@ -22,6 +23,7 @@ impl<'orig, 'parse> Registry<'orig, 'parse> { id_counter: 0, targets: HashMap::new(), footnote_ids: Vec::new(), + footnote_reference_counts: HashMap::new(), on_deck_footnote_ids: HashMap::new(), } } @@ -48,7 +50,7 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( registry: RefRegistry<'orig, 'parse>, label: Option<&'parse str>, definition: &'orig Vec>, -) -> Result { +) -> Result<(usize, usize), CustomError> { if let None = label { // If it has no label then it must always get a new ID. let contents = convert_reference_contents(registry.clone(), definition).await?; @@ -57,12 +59,21 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( registry.footnote_ids.push((None, contents)); registry.footnote_ids.len() - 1 }; - return Ok(pos); + return Ok((pos, 0)); } - if let Some(label) = label { + let reference_count = if let Some(label) = label { promote_footnote_definition(registry.clone(), label).await?; - } + let mut registry = registry.lock().unwrap(); + let reference_count = registry + .footnote_reference_counts + .entry(label) + .and_modify(|count| *count += 1) + .or_insert(0); + *reference_count + } else { + 0 + }; let existing_index = registry .lock() @@ -80,7 +91,7 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( .expect("If-statement proves this to be Some."); entry.1 = contents; } - Ok(existing_id) + Ok((existing_id, reference_count)) } else { let existing_id = { let mut registry = registry.lock().unwrap(); @@ -96,7 +107,7 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( .expect("If-statement proves this to be Some."); entry.1 = contents; } - Ok(existing_id) + Ok((existing_id, reference_count)) } }