mod extract_links;
pub(crate) use extract_links::*;
use pulldown_cmark::BrokenLink;
use pulldown_cmark::BrokenLinkCallback;
use pulldown_cmark::CowStr;
use pulldown_cmark::Options;
use pulldown_cmark::Parser;
use tracing::warn;
pub(crate) fn get_parser(markdown_input: &str) -> Parser<'_> {
Parser::new_ext(markdown_input, get_options())
}
fn get_options() -> Options {
let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH);
options.insert(Options::ENABLE_FOOTNOTES);
options.insert(Options::ENABLE_TABLES);
options
}
#[derive(Debug)]
pub(crate) struct Handler<'input> {
markdown_input: &'input str,
pub broken_links: Vec<(String, String, String)>,
}
impl<'input> Handler<'input> {
fn new(markdown_input: &'input str) -> Self {
let broken_links = Vec::new();
Self {
markdown_input,
broken_links,
}
}
}
impl<'input> BrokenLinkCallback<'input> for Handler<'input> {
fn handle_broken_link(
&mut self,
link: BrokenLink<'input>,
) -> Option<(CowStr<'input>, CowStr<'input>)> {
let txt: &str = self.markdown_input.get(link.span).unwrap_or("");
warn!(
"Issue with the markdown: reference: {}, `{}`, type: {:?}",
link.reference, txt, link.link_type,
);
self.broken_links.push((
link.reference.into_string(),
txt.into(),
format!("{:?}", link.link_type),
));
Some(("http://TODO".into(), ":BROKEN_LINK:".into()))
}
}
#[allow(dead_code)]
pub(crate) fn get_parser_with_broken_links_handler<'input>(
markdown_input: &'input str,
) -> Parser<'_, Handler<'_>> {
Parser::<'input, Handler<'_>>::new_with_broken_link_callback(
markdown_input,
get_options(),
Some(Handler::<'_>::new(markdown_input)),
)
}