mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 00:00:56 +00:00
fix(html2md): keep preformatted blocks as markdown code
This commit is contained in:
@@ -37,6 +37,30 @@ pub(crate) fn contains<D: Dom + ?Sized>(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn within<D: Dom + ?Sized>(
|
||||
dom: &D,
|
||||
root: D::NodeId,
|
||||
limit: usize,
|
||||
ids: &HashSet<String>,
|
||||
) -> Vec<String> {
|
||||
let mut found = Vec::new();
|
||||
walk(dom, root, limit, |node| {
|
||||
for attribute in ["id", "name"] {
|
||||
if attribute == "name" && dom.node_kind(node) != NodeKind::Element("a") {
|
||||
continue;
|
||||
}
|
||||
if let Some(id) = dom.attribute(node, attribute)
|
||||
&& ids.contains(id)
|
||||
&& !found.iter().any(|existing| existing == id)
|
||||
{
|
||||
found.push(id.to_owned());
|
||||
}
|
||||
}
|
||||
false
|
||||
});
|
||||
found
|
||||
}
|
||||
|
||||
fn walk<D: Dom + ?Sized>(
|
||||
dom: &D,
|
||||
root: D::NodeId,
|
||||
|
||||
+19
-13
@@ -354,14 +354,15 @@ impl<'a, D: Dom + ?Sized> Machine<'a, D> {
|
||||
}
|
||||
"code" | "pre" => {
|
||||
let remaining = self.options.max_depth - depth;
|
||||
if subtree_has_link(self.dom, node, remaining)
|
||||
|| (!self.anchor_targets.is_empty()
|
||||
&& crate::anchors::contains(
|
||||
self.dom,
|
||||
node,
|
||||
remaining,
|
||||
&self.anchor_targets,
|
||||
))
|
||||
if tag == "code"
|
||||
&& (subtree_has_link(self.dom, node, remaining)
|
||||
|| (!self.anchor_targets.is_empty()
|
||||
&& crate::anchors::contains(
|
||||
self.dom,
|
||||
node,
|
||||
remaining,
|
||||
&self.anchor_targets,
|
||||
)))
|
||||
{
|
||||
let html = crate::html_table::render(
|
||||
self.dom,
|
||||
@@ -370,13 +371,18 @@ impl<'a, D: Dom + ?Sized> Machine<'a, D> {
|
||||
self.options.max_depth,
|
||||
&self.anchor_targets,
|
||||
);
|
||||
if tag == "pre" {
|
||||
self.writer().block(html.into(), 2, 2);
|
||||
} else {
|
||||
self.writer().inline_html(&html);
|
||||
}
|
||||
self.writer().inline_html(&html);
|
||||
return;
|
||||
}
|
||||
if tag == "pre" && !self.anchor_targets.is_empty() {
|
||||
for id in
|
||||
crate::anchors::within(self.dom, node, remaining, &self.anchor_targets)
|
||||
{
|
||||
if self.emitted_anchors.insert(id.clone()) {
|
||||
self.writer().inline_html(&crate::anchors::markup(&id));
|
||||
}
|
||||
}
|
||||
}
|
||||
self.raw.clear();
|
||||
let end = if tag == "pre" {
|
||||
Task::EndPre(self.language(node))
|
||||
|
||||
@@ -867,6 +867,8 @@ fn html_fallback_preserves_referenced_targets_for_special_nodes() {
|
||||
false,
|
||||
);
|
||||
assert!(code.contains("<a id=\"L1\"></a>"), "{code}");
|
||||
assert!(code.contains("```\nlet x = 1;\n```"), "{code}");
|
||||
assert!(!code.contains("<pre>"), "{code}");
|
||||
let table = markdown(
|
||||
"<a href='#email'>Email</a><a href='#eq1'>Equation</a><a href='#video1'>Video</a><table><tr><td><input id='email' value='a@example.test'></td><td><math id='eq1'><mi>x</mi></math></td><td><video id='video1' src='/clip.mp4'></video></td></tr></table>",
|
||||
false,
|
||||
@@ -888,18 +890,15 @@ fn invalid_nested_and_empty_headings_do_not_emit_literal_markers() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preformatted_navigation_retains_link_targets() {
|
||||
fn preformatted_navigation_retains_literal_content_as_markdown_code() {
|
||||
let result = markdown(
|
||||
"<pre>ALL GAMES: <a href='home.shtml'>HOME GAMES</a> : <a href='away.shtml'>AWAY GAMES</a>\nScores stay aligned</pre>",
|
||||
false,
|
||||
);
|
||||
assert!(result.contains("<pre>"), "{result}");
|
||||
assert!(result.starts_with("```\n"), "{result}");
|
||||
assert!(!result.contains("<pre>"), "{result}");
|
||||
assert!(
|
||||
result.contains("<a href=\"home.shtml\">HOME GAMES</a>"),
|
||||
"{result}"
|
||||
);
|
||||
assert!(
|
||||
result.contains("<a href=\"away.shtml\">AWAY GAMES</a>"),
|
||||
result.contains("ALL GAMES: HOME GAMES : AWAY GAMES"),
|
||||
"{result}"
|
||||
);
|
||||
assert!(result.contains("Scores stay aligned"), "{result}");
|
||||
@@ -912,10 +911,12 @@ fn preformatted_code_preserves_externally_referenced_targets() {
|
||||
false,
|
||||
);
|
||||
assert!(result.contains("[Line 1](#L1)"), "{result}");
|
||||
assert!(result.contains("<a id=\"L1\"></a>"), "{result}");
|
||||
assert!(
|
||||
result.contains("<span id=\"L1\">let x = 1;</span>"),
|
||||
result.contains("```\nlet x = 1;\nlet y = 2;\n```"),
|
||||
"{result}"
|
||||
);
|
||||
assert!(!result.contains("<pre>"), "{result}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user