|
1 | 1 | use crate::md_elem::elem::*; |
2 | 2 | use std::borrow::Borrow; |
3 | 3 |
|
4 | | -pub(crate) fn inlines_to_plain_string<N: Borrow<Inline>>(inlines: &[N]) -> String { |
| 4 | +#[derive(Default, Copy, Clone)] |
| 5 | +pub(crate) struct InlineToStringOpts { |
| 6 | + pub(crate) footnotes: FootnoteToString, |
| 7 | +} |
| 8 | + |
| 9 | +#[derive(Default, Copy, Clone)] |
| 10 | +pub(crate) enum FootnoteToString { |
| 11 | + /// Includes all the surrounding Markdown. If the footnote id is `"1"`, this will render as `[^1]`. |
| 12 | + #[default] |
| 13 | + IncludeMarkdown, |
| 14 | + |
| 15 | + /// Includes only the footnote id. If the footnote id is `"1"`, this will render as `1`. |
| 16 | + OnlyFootnoteId, |
| 17 | +} |
| 18 | + |
| 19 | +pub(crate) fn inlines_to_plain_string<N: Borrow<Inline>>(inlines: &[N], opts: InlineToStringOpts) -> String { |
5 | 20 | let mut result = String::with_capacity(inlines.len() * 5); // random guess |
6 | | - build_inlines(&mut result, inlines); |
| 21 | + build_inlines(&mut result, inlines, opts); |
7 | 22 | result |
8 | 23 | } |
9 | 24 |
|
10 | | -fn build_inlines<N: Borrow<Inline>>(out: &mut String, inlines: &[N]) { |
| 25 | +fn build_inlines<N: Borrow<Inline>>(out: &mut String, inlines: &[N], opts: InlineToStringOpts) { |
11 | 26 | for inline in inlines { |
12 | | - build_inline(out, inline.borrow()); |
| 27 | + build_inline(out, inline.borrow(), opts); |
13 | 28 | } |
14 | 29 | } |
15 | 30 |
|
16 | | -fn build_inline(out: &mut String, elem: &Inline) { |
| 31 | +fn build_inline(out: &mut String, elem: &Inline, opts: InlineToStringOpts) { |
17 | 32 | match elem { |
18 | | - Inline::Span(Span { children, .. }) => build_inlines(out, children), |
| 33 | + Inline::Span(Span { children, .. }) => build_inlines(out, children, opts), |
19 | 34 | Inline::Text(Text { value, .. }) => out.push_str(value), |
20 | | - Inline::Link(Link::Standard(standard_link)) => build_inlines(out, &standard_link.display), |
| 35 | + Inline::Link(Link::Standard(standard_link)) => build_inlines(out, &standard_link.display, opts), |
21 | 36 | Inline::Link(Link::Autolink(autolink)) => out.push_str(&autolink.url), |
22 | 37 | Inline::Image(Image { alt, .. }) => out.push_str(alt), |
23 | 38 | Inline::Footnote(footnote) => { |
24 | | - out.push_str("[^"); |
| 39 | + if matches!(opts.footnotes, FootnoteToString::IncludeMarkdown) { |
| 40 | + out.push_str("[^"); |
| 41 | + } |
25 | 42 | out.push_str(footnote.as_str()); |
26 | | - out.push(']'); |
| 43 | + if matches!(opts.footnotes, FootnoteToString::IncludeMarkdown) { |
| 44 | + out.push(']'); |
| 45 | + } |
27 | 46 | } |
28 | 47 | } |
29 | 48 | } |
@@ -70,7 +89,7 @@ mod tests { |
70 | 89 | unwrap!(&md_elems[0], MdElem::Paragraph(contents)); |
71 | 90 | unwrap!(&contents.body[1], inline @ Inline::Text(_)); |
72 | 91 | VARIANTS_CHECKER.see(inline); |
73 | | - let actual = inlines_to_plain_string(&contents.body); |
| 92 | + let actual = inlines_to_plain_string(&contents.body, Default::default()); |
74 | 93 | assert_eq!(&actual, "Hello <foo> world"); |
75 | 94 | } |
76 | 95 |
|
@@ -119,7 +138,7 @@ mod tests { |
119 | 138 | let md_elems = MdDoc::parse(md, &options).unwrap().roots; |
120 | 139 | unwrap!(&md_elems[0], MdElem::Paragraph(p)); |
121 | 140 | p.body.iter().for_each(|inline| VARIANTS_CHECKER.see(inline)); |
122 | | - let actual = inlines_to_plain_string(&p.body); |
| 141 | + let actual = inlines_to_plain_string(&p.body, Default::default()); |
123 | 142 | assert_eq!(&actual, expect); |
124 | 143 | } |
125 | 144 | } |
0 commit comments