Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 29 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,45 +162,38 @@ Or you can parse the input into an AST yourself, manipulate it, and then use you

``` rust
extern crate comrak;
use comrak::{parse_document, format_html, Arena, Options};
use comrak::nodes::{AstNode, NodeValue};

// The returned nodes are created in the supplied Arena, and are bound by its lifetime.
let arena = Arena::new();

let root = parse_document(
&arena,
"This is my input.\n\n1. Also my input.\n2. Certainly my input.\n",
&Options::default());

fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F)
where F : Fn(&'a AstNode<'a>) {
f(node);
for c in node.children() {
iter_nodes(c, f);
}
}
use comrak::nodes::NodeValue;
use comrak::{format_html, parse_document, Arena, Options};

fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String {
// The returned nodes are created in the supplied Arena, and are bound by its lifetime.
let arena = Arena::new();

iter_nodes(root, &|node| {
match &mut node.data.borrow_mut().value {
&mut NodeValue::Text(ref mut text) => {
let orig = std::mem::replace(text, vec![]);
*text = String::from_utf8(orig).unwrap().replace("my", "your").as_bytes().to_vec();
// Parse the document into a root `AstNode`
let root = parse_document(&arena, document, &Options::default());

// Iterate over all the descendants of root.
for node in root.descendants() {
if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
// If the node is a text node, perform the string replacement.
*text = text.replace(orig_string, replacement)
}
_ => (),
}
});

let mut html = vec![];
format_html(root, &Options::default(), &mut html).unwrap();

assert_eq!(
String::from_utf8(html).unwrap(),
"<p>This is your input.</p>\n\
<ol>\n\
<li>Also your input.</li>\n\
<li>Certainly your input.</li>\n\
</ol>\n");

let mut html = vec![];
format_html(root, &Options::default(), &mut html).unwrap();

String::from_utf8(html).unwrap()
}

fn main() {
let doc = "This is my input.\n\n1. Also [my](#) input.\n2. Certainly *my* input.\n";
let orig = "my";
let repl = "your";
let html = replace_text(&doc, &orig, &repl);

println!("{}", html);
}
```

## Benchmarking
Expand Down
52 changes: 52 additions & 0 deletions examples/iterator_replace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
extern crate comrak;
use comrak::nodes::NodeValue;
use comrak::{format_html, parse_document, Arena, Options};
use ntest::{assert_false, assert_true};

fn replace_text(document: &str, orig_string: &str, replacement: &str) -> String {
// The returned nodes are created in the supplied Arena, and are bound by its lifetime.
let arena = Arena::new();

// Parse the document into a root `AstNode`
let root = parse_document(&arena, document, &Options::default());

// Iterate over all the descendants of root.
for node in root.descendants() {
if let NodeValue::Text(ref mut text) = node.data.borrow_mut().value {
// If the node is a text node, replace `orig_string` with `replacement`.
*text = text.replace(orig_string, replacement)
}
}

let mut html = vec![];
format_html(root, &Options::default(), &mut html).unwrap();

String::from_utf8(html).unwrap()
}

fn main() {
let doc = "This is my input.\n\n1. Also [my](#) input.\n2. Certainly *my* input.\n";
let orig = "my";
let repl = "your";
let html = replace_text(&doc, &orig, &repl);

println!("{}", html);
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn sample_replace() {
let doc = "Replace deeply nested *[foo](https://example.com)* with bar.\n\nReplace shallow foo with bar.";
let orig = "foo";
let repl = "bar";
let html = replace_text(&doc, &orig, &repl);
println!("{:?}", html);
assert_false!(html.contains("foo"));
assert_true!(html.contains("bar"));
assert_true!(html.contains("<a"));
assert_true!(html.contains("<p"));
}
}