Struct concisemark::Page
source · pub struct Page {
pub meta: Option<Meta>,
pub ast: Node,
pub content: String,
pub options: Option<PageOptions>,
}
Expand description
A markdown page
Fields§
§meta: Option<Meta>
Meta information for the page, such as author, tags …
ast: Node
Page AST (abstract syntax tree), see Page::transform
to learn how to modify it
content: String
The markdown file content (with meta
stripped). ast
does not store any text but only node range,
and content is necessary to retrive node text with ast
information.
options: Option<PageOptions>
Page options, a placehodler for future usage
Implementations§
source§impl Page
impl Page
pub fn with_options(self, options: PageOptions) -> Self
sourcepub fn render(&self) -> String
pub fn render(&self) -> String
Render markdown into HTML page
use concisemark::Page;
let content = "# Title";
let page = Page::new(content);
let html = page.render();
The output html will be
<div><h1>Title</h1></div>
sourcepub fn render_latex(&self) -> String
pub fn render_latex(&self) -> String
Render markdown into XeLaTex source
Note that latex can not embed image from url, you must download the image and fix the image path to generate a working tex file, the following is a dirty and quick example.
use concisemark::Page;
use concisemark::node::Node;
use concisemark::node::NodeTagName;
use concisemark::utils;
use std::fs::OpenOptions;
use std::process::Command;
use std::io::Write;
use indoc::indoc;
let content = indoc! {r#"
![animal-online](https://cn.bing.com/th?id=OHR.NorwayMuskox_EN-CN7806818932_1920x1080.jpg&w=720)
![animal-offlie](assets/th.jpg)
"#
};
let manifest_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
let draft_dir = manifest_dir.join("draft");
std::fs::create_dir_all(draft_dir.as_path()).unwrap();
let page = Page::new(content);
let hook = |node: &Node| -> Result<(), ()> {
let mut nodedata = node.data.borrow_mut();
if nodedata.tag.name == NodeTagName::Image {
let src = nodedata.tag.attrs.get("src").unwrap().to_owned();
let name = nodedata.tag.attrs.get("name").unwrap().to_owned();
let output_path;
if src.starts_with("https://") || src.starts_with("http://") {
output_path = utils::download_image_fs(src, draft_dir.as_path(), name).unwrap();
} else {
output_path = manifest_dir.join(src);
}
nodedata.tag.attrs.insert("src".to_owned(), format!("{}", output_path.display()));
}
Ok(())
};
page.transform(hook);
let setup = include_str!("../assets/setup.tex");
let wanted = indoc! {r#"
\begin{document}
\begin{figure}[H]
\centerline{\includegraphics[width=0.7\textwidth]{PLACEHOLDER_ONLINE}}
\caption{animal-online}
\end{figure}
\begin{figure}[H]
\centerline{\includegraphics[width=0.7\textwidth]{PLACEHOLDER_OFFLINE}}
\caption{animal-offlie}
\end{figure}
\end{document}
"#};
let wanted = wanted.replace(
"PLACEHOLDER_ONLINE",
&format!("{}", manifest_dir.join("draft").join("animal-online.jpg").display())
).replace(
"PLACEHOLDER_OFFLINE",
&format!("{}", manifest_dir.join("assets").join("th.jpg").display())
);
let pagesrc = &page.render_latex()[setup.len()..];
assert_eq!(wanted.trim(), pagesrc.trim());
let latex = page.render_latex();
let texfile = draft_dir.join("output.tex");
let mut f = OpenOptions::new().truncate(true).write(true).create(true).open(&texfile).unwrap();
f.write(latex.as_bytes()).unwrap();
let mut cmd = Command::new("xelatex");
cmd.current_dir(&draft_dir);
cmd.arg(&texfile);
_ = cmd.output();
sourcepub fn render_with_hook<F>(&self, hook: &F) -> String
pub fn render_with_hook<F>(&self, hook: &F) -> String
Render markdown into HTML page with hook
If the hook returns None, then the default rendering function will be used or else use the returned value as render result.
sourcepub fn transform<F, E>(&self, hook: F)
pub fn transform<F, E>(&self, hook: F)
Modify markdown AST node with hook.
The error status of the hook function (when returns an Err) will not stop the transform process, instead it will print the error as a log message.
The following is an exmaple to change image url
use concisemark::node::{Node, NodeTagName};
use concisemark::Page;
let content = "![imgs](/path/to/image.jpg)";
let page = Page::new(content);
let hook = |node: &Node| -> Result<(), ()> {
let mut nodedata = node.data.borrow_mut();
if nodedata.tag.name == NodeTagName::Image {
let src = nodedata.tag.attrs.get("src").unwrap().to_owned();
let src = if src.starts_with("/") {
format!("https://example.com{src}")
} else {
format!("https://example.com/{src}")
};
nodedata.tag.attrs.insert("src".to_owned(), src);
}
Ok(())
};
let img = &page.ast.children()[0].children()[0];
assert_eq!(img.data.borrow().tag.attrs.get("src").map(|s| s.as_str()), Some("/path/to/image.jpg"));
page.transform(hook);
assert_eq!(img.data.borrow().tag.attrs.get("src").map(|s| s.as_str()), Some("https://example.com/path/to/image.jpg"));