]> git.mxchange.org Git - simgear.git/blob - simgear/misc/SimpleMarkdown.cxx
canvas::Layout: support for contents margins.
[simgear.git] / simgear / misc / SimpleMarkdown.cxx
1 // Really simple markdown parser
2 //
3 // Copyright (C) 2014  Thomas Geymayer <tomgey@gmail.com>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Library General Public License for more details.
14 //
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
18
19 #include "SimpleMarkdown.hxx"
20
21 namespace simgear
22 {
23
24   // White space
25   static bool isSpace(const char c)
26   {
27     return c == ' ' || c == '\t';
28   }
29   
30   // Unordered list item
31   static bool isULItem(const char c)
32   {
33     return c == '*' || c == '+' || c == '-';
34   }
35
36   //----------------------------------------------------------------------------
37   std::string SimpleMarkdown::parse(const std::string& src)
38   {
39     std::string out;
40
41     int num_space = 0,
42         num_newline = 0;
43     bool line_empty = true;
44
45     for( std::string::const_iterator it = src.begin();
46                                      it != src.end();
47                                    ++it )
48     {
49       if( isSpace(*it) )
50       {
51         ++num_space;
52       }
53       else if( *it == '\n' )
54       {
55         // Two or more whitespace at end of line -> line break
56         if( !line_empty && num_space >= 2 )
57         {
58           out.push_back('\n');
59           line_empty = true;
60         }
61
62         ++num_newline;
63         num_space = 0;
64       }
65       else
66       {
67         // Remove all new lines before first printable character
68         if( out.empty() )
69           num_newline = 0;
70
71         // Two or more new lines (aka. at least one empty line) -> new paragraph
72         if( num_newline >= 2 )
73         {
74           out.append("\n\n");
75
76           line_empty = true;
77           num_newline = 0;
78         }
79
80         // Replace unordered list item markup at begin of line with bullet
81         // (TODO multilevel lists, indent multiple lines, etc.)
82         if( (line_empty || num_newline) && isULItem(*it) )
83         {
84           if( num_newline < 2 )
85             out.push_back('\n');
86           out.append("\xE2\x80\xA2");
87         }
88         else
89         {
90           // Collapse multiple whitespace
91           if( !line_empty && (num_space || num_newline) )
92             out.push_back(' ');
93           out.push_back(*it);
94         }
95
96         line_empty = false;
97         num_space = 0;
98         num_newline = 0;
99       }
100     }
101     return out;
102   }
103
104 } // namespace simgear