Introduce the document structure.
This commit is contained in:
parent
35d60c10ba
commit
d98a11059c
@ -1 +0,0 @@
|
|||||||
Two line breaks to end paragraph except in code blocks
|
|
23
org_mode_samples/sections_and_headings/Makefile
Normal file
23
org_mode_samples/sections_and_headings/Makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
SHELL := bash
|
||||||
|
.ONESHELL:
|
||||||
|
.SHELLFLAGS := -eu -o pipefail -c
|
||||||
|
.DELETE_ON_ERROR:
|
||||||
|
MAKEFLAGS += --warn-undefined-variables
|
||||||
|
MAKEFLAGS += --no-builtin-rules
|
||||||
|
SRCFILES := $(wildcard *.org)
|
||||||
|
OUTFILES := $(patsubst %.org,%.tree.txt,$(SRCFILES))
|
||||||
|
|
||||||
|
ifeq ($(origin .RECIPEPREFIX), undefined)
|
||||||
|
$(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
|
||||||
|
endif
|
||||||
|
.RECIPEPREFIX = >
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: $(OUTFILES)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
> rm -rf $(OUTFILES)
|
||||||
|
|
||||||
|
%.tree.txt: %.org ../common.el ../dump_org_ast.bash
|
||||||
|
> ../dump_org_ast.bash $< $@
|
@ -0,0 +1 @@
|
|||||||
|
* Start a document with an immediate heading
|
@ -0,0 +1,7 @@
|
|||||||
|
Before the first heading
|
||||||
|
* The first heading
|
||||||
|
body of the first section
|
||||||
|
** Child heading
|
||||||
|
body of child heading
|
||||||
|
* second top-level heading
|
||||||
|
body of second top-level heading
|
@ -1,4 +1,4 @@
|
|||||||
use crate::parser::document;
|
// use crate::parser::document;
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
use tracing_subscriber::fmt::format::FmtSpan;
|
use tracing_subscriber::fmt::format::FmtSpan;
|
||||||
|
|
||||||
@ -18,8 +18,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.with_span_events(FmtSpan::ENTER | FmtSpan::EXIT)
|
.with_span_events(FmtSpan::ENTER | FmtSpan::EXIT)
|
||||||
.finish();
|
.finish();
|
||||||
tracing::subscriber::set_global_default(subscriber)?;
|
tracing::subscriber::set_global_default(subscriber)?;
|
||||||
let parsed = document(TEST_DOC);
|
// let parsed = document(TEST_DOC);
|
||||||
println!("{}\n\n\n", TEST_DOC);
|
// println!("{}\n\n\n", TEST_DOC);
|
||||||
println!("{:#?}", parsed);
|
// println!("{:#?}", parsed);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,42 @@
|
|||||||
//! A single element of text.
|
use super::element::Element;
|
||||||
use super::combinator::context_many1;
|
use super::source::Source;
|
||||||
use super::error::Res;
|
|
||||||
use super::paragraph::paragraph;
|
|
||||||
use super::parser_context::ContextElement;
|
|
||||||
use super::parser_context::ContextTree;
|
|
||||||
use super::token::Paragraph;
|
|
||||||
use super::token::Token;
|
|
||||||
use super::Context;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
type UnboundMatcher<'r, 's, I, O, E> = dyn Fn(Context<'r, 's>, I) -> IResult<I, O, E>;
|
#[derive(Debug)]
|
||||||
|
pub struct Document<'s> {
|
||||||
// TODO: Implement FromStr for Document
|
pub source: &'s str,
|
||||||
|
pub zeroth_section: Option<Section<'s>>,
|
||||||
pub fn document(input: &str) -> Res<&str, Vec<Paragraph>> {
|
pub children: Vec<Heading<'s>>,
|
||||||
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
}
|
||||||
let document_context =
|
|
||||||
initial_context.with_additional_node(ContextElement::DocumentRoot(input));
|
#[derive(Debug)]
|
||||||
let (remaining, tokens) = context_many1(&document_context, paragraph)(input)?;
|
pub struct Heading<'s> {
|
||||||
let paragraphs = tokens
|
pub source: &'s str,
|
||||||
.into_iter()
|
pub children: Vec<DocumentElement<'s>>,
|
||||||
.map(|token| match token {
|
}
|
||||||
Token::TextElement(_) => unreachable!(),
|
|
||||||
Token::Paragraph(paragraph) => paragraph,
|
#[derive(Debug)]
|
||||||
})
|
pub struct Section<'s> {
|
||||||
.collect();
|
pub source: &'s str,
|
||||||
Ok((remaining, paragraphs))
|
pub children: Vec<Element<'s>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DocumentElement<'s> {
|
||||||
|
Heading(Heading<'s>),
|
||||||
|
Section(Section<'s>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> Source<'s> for Document<'s> {
|
||||||
|
fn get_source(&'s self) -> &'s str {
|
||||||
|
self.source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> Source<'s> for DocumentElement<'s> {
|
||||||
|
fn get_source(&'s self) -> &'s str {
|
||||||
|
match self {
|
||||||
|
DocumentElement::Heading(obj) => obj.source,
|
||||||
|
DocumentElement::Section(obj) => obj.source,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
use super::greater_element::PlainList;
|
use super::greater_element::PlainList;
|
||||||
use super::lesser_element::Paragraph;
|
use super::lesser_element::Paragraph;
|
||||||
|
use super::source::Source;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Element<'s> {
|
pub enum Element<'s> {
|
||||||
Paragraph(Paragraph<'s>),
|
Paragraph(Paragraph<'s>),
|
||||||
PlainList(PlainList<'s>),
|
PlainList(PlainList<'s>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'s> Source<'s> for Element<'s> {
|
||||||
|
fn get_source(&'s self) -> &'s str {
|
||||||
|
match self {
|
||||||
|
Element::Paragraph(obj) => obj.source,
|
||||||
|
Element::PlainList(obj) => obj.source,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,10 +12,10 @@ mod paragraph;
|
|||||||
mod parser_context;
|
mod parser_context;
|
||||||
mod parser_with_context;
|
mod parser_with_context;
|
||||||
mod plain_list;
|
mod plain_list;
|
||||||
|
mod source;
|
||||||
mod text;
|
mod text;
|
||||||
mod token;
|
mod token;
|
||||||
mod util;
|
mod util;
|
||||||
pub use document::document;
|
|
||||||
type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;
|
type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;
|
||||||
pub use parser_context::ContextTree;
|
pub use parser_context::ContextTree;
|
||||||
pub use plain_list::item;
|
pub use plain_list::item;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
pub trait Source<'s> {
|
use super::source::Source;
|
||||||
fn get_source(&'s self) -> &'s str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Object<'s> {
|
pub enum Object<'s> {
|
||||||
|
29
src/parser/old_document.rs
Normal file
29
src/parser/old_document.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//! A single element of text.
|
||||||
|
use super::combinator::context_many1;
|
||||||
|
use super::error::Res;
|
||||||
|
use super::paragraph::paragraph;
|
||||||
|
use super::parser_context::ContextElement;
|
||||||
|
use super::parser_context::ContextTree;
|
||||||
|
use super::token::Paragraph;
|
||||||
|
use super::token::Token;
|
||||||
|
use super::Context;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
|
type UnboundMatcher<'r, 's, I, O, E> = dyn Fn(Context<'r, 's>, I) -> IResult<I, O, E>;
|
||||||
|
|
||||||
|
// TODO: Implement FromStr for Document
|
||||||
|
|
||||||
|
pub fn document(input: &str) -> Res<&str, Vec<Paragraph>> {
|
||||||
|
let initial_context: ContextTree<'_, '_> = ContextTree::new();
|
||||||
|
let document_context =
|
||||||
|
initial_context.with_additional_node(ContextElement::DocumentRoot(input));
|
||||||
|
let (remaining, tokens) = context_many1(&document_context, paragraph)(input)?;
|
||||||
|
let paragraphs = tokens
|
||||||
|
.into_iter()
|
||||||
|
.map(|token| match token {
|
||||||
|
Token::TextElement(_) => unreachable!(),
|
||||||
|
Token::Paragraph(paragraph) => paragraph,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok((remaining, paragraphs))
|
||||||
|
}
|
3
src/parser/source.rs
Normal file
3
src/parser/source.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub trait Source<'s> {
|
||||||
|
fn get_source(&'s self) -> &'s str;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user