aboutsummaryrefslogtreecommitdiffstats
path: root/src/document_tree
diff options
context:
space:
mode:
authorPhil Schaf2015-11-14 20:13:45 +0100
committerPhil Schaf2015-11-14 20:13:45 +0100
commit5fdb21df228c78061cce9ee910fa87da0fd99d46 (patch)
tree707d234259202381be0c784e8f1efea8eb5081ec /src/document_tree
parent9c2f818b7e7139ed7a5da573d1cc104defa7579f (diff)
downloadrust-rst-5fdb21df228c78061cce9ee910fa87da0fd99d46.tar.bz2
redesign
Diffstat (limited to 'src/document_tree')
-rw-r--r--src/document_tree/attribute_types.rs25
-rw-r--r--src/document_tree/element_categories.rs59
-rw-r--r--src/document_tree/element_types.rs96
-rw-r--r--src/document_tree/elements.rs207
-rw-r--r--src/document_tree/extra_attributes.rs56
-rw-r--r--src/document_tree/mod.rs21
6 files changed, 464 insertions, 0 deletions
diff --git a/src/document_tree/attribute_types.rs b/src/document_tree/attribute_types.rs
new file mode 100644
index 0000000..83ce618
--- /dev/null
+++ b/src/document_tree/attribute_types.rs
@@ -0,0 +1,25 @@
+#[derive(Debug)]
+pub enum EnumeratedListType {
+ Arabic,
+ LowerAlpha,
+ UpperAlpha,
+ LowerRoman,
+ UpperRoman,
+}
+
+#[derive(Debug)]
+pub enum FixedSpace { Default, Preserve } // yes, default really is not “Default”
+impl Default for FixedSpace { fn default() -> FixedSpace { FixedSpace::Preserve } }
+
+#[derive(Debug)] pub enum AlignH { Left, Center, Right}
+#[derive(Debug)] pub enum AlignHV { Top, Middle, Bottom, Left, Center, Right }
+
+#[derive(Debug)] pub struct ID(String);
+#[derive(Debug)] pub struct NameToken(String);
+
+#[derive(Debug)]
+pub enum Measure {
+ Pixel(usize),
+ Em(usize),
+ //TODO
+}
diff --git a/src/document_tree/element_categories.rs b/src/document_tree/element_categories.rs
new file mode 100644
index 0000000..5f12cc6
--- /dev/null
+++ b/src/document_tree/element_categories.rs
@@ -0,0 +1,59 @@
+use super::elements::*;
+
+pub trait HasChildren<C> {
+ fn add_child<R: Into<C>>(&mut self, R);
+}
+
+macro_rules! synonymous_enum {( $name:ident { $( $entry:ident ),* } ) => (
+ #[derive(Debug)]
+ pub enum $name {
+ $(
+ $entry($entry),
+ )*
+ }
+
+ $(
+ impl Into<$name> for $entry {
+ fn into(self) -> $name {
+ $name::$entry(self)
+ }
+ }
+ )*
+)}
+
+synonymous_enum!(SubStructure { Topic, Sidebar, Transition, Section, BodyElement });
+synonymous_enum!(StructuralSubElement { Title, Subtitle, Decoration, Docinfo, Transition, SubStructure });
+synonymous_enum!(BodyElement {
+ //Simple
+ Paragraph, LiteralBlock, DoctestBlock, MathBlock, Rubric, SubstitutionDefinition, Comment, Pending, Target, Raw, Image,
+ //Compound
+ Compound, Container,
+ BulletList, EnumeratedList, DefinitionList, FieldList, OptionList,
+ LineBlock, BlockQuote, Admonition, Attention, Hint, Note, Caution, Danger, Error, Important, Tip, Warning, Footnote, Citation, SystemMessage, Figure, Table
+});
+
+synonymous_enum!(BibliographicElement { Author, Authors, Organization, Address, Contact, Version, Revision, Status, Date, Copyright, Field });
+
+synonymous_enum!(TextOrInlineElement {
+ TextElement, Emphasis, Strong, Literal, Reference, FootnoteReference, CitationReference, SubstitutionReference, TitleReference, Abbreviation, Acronym, Superscript, Subscript, Inline, Problematic, Generated, Math,
+ //also have non-inline versions. Inline image is no figure child, inline target has content
+ TargetInline, RawInline, ImageInline
+});
+
+//--------------\\
+//Content Models\\
+//--------------\\
+
+synonymous_enum!(SubSection { Title, Subtitle, Docinfo, Decoration, SubStructure, BodyElement });
+synonymous_enum!(AuthorInfo { Author, Organization, Address, Contact });
+synonymous_enum!(DecorationElement { Header, Footer });
+synonymous_enum!(SubTopic { Title, BodyElement });
+synonymous_enum!(SubSidebar { Topic, Title, Subtitle, BodyElement });
+synonymous_enum!(SubDLItem { Term, Classifier, Definition });
+synonymous_enum!(SubField { FieldName, FieldBody });
+synonymous_enum!(SubOptionListItem { OptionGroup, Description });
+synonymous_enum!(SubOption { OptionString, OptionArgument });
+synonymous_enum!(SubLineBlock { LineBlock, Line });
+synonymous_enum!(SubBlockQuote { Attribution, BodyElement });
+synonymous_enum!(SubFootnote { Label_, BodyElement });
+synonymous_enum!(SubFigure { Image, Caption, Legend, BodyElement });
diff --git a/src/document_tree/element_types.rs b/src/document_tree/element_types.rs
new file mode 100644
index 0000000..232d44f
--- /dev/null
+++ b/src/document_tree/element_types.rs
@@ -0,0 +1,96 @@
+
+// enum ElementType {
+// //structual elements
+// Section, Topic, Sidebar,
+//
+// //structural subelements
+// Title, Subtitle, Decoration, Docinfo, Transition,
+//
+// //bibliographic elements
+// Author, Authors, Organization,
+// Address { space: FixedSpace },
+// Contact, Version, Revision, Status,
+// Date, Copyright, Field,
+//
+// //decoration elements
+// Header, Footer,
+//
+// //simple body elements
+// Paragraph,
+// LiteralBlock { space: FixedSpace },
+// DoctestBlock { space: FixedSpace },
+// MathBlock, Rubric,
+// SubstitutionDefinition { ltrim: bool, rtrim: bool },
+// Comment { space: FixedSpace },
+// Pending,
+// Target { refuri: Url, refid: ID, refname: Vec<NameToken>, anonymous: bool },
+// Raw { space: FixedSpace, format: Vec<NameToken> },
+// Image {
+// align: AlignHV,
+// uri: Url,
+// alt: String,
+// height: Measure,
+// width: Measure,
+// scale: f64,
+// },
+//
+// //compound body elements
+// Compound, Container,
+//
+// BulletList { bullet: String },
+// EnumeratedList { enumtype: EnumeratedListType, prefix: String, suffix: String },
+// DefinitionList, FieldList, OptionList,
+//
+// LineBlock, BlockQuote,
+// Admonition, Attention, Hint, Note,
+// Caution, Danger, Error, Important,
+// Tip, Warning,
+// Footnote { backrefs: Vec<ID>, auto: bool },
+// Citation { backrefs: Vec<ID> },
+// SystemMessage { backrefs: Vec<ID>, level: usize, line: usize, type_: NameToken },
+// Figure { align: AlignH, width: usize },
+// Table, //TODO
+//
+// //body sub elements
+// ListItem,
+//
+// DefinitionListItem, Term,
+// Classifier, Definition,
+//
+// FieldName, FieldBody,
+//
+// OptionListItem, OptionGroup, Description, Option_, OptionString,
+// OptionArgument { delimiter: String },
+//
+// Line, Attribution, Label_,
+//
+// Caption, Legend,
+//
+// //inline elements
+// Emphasis, Strong, Literal,
+// Reference { name: String, refuri: Url, refid: ID, refname: Vec<NameToken> },
+// FootnoteReference { refid: ID, refname: Vec<NameToken>, auto: bool },
+// CitationReference { refid: ID, refname: Vec<NameToken> },
+// SubstitutionReference { refname: Vec<NameToken> },
+// TitleReference,
+// Abbreviation, Acronym,
+// Superscript, Subscript,
+// Inline,
+// Problematic { refid: ID },
+// Generated, Math,
+//
+// //also have non-inline versions. Inline image is no figure child, inline target has content
+// TargetInline { refuri: Url, refid: ID, refname: Vec<NameToken>, anonymous: bool },
+// RawInline { space: FixedSpace, format: Vec<NameToken> },
+// ImageInline {
+// align: AlignHV,
+// uri: Url,
+// alt: String,
+// height: Measure,
+// width: Measure,
+// scale: f64,
+// },
+//
+// //text element
+// TextElement,
+// }
diff --git a/src/document_tree/elements.rs b/src/document_tree/elements.rs
new file mode 100644
index 0000000..e6709b4
--- /dev/null
+++ b/src/document_tree/elements.rs
@@ -0,0 +1,207 @@
+use url::Url;
+
+use super::extra_attributes::{self,ExtraAttributes};
+use super::element_categories::*;
+
+
+//-----------------\\
+//Element hierarchy\\
+//-----------------\\
+
+pub trait Element {
+ fn ids(&self) -> &Vec<String>;
+ fn names(&self) -> &Vec<String>;
+ fn source(&self) -> &Option<Url>;
+ fn classes(&self) -> &Vec<String>;
+}
+
+#[derive(Default,Debug)]
+pub struct CommonAttributes {
+ ids: Vec<String>,
+ names: Vec<String>,
+ //left out dupnames
+ source: Option<Url>,
+ classes: Vec<String>,
+}
+
+//----\\
+//impl\\
+//----\\
+
+macro_rules! impl_element(($name:ident) => {
+ impl Element for $name {
+ fn ids(&self) -> &Vec<String> { &self.common.ids }
+ fn names(&self) -> &Vec<String> { &self.common.names }
+ fn source(&self) -> &Option<Url> { &self.common.source }
+ fn classes(&self) -> &Vec<String> { &self.common.classes }
+ }
+});
+
+macro_rules! impl_children(($name:ident, $childtype:ident) => {
+ impl HasChildren<$childtype> for $name {
+ fn add_child<R: Into<$childtype>>(&mut self, child: R) {
+ self.children.push(Box::new(child.into()));
+ }
+ }
+});
+
+macro_rules! impl_extra(($name:ident) => {
+ impl ExtraAttributes<extra_attributes::$name> for $name {
+ fn extra(&self) -> &extra_attributes::$name { &self.extra }
+ }
+});
+
+macro_rules! impl_elem(
+ ($name:ident) => {
+ #[derive(Default,Debug)]
+ pub struct $name { common: CommonAttributes }
+ impl_element!($name);
+ };
+ ($name:ident; +) => {
+ #[derive(Default,Debug)]
+ pub struct $name { common: CommonAttributes, extra: extra_attributes::$name }
+ impl_element!($name); impl_extra!($name);
+ };
+ ($name:ident; *) => { //same as above with no default
+ #[derive(Debug)]
+ pub struct $name { common: CommonAttributes, extra: extra_attributes::$name }
+ impl_element!($name); impl_extra!($name);
+ };
+ ($name:ident, $childtype:ident) => {
+ #[derive(Default,Debug)]
+ pub struct $name { common: CommonAttributes, children: Vec<Box<$childtype>> }
+ impl_element!($name); impl_children!($name, $childtype);
+ };
+ ($name:ident, $childtype:ident; +) => {
+ #[derive(Default,Debug)]
+ pub struct $name { common: CommonAttributes, extra: extra_attributes::$name, children: Vec<Box<$childtype>> }
+ impl_element!($name); impl_extra!($name); impl_children!($name, $childtype);
+ };
+);
+
+macro_rules! impl_elems(( $( ($($args:tt)*) )* ) => {
+ $( impl_elem!($($args)*); )*
+});
+
+impl_elems!(
+ //structual elements
+ (Section, SubSection)
+ (Topic, SubTopic)
+ (Sidebar, SubSidebar)
+
+ //structural subelements
+ (Title, TextOrInlineElement)
+ (Subtitle, TextOrInlineElement)
+ (Decoration, DecorationElement)
+ (Docinfo, BibliographicElement)
+ (Transition)
+
+ //bibliographic elements
+ (Author, TextOrInlineElement)
+ (Authors, AuthorInfo)
+ (Organization, TextOrInlineElement)
+ (Address, TextOrInlineElement; +)
+ (Contact, TextOrInlineElement)
+ (Version, TextOrInlineElement)
+ (Revision, TextOrInlineElement)
+ (Status, TextOrInlineElement)
+ (Date, TextOrInlineElement)
+ (Copyright, TextOrInlineElement)
+ (Field, SubField)
+
+ //decoration elements
+ (Header, BodyElement)
+ (Footer, BodyElement)
+
+ //simple body elements
+ (Paragraph, TextOrInlineElement)
+ (LiteralBlock, TextOrInlineElement; +)
+ (DoctestBlock, TextOrInlineElement; +)
+ (MathBlock)
+ (Rubric, TextOrInlineElement)
+ (SubstitutionDefinition, TextOrInlineElement; +)
+ (Comment, TextOrInlineElement; +)
+ (Pending)
+ (Target; +)
+ (Raw; +)
+ (Image; *)
+
+ //compound body elements
+ (Compound, BodyElement)
+ (Container, BodyElement)
+
+ (BulletList, ListItem; +)
+ (EnumeratedList, ListItem; +)
+ (DefinitionList, DefinitionListItem)
+ (FieldList, Field)
+ (OptionList, OptionListItem)
+
+ (LineBlock, SubLineBlock)
+ (BlockQuote, SubBlockQuote)
+ (Admonition, SubTopic)
+ (Attention, BodyElement)
+ (Hint, BodyElement)
+ (Note, BodyElement)
+ (Caution, BodyElement)
+ (Danger, BodyElement)
+ (Error, BodyElement)
+ (Important, BodyElement)
+ (Tip, BodyElement)
+ (Warning, BodyElement)
+ (Footnote, SubFootnote; +)
+ (Citation, SubFootnote; +)
+ (SystemMessage, BodyElement; +)
+ (Figure, SubFigure; +)
+ (Table; +) //TODO
+
+ //body sub elements
+ (ListItem, BodyElement)
+
+ (DefinitionListItem, SubDLItem)
+ (Term, TextOrInlineElement)
+ (Classifier, TextOrInlineElement)
+ (Definition, BodyElement)
+
+ (FieldName, TextOrInlineElement)
+ (FieldBody, BodyElement)
+
+ (OptionListItem, SubOptionListItem)
+ (OptionGroup, Option_)
+ (Description, BodyElement)
+ (Option_, SubOption)
+ (OptionString, TextOrInlineElement)
+ (OptionArgument, TextOrInlineElement; +)
+
+ (Line, TextOrInlineElement)
+ (Attribution, TextOrInlineElement)
+ (Label_, TextOrInlineElement)
+
+ (Caption, TextOrInlineElement)
+ (Legend, BodyElement)
+
+ //inline elements
+ (Emphasis, TextOrInlineElement)
+ (Literal, TextOrInlineElement)
+ (Reference, TextOrInlineElement; +)
+ (Strong, TextOrInlineElement)
+ (FootnoteReference, TextOrInlineElement; +)
+ (CitationReference, TextOrInlineElement; +)
+ (SubstitutionReference, TextOrInlineElement; +)
+ (TitleReference, TextOrInlineElement)
+ (Abbreviation, TextOrInlineElement)
+ (Acronym, TextOrInlineElement)
+ (Superscript, TextOrInlineElement)
+ (Subscript, TextOrInlineElement)
+ (Inline, TextOrInlineElement)
+ (Problematic, TextOrInlineElement; +)
+ (Generated, TextOrInlineElement)
+ (Math)
+
+ //also have non-inline versions. Inline image is no figure child, inline target has content
+ (TargetInline, TextOrInlineElement; +)
+ (RawInline; +)
+ (ImageInline; *)
+
+ //text element
+ (TextElement)
+);
diff --git a/src/document_tree/extra_attributes.rs b/src/document_tree/extra_attributes.rs
new file mode 100644
index 0000000..2141469
--- /dev/null
+++ b/src/document_tree/extra_attributes.rs
@@ -0,0 +1,56 @@
+use url::Url;
+
+use super::attribute_types::{FixedSpace,ID,NameToken,AlignHV,AlignH,Measure,EnumeratedListType};
+
+pub trait ExtraAttributes<A> {
+ fn extra(&self) -> &A;
+}
+
+#[derive(Default,Debug)] pub struct Address { pub space: FixedSpace }
+#[derive(Default,Debug)] pub struct LiteralBlock { pub space: FixedSpace }
+#[derive(Default,Debug)] pub struct DoctestBlock { pub space: FixedSpace }
+#[derive(Default,Debug)] pub struct SubstitutionDefinition { pub ltrim: Option<bool>, pub rtrim: Option<bool> }
+#[derive(Default,Debug)] pub struct Comment { pub space: FixedSpace }
+#[derive(Default,Debug)] pub struct Target { pub refuri: Option<Url>, pub refid: Option<ID>, pub refname: Vec<NameToken>, pub anonymous: Option<bool> }
+#[derive(Default,Debug)] pub struct Raw { pub space: FixedSpace, pub format: Vec<NameToken> }
+#[derive(Debug)]
+pub struct Image {
+ pub align: Option<AlignHV>,
+ pub uri: Url,
+ pub alt: Option<String>,
+ pub height: Option<Measure>,
+ pub width: Option<Measure>,
+ pub scale: Option<f64>,
+}
+
+//bools usually are XML yesorno. “auto” however either exists and is set to something random like “1” or doesn’t exist
+
+#[derive(Default,Debug)] pub struct BulletList { pub bullet: Option<String> }
+#[derive(Default,Debug)] pub struct EnumeratedList { pub enumtype: Option<EnumeratedListType>, pub prefix: Option<String>, pub suffix: Option<String> }
+
+#[derive(Default,Debug)] pub struct Footnote { pub backrefs: Vec<ID>, pub auto: Option<bool> }
+#[derive(Default,Debug)] pub struct Citation { pub backrefs: Vec<ID> }
+#[derive(Default,Debug)] pub struct SystemMessage { pub backrefs: Vec<ID>, pub level: Option<usize>, pub line: Option<usize>, pub type_: Option<NameToken> }
+#[derive(Default,Debug)] pub struct Figure { pub align: Option<AlignH>, pub width: Option<usize> }
+#[derive(Default,Debug)] pub struct Table; //TODO
+
+#[derive(Default,Debug)] pub struct OptionArgument { pub delimiter: Option<String> }
+
+#[derive(Default,Debug)] pub struct Reference { pub name: Option<String>, pub refuri: Option<Url>, pub refid: Option<ID>, pub refname: Vec<NameToken> }
+#[derive(Default,Debug)] pub struct FootnoteReference { pub refid: Option<ID>, pub refname: Vec<NameToken>, pub auto: Option<bool> }
+#[derive(Default,Debug)] pub struct CitationReference { pub refid: Option<ID>, pub refname: Vec<NameToken> }
+#[derive(Default,Debug)] pub struct SubstitutionReference { pub refname: Vec<NameToken> }
+#[derive(Default,Debug)] pub struct Problematic { pub refid: Option<ID> }
+
+//also have non-inline versions. Inline image is no figure child, inline target has content
+#[derive(Default,Debug)] pub struct TargetInline { pub refuri: Option<Url>, pub refid: Option<ID>, pub refname: Vec<NameToken>, pub anonymous: Option<bool> }
+#[derive(Default,Debug)] pub struct RawInline { pub space: FixedSpace, pub format: Vec<NameToken> }
+#[derive(Debug)]
+pub struct ImageInline {
+ pub align: Option<AlignHV>,
+ pub uri: Url,
+ pub alt: Option<String>,
+ pub height: Option<Measure>,
+ pub width: Option<Measure>,
+ pub scale: Option<f64>,
+}
diff --git a/src/document_tree/mod.rs b/src/document_tree/mod.rs
new file mode 100644
index 0000000..868b9f8
--- /dev/null
+++ b/src/document_tree/mod.rs
@@ -0,0 +1,21 @@
+///http://docutils.sourceforge.net/docs/ref/doctree.html
+///serves as AST
+
+pub mod elements;
+pub mod element_categories;
+pub mod extra_attributes;
+pub mod attribute_types;
+
+use self::element_categories::StructuralSubElement;
+
+pub use self::elements::*; //Element,CommonAttributes,
+pub use self::extra_attributes::ExtraAttributes;
+pub use self::element_categories::HasChildren;
+
+#[derive(Default,Debug)]
+pub struct Document { children: Vec<Box<StructuralSubElement>> }
+impl HasChildren<StructuralSubElement> for Document {
+ fn add_child<R: Into<StructuralSubElement>>(&mut self, child: R) {
+ self.children.push(Box::new(child.into()));
+ }
+}