summaryrefslogtreecommitdiffstats
path: root/src/qdoc/qdoc/src/qdoc/atom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qdoc/qdoc/src/qdoc/atom.cpp')
-rw-r--r--src/qdoc/qdoc/src/qdoc/atom.cpp432
1 files changed, 432 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/atom.cpp b/src/qdoc/qdoc/src/qdoc/atom.cpp
new file mode 100644
index 000000000..10f67696c
--- /dev/null
+++ b/src/qdoc/qdoc/src/qdoc/atom.cpp
@@ -0,0 +1,432 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "atom.h"
+
+#include "location.h"
+#include "qdocdatabase.h"
+
+#include <QtCore/qregularexpression.h>
+
+#include <cstdio>
+
+QT_BEGIN_NAMESPACE
+
+/*! \class Atom
+ \brief The Atom class is the fundamental unit for representing
+ documents internally.
+
+ Atoms have a \i type and are completed by a \i string whose
+ meaning depends on the \i type. For example, the string
+ \quotation
+ \i italic text looks nicer than \bold bold text
+ \endquotation
+ is represented by the following atoms:
+ \quotation
+ (FormattingLeft, ATOM_FORMATTING_ITALIC)
+ (String, "italic")
+ (FormattingRight, ATOM_FORMATTING_ITALIC)
+ (String, " text is more attractive than ")
+ (FormattingLeft, ATOM_FORMATTING_BOLD)
+ (String, "bold")
+ (FormattingRight, ATOM_FORMATTING_BOLD)
+ (String, " text")
+ \endquotation
+
+ \also Text
+*/
+
+/*! \enum Atom::AtomType
+
+ \value AnnotatedList
+ \value AutoLink
+ \value BaseName
+ \value BriefLeft
+ \value BriefRight
+ \value C
+ \value CaptionLeft
+ \value CaptionRight
+ \value Code
+ \value CodeBad
+ \value CodeQuoteArgument
+ \value CodeQuoteCommand
+ \value DetailsLeft
+ \value DetailsRight
+ \value DivLeft
+ \value DivRight
+ \value ExampleFileLink
+ \value ExampleImageLink
+ \value FormatElse
+ \value FormatEndif
+ \value FormatIf
+ \value FootnoteLeft
+ \value FootnoteRight
+ \value FormattingLeft
+ \value FormattingRight
+ \value GeneratedList
+ \value Image
+ \value ImageText
+ \value ImportantNote
+ \value InlineImage
+ \value Keyword
+ \value LineBreak
+ \value Link
+ \value LinkNode
+ \value ListLeft
+ \value ListItemNumber
+ \value ListTagLeft
+ \value ListTagRight
+ \value ListItemLeft
+ \value ListItemRight
+ \value ListRight
+ \value NavAutoLink
+ \value NavLink
+ \value Nop
+ \value Note
+ \value ParaLeft
+ \value ParaRight
+ \value Qml
+ \value QuotationLeft
+ \value QuotationRight
+ \value RawString
+ \value SectionLeft
+ \value SectionRight
+ \value SectionHeadingLeft
+ \value SectionHeadingRight
+ \value SidebarLeft
+ \value SidebarRight
+ \value SinceList
+ \value SinceTagLeft
+ \value SinceTagRight
+ \value String
+ \value TableLeft
+ \value TableRight
+ \value TableHeaderLeft
+ \value TableHeaderRight
+ \value TableRowLeft
+ \value TableRowRight
+ \value TableItemLeft
+ \value TableItemRight
+ \value TableOfContents
+ \value Target
+ \value UnhandledFormat
+ \value UnknownCommand
+*/
+
+static const struct
+{
+ const char *english;
+ int no;
+} atms[] = { { "AnnotatedList", Atom::AnnotatedList },
+ { "AutoLink", Atom::AutoLink },
+ { "BaseName", Atom::BaseName },
+ { "br", Atom::BR },
+ { "BriefLeft", Atom::BriefLeft },
+ { "BriefRight", Atom::BriefRight },
+ { "C", Atom::C },
+ { "CaptionLeft", Atom::CaptionLeft },
+ { "CaptionRight", Atom::CaptionRight },
+ { "Code", Atom::Code },
+ { "CodeBad", Atom::CodeBad },
+ { "CodeQuoteArgument", Atom::CodeQuoteArgument },
+ { "CodeQuoteCommand", Atom::CodeQuoteCommand },
+ { "ComparesLeft", Atom::ComparesLeft },
+ { "ComparesRight", Atom::ComparesRight },
+ { "DetailsLeft", Atom::DetailsLeft },
+ { "DetailsRight", Atom::DetailsRight },
+ { "DivLeft", Atom::DivLeft },
+ { "DivRight", Atom::DivRight },
+ { "ExampleFileLink", Atom::ExampleFileLink },
+ { "ExampleImageLink", Atom::ExampleImageLink },
+ { "FootnoteLeft", Atom::FootnoteLeft },
+ { "FootnoteRight", Atom::FootnoteRight },
+ { "FormatElse", Atom::FormatElse },
+ { "FormatEndif", Atom::FormatEndif },
+ { "FormatIf", Atom::FormatIf },
+ { "FormattingLeft", Atom::FormattingLeft },
+ { "FormattingRight", Atom::FormattingRight },
+ { "GeneratedList", Atom::GeneratedList },
+ { "hr", Atom::HR },
+ { "Image", Atom::Image },
+ { "ImageText", Atom::ImageText },
+ { "ImportantLeft", Atom::ImportantLeft },
+ { "ImportantRight", Atom::ImportantRight },
+ { "InlineImage", Atom::InlineImage },
+ { "Keyword", Atom::Keyword },
+ { "LegaleseLeft", Atom::LegaleseLeft },
+ { "LegaleseRight", Atom::LegaleseRight },
+ { "LineBreak", Atom::LineBreak },
+ { "Link", Atom::Link },
+ { "LinkNode", Atom::LinkNode },
+ { "ListLeft", Atom::ListLeft },
+ { "ListItemNumber", Atom::ListItemNumber },
+ { "ListTagLeft", Atom::ListTagLeft },
+ { "ListTagRight", Atom::ListTagRight },
+ { "ListItemLeft", Atom::ListItemLeft },
+ { "ListItemRight", Atom::ListItemRight },
+ { "ListRight", Atom::ListRight },
+ { "NavAutoLink", Atom::NavAutoLink },
+ { "NavLink", Atom::NavLink },
+ { "Nop", Atom::Nop },
+ { "NoteLeft", Atom::NoteLeft },
+ { "NoteRight", Atom::NoteRight },
+ { "ParaLeft", Atom::ParaLeft },
+ { "ParaRight", Atom::ParaRight },
+ { "Qml", Atom::Qml },
+ { "QuotationLeft", Atom::QuotationLeft },
+ { "QuotationRight", Atom::QuotationRight },
+ { "RawString", Atom::RawString },
+ { "SectionLeft", Atom::SectionLeft },
+ { "SectionRight", Atom::SectionRight },
+ { "SectionHeadingLeft", Atom::SectionHeadingLeft },
+ { "SectionHeadingRight", Atom::SectionHeadingRight },
+ { "SidebarLeft", Atom::SidebarLeft },
+ { "SidebarRight", Atom::SidebarRight },
+ { "SinceList", Atom::SinceList },
+ { "SinceTagLeft", Atom::SinceTagLeft },
+ { "SinceTagRight", Atom::SinceTagRight },
+ { "SnippetCommand", Atom::SnippetCommand },
+ { "SnippetIdentifier", Atom::SnippetIdentifier },
+ { "SnippetLocation", Atom::SnippetLocation },
+ { "String", Atom::String },
+ { "TableLeft", Atom::TableLeft },
+ { "TableRight", Atom::TableRight },
+ { "TableHeaderLeft", Atom::TableHeaderLeft },
+ { "TableHeaderRight", Atom::TableHeaderRight },
+ { "TableRowLeft", Atom::TableRowLeft },
+ { "TableRowRight", Atom::TableRowRight },
+ { "TableItemLeft", Atom::TableItemLeft },
+ { "TableItemRight", Atom::TableItemRight },
+ { "TableOfContents", Atom::TableOfContents },
+ { "Target", Atom::Target },
+ { "UnhandledFormat", Atom::UnhandledFormat },
+ { "WarningLeft", Atom::WarningLeft },
+ { "WarningRight", Atom::WarningRight },
+ { "UnknownCommand", Atom::UnknownCommand },
+ { nullptr, 0 } };
+
+/*! \fn Atom::Atom(AtomType type, const QString &string)
+
+ Constructs an atom of the specified \a type with the single
+ parameter \a string and does not put the new atom in a list.
+*/
+
+/*! \fn Atom::Atom(AtomType type, const QString &p1, const QString &p2)
+
+ Constructs an atom of the specified \a type with the two
+ parameters \a p1 and \a p2 and does not put the new atom
+ in a list.
+*/
+
+/*! \fn Atom(Atom *previous, AtomType type, const QString &string)
+
+ Constructs an atom of the specified \a type with the single
+ parameter \a string and inserts the new atom into the list
+ after the \a previous atom.
+*/
+
+/*! \fn Atom::Atom(Atom *previous, AtomType type, const QString &p1, const QString &p2)
+
+ Constructs an atom of the specified \a type with the two
+ parameters \a p1 and \a p2 and inserts the new atom into
+ the list after the \a previous atom.
+*/
+
+/*! \fn void Atom::appendChar(QChar ch)
+
+ Appends \a ch to the string parameter of this atom.
+
+ \also string()
+*/
+
+/*! \fn void Atom::concatenateString(const QString &string)
+
+ Appends \a string to the string parameter of this atom.
+
+ \also string()
+*/
+
+/*! \fn void Atom::chopString()
+
+ \also string()
+*/
+
+/*! \fn Atom *Atom::next()
+ Return the next atom in the atom list.
+ \also type(), string()
+*/
+
+/*!
+ Return the next Atom in the list if it is of AtomType \a t.
+ Otherwise return 0.
+ */
+const Atom *Atom::next(AtomType t) const
+{
+ return (m_next && (m_next->type() == t)) ? m_next : nullptr;
+}
+
+/*!
+ Return the next Atom in the list if it is of AtomType \a t
+ and its string part is \a s. Otherwise return 0.
+ */
+const Atom *Atom::next(AtomType t, const QString &s) const
+{
+ return (m_next && (m_next->type() == t) && (m_next->string() == s)) ? m_next : nullptr;
+}
+
+/*! \fn const Atom *Atom::next() const
+ Return the next atom in the atom list.
+ \also type(), string()
+*/
+
+/*! \fn AtomType Atom::type() const
+ Return the type of this atom.
+ \also string(), next()
+*/
+
+/*!
+ Return the type of this atom as a string. Return "Invalid" if
+ type() returns an impossible value.
+
+ This is only useful for debugging.
+
+ \also type()
+*/
+QString Atom::typeString() const
+{
+ static bool deja = false;
+
+ if (!deja) {
+ int i = 0;
+ while (atms[i].english != nullptr) {
+ if (atms[i].no != i)
+ Location::internalError(QStringLiteral("QDoc::Atom: atom %1 missing").arg(i));
+ ++i;
+ }
+ deja = true;
+ }
+
+ int i = static_cast<int>(type());
+ if (i < 0 || i > static_cast<int>(Last))
+ return QLatin1String("Invalid");
+ return QLatin1String(atms[i].english);
+}
+
+/*! \fn const QString &Atom::string() const
+
+ Returns the string parameter that together with the type
+ characterizes this atom.
+
+ \also type(), next()
+*/
+
+/*!
+ For a link atom, returns the string representing the link text
+ if one exist in the list of atoms.
+*/
+QString Atom::linkText() const
+{
+ Q_ASSERT(m_type == Atom::Link);
+ QString result;
+
+ if (next() && next()->string() == ATOM_FORMATTING_LINK) {
+ auto *atom = next()->next();
+ while (atom && atom->type() != Atom::FormattingRight) {
+ result += atom->string();
+ atom = atom->next();
+ }
+ return result;
+ }
+
+ return string();
+}
+
+/*!
+ The only constructor for LinkAtom. It creates an Atom of
+ type Atom::Link. \a p1 being the link target. \a p2 is the
+ parameters in square brackets. Normally there is just one
+ word in the square brackets, but there can be up to three
+ words separated by spaces. The constructor splits \a p2 on
+ the space character.
+ */
+LinkAtom::LinkAtom(const QString &p1, const QString &p2, Location location)
+ : Atom(Atom::Link, p1),
+ location(location),
+ m_resolved(false),
+ m_genus(Node::DontCare),
+ m_domain(nullptr),
+ m_squareBracketParams(p2)
+{
+ // nada.
+}
+
+/*!
+ This function resolves the parameters that were enclosed in
+ square brackets. If the parameters have already been resolved,
+ it does nothing and returns immediately.
+ */
+void LinkAtom::resolveSquareBracketParams()
+{
+ if (m_resolved)
+ return;
+ const QStringList params = m_squareBracketParams.toLower().split(QLatin1Char(' '));
+ for (const auto &param : params) {
+ if (!m_domain) {
+ m_domain = QDocDatabase::qdocDB()->findTree(param);
+ if (m_domain) {
+ continue;
+ }
+ }
+
+ if (param == "qml") {
+ m_genus = Node::QML;
+ continue;
+ }
+ if (param == "cpp") {
+ m_genus = Node::CPP;
+ continue;
+ }
+ if (param == "doc") {
+ m_genus = Node::DOC;
+ continue;
+ }
+ if (param == "api") {
+ m_genus = Node::API;
+ continue;
+ }
+ break;
+ }
+ m_resolved = true;
+}
+
+/*!
+ Standard copy constructor of LinkAtom \a t.
+ */
+LinkAtom::LinkAtom(const LinkAtom &t)
+ : Atom(Link, t.string()),
+ location(t.location),
+ m_resolved(t.m_resolved),
+ m_genus(t.m_genus),
+ m_domain(t.m_domain),
+ m_squareBracketParams(t.m_squareBracketParams)
+{
+ // nothing
+}
+
+/*!
+ Special copy constructor of LinkAtom \a t, where
+ where the new LinkAtom will not be the first one
+ in the list.
+ */
+LinkAtom::LinkAtom(Atom *previous, const LinkAtom &t)
+ : Atom(previous, Link, t.string()),
+ location(t.location),
+ m_resolved(t.m_resolved),
+ m_genus(t.m_genus),
+ m_domain(t.m_domain),
+ m_squareBracketParams(t.m_squareBracketParams)
+{
+ previous->m_next = this;
+}
+
+QT_END_NAMESPACE