diff options
Diffstat (limited to 'src/document_tree')
| -rw-r--r-- | src/document_tree/attribute_types.rs | 155 | ||||
| -rw-r--r-- | src/document_tree/element_categories.rs | 130 | ||||
| -rw-r--r-- | src/document_tree/element_types.rs | 96 | ||||
| -rw-r--r-- | src/document_tree/elements.rs | 288 | ||||
| -rw-r--r-- | src/document_tree/extra_attributes.rs | 112 | ||||
| -rw-r--r-- | src/document_tree/macro_util.rs | 42 |
6 files changed, 0 insertions, 823 deletions
diff --git a/src/document_tree/attribute_types.rs b/src/document_tree/attribute_types.rs deleted file mode 100644 index 30f3767..0000000 --- a/src/document_tree/attribute_types.rs +++ /dev/null @@ -1,155 +0,0 @@ -use std::str::FromStr; - -use failure::{Error,bail,format_err}; -use serde_derive::Serialize; -use regex::Regex; - -use crate::url::Url; - -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] -pub enum EnumeratedListType { - Arabic, - LowerAlpha, - UpperAlpha, - LowerRoman, - UpperRoman, -} - -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] -pub enum FixedSpace { Default, Preserve } // yes, default really is not “Default” -impl Default for FixedSpace { fn default() -> FixedSpace { FixedSpace::Preserve } } - -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub enum AlignH { Left, Center, Right} -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub enum AlignHV { Top, Middle, Bottom, Left, Center, Right } -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub enum AlignV { Top, Middle, Bottom } - -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub enum TableAlignH { Left, Right, Center, Justify, Char } -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub enum TableBorder { Top, Bottom, TopBottom, All, Sides, None } - -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub struct ID(pub String); -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub struct NameToken(pub String); - -// The table DTD has the cols attribute of tgroup as required, but having -// TableGroupCols not implement Default would leave no possible implementation -// for TableGroup::with_children. -#[derive(Debug,PartialEq,Eq,Hash,Serialize,Clone)] pub struct TableGroupCols(pub usize); -impl Default for TableGroupCols { - fn default() -> Self { - TableGroupCols(0) - } -} - -// no eq for f64 -#[derive(Debug,PartialEq,Serialize,Clone)] -pub enum Measure { // http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#length-units - Em(f64), - Ex(f64), - Mm(f64), - Cm(f64), - In(f64), - Px(f64), - Pt(f64), - Pc(f64), -} - -impl FromStr for AlignHV { - type Err = Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - use self::AlignHV::*; - Ok(match s { - "top" => Top, - "middle" => Middle, - "bottom" => Bottom, - "left" => Left, - "center" => Center, - "right" => Right, - s => bail!("Invalid Alignment {}", s), - }) - } -} - -impl From<&str> for ID { - fn from(s: &str) -> Self { - ID(s.to_owned().replace(' ', "-")) - } -} - -impl From<&str> for NameToken { - fn from(s: &str) -> Self { - NameToken(s.to_owned()) - } -} - -impl FromStr for Measure { - type Err = Error; - fn from_str(s: &str) -> Result<Self, Self::Err> { - use self::Measure::*; - let re = Regex::new(r"(?P<float>\d+\.\d*|\.?\d+)\s*(?P<unit>em|ex|mm|cm|in|px|pt|pc)").unwrap(); - let caps: regex::Captures = re.captures(s).ok_or_else(|| format_err!("Invalid measure"))?; - let value: f64 = caps["float"].parse()?; - Ok(match &caps["unit"] { - "em" => Em(value), - "ex" => Ex(value), - "mm" => Mm(value), - "cm" => Cm(value), - "in" => In(value), - "px" => Px(value), - "pt" => Pt(value), - "pc" => Pc(value), - _ => unreachable!(), - }) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_parse_measure() { - let _a: Measure = "1.5em".parse().unwrap(); - let _b: Measure = "20 mm".parse().unwrap(); - let _c: Measure = ".5in".parse().unwrap(); - let _d: Measure = "1.pc".parse().unwrap(); - } -} - -pub(crate) trait CanBeEmpty { - fn is_empty(&self) -> bool; -} - -/* Specialization necessary -impl<T> CanBeEmpty for T { - fn is_empty(&self) -> bool { false } -} -*/ -macro_rules! impl_cannot_be_empty { - ($t:ty) => { - impl CanBeEmpty for $t { - fn is_empty(&self) -> bool { false } - } - }; - ($t:ty, $($ts:ty),*) => { - impl_cannot_be_empty!($t); - impl_cannot_be_empty!($($ts),*); - }; -} -impl_cannot_be_empty!(Url); -impl_cannot_be_empty!(TableGroupCols); - -impl<T> CanBeEmpty for Option<T> { - fn is_empty(&self) -> bool { self.is_none() } -} - -impl<T> CanBeEmpty for Vec<T> { - fn is_empty(&self) -> bool { self.is_empty() } -} - -impl CanBeEmpty for bool { - fn is_empty(&self) -> bool { !self } -} - -impl CanBeEmpty for FixedSpace { - fn is_empty(&self) -> bool { self == &FixedSpace::default() } -} - diff --git a/src/document_tree/element_categories.rs b/src/document_tree/element_categories.rs deleted file mode 100644 index db3f420..0000000 --- a/src/document_tree/element_categories.rs +++ /dev/null @@ -1,130 +0,0 @@ -use std::fmt::{self,Debug,Formatter}; - -use serde_derive::Serialize; - -use super::elements::*; - -pub trait HasChildren<C> { - fn with_children(children: Vec<C>) -> Self; - fn children(&self) -> &Vec<C>; - fn children_mut(&mut self) -> &mut Vec<C>; - fn append_child<R: Into<C>>(&mut self, child: R) { - self.children_mut().push(child.into()); - } - fn append_children<R: Into<C> + Clone>(&mut self, more: &[R]) { - let children = self.children_mut(); - children.reserve(more.len()); - for child in more { - children.push(child.clone().into()); - } - } -} - -macro_rules! impl_into { - ([ $( (($subcat:ident :: $entry:ident), $supcat:ident), )+ ]) => { - $( impl_into!($subcat::$entry => $supcat); )+ - }; - ($subcat:ident :: $entry:ident => $supcat:ident ) => { - impl Into<$supcat> for $entry { - fn into(self) -> $supcat { - $supcat::$subcat(Box::new(self.into())) - } - } - }; -} - -macro_rules! synonymous_enum { - ( $subcat:ident : $($supcat:ident),+ ; $midcat:ident : $supsupcat:ident { $($entry:ident),+ $(,)* } ) => { - synonymous_enum!($subcat : $( $supcat ),+ , $midcat { $($entry,)* }); - $( impl_into!($midcat::$entry => $supsupcat); )+ - }; - ( $subcat:ident : $($supcat:ident),+ { $($entry:ident),+ $(,)* } ) => { - synonymous_enum!($subcat { $( $entry, )* }); - cartesian!(impl_into, [ $( ($subcat::$entry) ),+ ], [ $($supcat),+ ]); - }; - ( $name:ident { $( $entry:ident ),+ $(,)* } ) => { - #[derive(PartialEq,Serialize,Clone)] - pub enum $name { $( - $entry(Box<$entry>), - )* } - - impl Debug for $name { - fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { - match *self { - $( $name::$entry(ref inner) => inner.fmt(fmt), )* - } - } - } - - $( impl Into<$name> for $entry { - fn into(self) -> $name { - $name::$entry(Box::new(self)) - } - } )* - }; -} - -synonymous_enum!(StructuralSubElement { Title, Subtitle, Decoration, Docinfo, SubStructure }); -synonymous_enum!(SubStructure: StructuralSubElement { Topic, Sidebar, Transition, Section, BodyElement }); -synonymous_enum!(BodyElement: SubTopic, SubSidebar, SubBlockQuote, SubFootnote, SubFigure; SubStructure: StructuralSubElement { - //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 { - String, 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!(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 { Caption, Legend, BodyElement }); -synonymous_enum!(SubTable { Title, TableGroup }); -synonymous_enum!(SubTableGroup { TableColspec, TableHead, TableBody }); - -#[cfg(test)] -mod test { - use std::default::Default; - use super::*; - - #[test] - fn test_convert_basic() { - let _: BodyElement = Paragraph::default().into(); - } - - #[test] - fn test_convert_more() { - let _: SubStructure = Paragraph::default().into(); - } - - #[test] - fn test_convert_even_more() { - let _: StructuralSubElement = Paragraph::default().into(); - } - - #[test] - fn test_convert_super() { - let be: BodyElement = Paragraph::default().into(); - let _: StructuralSubElement = be.into(); - } -} diff --git a/src/document_tree/element_types.rs b/src/document_tree/element_types.rs deleted file mode 100644 index 429573e..0000000 --- a/src/document_tree/element_types.rs +++ /dev/null @@ -1,96 +0,0 @@ - -// 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: Table -// -// //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 deleted file mode 100644 index 7406cd7..0000000 --- a/src/document_tree/elements.rs +++ /dev/null @@ -1,288 +0,0 @@ -use std::path::PathBuf; -use serde_derive::Serialize; - -use super::attribute_types::{CanBeEmpty,ID,NameToken}; -use super::extra_attributes::{self,ExtraAttributes}; -use super::element_categories::*; - - -//-----------------\\ -//Element hierarchy\\ -//-----------------\\ - -pub trait Element { - /// A list containing one or more unique identifier keys - fn ids (& self) -> & Vec<ID>; - fn ids_mut(&mut self) -> &mut Vec<ID>; - /// a list containing the names of an element, typically originating from the element's title or content. - /// Each name in names must be unique; if there are name conflicts (two or more elements want to the same name), - /// the contents will be transferred to the dupnames attribute on the duplicate elements. - /// An element may have at most one of the names or dupnames attributes, but not both. - fn names (& self) -> & Vec<NameToken>; - fn names_mut(&mut self) -> &mut Vec<NameToken>; - fn source (& self) -> & Option<PathBuf>; - fn source_mut(&mut self) -> &mut Option<PathBuf>; - fn classes (& self) -> & Vec<String>; - fn classes_mut(&mut self) -> &mut Vec<String>; -} - -#[derive(Debug,Default,PartialEq,Serialize,Clone)] -pub struct CommonAttributes { - #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] - ids: Vec<ID>, - #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] - names: Vec<NameToken>, - #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] - source: Option<PathBuf>, - #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] - classes: Vec<String>, - //TODO: dupnames -} - -//----\\ -//impl\\ -//----\\ - -macro_rules! impl_element { ($name:ident) => ( - impl Element for $name { - fn ids (& self) -> & Vec<ID> { & self.common.ids } - fn ids_mut(&mut self) -> &mut Vec<ID> { &mut self.common.ids } - fn names (& self) -> & Vec<NameToken> { & self.common.names } - fn names_mut(&mut self) -> &mut Vec<NameToken> { &mut self.common.names } - fn source (& self) -> & Option<PathBuf> { & self.common.source } - fn source_mut(&mut self) -> &mut Option<PathBuf> { &mut self.common.source } - fn classes (& self) -> & Vec<String> { & self.common.classes } - fn classes_mut(&mut self) -> &mut Vec<String> { &mut self.common.classes } - } -)} - -macro_rules! impl_children { ($name:ident, $childtype:ident) => ( - impl HasChildren<$childtype> for $name { - #[allow(clippy::needless_update)] - fn with_children(children: Vec<$childtype>) -> $name { $name { children: children, ..Default::default() } } - fn children (& self) -> & Vec<$childtype> { & self.children } - fn children_mut(&mut self) -> &mut Vec<$childtype> { &mut self.children } - } -)} - -macro_rules! impl_extra { ($name:ident $($more:tt)*) => ( - impl ExtraAttributes<extra_attributes::$name> for $name { - #[allow(clippy::needless_update)] - fn with_extra(extra: extra_attributes::$name) -> $name { $name { common: Default::default(), extra: extra $($more)* } } - fn extra (& self) -> & extra_attributes::$name { & self.extra } - fn extra_mut(&mut self) -> &mut extra_attributes::$name { &mut self.extra } - } -)} - -trait HasExtraAndChildren<C, A> { - fn with_extra_and_children(extra: A, children: Vec<C>) -> Self; -} - -impl<T, C, A> HasExtraAndChildren<C, A> for T where T: HasChildren<C> + ExtraAttributes<A> { - #[allow(clippy::needless_update)] - fn with_extra_and_children(extra: A, mut children: Vec<C>) -> Self { - let mut r = Self::with_extra(extra); - r.children_mut().extend(children.drain(..)); - r - } -} - -macro_rules! impl_new {( - $(#[$attr:meta])* - pub struct $name:ident { $( - $(#[$fattr:meta])* - $field:ident : $typ:path - ),* $(,)* } -) => ( - $(#[$attr])* - #[derive(Debug,PartialEq,Serialize,Clone)] - pub struct $name { $( - $(#[$fattr])* $field: $typ, - )* } - impl $name { - pub fn new( $( $field: $typ, )* ) -> $name { $name { $( $field: $field, )* } } - } -)} - -macro_rules! impl_elem { - ($name:ident) => { - impl_new!(#[derive(Default)] pub struct $name { - #[serde(flatten)] common: CommonAttributes, - }); - impl_element!($name); - }; - ($name:ident; +) => { - impl_new!(#[derive(Default)] pub struct $name { - #[serde(flatten)] common: CommonAttributes, - #[serde(flatten)] extra: extra_attributes::$name, - }); - impl_element!($name); impl_extra!($name, ..Default::default()); - }; - ($name:ident; *) => { //same as above with no default - impl_new!(pub struct $name { - #[serde(flatten)] common: CommonAttributes, - #[serde(flatten)] extra: extra_attributes::$name - }); - impl_element!($name); impl_extra!($name); - }; - ($name:ident, $childtype:ident) => { - impl_new!(#[derive(Default)] pub struct $name { - #[serde(flatten)] common: CommonAttributes, - children: Vec<$childtype>, - }); - impl_element!($name); impl_children!($name, $childtype); - }; - ($name:ident, $childtype:ident; +) => { - impl_new!(#[derive(Default)] pub struct $name { - #[serde(flatten)] common: CommonAttributes, - #[serde(flatten)] extra: extra_attributes::$name, - children: Vec<$childtype>, - }); - impl_element!($name); impl_extra!($name, ..Default::default()); impl_children!($name, $childtype); - }; -} - -macro_rules! impl_elems { ( $( ($($args:tt)*) )* ) => ( - $( impl_elem!($($args)*); )* -)} - - -#[derive(Default,Debug,Serialize)] -pub struct Document { children: Vec<StructuralSubElement> } -impl_children!(Document, StructuralSubElement); - -impl_elems!( - //structual elements - (Section, StructuralSubElement) - (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, String) - (Rubric, TextOrInlineElement) - (SubstitutionDefinition, TextOrInlineElement; +) - (Comment, TextOrInlineElement; +) - (Pending) - (Target; +) - (Raw, String; +) - (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, SubTable; +) - - //table elements - (TableGroup, SubTableGroup; +) - (TableHead, TableRow; +) - (TableBody, TableRow; +) - (TableRow, TableEntry; +) - (TableEntry, BodyElement; +) - (TableColspec; +) - - //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, String) - (OptionArgument, String; +) - - (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, String) - - //also have non-inline versions. Inline image is no figure child, inline target has content - (TargetInline, String; +) - (RawInline, String; +) - (ImageInline; *) - - //text element = String -); - -impl<'a> From<&'a str> for TextOrInlineElement { - fn from(s: &'a str) -> Self { - s.to_owned().into() - } -} diff --git a/src/document_tree/extra_attributes.rs b/src/document_tree/extra_attributes.rs deleted file mode 100644 index 55896ab..0000000 --- a/src/document_tree/extra_attributes.rs +++ /dev/null @@ -1,112 +0,0 @@ -use serde_derive::Serialize; - -use crate::url::Url; -use super::attribute_types::{CanBeEmpty,FixedSpace,ID,NameToken,AlignHV,AlignH,AlignV,TableAlignH,TableBorder,TableGroupCols,Measure,EnumeratedListType}; - -pub trait ExtraAttributes<A> { - fn with_extra(extra: A) -> Self; - fn extra (& self) -> & A; - fn extra_mut(&mut self) -> &mut A; -} - -macro_rules! impl_extra { - ( $name:ident { $( $(#[$pattr:meta])* $param:ident : $type:ty ),* $(,)* } ) => ( - impl_extra!( - #[derive(Default,Debug,PartialEq,Serialize,Clone)] - $name { $( $(#[$pattr])* $param : $type, )* } - ); - ); - ( $(#[$attr:meta])+ $name:ident { $( $(#[$pattr:meta])* $param:ident : $type:ty ),* $(,)* } ) => ( - $(#[$attr])+ - pub struct $name { $( - $(#[$pattr])* - #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] - pub $param : $type, - )* } - ); -} - -impl_extra!(Address { space: FixedSpace }); -impl_extra!(LiteralBlock { space: FixedSpace }); -impl_extra!(DoctestBlock { space: FixedSpace }); -impl_extra!(SubstitutionDefinition { ltrim: bool, rtrim: bool }); -impl_extra!(Comment { space: FixedSpace }); -impl_extra!(Target { - /// External reference to a URI/URL - refuri: Option<Url>, - /// References to ids attributes in other elements - refid: Option<ID>, - /// Internal reference to the names attribute of another element. May resolve to either an internal or external reference. - refname: Vec<NameToken>, - anonymous: bool, -}); -impl_extra!(Raw { space: FixedSpace, format: Vec<NameToken> }); -impl_extra!(#[derive(Debug,PartialEq,Serialize,Clone)] Image { - uri: Url, - align: Option<AlignHV>, - alt: Option<String>, - height: Option<Measure>, - width: Option<Measure>, - scale: Option<u8>, - target: Option<Url>, // Not part of the DTD but a valid argument -}); - -//bools usually are XML yesorno. “auto” however either exists and is set to something random like “1” or doesn’t exist -//does auto actually mean the numbering prefix? - -impl_extra!(BulletList { bullet: Option<String> }); -impl_extra!(EnumeratedList { enumtype: Option<EnumeratedListType>, prefix: Option<String>, suffix: Option<String> }); - -impl_extra!(Footnote { backrefs: Vec<ID>, auto: bool }); -impl_extra!(Citation { backrefs: Vec<ID> }); -impl_extra!(SystemMessage { backrefs: Vec<ID>, level: Option<usize>, line: Option<usize>, type_: Option<NameToken> }); -impl_extra!(Figure { align: Option<AlignH>, width: Option<usize> }); -impl_extra!(Table { frame: Option<TableBorder>, colsep: Option<bool>, rowsep: Option<bool>, pgwide: Option<bool> }); - -impl_extra!(TableGroup { cols: TableGroupCols, colsep: Option<bool>, rowsep: Option<bool>, align: Option<TableAlignH> }); -impl_extra!(TableHead { valign: Option<AlignV> }); -impl_extra!(TableBody { valign: Option<AlignV> }); -impl_extra!(TableRow { rowsep: Option<bool>, valign: Option<AlignV> }); -impl_extra!(TableEntry { colname: Option<NameToken>, namest: Option<NameToken>, nameend: Option<NameToken>, morerows: Option<usize>, colsep: Option<bool>, rowsep: Option<bool>, align: Option<TableAlignH>, r#char: Option<char>, charoff: Option<usize>, valign: Option<AlignV>, morecols: Option<usize> }); -impl_extra!(TableColspec { colnum: Option<usize>, colname: Option<NameToken>, colwidth: Option<String>, colsep: Option<bool>, rowsep: Option<bool>, align: Option<TableAlignH>, r#char: Option<char>, charoff: Option<usize>, stub: Option<bool> }); - -impl_extra!(OptionArgument { delimiter: Option<String> }); - -impl_extra!(Reference { - name: Option<NameToken>, //TODO: is CDATA in the DTD, so maybe no nametoken? - /// External reference to a URI/URL - refuri: Option<Url>, - /// References to ids attributes in other elements - refid: Option<ID>, - /// Internal reference to the names attribute of another element - refname: Vec<NameToken>, -}); -impl_extra!(FootnoteReference { refid: Option<ID>, refname: Vec<NameToken>, auto: bool }); -impl_extra!(CitationReference { refid: Option<ID>, refname: Vec<NameToken> }); -impl_extra!(SubstitutionReference { refname: Vec<NameToken> }); -impl_extra!(Problematic { refid: Option<ID> }); - -//also have non-inline versions. Inline image is no figure child, inline target has content -impl_extra!(TargetInline { - /// External reference to a URI/URL - refuri: Option<Url>, - /// References to ids attributes in other elements - refid: Option<ID>, - /// Internal reference to the names attribute of another element. May resolve to either an internal or external reference. - refname: Vec<NameToken>, - anonymous: bool, -}); -impl_extra!(RawInline { space: FixedSpace, format: Vec<NameToken> }); -pub type ImageInline = Image; - -impl Image { - pub fn new(uri: Url) -> Image { Image { - uri, - align: None, - alt: None, - height: None, - width: None, - scale: None, - target: None, - } } -} diff --git a/src/document_tree/macro_util.rs b/src/document_tree/macro_util.rs deleted file mode 100644 index d9b8a3e..0000000 --- a/src/document_tree/macro_util.rs +++ /dev/null @@ -1,42 +0,0 @@ -macro_rules! cartesian_impl { - ($out:tt [] $b:tt $init_b:tt $submacro:tt) => { - $submacro!{$out} - }; - ($out:tt [$a:tt, $($at:tt)*] [] $init_b:tt $submacro:tt) => { - cartesian_impl!{$out [$($at)*] $init_b $init_b $submacro} - }; - ([$($out:tt)*] [$a:tt, $($at:tt)*] [$b:tt, $($bt:tt)*] $init_b:tt $submacro:tt) => { - cartesian_impl!{[$($out)* ($a, $b),] [$a, $($at)*] [$($bt)*] $init_b $submacro} - }; -} - -macro_rules! cartesian { - ( $submacro:tt, [$($a:tt)*], [$($b:tt)*]) => { - cartesian_impl!{[] [$($a)*,] [$($b)*,] [$($b)*,] $submacro} - }; -} - - -#[cfg(test)] -mod test { - macro_rules! print_cartesian { - ( [ $(($a1:tt, $a2:tt)),* , ] ) => { - fn test_f(x:i64, y:i64) -> Result<(i64, i64), ()> { - match (x, y) { - $( - ($a1, $a2) => { Ok(($a1, $a2)) } - )* - _ => { Err(()) } - } - } - }; - } - - #[test] - fn test_print_cartesian() { - cartesian!(print_cartesian, [1, 2, 3], [4, 5, 6]); - assert_eq!(test_f(1, 4), Ok((1, 4))); - assert_eq!(test_f(1, 3), Err(())); - assert_eq!(test_f(3, 5), Ok((3, 5))); - } -} |
