1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <qregexp.h>
43 #include "atom.h"
44 #include "location.h"
45 #include <stdio.h>
46 
47 QT_BEGIN_NAMESPACE
48 
49 QString Atom::BOLD_          ("bold");
50 QString Atom::INDEX_         ("index");
51 QString Atom::ITALIC_        ("italic");
52 QString Atom::LINK_          ("link");
53 QString Atom::PARAMETER_     ("parameter");
54 QString Atom::SPAN_          ("span");
55 QString Atom::SUBSCRIPT_     ("subscript");
56 QString Atom::SUPERSCRIPT_   ("superscript");
57 QString Atom::TELETYPE_      ("teletype");
58 QString Atom::UNDERLINE_     ("underline");
59 
60 QString Atom::BULLET_        ("bullet");
61 QString Atom::TAG_           ("tag");
62 QString Atom::VALUE_         ("value");
63 QString Atom::LOWERALPHA_    ("loweralpha");
64 QString Atom::LOWERROMAN_    ("lowerroman");
65 QString Atom::NUMERIC_       ("numeric");
66 QString Atom::UPPERALPHA_    ("upperalpha");
67 QString Atom::UPPERROMAN_    ("upperroman");
68 
69 /*! \class Atom
70     \brief The Atom class is the fundamental unit for representing
71     documents internally.
72 
73   Atoms have a \i type and are completed by a \i string whose
74   meaning depends on the \i type. For example, the string
75   \quotation
76       \i italic text looks nicer than \bold bold text
77   \endquotation
78   is represented by the following atoms:
79   \quotation
80       (FormattingLeft, ATOM_FORMATTING_ITALIC)
81       (String, "italic")
82       (FormattingRight, ATOM_FORMATTING_ITALIC)
83       (String, " text is more attractive than ")
84       (FormattingLeft, ATOM_FORMATTING_BOLD)
85       (String, "bold")
86       (FormattingRight, ATOM_FORMATTING_BOLD)
87       (String, " text")
88   \endquotation
89 
90   \also Text
91 */
92 
93 /*! \enum Atom::Type
94 
95   \value AbstractLeft
96   \value AbstractRight
97   \value AnnotatedList
98   \value AutoLink
99   \value BaseName
100   \value BriefLeft
101   \value BriefRight
102   \value C
103   \value CaptionLeft
104   \value CaptionRight
105   \value Code
106   \value CodeBad
107   \value CodeNew
108   \value CodeOld
109   \value CodeQuoteArgument
110   \value CodeQuoteCommand
111   \value DivLeft
112   \value DivRight
113   \value EndQmlText
114   \value FormatElse
115   \value FormatEndif
116   \value FormatIf
117   \value FootnoteLeft
118   \value FootnoteRight
119   \value FormattingLeft
120   \value FormattingRight
121   \value GeneratedList
122   \value Image
123   \value ImageText
124   \value InlineImage
125   \value LineBreak
126   \value Link
127   \value LinkNode
128   \value ListLeft
129   \value ListItemNumber
130   \value ListTagLeft
131   \value ListTagRight
132   \value ListItemLeft
133   \value ListItemRight
134   \value ListRight
135   \value Nop
136   \value ParaLeft
137   \value ParaRight
138   \value Qml
139   \value QmlText
140   \value QuotationLeft
141   \value QuotationRight
142   \value RawString
143   \value SectionLeft
144   \value SectionRight
145   \value SectionHeadingLeft
146   \value SectionHeadingRight
147   \value SidebarLeft
148   \value SidebarRight
149   \value SinceList
150   \value String
151   \value TableLeft
152   \value TableRight
153   \value TableHeaderLeft
154   \value TableHeaderRight
155   \value TableRowLeft
156   \value TableRowRight
157   \value TableItemLeft
158   \value TableItemRight
159   \value TableOfContents
160   \value Target
161   \value UnhandledFormat
162   \value UnknownCommand
163 */
164 
165 static const struct {
166     const char *english;
167     int no;
168 } atms[] = {
169     { "AbstractLeft", Atom::AbstractLeft },
170     { "AbstractRight", Atom::AbstractRight },
171     { "AnnotatedList", Atom::AnnotatedList },
172     { "AutoLink", Atom::AutoLink },
173     { "BaseName", Atom::BaseName },
174     { "BriefLeft", Atom::BriefLeft },
175     { "BriefRight", Atom::BriefRight },
176     { "C", Atom::C },
177     { "CaptionLeft", Atom::CaptionLeft },
178     { "CaptionRight", Atom::CaptionRight },
179     { "Code", Atom::Code },
180     { "CodeBad", Atom::CodeBad },
181     { "CodeNew", Atom::CodeNew },
182     { "CodeOld", Atom::CodeOld },
183     { "CodeQuoteArgument", Atom::CodeQuoteArgument },
184     { "CodeQuoteCommand", Atom::CodeQuoteCommand },
185     { "DivLeft", Atom::DivLeft },
186     { "DivRight", Atom::DivRight },
187     { "EndQmlText", Atom::EndQmlText },
188     { "FootnoteLeft", Atom::FootnoteLeft },
189     { "FootnoteRight", Atom::FootnoteRight },
190     { "FormatElse", Atom::FormatElse },
191     { "FormatEndif", Atom::FormatEndif },
192     { "FormatIf", Atom::FormatIf },
193     { "FormattingLeft", Atom::FormattingLeft },
194     { "FormattingRight", Atom::FormattingRight },
195     { "GeneratedList", Atom::GeneratedList },
196     { "GuidLink", Atom::GuidLink},
197     { "Image", Atom::Image },
198     { "ImageText", Atom::ImageText },
199     { "InlineImage", Atom::InlineImage },
200     { "JavaScript", Atom::JavaScript },
201     { "EndJavaScript", Atom::EndJavaScript },
202     { "LegaleseLeft", Atom::LegaleseLeft },
203     { "LegaleseRight", Atom::LegaleseRight },
204     { "LineBreak", Atom::LineBreak },
205     { "Link", Atom::Link },
206     { "LinkNode", Atom::LinkNode },
207     { "ListLeft", Atom::ListLeft },
208     { "ListItemNumber", Atom::ListItemNumber },
209     { "ListTagLeft", Atom::ListTagLeft },
210     { "ListTagRight", Atom::ListTagRight },
211     { "ListItemLeft", Atom::ListItemLeft },
212     { "ListItemRight", Atom::ListItemRight },
213     { "ListRight", Atom::ListRight },
214     { "Nop", Atom::Nop },
215     { "ParaLeft", Atom::ParaLeft },
216     { "ParaRight", Atom::ParaRight },
217     { "Qml", Atom::Qml},
218     { "QmlText", Atom::QmlText },
219     { "QuotationLeft", Atom::QuotationLeft },
220     { "QuotationRight", Atom::QuotationRight },
221     { "RawString", Atom::RawString },
222     { "SectionLeft", Atom::SectionLeft },
223     { "SectionRight", Atom::SectionRight },
224     { "SectionHeadingLeft", Atom::SectionHeadingLeft },
225     { "SectionHeadingRight", Atom::SectionHeadingRight },
226     { "SidebarLeft", Atom::SidebarLeft },
227     { "SidebarRight", Atom::SidebarRight },
228     { "SinceList", Atom::SinceList },
229     { "SnippetCommand", Atom::SnippetCommand },
230     { "SnippetIdentifier", Atom::SnippetIdentifier },
231     { "SnippetLocation", Atom::SnippetLocation },
232     { "String", Atom::String },
233     { "TableLeft", Atom::TableLeft },
234     { "TableRight", Atom::TableRight },
235     { "TableHeaderLeft", Atom::TableHeaderLeft },
236     { "TableHeaderRight", Atom::TableHeaderRight },
237     { "TableRowLeft", Atom::TableRowLeft },
238     { "TableRowRight", Atom::TableRowRight },
239     { "TableItemLeft", Atom::TableItemLeft },
240     { "TableItemRight", Atom::TableItemRight },
241     { "TableOfContents", Atom::TableOfContents },
242     { "Target", Atom::Target },
243     { "UnhandledFormat", Atom::UnhandledFormat },
244     { "UnknownCommand", Atom::UnknownCommand },
245     { 0, 0 }
246 };
247 
248 /*! \fn Atom::Atom(Type type, const QString& string)
249 
250   Constructs an atom (\a type, \a string) outside of any atom list.
251 */
252 
253 /*! \fn Atom(Atom *prev, Type type, const QString& string)
254 
255   Constructs an atom (\a type, \a string) that follows \a prev in \a
256   prev's atom list.
257 */
258 
259 /*! \fn void Atom::appendChar(QChar ch)
260 
261   Appends \a ch to the string parameter of this atom.
262 
263   \also string()
264 */
265 
266 /*! \fn void Atom::appendString(const QString& string)
267 
268   Appends \a string to the string parameter of this atom.
269 
270   \also string()
271 */
272 
273 /*! \fn void Atom::chopString()
274 
275   \also string()
276 */
277 
278 /*! \fn Atom *Atom::next()
279   Return the next atom in the atom list.
280   \also type(), string()
281 */
282 
283 /*!
284   Return the next Atom in the list if it is of Type \a t.
285   Otherwise return 0.
286  */
next(Type t) const287 const Atom* Atom::next(Type t) const
288 {
289     return (nxt && (nxt->type() == t)) ? nxt : 0;
290 }
291 
292 /*!
293   Return the next Atom in the list if it is of Type \a t
294   and its string part is \a s. Otherwise return 0.
295  */
next(Type t,const QString & s) const296 const Atom* Atom::next(Type t, const QString& s) const
297 {
298     return (nxt && (nxt->type() == t) && (nxt->string() == s)) ? nxt : 0;
299 }
300 
301 /*! \fn const Atom *Atom::next() const
302   Return the next atom in the atom list.
303   \also type(), string()
304 */
305 
306 /*! \fn Type Atom::type() const
307   Return the type of this atom.
308   \also string(), next()
309 */
310 
311 /*!
312   Return the type of this atom as a string. Return "Invalid" if
313   type() returns an impossible value.
314 
315   This is only useful for debugging.
316 
317   \also type()
318 */
typeString() const319 QString Atom::typeString() const
320 {
321     static bool deja = false;
322 
323     if (!deja) {
324 	int i = 0;
325 	while (atms[i].english != 0) {
326 	    if (atms[i].no != i)
327 		Location::internalError(tr("atom %1 missing").arg(i));
328 	    i++;
329 	}
330 	deja = true;
331     }
332 
333     int i = (int) type();
334     if (i < 0 || i > (int) Last)
335         return QLatin1String("Invalid");
336     return QLatin1String(atms[i].english);
337 }
338 
339 /*! \fn const QString& Atom::string() const
340 
341   Returns the string parameter that together with the type
342   characterizes this atom.
343 
344   \also type(), next()
345 */
346 
347 /*!
348   Dumps this Atom to stderr in printer friendly form.
349  */
dump() const350 void Atom::dump() const
351 {
352     QString str = string();
353     str.replace("\\", "\\\\");
354     str.replace("\"", "\\\"");
355     str.replace("\n", "\\n");
356     str.replace(QRegExp("[^\x20-\x7e]"), "?");
357     if (!str.isEmpty())
358         str = " \"" + str + "\"";
359     fprintf(stderr,
360             "    %-15s%s\n",
361             typeString().toLatin1().data(),
362             str.toLatin1().data());
363 }
364 
365 QT_END_NAMESPACE
366