feat(node): more headline operations

This commit is contained in:
PoiScript 2019-08-11 11:40:52 +08:00
parent f2d0a1dd2d
commit 5db7ec7465
9 changed files with 311 additions and 48 deletions

View file

@ -2,7 +2,7 @@ use indextree::{Arena, NodeEdge, NodeId};
use std::io::{Error, Write};
use crate::config::ParseConfig;
use crate::elements::Element;
use crate::elements::{Element, Title};
use crate::export::*;
use crate::node::HeadlineNode;
use crate::parsers::{parse_container, Container};
@ -19,17 +19,15 @@ pub enum Event<'a> {
}
impl Org<'_> {
pub fn parse(text: &str) -> Org<'_> {
Org::parse_with_config(text, &ParseConfig::default())
pub fn new() -> Org<'static> {
let mut arena = Arena::new();
let root = arena.new_node(Element::Document);
Org { arena, root }
}
pub fn parse_with_config<'a>(content: &'a str, config: &ParseConfig) -> Org<'a> {
let mut arena = Arena::new();
let node = arena.new_node(Element::Document);
parse_container(&mut arena, Container::Document { content, node }, config);
Org { arena, root: node }
pub fn parse(text: &str) -> Org<'_> {
Org::parse_with_config(text, &ParseConfig::default())
}
pub fn iter(&self) -> impl Iterator<Item = Event<'_>> + '_ {
@ -44,7 +42,7 @@ impl Org<'_> {
.descendants(&self.arena)
.skip(1)
.filter_map(move |node| match self.arena[node].get() {
Element::Headline => Some(HeadlineNode(node)),
&Element::Headline { level } => Some(HeadlineNode::new(node, level, self)),
_ => None,
})
}
@ -90,6 +88,41 @@ 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")]
use serde::{ser::Serializer, Serialize};