use crate::{Error, Form, InlineNode, Location};
use super::location_mapping::LocationMappingContext;
pub(crate) trait MarkedText<'a>: Sized {
type Content: LocationMappable<'a>;
fn id(&self) -> Option<&'a str>;
fn location(&self) -> &Location;
fn content(&self) -> &Self::Content;
fn location_mut(&mut self) -> &mut Location;
fn content_mut(&mut self) -> &mut Self::Content;
fn form(&self) -> &Form;
fn map_locations(&mut self, ctx: &LocationMappingContext<'_, 'a>) -> Result<(), Error> {
let form = self.form().clone();
let mapped_outer = ctx.map_location(self.location(), Some(&form))?;
let extended_location = super::location_mapping::extend_attribute_location_if_needed(
ctx.state,
ctx.processed,
mapped_outer,
);
*self.location_mut() = extended_location;
self.content_mut().map_locations_with(ctx, Some(&form))?;
Ok(())
}
}
pub trait LocationMappable<'a> {
fn map_locations_with(
&mut self,
ctx: &LocationMappingContext<'_, 'a>,
form: Option<&Form>,
) -> Result<(), Error>;
}
impl<'a> LocationMappable<'a> for Vec<InlineNode<'a>> {
fn map_locations_with(
&mut self,
ctx: &LocationMappingContext<'_, 'a>,
form: Option<&Form>,
) -> Result<(), Error> {
*self =
super::location_mapping::map_inner_content_locations(std::mem::take(self), ctx, form)?;
Ok(())
}
}
macro_rules! impl_marked_text {
($($type:ident),+ $(,)?) => {
$(
impl<'a> MarkedText<'a> for crate::$type<'a> {
type Content = Vec<InlineNode<'a>>;
fn id(&self) -> Option<&'a str> {
self.id
}
fn location(&self) -> &Location {
&self.location
}
fn content(&self) -> &Self::Content {
&self.content
}
fn location_mut(&mut self) -> &mut Location {
&mut self.location
}
fn content_mut(&mut self) -> &mut Self::Content {
&mut self.content
}
fn form(&self) -> &Form {
&self.form
}
}
)+
};
}
impl_marked_text!(
Bold,
Italic,
Monospace,
Highlight,
Subscript,
Superscript,
CurvedQuotation,
CurvedApostrophe,
);
pub(crate) fn map_marked_text_locations<'a>(
inline: &mut InlineNode<'a>,
ctx: &LocationMappingContext<'_, 'a>,
) -> Result<(), Error> {
match inline {
InlineNode::BoldText(node) => node.map_locations(ctx),
InlineNode::ItalicText(node) => node.map_locations(ctx),
InlineNode::MonospaceText(node) => node.map_locations(ctx),
InlineNode::HighlightText(node) => node.map_locations(ctx),
InlineNode::SubscriptText(node) => node.map_locations(ctx),
InlineNode::SuperscriptText(node) => node.map_locations(ctx),
InlineNode::CurvedQuotationText(node) => node.map_locations(ctx),
InlineNode::CurvedApostropheText(node) => node.map_locations(ctx),
InlineNode::RawText(_)
| InlineNode::PlainText(_)
| InlineNode::VerbatimText(_)
| InlineNode::LineBreak(_)
| InlineNode::InlineAnchor(_)
| InlineNode::CalloutRef(_)
| InlineNode::Macro(_)
| InlineNode::StandaloneCurvedApostrophe(_) => Ok(()),
}
}