feat(node): finish headline inserting functions
This commit is contained in:
parent
89758da638
commit
0e58afada7
|
@ -223,7 +223,10 @@ mod node;
|
||||||
mod org;
|
mod org;
|
||||||
mod parsers;
|
mod parsers;
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
|
||||||
pub use config::ParseConfig;
|
pub use config::ParseConfig;
|
||||||
pub use elements::Element;
|
pub use elements::Element;
|
||||||
pub use node::HeadlineNode;
|
pub use error::OrgizeError;
|
||||||
pub use org::Org;
|
pub use node::{DocumentNode, HeadlineNode};
|
||||||
|
pub use org::{Event, Org};
|
||||||
|
|
280
src/node.rs
280
src/node.rs
|
@ -5,6 +5,7 @@ use crate::config::ParseConfig;
|
||||||
use crate::elements::{Element, Title};
|
use crate::elements::{Element, Title};
|
||||||
use crate::parsers::{parse_container, Container, OwnedArena};
|
use crate::parsers::{parse_container, Container, OwnedArena};
|
||||||
use crate::Org;
|
use crate::Org;
|
||||||
|
use crate::OrgizeError;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct HeadlineNode {
|
pub struct HeadlineNode {
|
||||||
|
@ -14,7 +15,7 @@ pub struct HeadlineNode {
|
||||||
pub(crate) section_node: Option<NodeId>,
|
pub(crate) section_node: Option<NodeId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a: 'b, 'b> HeadlineNode {
|
impl HeadlineNode {
|
||||||
pub(crate) fn new(node: NodeId, level: usize, org: &Org<'_>) -> HeadlineNode {
|
pub(crate) fn new(node: NodeId, level: usize, org: &Org<'_>) -> HeadlineNode {
|
||||||
let title_node = org.arena[node].first_child().unwrap();
|
let title_node = org.arena[node].first_child().unwrap();
|
||||||
let section_node = if let Some(node) = org.arena[title_node].next_sibling() {
|
let section_node = if let Some(node) = org.arena[title_node].next_sibling() {
|
||||||
|
@ -38,7 +39,7 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
self.level
|
self.level
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title(self, org: &'b Org<'a>) -> &'b Title<'a> {
|
pub fn title<'a: 'b, 'b>(self, org: &'b Org<'a>) -> &'b Title<'a> {
|
||||||
if let Element::Title(title) = org.arena[self.title_node].get() {
|
if let Element::Title(title) = org.arena[self.title_node].get() {
|
||||||
title
|
title
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,7 +47,7 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title_mut(self, org: &'b mut Org<'a>) -> &'b mut Title<'a> {
|
pub fn title_mut<'a: 'b, 'b>(self, org: &'b mut Org<'a>) -> &'b mut Title<'a> {
|
||||||
if let Element::Title(title) = org.arena[self.title_node].get_mut() {
|
if let Element::Title(title) = org.arena[self.title_node].get_mut() {
|
||||||
title
|
title
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,7 +55,7 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_title_content<S: Into<Cow<'a, str>>>(self, content: S, org: &mut Org<'a>) {
|
pub fn set_title_content<'a, S: Into<Cow<'a, str>>>(self, content: S, org: &mut Org<'a>) {
|
||||||
let content = content.into();
|
let content = content.into();
|
||||||
|
|
||||||
let children: Vec<_> = self.title_node.children(&org.arena).collect();
|
let children: Vec<_> = self.title_node.children(&org.arena).collect();
|
||||||
|
@ -82,9 +83,13 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.title_mut(org).raw = content;
|
self.title_mut(org).raw = content;
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_section_content<S: Into<Cow<'a, str>>>(self, content: S, org: &mut Org<'a>) {
|
pub fn set_section_content<'a, S: Into<Cow<'a, str>>>(self, content: S, org: &mut Org<'a>) {
|
||||||
let node = if let Some(node) = self.section_node {
|
let node = if let Some(node) = self.section_node {
|
||||||
let children: Vec<_> = node.children(&org.arena).collect();
|
let children: Vec<_> = node.children(&org.arena).collect();
|
||||||
for child in children {
|
for child in children {
|
||||||
|
@ -109,11 +114,15 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
&ParseConfig::default(),
|
&ParseConfig::default(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parent(self, org: &Org<'_>) -> Option<HeadlineNode> {
|
pub fn parent(self, org: &Org<'_>) -> Option<HeadlineNode> {
|
||||||
org.arena[self.node].parent().map(|node| {
|
org.arena[self.node].parent().map(|node| {
|
||||||
if let &Element::Headline { level } = org.arena[node].get() {
|
if let Element::Headline { level } = *org.arena[node].get() {
|
||||||
HeadlineNode::new(node, level, org)
|
HeadlineNode::new(node, level, org)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
@ -121,49 +130,262 @@ impl<'a: 'b, 'b> HeadlineNode {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn children<'c>(self, org: &'c Org<'_>) -> impl Iterator<Item = HeadlineNode> + 'c {
|
||||||
|
self.node.children(&org.arena).filter_map(move |node| {
|
||||||
|
if let Element::Headline { level } = *org.arena[node].get() {
|
||||||
|
Some(HeadlineNode::new(node, level, org))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn previous_headline(self, org: &Org<'_>) -> Option<HeadlineNode> {
|
||||||
|
if let Some(node) = org.arena[self.node].previous_sibling() {
|
||||||
|
if let Element::Headline { level } = *org.arena[node].get() {
|
||||||
|
Some(HeadlineNode::new(node, level, org))
|
||||||
|
} else {
|
||||||
|
debug_assert_eq!(node, self.section_node.unwrap());
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_headline(self, org: &Org<'_>) -> Option<HeadlineNode> {
|
||||||
|
if let Some(node) = org.arena[self.node].next_sibling() {
|
||||||
|
if let Element::Headline { level } = *org.arena[node].get() {
|
||||||
|
Some(HeadlineNode::new(node, level, org))
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn detach(self, org: &mut Org<'_>) {
|
pub fn detach(self, org: &mut Org<'_>) {
|
||||||
self.node.detach(&mut org.arena);
|
self.node.detach(&mut org.arena);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_detached(self, org: &Org<'_>) -> bool {
|
pub fn is_detached(self, org: &Org<'_>) -> bool {
|
||||||
self.parent(&org).is_none()
|
self.parent(&org).is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(self, headline: &HeadlineNode, org: &mut Org<'_>) {
|
fn check_level(self, min: usize, max: Option<usize>) -> Result<(), OrgizeError> {
|
||||||
if self.is_detached(org) || headline.level <= self.level {
|
match max {
|
||||||
// TODO: return an error
|
Some(max) if self.level > max || self.level < min => Err(OrgizeError::HeadlineLevel {
|
||||||
return;
|
min: Some(min),
|
||||||
} else {
|
max: Some(max),
|
||||||
self.node.append(headline.node, &mut org.arena);
|
at: self.node,
|
||||||
|
}),
|
||||||
|
None if self.level < min => Err(OrgizeError::HeadlineLevel {
|
||||||
|
min: Some(min),
|
||||||
|
max: None,
|
||||||
|
at: self.node,
|
||||||
|
}),
|
||||||
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepend(self, headline: &HeadlineNode, org: &mut Org<'_>) {
|
pub fn append(self, headline: HeadlineNode, org: &mut Org<'_>) -> Result<(), OrgizeError> {
|
||||||
if self.is_detached(org) || headline.level <= self.level {
|
if !headline.is_detached(org) {
|
||||||
// TODO: return an error
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
return;
|
}
|
||||||
} else if let Some(node) = self.section_node {
|
|
||||||
|
if let Some(last_headline) = org.headlines().last() {
|
||||||
|
headline.check_level(self.level + 1, Some(last_headline.level))?;
|
||||||
|
} else {
|
||||||
|
headline.check_level(self.level + 1, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.node.append(headline.node, &mut org.arena);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepend(self, headline: HeadlineNode, org: &mut Org<'_>) -> Result<(), OrgizeError> {
|
||||||
|
if !headline.is_detached(org) {
|
||||||
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(first_headline) = self.children(org).next() {
|
||||||
|
headline.check_level(first_headline.level, None)?;
|
||||||
|
} else {
|
||||||
|
headline.check_level(self.level + 1, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(node) = self.section_node {
|
||||||
node.insert_after(headline.node, &mut org.arena);
|
node.insert_after(headline.node, &mut org.arena);
|
||||||
} else {
|
} else {
|
||||||
self.title_node.insert_after(headline.node, &mut org.arena);
|
self.title_node.insert_after(headline.node, &mut org.arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_before(self, headline: &HeadlineNode, org: &mut Org<'_>) {
|
pub fn insert_before(
|
||||||
if self.is_detached(org) || headline.level < self.level {
|
self,
|
||||||
// TODO: return an error
|
headline: HeadlineNode,
|
||||||
return;
|
org: &mut Org<'_>,
|
||||||
} else {
|
) -> Result<(), OrgizeError> {
|
||||||
self.node.insert_after(headline.node, &mut org.arena);
|
if !headline.is_detached(org) {
|
||||||
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(previous) = self.previous_headline(org) {
|
||||||
|
headline.check_level(self.level, Some(previous.level))?;
|
||||||
|
} else {
|
||||||
|
headline.check_level(self.level, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.node.insert_before(headline.node, &mut org.arena);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_after(self, headline: &HeadlineNode, org: &mut Org<'_>) {
|
pub fn insert_after(
|
||||||
if self.is_detached(org) || headline.level < self.level {
|
self,
|
||||||
// TODO: return an error
|
headline: HeadlineNode,
|
||||||
return;
|
org: &mut Org<'_>,
|
||||||
} else {
|
) -> Result<(), OrgizeError> {
|
||||||
self.node.insert_after(headline.node, &mut org.arena);
|
if !headline.is_detached(org) {
|
||||||
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(next) = self.next_headline(org) {
|
||||||
|
headline.check_level(next.level, Some(self.level))?;
|
||||||
|
} else if let Some(parent) = self.parent(org) {
|
||||||
|
headline.check_level(parent.level + 1, Some(self.level))?;
|
||||||
|
} else {
|
||||||
|
headline.check_level(1, Some(self.level))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.node.insert_after(headline.node, &mut org.arena);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct DocumentNode {
|
||||||
|
pub(crate) section_node: Option<NodeId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DocumentNode {
|
||||||
|
pub(crate) fn new(org: &Org<'_>) -> DocumentNode {
|
||||||
|
if let Some(node) = org.arena[org.root].first_child() {
|
||||||
|
if let Element::Section = org.arena[node].get() {
|
||||||
|
DocumentNode {
|
||||||
|
section_node: Some(node),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DocumentNode { section_node: None }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DocumentNode { section_node: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn children<'c>(self, org: &'c Org<'_>) -> impl Iterator<Item = HeadlineNode> + 'c {
|
||||||
|
org.root.children(&org.arena).filter_map(move |node| {
|
||||||
|
if let Element::Headline { level } = *org.arena[node].get() {
|
||||||
|
Some(HeadlineNode::new(node, level, org))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_section_content<'a, S: Into<Cow<'a, str>>>(self, content: S, org: &mut Org<'a>) {
|
||||||
|
let node = if let Some(node) = self.section_node {
|
||||||
|
let children: Vec<_> = node.children(&org.arena).collect();
|
||||||
|
for child in children {
|
||||||
|
child.detach(&mut org.arena);
|
||||||
|
}
|
||||||
|
node
|
||||||
|
} else {
|
||||||
|
let node = org.arena.new_node(Element::Section);
|
||||||
|
org.root.append(node, &mut org.arena);
|
||||||
|
node
|
||||||
|
};
|
||||||
|
|
||||||
|
match content.into() {
|
||||||
|
Cow::Borrowed(content) => parse_container(
|
||||||
|
&mut org.arena,
|
||||||
|
Container::Block { node, content },
|
||||||
|
&ParseConfig::default(),
|
||||||
|
),
|
||||||
|
Cow::Owned(ref content) => parse_container(
|
||||||
|
&mut OwnedArena::new(&mut org.arena),
|
||||||
|
Container::Block { node, content },
|
||||||
|
&ParseConfig::default(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(self, headline: HeadlineNode, org: &mut Org<'_>) -> Result<(), OrgizeError> {
|
||||||
|
if !headline.is_detached(org) {
|
||||||
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(last_headline) = org.headlines().last() {
|
||||||
|
headline.check_level(1, Some(last_headline.level))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
org.root.append(headline.node, &mut org.arena);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepend(self, headline: HeadlineNode, org: &mut Org<'_>) -> Result<(), OrgizeError> {
|
||||||
|
if !headline.is_detached(org) {
|
||||||
|
return Err(OrgizeError::Detached { at: headline.node });
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(first_headline) = self.children(org).next() {
|
||||||
|
headline.check_level(first_headline.level, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(node) = self.section_node {
|
||||||
|
node.insert_after(headline.node, &mut org.arena);
|
||||||
|
} else {
|
||||||
|
org.root.prepend(headline.node, &mut org.arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
96
src/org.rs
96
src/org.rs
|
@ -4,12 +4,12 @@ use std::io::{Error, Write};
|
||||||
use crate::config::ParseConfig;
|
use crate::config::ParseConfig;
|
||||||
use crate::elements::{Element, Title};
|
use crate::elements::{Element, Title};
|
||||||
use crate::export::*;
|
use crate::export::*;
|
||||||
use crate::node::HeadlineNode;
|
use crate::node::{DocumentNode, HeadlineNode};
|
||||||
use crate::parsers::{parse_container, Container};
|
use crate::parsers::{parse_container, Container};
|
||||||
|
|
||||||
pub struct Org<'a> {
|
pub struct Org<'a> {
|
||||||
pub(crate) arena: Arena<Element<'a>>,
|
pub(crate) arena: Arena<Element<'a>>,
|
||||||
root: NodeId,
|
pub(crate) root: NodeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -18,7 +18,7 @@ pub enum Event<'a> {
|
||||||
End(&'a Element<'a>),
|
End(&'a Element<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Org<'_> {
|
impl<'a> Org<'a> {
|
||||||
pub fn new() -> Org<'static> {
|
pub fn new() -> Org<'static> {
|
||||||
let mut arena = Arena::new();
|
let mut arena = Arena::new();
|
||||||
let root = arena.new_node(Element::Document);
|
let root = arena.new_node(Element::Document);
|
||||||
|
@ -26,15 +26,31 @@ impl Org<'_> {
|
||||||
Org { arena, root }
|
Org { arena, root }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(text: &str) -> Org<'_> {
|
pub fn parse(text: &'a str) -> Org<'a> {
|
||||||
Org::parse_with_config(text, &ParseConfig::default())
|
Org::parse_with_config(text, &ParseConfig::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = Event<'_>> + '_ {
|
pub fn parse_with_config(content: &'a str, config: &ParseConfig) -> Org<'a> {
|
||||||
self.root.traverse(&self.arena).map(move |edge| match edge {
|
let mut org = Org::new();
|
||||||
NodeEdge::Start(e) => Event::Start(self.arena[e].get()),
|
|
||||||
NodeEdge::End(e) => Event::End(self.arena[e].get()),
|
parse_container(
|
||||||
})
|
&mut org.arena,
|
||||||
|
Container::Document {
|
||||||
|
content,
|
||||||
|
node: org.root,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
org.check().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
org
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn document(&self) -> DocumentNode {
|
||||||
|
DocumentNode::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn headlines(&self) -> impl Iterator<Item = HeadlineNode> + '_ {
|
pub fn headlines(&self) -> impl Iterator<Item = HeadlineNode> + '_ {
|
||||||
|
@ -47,6 +63,33 @@ impl Org<'_> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn arena(&self) -> &Arena<Element<'a>> {
|
||||||
|
&self.arena
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_headline(&mut self, title: Title<'a>) -> HeadlineNode {
|
||||||
|
let level = title.level;
|
||||||
|
let title_raw = title.raw.clone();
|
||||||
|
let headline_node = self.arena.new_node(Element::Headline { level });
|
||||||
|
let title_node = self.arena.new_node(Element::Title(title));
|
||||||
|
headline_node.append(title_node, &mut self.arena);
|
||||||
|
let headline_node = HeadlineNode {
|
||||||
|
node: headline_node,
|
||||||
|
level,
|
||||||
|
title_node,
|
||||||
|
section_node: None,
|
||||||
|
};
|
||||||
|
headline_node.set_title_content(title_raw, self);
|
||||||
|
headline_node
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = Event<'_>> + '_ {
|
||||||
|
self.root.traverse(&self.arena).map(move |edge| match edge {
|
||||||
|
NodeEdge::Start(e) => Event::Start(self.arena[e].get()),
|
||||||
|
NodeEdge::End(e) => Event::End(self.arena[e].get()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn html<W: Write>(&self, wrtier: W) -> Result<(), Error> {
|
pub fn html<W: Write>(&self, wrtier: W) -> Result<(), Error> {
|
||||||
self.html_with_handler(wrtier, DefaultHtmlHandler)
|
self.html_with_handler(wrtier, DefaultHtmlHandler)
|
||||||
}
|
}
|
||||||
|
@ -88,41 +131,6 @@ impl Org<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Org<'a> {
|
|
||||||
pub fn parse_with_config(content: &'a str, config: &ParseConfig) -> Org<'a> {
|
|
||||||
let mut org = Org::new();
|
|
||||||
|
|
||||||
parse_container(
|
|
||||||
&mut org.arena,
|
|
||||||
Container::Document {
|
|
||||||
content,
|
|
||||||
node: org.root,
|
|
||||||
},
|
|
||||||
config,
|
|
||||||
);
|
|
||||||
|
|
||||||
org
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_headline(&mut self, title: Title<'a>) -> HeadlineNode {
|
|
||||||
let title_level = title.level;
|
|
||||||
let title_raw = title.raw.clone();
|
|
||||||
let headline_node = self
|
|
||||||
.arena
|
|
||||||
.new_node(Element::Headline { level: title_level });
|
|
||||||
let title_node = self.arena.new_node(Element::Title(title));
|
|
||||||
headline_node.append(title_node, &mut self.arena);
|
|
||||||
let headline_node = HeadlineNode {
|
|
||||||
node: headline_node,
|
|
||||||
level: title_level,
|
|
||||||
title_node,
|
|
||||||
section_node: None,
|
|
||||||
};
|
|
||||||
headline_node.set_title_content(title_raw, self);
|
|
||||||
headline_node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "ser")]
|
#[cfg(feature = "ser")]
|
||||||
use serde::{ser::Serializer, Serialize};
|
use serde::{ser::Serializer, Serialize};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
use orgize::elements::Title;
|
||||||
use orgize::Org;
|
use orgize::Org;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
use serde_json::to_string;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_content() {
|
fn set_content() {
|
||||||
|
@ -22,3 +24,45 @@ section 1
|
||||||
<h2>a <b>bold</b> title</h2><section><p>and a <u>underline</u> section</p></section></main>"
|
<h2>a <b>bold</b> title</h2><section><p>and a <u>underline</u> section</p></section></main>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert() {
|
||||||
|
let mut org = Org::new();
|
||||||
|
let document = org.document();
|
||||||
|
|
||||||
|
let h1 = org.new_headline(Title {
|
||||||
|
level: 1,
|
||||||
|
raw: "title".into(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
h1.set_section_content("section", &mut org);
|
||||||
|
document.prepend(h1, &mut org).unwrap();
|
||||||
|
dbg!(to_string(&org).unwrap());
|
||||||
|
|
||||||
|
let h3 = org.new_headline(Title {
|
||||||
|
level: 3,
|
||||||
|
raw: "title".into(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
h3.set_section_content("section", &mut org);
|
||||||
|
document.prepend(h3, &mut org).unwrap();
|
||||||
|
dbg!(to_string(&org).unwrap());
|
||||||
|
|
||||||
|
let h2 = org.new_headline(Title {
|
||||||
|
level: 2,
|
||||||
|
raw: "title".into(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
h2.set_section_content("section", &mut org);
|
||||||
|
h1.insert_before(h2, &mut org).unwrap();
|
||||||
|
dbg!(to_string(&org).unwrap());
|
||||||
|
|
||||||
|
let mut writer = Vec::new();
|
||||||
|
org.html(&mut writer).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
String::from_utf8(writer).unwrap(),
|
||||||
|
"<main><h3>title</h3><section><p>section</p></section>\
|
||||||
|
<h2>title</h2><section><p>section</p></section>\
|
||||||
|
<h1>title</h1><section><p>section</p></section></main>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue