Flag absolute anchors
This commit is contained in:
parent
1d801dce06
commit
88fdd3084e
6 changed files with 100 additions and 26 deletions
|
|
@ -396,7 +396,7 @@ impl Graph {
|
|||
);
|
||||
} else {
|
||||
if let Some(destination) = anchor.destination()
|
||||
&& !anchor.external()
|
||||
&& !anchor.absolute()
|
||||
{
|
||||
let trimmed_destination = destination
|
||||
.trim_start_matches("/node/")
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ pub fn parse(
|
|||
log!(VERBOSE, "End: Next lexeme is a pipe");
|
||||
buffer.text.push_str(&lexeme.text());
|
||||
candidate.set_text(&buffer.text.clone());
|
||||
if buffer.text.starts_with('/') {
|
||||
candidate.set_absolute(true);
|
||||
}
|
||||
} else {
|
||||
log!(
|
||||
VERBOSE,
|
||||
|
|
@ -84,6 +87,13 @@ pub fn parse(
|
|||
"State: Found a pipe, but no boundary: destination follows"
|
||||
);
|
||||
candidate.set_balanced(true);
|
||||
if lexeme.match_next_first_char('/') {
|
||||
log!(
|
||||
VERBOSE,
|
||||
"State: Destination starts with a dash, marking as absolute"
|
||||
);
|
||||
candidate.set_absolute(true);
|
||||
}
|
||||
return true;
|
||||
} else if lexeme.match_char(':') {
|
||||
log!(VERBOSE, "State: Found a colon, marking anchor as external");
|
||||
|
|
@ -205,8 +215,10 @@ mod tests {
|
|||
fn needless_three_pipe_anchor() {
|
||||
assert_eq!(
|
||||
read("|Node|Destination|"),
|
||||
concat!(r#"<p><a class="detached" title="" "#,
|
||||
r#"href="/node/Destination">Node</a></p>"#)
|
||||
concat!(
|
||||
r#"<p><a class="detached" title="" "#,
|
||||
r#"href="/node/Destination">Node</a></p>"#
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -225,9 +237,11 @@ mod tests {
|
|||
fn anchor_to_node_s() {
|
||||
assert_eq!(
|
||||
read("The |letter s|s|'s node: |s|!"),
|
||||
concat!(r#"<p>The <a class="detached" title="" "#,
|
||||
concat!(
|
||||
r#"<p>The <a class="detached" title="" "#,
|
||||
r#"href="/node/s">letter s</a>'s node: "#,
|
||||
r#"<a class="detached" title="" href="/node/s">s</a>!</p>"#)
|
||||
r#"<a class="detached" title="" href="/node/s">s</a>!</p>"#
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -246,9 +260,11 @@ mod tests {
|
|||
fn leading_plural_anchor() {
|
||||
assert_eq!(
|
||||
read("Interfaces are |element|s of |system|s."),
|
||||
concat!(r#"<p>Interfaces are <a class="detached" title="" "#,
|
||||
concat!(
|
||||
r#"<p>Interfaces are <a class="detached" title="" "#,
|
||||
r#"href="/node/element">elements</a> of <a class="detached" "#,
|
||||
r#"title="" href="/node/system">systems</a>.</p>"#)
|
||||
r#"title="" href="/node/system">systems</a>.</p>"#
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -268,9 +284,11 @@ mod tests {
|
|||
fn explicit_end_of_destination() {
|
||||
assert_eq!(
|
||||
read("interactions are |basic elements|BasicElements| of systems"),
|
||||
concat!(r#"<p>interactions are <a class="detached" title="" "#,
|
||||
concat!(
|
||||
r#"<p>interactions are <a class="detached" title="" "#,
|
||||
r#"href="/node/BasicElements">basic elements</a> of "#,
|
||||
r#"systems</p>"#)
|
||||
r#"systems</p>"#
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -327,6 +345,21 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn absolute_anchor() {
|
||||
let parse_result =
|
||||
parser::rich_read("see the |raw endpoints|/data|.", &Graph::load());
|
||||
println!("Parsed tokens: {:#?}", parse_result.tokens);
|
||||
assert_eq!(
|
||||
parse_result.text.unwrap(),
|
||||
concat!(
|
||||
r#"<p>see the <a class="absolute" title="" "#,
|
||||
r#"href="/data">"#,
|
||||
r#"raw endpoints</a>.</p>"#,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn http_external_anchor() {
|
||||
assert_eq!(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub struct Anchor {
|
|||
node: Option<Node>,
|
||||
leading: bool,
|
||||
balanced: bool,
|
||||
absolute: bool,
|
||||
external: bool,
|
||||
}
|
||||
|
||||
|
|
@ -34,10 +35,17 @@ impl Anchor {
|
|||
self.balanced = balanced;
|
||||
}
|
||||
|
||||
pub const fn absolute(&self) -> bool { self.absolute }
|
||||
|
||||
pub const fn set_absolute(&mut self, absolute: bool) {
|
||||
self.absolute = absolute;
|
||||
}
|
||||
|
||||
pub const fn external(&self) -> bool { self.external }
|
||||
|
||||
pub const fn set_external(&mut self, external: bool) {
|
||||
self.external = external;
|
||||
self.absolute = true;
|
||||
}
|
||||
|
||||
pub const fn set_leading(&mut self, leading: bool) {
|
||||
|
|
@ -58,21 +66,28 @@ impl Anchor {
|
|||
|
||||
fn route(&mut self) {
|
||||
self.destination = if let Some(destination) = self.destination.clone() {
|
||||
if destination.contains(':') || destination.contains('/') {
|
||||
if destination.contains(':') || destination.starts_with('/') {
|
||||
Some(destination)
|
||||
} else if destination.is_empty() && self.text.is_empty() {
|
||||
None
|
||||
} else if destination.is_empty() {
|
||||
self.node_id = Some(self.text.clone());
|
||||
self.node_id = Some(Self::strip_fragment(&self.text));
|
||||
Some(format!("/node/{}", self.text))
|
||||
} else {
|
||||
self.node_id = self.destination.clone();
|
||||
self.node_id = self
|
||||
.destination
|
||||
.clone()
|
||||
.map(|d| Anchor::strip_fragment(&d));
|
||||
Some(format!("/node/{destination}"))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_fragment(target: &str) -> String {
|
||||
target.split('#').next().unwrap_or(target).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Parseable for Anchor {
|
||||
|
|
@ -100,19 +115,31 @@ impl Parseable for Anchor {
|
|||
String::default()
|
||||
};
|
||||
|
||||
let classes = if self.node.is_some() {
|
||||
String::from(r#"class="attached""#)
|
||||
} else if !self.external {
|
||||
String::from(r#"class="detached""#)
|
||||
} else if self.external {
|
||||
let classes = if self.external {
|
||||
String::from(r#"class="external""#)
|
||||
} else if self.absolute {
|
||||
String::from(r#"class="absolute""#)
|
||||
} else if self.node.is_some() {
|
||||
String::from(r#"class="attached""#)
|
||||
} else {
|
||||
String::default()
|
||||
String::from(r#"class="detached""#)
|
||||
};
|
||||
|
||||
let text = if destination.contains('#')
|
||||
&& !self.absolute
|
||||
&& destination == &format!("/node/{}", self.text)
|
||||
{
|
||||
self.text
|
||||
.split('#')
|
||||
.next()
|
||||
.unwrap_or(&self.text)
|
||||
.to_string()
|
||||
} else {
|
||||
self.text.clone()
|
||||
};
|
||||
|
||||
format!(
|
||||
r#"<a {classes} title="{summary}" href="{}">{}</a>"#,
|
||||
destination, self.text,
|
||||
r#"<a {classes} title="{summary}" href="{destination}">{text}</a>"#
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue