MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
markupparser.h
1 //© Copyright 2010 - 2012 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _uimarkupparser_h
41 #define _uimarkupparser_h
42 
43 #include "countedptr.h"
44 #include "colourvalue.h"
45 
46 namespace Mezzanine
47 {
48  namespace UI
49  {
50  class FontData;
51  class TextLayer;
52  class Character;
53  class CharacterTraits;
54  class TextToken;
55  class TagToken;
56  class TokenString;
57  ///////////////////////////////////////////////////////////////////////////////
58  /// @brief This is a base class for tags that implement the functionality of a markup language.
59  /// @details When creating markup tags it is important to understand the disinction between range tags
60  /// and non-range tags. Range tags render nothing themselves and instead alter all the characters
61  /// between both ends of the tag. Non-range tags can create characters of their own to be inserted, however
62  /// when doing so it should be limited to creating only one per processing of a tag. This helps to make
63  /// specific configurations easier to implement for the end user, as well as simplify the logic used when
64  /// editing strings and tokens handled by text layers.
65  ///////////////////////////////////////
67  {
68  public:
69  /// @brief Basic container type for the storage of @ref Character instances by this class.
70  typedef std::list<Character*> CharacterContainer;
71  /// @brief Iterator type for @ref Character instances stored by this class.
72  typedef CharacterContainer::iterator CharacterIterator;
73  /// @brief Const Iterator type for @ref Character instances stored by this class.
74  typedef CharacterContainer::const_iterator ConstCharacterIterator;
75  /// @brief An std::pair used to report the result of a MarkupTag being processed any the character it may have generated.
76  typedef std::pair<Boolean,Character*> ProcessResult;
77  public:
78  /// @brief Class constructor.
79  MarkupTag() { }
80  /// @brief Class destructor.
81  virtual ~MarkupTag() { }
82 
83  ///////////////////////////////////////////////////////////////////////////////
84  // Utility
85 
86  /// @brief Gets the name of this tag.
87  /// @return Returns a String containing the name of this tag.
88  virtual const String& GetName() const = 0;
89  /// @brief Gets whether or not this tag applies to a range of characters.
90  /// @return Returns true if this tag requires a closing tag to accompany to be valid, false otherwise.
91  virtual Boolean IsRangeTag() const = 0;
92 
93  /// @brief Processes this tag.
94  /// @param Params A NameValuePairMap of all the parameters provided for this tag.
95  /// @param Traits The character traits to be modified and used for future character construction.
96  /// @param Layer A pointer to the TextLayer currently being parsed.
97  /// @return Returns a process result where the first value is true if this tag succeeded in making it's alterations and
98  /// the second value contains a pointer to a generated character if one was generated. The second value can be NULL.
99  virtual ProcessResult Process(NameValuePairMap& Params, CharacterTraits& Traits, TextLayer* Layer) const = 0;
100  };//MarkupTag
101 
102  ///////////////////////////////////////////////////////////////////////////////
103  /// @brief This is a base class for the parsing of markup texts contained in text layers.
104  /// @details This class implements every aspect of the markup language except for the tags and their functionality.
105  /// It is expected that tags can be broken down into one of two processes, either they will generate a character, or
106  /// they will alter the styling used to render an existing range of characters. @n @n
107  /// The styling and syntax of the markup language is similar (but not identical) to BBCode. Developers can set which
108  /// glyphs are to be used to mark the start and end of a markup tag. Tags can be start tags, end tags, and individual
109  /// tags. Individual tags are the character generators. They make the character and are done with influencing any other
110  /// characters. Start tags and end tags together define a range of characters they are to influence. Use of the forward
111  /// slash '/' is prohibited unless you are noting an end tag, in which case the slash is to be followed by the tag name
112  /// (this is case sensitive) and nothing else, within the markup start and end glyphs. An end tag cannot have parameters
113  /// defined in it, and if any are included they will be parsed as a part of the tag name. A start tag cannot have a forward
114  /// slash '/'. Instead it must start with the tag name, then a space, and then list the parameter names and values linked by
115  /// an equals sign '=', and separated by spaces. Spaces between the markup tag start and end glyphs and tag names should be
116  /// avoided. @n @n
117  /// Relevant parameters and their possibile values are based on the tag being used, and you should check the markup
118  /// implemenation for that information. Depending on the number of parameters needed for the tag this markup system supports
119  /// both short notation, and long notation. Short notation is only supported when there is one parameter, and is implemented
120  /// as "{tagname}{equals}{value}". For example a sprite could be implemented as "[Sprite=Awesome]" where everything after the
121  /// equals to the end tag is treated as the value to set, in this case the name of the sprite to be set. In situations like this
122  /// the value is always given the name "Value" in the NameValuePairMap of parameters that is passed around during parsing. Long
123  /// notation involves being explicit with the names of values, and is necessary for tags that require multiple parameters. In
124  /// long notation there should be minimal spaces, used only to separate the tag name and each parameter from each other.
125  ///////////////////////////////////////
127  {
128  public:
129  /// @brief Basic container type for the storage of @ref Character instances used during processing by this class.
130  typedef std::list<Character*> CharacterContainer;
131  /// @brief Iterator type for @ref Character instances being processed by this class.
132  typedef CharacterContainer::iterator CharacterIterator;
133  /// @brief Const Iterator type for @ref Character instances being processed by this class.
134  typedef CharacterContainer::const_iterator ConstCharacterIterator;
135  /// @brief Basic container type for the storage of @ref MarkupTag instances by this class.
136  typedef std::map<String,MarkupTag*> TagContainer;
137  /// @brief Iterator type for @ref MarkupTag instances stored by this class.
138  typedef TagContainer::iterator TagIterator;
139  /// @brief Const Iterator type for @ref MarkupTag instances stored by this class.
140  typedef TagContainer::const_iterator ConstTagIterator;
141  /// @brief An std::pair type used to map a TagToken to the MarkupTag implementation it is calling.
142  typedef std::pair<TagToken*,MarkupTag*> TokenTagPair;
143  /// @brief Basic container type for the storage of @ref TokenTagPair instances used during processing by this class.
144  typedef std::vector<TokenTagPair> TagVector;
145  /// @brief Iterator type for @ref TokenTagPair instances being processed by this class.
146  typedef TagVector::iterator TagVecIterator;
147  /// @brief Const Iterator type for @ref TokenTagPair instances being processed by this class.
148  typedef TagVector::const_iterator ConstTagVecIterator;
149  /// @brief Basic container type for the storage of @ref TextToken instances used during processing by this class.
150  typedef std::vector<TextToken*> TokenContainer;
151  /// @brief Iterator type for @ref TextToken instances being processed by this class.
152  typedef TokenContainer::iterator TokenIterator;
153  /// @brief Const Iterator type for @ref TextToken instances being processed by this class.
154  typedef TokenContainer::const_iterator ConstTokenIterator;
155  protected:
156  /// @brief Map of tags recognized by this parser.
158  /// @brief Populates the tag map with the tags recognized by this parser.
159  virtual void Initialize() = 0;
160  /// @brief Helper method for creating text tokens.
161  virtual TextToken* CreateTextToken(const String& Text) const;
162  /// @brief Helper method for creating tag tokens.
163  virtual TextToken* CreateTagToken(const String& Text) const;
164  /// @brief Helper method for converting text tokens into characters.
165  virtual void GenerateCharactersFromToken(const TextToken* Token, TextLayer* Layer, const CharacterTraits& Traits, CharacterContainer& Characters) const;
166  /// @brief Helper method for regenerating current traits after a tag is disabled.
167  virtual void RegenerateTraits(CharacterTraits& Traits, const TagVector& ActiveTags, TextLayer* Layer) const;
168  public:
169  /// @brief Class constructor.
170  MarkupParser();
171  /// @brief Class destructor.
172  virtual ~MarkupParser();
173 
174  ///////////////////////////////////////////////////////////////////////////////
175  // Utility
176 
177  /// @brief Gets the name of this parser implementation.
178  /// @return Returns a string containing the name of this markup parser implementation.
179  virtual String GetName() const = 0;
180  /// @brief Gets the ID for the character that marks the start of a markup section.
181  /// @return Returns an Int32 representing the start of a markup section.
182  virtual Char8 GetMarkupTagStart() const = 0;
183  /// @brief Gets the ID for the character that marks the end of a markup section.
184  /// @return Returns an Int32 representing the end of a markup section.
185  virtual Char8 GetMarkupTagEnd() const = 0;
186 
187  ///////////////////////////////////////////////////////////////////////////////
188  // Parsing Methods
189 
190  /// @brief Processes a string encoded in UTF8 into a list of renderable characters.
191  /// @param Source The source string containing raw text and (maybe) markup tags to convert into characters.
192  /// @param InitialTraits The colour, highlight colour, and font characters are to have by default without otherwise being set via markup.
193  /// @param CallingLayer The TextLayer instance calling this method.
194  /// @return Returns a list of renderable characters generated by this parser.
195  virtual CharacterContainer Parse(const String& Source, const CharacterTraits& InitialTraits, TextLayer* CallingLayer) const;
196  /// @brief Processes a collection of text tokens into a list of renderable characters.
197  /// @param Tokens A TokenString storing all the lex'd text that is to be parsed.
198  /// @param InitialTraits The colour, highlight colour, and font characters are to have by default without otherwise being set via markup.
199  /// @param CallingLayer The TextLayer instance calling this method.
200  /// @return Returns a list of renderable characters generated by this parser.
201  virtual CharacterContainer ParseTextTokens(TokenString* Tokens, const CharacterTraits& InitialTraits, TextLayer* CallingLayer) const;
202  /// @brief Converts a string into a series of tokens that can be parsed more readily.
203  /// @warning This method will naively search each character in the string looking for a match to the character provided by
204  /// "GetMarkupTagStart()" and/or "GetMarkupTagEnd()". If the provided string is properly formatted UTF-8 this will not cause
205  /// problems. If the encoding is wrong however, this can lead to detecting tags improperly and rendering the wrong
206  /// characters. In extreme cases it could try to look for a character that isn't available which will lead to an exception during parsing.
207  /// @param Source The source string containing raw text and (maybe) markup tags to convert into tokens.
208  /// @return Returns a pointer to a TokenString storing all the tokens generated.
209  virtual TokenString* Lex(const String& Source) const;
210  };//MarkupParser
211  }//UI
212 }//Mezzanine
213 
214 #endif