diff --git a/src/compiler/compiler.rs b/src/compiler/compiler.rs
index 7714571..de7c04f 100644
--- a/src/compiler/compiler.rs
+++ b/src/compiler/compiler.rs
@@ -1,3 +1,4 @@
+use std::cell::Ref;
use std::cell::RefCell;
use std::cell::RefMut;
use std::collections::HashMap;
@@ -20,6 +21,8 @@ pub struct Compiler {
cache: Option<RefCell<Connection>>,
reference_count: RefCell<HashMap<String, HashMap<String, usize>>>,
// TODO: External references, i.e resolved later
+
+ sections_counter: RefCell<Vec<usize>>,
}
impl Compiler {
@@ -35,9 +38,34 @@ impl Compiler {
target,
cache: cache.map(|con| RefCell::new(con)),
reference_count: RefCell::new(HashMap::new()),
+ sections_counter: RefCell::new(vec![]),
}
}
+ /// Gets the section counter for a given depth
+ /// This function modifies the section counter
+ pub fn section_counter(&self, depth: usize) -> Ref<'_, Vec<usize>>
+ {
+ // Increment current counter
+ if self.sections_counter.borrow().len() == depth {
+ self.sections_counter.borrow_mut().last_mut()
+ .map(|id| *id += 1);
+ return Ref::map(self.sections_counter.borrow(), |b| &*b);
+ }
+
+ // Close
+ while self.sections_counter.borrow().len() > depth {
+ self.sections_counter.borrow_mut().pop();
+ }
+
+ // Open
+ while self.sections_counter.borrow().len() < depth {
+ self.sections_counter.borrow_mut().push(1);
+ }
+
+ Ref::map(self.sections_counter.borrow(), |b| &*b)
+ }
+
/// Sanitizes text for a [`Target`]
pub fn sanitize<S: AsRef<str>>(target: Target, str: S) -> String {
match target {
diff --git a/src/elements/script.rs b/src/elements/script.rs
index 325adc4..9c64c78 100644
--- a/src/elements/script.rs
+++ b/src/elements/script.rs
@@ -282,7 +282,7 @@ impl RegexRule for ScriptRule {
mod tests {
use super::*;
use crate::elements::link::Link;
-use crate::elements::list::ListEntry;
+ use crate::elements::list::ListEntry;
use crate::elements::list::ListMarker;
use crate::elements::paragraph::Paragraph;
use crate::elements::style::Style;
diff --git a/src/elements/section.rs b/src/elements/section.rs
index 60e97a9..6d2be6b 100644
--- a/src/elements/section.rs
+++ b/src/elements/section.rs
@@ -17,6 +17,7 @@ use mlua::Error::BadArgument;
use mlua::Function;
use mlua::Lua;
use regex::Regex;
+use section_kind::NO_NUMBER;
use std::ops::Range;
use std::rc::Rc;
use std::sync::Arc;
@@ -38,13 +39,25 @@ impl Element for Section {
fn compile(&self, compiler: &Compiler, _document: &dyn Document) -> Result<String, String> {
match compiler.target() {
Target::HTML => {
+ let mut number = String::new();
+
+ if (self.kind & NO_NUMBER) != NO_NUMBER {
+ let numbering = compiler.section_counter(self.depth);
+ number = numbering
+ .iter()
+ .map(|n| n.to_string())
+ .collect::<Vec<_>>()
+ .join(".");
+ number += " ";
+ }
+
Ok(format!(
- r#"<h{0} id="{1}">{2}</h{0}>"#,
- self.depth,
- Compiler::refname(compiler.target(), self.title.as_str()),
- Compiler::sanitize(compiler.target(), self.title.as_str())
- ))
- },
+ r#"<h{0} id="{1}">{number}{2}</h{0}>"#,
+ self.depth,
+ Compiler::refname(compiler.target(), self.title.as_str()),
+ Compiler::sanitize(compiler.target(), self.title.as_str())
+ ))
+ }
Target::LATEX => Err("Unimplemented compiler".to_string()),
}
}
@@ -136,15 +149,15 @@ impl RegexRule for SectionRule {
};
// [Optional] Reference name
- let section_refname = matches.get(2).map_or_else(
- || None,
- |refname| {
- // Check for duplicate reference
- if let Some(elem_reference) = document.get_reference(refname.as_str())
- {
- let elem = document.get_from_reference(&elem_reference).unwrap();
+ let section_refname =
+ matches.get(2).map_or_else(
+ || None,
+ |refname| {
+ // Check for duplicate reference
+ if let Some(elem_reference) = document.get_reference(refname.as_str()) {
+ let elem = document.get_from_reference(&elem_reference).unwrap();
- result.push(
+ result.push(
Report::build(ReportKind::Warning, token.source(), refname.start())
.with_message("Duplicate reference name")
.with_label(
@@ -163,10 +176,10 @@ impl RegexRule for SectionRule {
.with_color(parser.colors().warning))
.with_note(format!("Previous reference was overwritten"))
.finish());
- }
- Some(refname.as_str().to_string())
- },
- );
+ }
+ Some(refname.as_str().to_string())
+ },
+ );
// Section kind
let section_kind = match matches.get(3) {