Add support for target links.
This commit is contained in:
parent
d2ea6b6a0f
commit
59a91331cc
@ -14,9 +14,17 @@ pub(crate) struct RenderTarget {
|
|||||||
post_blank: organic::types::PostBlank,
|
post_blank: organic::types::PostBlank,
|
||||||
}
|
}
|
||||||
|
|
||||||
render!(RenderTarget, ITarget, original, _render_context, {
|
render!(RenderTarget, ITarget, original, render_context, {
|
||||||
|
let id = format!(
|
||||||
|
"{}{}",
|
||||||
|
render_context
|
||||||
|
.id_addition
|
||||||
|
.map(|id_addition| format!("sec{}.", id_addition))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
original.id
|
||||||
|
);
|
||||||
Ok(RenderTarget {
|
Ok(RenderTarget {
|
||||||
id: original.id.clone(),
|
id,
|
||||||
post_blank: original.post_blank,
|
post_blank: original.post_blank,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -14,7 +14,7 @@ type IdCounter = u16;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Registry<'orig, 'parse> {
|
pub(crate) struct Registry<'orig, 'parse> {
|
||||||
id_counter: IdCounter,
|
id_counter: IdCounter,
|
||||||
targets: HashMap<&'parse str, String>,
|
targets: HashMap<String, String>,
|
||||||
footnote_ids: Vec<(Option<&'parse str>, Vec<IAstNode>)>,
|
footnote_ids: Vec<(Option<&'parse str>, Vec<IAstNode>)>,
|
||||||
footnote_reference_counts: HashMap<&'parse str, usize>,
|
footnote_reference_counts: HashMap<&'parse str, usize>,
|
||||||
on_deck_footnote_ids: HashMap<&'parse str, &'orig Vec<Element<'parse>>>,
|
on_deck_footnote_ids: HashMap<&'parse str, &'orig Vec<Element<'parse>>>,
|
||||||
@ -31,8 +31,8 @@ impl<'orig, 'parse> Registry<'orig, 'parse> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_target<'reg>(&'reg mut self, body: &'parse str) -> &'reg String {
|
pub(crate) fn get_target<S: Into<String>>(&mut self, body: S) -> &String {
|
||||||
self.targets.entry(body).or_insert_with(|| {
|
self.targets.entry(body.into()).or_insert_with(|| {
|
||||||
self.id_counter += 1;
|
self.id_counter += 1;
|
||||||
format!("target_{}", self.id_counter)
|
format!("target_{}", self.id_counter)
|
||||||
})
|
})
|
||||||
|
@ -3,6 +3,7 @@ use url::Url;
|
|||||||
|
|
||||||
use super::get_web_path;
|
use super::get_web_path;
|
||||||
use super::macros::intermediate;
|
use super::macros::intermediate;
|
||||||
|
use super::IntermediateContext;
|
||||||
|
|
||||||
use super::IObject;
|
use super::IObject;
|
||||||
use crate::context::RenderContext;
|
use crate::context::RenderContext;
|
||||||
@ -30,7 +31,8 @@ intermediate!(
|
|||||||
ret
|
ret
|
||||||
};
|
};
|
||||||
let raw_link = original.get_raw_link();
|
let raw_link = original.get_raw_link();
|
||||||
let target = LinkTarget::from_string(&raw_link)?;
|
let target =
|
||||||
|
LinkTarget::from_string(intermediate_context.clone(), raw_link.clone().into_owned())?;
|
||||||
Ok(IRegularLink {
|
Ok(IRegularLink {
|
||||||
raw_link: raw_link.into_owned(),
|
raw_link: raw_link.into_owned(),
|
||||||
children,
|
children,
|
||||||
@ -47,38 +49,44 @@ pub(crate) enum LinkTarget {
|
|||||||
post_id: Option<String>,
|
post_id: Option<String>,
|
||||||
subpath: String,
|
subpath: String,
|
||||||
},
|
},
|
||||||
|
Target {
|
||||||
|
target_id: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LinkTarget {
|
impl LinkTarget {
|
||||||
pub(crate) fn from_string<S: AsRef<str>>(input: S) -> Result<LinkTarget, CustomError> {
|
pub(crate) fn from_string(
|
||||||
fn impl_from_string(input: &str) -> Result<LinkTarget, CustomError> {
|
intermediate_context: IntermediateContext<'_, '_>,
|
||||||
let parsed = Url::parse(input);
|
input: String,
|
||||||
if let Err(url::ParseError::RelativeUrlWithoutBase) = parsed {
|
) -> Result<LinkTarget, CustomError> {
|
||||||
// For URLs to targets.
|
let parsed = Url::parse(&input);
|
||||||
// TODO: This shouldn't be raw but instead a variant for targets.
|
if let Err(url::ParseError::RelativeUrlWithoutBase) = parsed {
|
||||||
return Ok(LinkTarget::Raw(input.to_owned()));
|
let target_id = {
|
||||||
}
|
let mut registry = intermediate_context.registry.lock().unwrap();
|
||||||
let parsed = parsed?;
|
let target_id = registry.get_target(input).to_owned();
|
||||||
match parsed.scheme() {
|
target_id
|
||||||
"post" => {
|
};
|
||||||
let post_id = parsed.host_str().map(str::to_owned);
|
return Ok(LinkTarget::Target { target_id });
|
||||||
let subpath = {
|
}
|
||||||
let subpath = parsed.path();
|
let parsed = parsed?;
|
||||||
if let Some(subpath) = subpath.strip_prefix('/') {
|
match parsed.scheme() {
|
||||||
subpath
|
"post" => {
|
||||||
} else {
|
let post_id = parsed.host_str().map(str::to_owned);
|
||||||
subpath
|
let subpath = {
|
||||||
}
|
let subpath = parsed.path();
|
||||||
};
|
if let Some(subpath) = subpath.strip_prefix('/') {
|
||||||
Ok(LinkTarget::Post {
|
subpath
|
||||||
post_id,
|
} else {
|
||||||
subpath: subpath.to_owned(),
|
subpath
|
||||||
})
|
}
|
||||||
}
|
};
|
||||||
_ => Ok(LinkTarget::Raw(input.to_owned())),
|
Ok(LinkTarget::Post {
|
||||||
}
|
post_id,
|
||||||
|
subpath: subpath.to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => Ok(LinkTarget::Raw(input.to_owned())),
|
||||||
}
|
}
|
||||||
impl_from_string(input.as_ref())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_final_target(
|
pub(crate) fn generate_final_target(
|
||||||
@ -105,6 +113,14 @@ impl LinkTarget {
|
|||||||
.map_or(Ok(None), |r| r.map(Some))?;
|
.map_or(Ok(None), |r| r.map(Some))?;
|
||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
LinkTarget::Target { target_id } => Ok(Some(format!(
|
||||||
|
"#{}{}",
|
||||||
|
render_context
|
||||||
|
.id_addition
|
||||||
|
.map(|id_addition| format!("sec{}.", id_addition))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
target_id
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user