1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright (C) 2016 Élisabeth HENRY.
//
// This file is part of Crowbook.
//
// Crowbook is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// Caribon is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received ba copy of the GNU Lesser General Public License
// along with Crowbook.  If not, see <http://www.gnu.org/licenses/>.

#[derive(Debug, Clone, PartialEq)]
/// The inner type for an annotation.
///
/// This Enum might grow additional variants, so library users should
/// **not** rely on exhaustive matching.
pub enum Data {
    GrammarError(String),
    __NonExhaustive,
}

/// A single token representing a Markdown element.
///
/// A Markdown document is, thus, a Vec of `Token`s.
///
/// This Enum might grow additional variants, so library users should
/// **not** rely on exhaustive matching.
#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    /// The most simple element, containing a String
    Str(String),
    /// A paragraph, containing a list of elements
    Paragraph(Vec<Token>),
    /// A header with a header number and the title
    Header(i32, Vec<Token>),
    /// *Emphasis*, a.k.a. italics
    Emphasis(Vec<Token>),
    /// **Strong**, a.k.a. bold
    Strong(Vec<Token>),
    /// `Code`, a.k.a. verbatim
    Code(Vec<Token>),
    /// A quote
    BlockQuote(Vec<Token>),
    /// Code block with language and content
    CodeBlock(String, Vec<Token>),

    /// Unordered list, with a vector of `Item`s
    List(Vec<Token>),
    /// Ordered list, with a starting number, and a list of `Item`s
    OrderedList(usize, Vec<Token>),
    /// Item of a list
    Item(Vec<Token>),

    /// Table with number of rows, and a list of `TableHead` and `TableRows`
    Table(i32, Vec<Token>),
    /// Table header, contains `TableCell`s
    TableHead(Vec<Token>),
    /// Row of a table, contains `TableCell`s
    TableRow(Vec<Token>),
    /// Cell of a table
    TableCell(Vec<Token>),

    /// A footnote, contains the content it is pointing to.
    Footnote(Vec<Token>),

    /// Horizontal rule
    Rule,
    /// Softbreak, usually rendered by a space
    SoftBreak,
    /// Hardbreak
    HardBreak,

    /// A link with an url, a title, and the linked text
    Link(String, String, Vec<Token>),
    /// An image with a source url, a title and an alt tex
    Image(String, String, Vec<Token>),
    /// Similar to previous, but when image is in a standalone paragraph
    StandaloneImage(String, String, Vec<Token>),

    /// An annotation inserted by crowbook for e.g. grammar checking
    Annotation(Data, Vec<Token>),

    /// Hint that destructuring should not be exhaustive
    #[doc(hidden)]
    __NonExhaustive,
}

use Token::*;

impl Token {
    /// Returns the inner list of tokens contained in this token (if any)
    pub fn inner(&self) -> Option<&[Token]> {
        match *self {
            Rule | SoftBreak | HardBreak | Str(_) => None,

            Paragraph(ref v) |
            Header(_, ref v) |
            Emphasis(ref v) |
            Strong(ref v) |
            Code(ref v) |
            BlockQuote(ref v) |
            CodeBlock(_, ref v) |
            List(ref v) |
            OrderedList(_, ref v) |
            Item(ref v) |
            Table(_, ref v) |
            TableHead(ref v) |
            TableRow(ref v) |
            TableCell(ref v) |
            Footnote(ref v) |
            Link(_, _, ref v) |
            Image(_, _, ref v) |
            StandaloneImage(_, _, ref v) |
            Annotation(_, ref v) => Some(v),

            __NonExhaustive => unreachable!(),
        }
    }

    /// Returns the inner list of tokens contained in this token (if any) (mutable version)
    pub fn inner_mut(&mut self) -> Option<&mut Vec<Token>> {
        match *self {
            Rule | SoftBreak | HardBreak | Str(_) => None,

            Paragraph(ref mut v) |
            Annotation(_, ref mut v) |
            Header(_, ref mut v) |
            Emphasis(ref mut v) |
            Strong(ref mut v) |
            Code(ref mut v) |
            BlockQuote(ref mut v) |
            CodeBlock(_, ref mut v) |
            List(ref mut v) |
            OrderedList(_, ref mut v) |
            Item(ref mut v) |
            Table(_, ref mut v) |
            TableHead(ref mut v) |
            TableRow(ref mut v) |
            TableCell(ref mut v) |
            Footnote(ref mut v) |
            Link(_, _, ref mut v) |
            Image(_, _, ref mut v) |
            StandaloneImage(_, _, ref mut v) => Some(v),

            __NonExhaustive => unreachable!(),
        }
    }

    /// Checks whether token is an str
    pub fn is_str(&self) -> bool {
        if let Token::Str(_) = *self {
            true
        } else {
            false
        }
    }

    /// Checks whether token is an image
    ///
    /// **Returns** `true` if and only if token is Image variant
    /// (StandaloneImage returns *false*, like other variants)
    pub fn is_image(&self) -> bool {
        if let Token::Image(_, _, _) = *self {
            true
        } else {
            false
        }
    }
}