Beginning to hand out footnote ids.

This commit is contained in:
Tom Alexander 2023-10-29 12:06:40 -04:00
parent 06dcd22e69
commit 52ca300de3
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 69 additions and 4 deletions

View File

@ -1 +1 @@
!!!!!!!! footnote_reference
<sup><a id="{.reference_id}" href="{.definition_link}">{.label}</a></sup>

View File

@ -0,0 +1,25 @@
# Test proves that:
#
# - Anonymous references with identical content get unique IDs.
# - Unreferenced footnote definitions are dropped.
# - Footnote definitions that come before their first reference are dropped.
foo[fn:2:something]
bar[fn::something]
baz[fn::something]
cat[fn::something]
dog[fn:3]
[fn:3] ipsum
[fn:4] lorem
[fn:3] dolar
[fn:5] not referenced
stuff[fn:4] and things

View File

@ -3,13 +3,16 @@ use crate::error::CustomError;
use super::registry::Registry;
#[derive(Debug)]
pub(crate) struct IFootnoteReference {}
pub(crate) struct IFootnoteReference {
footnote_id: usize,
}
impl IFootnoteReference {
pub(crate) async fn new<'parse>(
registry: &mut Registry<'parse>,
original: &organic::types::FootnoteReference<'parse>,
) -> Result<IFootnoteReference, CustomError> {
Ok(IFootnoteReference {})
let footnote_id = registry.get_footnote_reference_id(original.label, &original.definition);
Ok(IFootnoteReference { footnote_id })
}
}

View File

@ -1,10 +1,13 @@
use std::collections::HashMap;
use organic::types::Object;
type IdCounter = u16;
pub(crate) struct Registry<'parse> {
pub(crate) struct Registry<'intermediate, 'parse> {
id_counter: IdCounter,
targets: HashMap<&'parse str, String>,
footnote_ids: Vec<(Option<&'parse str>, &Vec<Object<'parse>>)>,
}
impl<'parse> Registry<'parse> {
@ -12,6 +15,7 @@ impl<'parse> Registry<'parse> {
Registry {
id_counter: 0,
targets: HashMap::new(),
footnote_ids: Vec::new(),
}
}
@ -21,4 +25,37 @@ impl<'parse> Registry<'parse> {
format!("target_{}", self.id_counter)
})
}
/// Get a 0-indexed ID for a footnote.
///
/// This needs to be incremented to be 1-indexed for render.
pub(crate) fn get_footnote_reference_id<'b>(
&'b mut self,
label: Option<&'parse str>,
definition: &'parse Vec<Object<'parse>>,
) -> usize {
if let None = label {
// If it has no label then it must always get a new ID.
self.footnote_ids.push((None, definition));
return self.footnote_ids.len();
}
if let Some(existing_id) = self
.footnote_ids
.iter()
.position(|(id, _definition)| *id == label)
{
if !definition.is_empty() {
let entry = self
.footnote_ids
.get_mut(existing_id)
.expect("If-statement proves this to be Some.");
entry.1 = definition;
}
existing_id
} else {
self.footnote_ids.push((label, definition));
self.footnote_ids.len()
}
}
}