/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "webxmlgenerator.h"

#include "helpprojectwriter.h"
#include "node.h"
#include "qdocdatabase.h"
#include "separator.h"
#include "quoter.h"
#include "tree.h"

#include <QtCore/qxmlstream.h>

QT_BEGIN_NAMESPACE

static CodeMarker *marker_ = nullptr;

void WebXMLGenerator::initializeGenerator(const Config &config)
{
    HtmlGenerator::initializeGenerator(config);
}

void WebXMLGenerator::terminateGenerator()
{
    Generator::terminateGenerator();
}

QString WebXMLGenerator::format()
{
    return "WebXML";
}

QString WebXMLGenerator::fileExtension() const
{
    // As this is meant to be an intermediate format,
    // use .html for internal references. The name of
    // the output file is set separately in
    // beginSubPage() calls.
    return "html";
}

/*!
    Most of the output is generated by QDocIndexFiles and the append() callback.
    Some pages produce supplementary output while being generated, and that's
    handled here.
*/
int WebXMLGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker)
{
    if (supplement && currentWriter)
        addAtomElements(*currentWriter.data(), atom, relative, marker);
    return 0;
}

void WebXMLGenerator::generateCppReferencePage(Aggregate *aggregate, CodeMarker * /* marker */)
{
    QByteArray data;
    QXmlStreamWriter writer(&data);
    writer.setAutoFormatting(true);
    beginSubPage(aggregate, Generator::fileName(aggregate, "webxml"));
    writer.writeStartDocument();
    writer.writeStartElement("WebXML");
    writer.writeStartElement("document");

    generateIndexSections(writer, aggregate);

    writer.writeEndElement(); // document
    writer.writeEndElement(); // WebXML
    writer.writeEndDocument();

    out() << data;
    endSubPage();
}

void WebXMLGenerator::generatePageNode(PageNode *pn, CodeMarker * /* marker */)
{
    QByteArray data;
    currentWriter.reset(new QXmlStreamWriter(&data));
    currentWriter->setAutoFormatting(true);
    beginSubPage(pn, Generator::fileName(pn, "webxml"));
    currentWriter->writeStartDocument();
    currentWriter->writeStartElement("WebXML");
    currentWriter->writeStartElement("document");

    generateIndexSections(*currentWriter.data(), pn);

    currentWriter->writeEndElement(); // document
    currentWriter->writeEndElement(); // WebXML
    currentWriter->writeEndDocument();

    out() << data;
    endSubPage();
}

void WebXMLGenerator::generateExampleFilePage(const Node *en, const QString &file,
                                              CodeMarker * /* marker */)
{
    QByteArray data;
    QXmlStreamWriter writer(&data);
    writer.setAutoFormatting(true);
    beginFilePage(en, linkForExampleFile(file, en, "webxml"));
    writer.writeStartDocument();
    writer.writeStartElement("WebXML");
    writer.writeStartElement("document");
    writer.writeStartElement("page");
    writer.writeAttribute("name", file);
    writer.writeAttribute("href", linkForExampleFile(file, en));
    QString title = exampleFileTitle(static_cast<const ExampleNode *>(en), file);
    writer.writeAttribute("title", title);
    writer.writeAttribute("fulltitle", title);
    writer.writeAttribute("subtitle", file);
    writer.writeStartElement("description");
    QString userFriendlyFilePath; // unused
    writer.writeAttribute("path",
                          Doc::resolveFile(en->doc().location(), file, &userFriendlyFilePath));
    writer.writeAttribute("line", "0");
    writer.writeAttribute("column", "0");

    Quoter quoter;
    Doc::quoteFromFile(en->doc().location(), quoter, file);
    QString code = quoter.quoteTo(en->location(), QString(), QString());
    writer.writeTextElement("code", trimmedTrailing(code, QString(), QString()));

    writer.writeEndElement(); // description
    writer.writeEndElement(); // page
    writer.writeEndElement(); // document
    writer.writeEndElement(); // WebXML
    writer.writeEndDocument();

    out() << data;
    endFilePage();
}

void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer, Node *node)
{
    marker_ = CodeMarker::markerForFileName(node->location().filePath());
    QDocIndexFiles::qdocIndexFiles()->generateIndexSections(writer, node, this);
    // generateIndexSections does nothing for groups, so handle them explicitly
    if (node->isGroup())
        QDocIndexFiles::qdocIndexFiles()->generateIndexSection(writer, node, this);
}

// Handles callbacks from QDocIndexFiles to add documentation to node
void WebXMLGenerator::append(QXmlStreamWriter &writer, Node *node)
{
    Q_ASSERT(marker_);

    writer.writeStartElement("description");
    writer.writeAttribute("path", node->doc().location().filePath());
    writer.writeAttribute("line", QString::number(node->doc().location().lineNo()));
    writer.writeAttribute("column", QString::number(node->doc().location().columnNo()));

    if (node->isTextPageNode())
        generateRelations(writer, node);

    if (node->isModule()) {
        writer.writeStartElement("generatedlist");
        writer.writeAttribute("contents", "classesbymodule");
        CollectionNode *cnn = static_cast<CollectionNode *>(node);

        if (cnn->hasNamespaces()) {
            writer.writeStartElement("section");
            writer.writeStartElement("heading");
            writer.writeAttribute("level", "1");
            writer.writeCharacters("Namespaces");
            writer.writeEndElement(); // heading
            NodeMap namespaces;
            cnn->getMemberNamespaces(namespaces);
            generateAnnotatedList(writer, node, namespaces);
            writer.writeEndElement(); // section
        }
        if (cnn->hasClasses()) {
            writer.writeStartElement("section");
            writer.writeStartElement("heading");
            writer.writeAttribute("level", "1");
            writer.writeCharacters("Classes");
            writer.writeEndElement(); // heading
            NodeMap classes;
            cnn->getMemberClasses(classes);
            generateAnnotatedList(writer, node, classes);
            writer.writeEndElement(); // section
        }
        writer.writeEndElement(); // generatedlist
    }

    inLink = inContents = inSectionHeading = hasQuotingInformation = false;
    numTableRows = 0;

    const Atom *atom = node->doc().body().firstAtom();
    while (atom)
        atom = addAtomElements(writer, atom, node, marker_);

    QVector<Text> alsoList = node->doc().alsoList();
    supplementAlsoList(node, alsoList);

    if (!alsoList.isEmpty()) {
        writer.writeStartElement("see-also");
        for (int i = 0; i < alsoList.size(); ++i) {
            const Atom *atom = alsoList.at(i).firstAtom();
            while (atom)
                atom = addAtomElements(writer, atom, node, marker_);
        }
        writer.writeEndElement(); // see-also
    }

    if (node->isExample()) {
        supplement = true;
        generateRequiredLinks(node, marker_);
        supplement = false;
    } else if (node->isGroup()) {
        CollectionNode *cn = static_cast<CollectionNode *>(node);
        if (!cn->noAutoList())
            generateAnnotatedList(writer, node, cn->members());
    }

    writer.writeEndElement(); // description
}

void WebXMLGenerator::generateDocumentation(Node *node)
{
    // Don't generate nodes that are already processed, or if they're not supposed to
    // generate output, ie. external, index or images nodes.
    if (!node->url().isNull() || node->isExternalPage() || node->isIndexNode())
        return;

    if (node->isInternal() && !showInternal_)
        return;

    if (node->parent()) {
        if (node->isNamespace() || node->isClassNode() || node->isHeader())
            generateCppReferencePage(static_cast<Aggregate *>(node), nullptr);
        else if (node->isCollectionNode()) {
            if (node->wasSeen()) {
                // see remarks in base class impl.
                qdb_->mergeCollections(static_cast<CollectionNode *>(node));
                generatePageNode(static_cast<PageNode *>(node), nullptr);
            }
        } else if (node->isTextPageNode())
            generatePageNode(static_cast<PageNode *>(node), nullptr);
        // else if TODO: anything else?
    }

    if (node->isAggregate()) {
        Aggregate *aggregate = static_cast<Aggregate *>(node);
        for (auto c : aggregate->childNodes()) {
            if ((c->isAggregate() || c->isTextPageNode() || c->isCollectionNode())
                && !c->isPrivate())
                generateDocumentation(c);
        }
    }
}

const Atom *WebXMLGenerator::addAtomElements(QXmlStreamWriter &writer, const Atom *atom,
                                             const Node *relative, CodeMarker *marker)
{
    bool keepQuoting = false;

    if (!atom)
        return nullptr;

    switch (atom->type()) {
    case Atom::AnnotatedList: {
        const CollectionNode *cn = qdb_->getCollectionNode(atom->string(), Node::Group);
        if (cn)
            generateAnnotatedList(writer, relative, cn->members());
    } break;
    case Atom::AutoLink:
        if (!inLink && !inSectionHeading) {
            const Node *node = nullptr;
            QString link = getLink(atom, relative, &node);
            if (node) {
                startLink(writer, atom, node, link);
                if (inLink) {
                    writer.writeCharacters(atom->string());
                    writer.writeEndElement(); // link
                    inLink = false;
                }
            } else {
                writer.writeCharacters(atom->string());
            }
        } else {
            writer.writeCharacters(atom->string());
        }
        break;
    case Atom::BaseName:
        break;
    case Atom::BriefLeft:

        writer.writeStartElement("brief");
        switch (relative->nodeType()) {
        case Node::Property:
            writer.writeCharacters("This property");
            break;
        case Node::Variable:
            writer.writeCharacters("This variable");
            break;
        default:
            break;
        }
        if (relative->isProperty() || relative->isVariable()) {
            QString str;
            const Atom *a = atom->next();
            while (a != nullptr && a->type() != Atom::BriefRight) {
                if (a->type() == Atom::String || a->type() == Atom::AutoLink)
                    str += a->string();
                a = a->next();
            }
            str[0] = str[0].toLower();
            if (str.endsWith('.'))
                str.chop(1);

            const QVector<QStringRef> words = str.splitRef(' ');
            if (!words.isEmpty()) {
                const QStringRef &first(words.at(0));
                if (!(first == "contains" || first == "specifies" || first == "describes"
                      || first == "defines" || first == "holds" || first == "determines"))
                    writer.writeCharacters(" holds ");
                else
                    writer.writeCharacters(" ");
            }
        }
        break;

    case Atom::BriefRight:
        if (relative->isProperty() || relative->isVariable())
            writer.writeCharacters(".");

        writer.writeEndElement(); // brief
        break;

    case Atom::C:
        writer.writeStartElement("teletype");
        if (inLink)
            writer.writeAttribute("type", "normal");
        else
            writer.writeAttribute("type", "highlighted");

        writer.writeCharacters(plainCode(atom->string()));
        writer.writeEndElement(); // teletype
        break;

    case Atom::Code:
        if (!hasQuotingInformation)
            writer.writeTextElement(
                    "code", trimmedTrailing(plainCode(atom->string()), QString(), QString()));
        else
            keepQuoting = true;
        break;

#ifdef QDOC_QML
    case Atom::Qml:
        if (!hasQuotingInformation)
            writer.writeTextElement(
                    "qml", trimmedTrailing(plainCode(atom->string()), QString(), QString()));
        else
            keepQuoting = true;
#endif
    case Atom::CodeBad:
        writer.writeTextElement("badcode",
                                trimmedTrailing(plainCode(atom->string()), QString(), QString()));
        break;

    case Atom::CodeNew:
        writer.writeTextElement("para", "you can rewrite it as");
        writer.writeTextElement("newcode",
                                trimmedTrailing(plainCode(atom->string()), QString(), QString()));
        break;

    case Atom::CodeOld:
        writer.writeTextElement("para", "For example, if you have code like");
        writer.writeTextElement("oldcode",
                                trimmedTrailing(plainCode(atom->string()), QString(), QString()));
        break;

    case Atom::CodeQuoteArgument:
        if (quoting_) {
            if (quoteCommand == "dots") {
                writer.writeAttribute("indent", atom->string());
                writer.writeCharacters("...");
            } else {
                writer.writeCharacters(atom->string());
            }
            writer.writeEndElement(); // code
            keepQuoting = true;
        }
        break;

    case Atom::CodeQuoteCommand:
        if (quoting_) {
            quoteCommand = atom->string();
            writer.writeStartElement(quoteCommand);
        }
        break;

    case Atom::ExampleFileLink: {
        if (!inLink) {
            QString link = linkForExampleFile(atom->string(), relative);
            if (!link.isEmpty())
                startLink(writer, atom, relative, link);
        }
    } break;

    case Atom::ExampleImageLink: {
        if (!inLink) {
            QString link = atom->string();
            if (!link.isEmpty())
                startLink(writer, atom, nullptr, "images/used-in-examples/" + link);
        }
    } break;

    case Atom::FootnoteLeft:
        writer.writeStartElement("footnote");
        break;

    case Atom::FootnoteRight:
        writer.writeEndElement(); // footnote
        break;

    case Atom::FormatEndif:
        writer.writeEndElement(); // raw
        break;
    case Atom::FormatIf:
        writer.writeStartElement("raw");
        writer.writeAttribute("format", atom->string());
        break;
    case Atom::FormattingLeft: {
        if (atom->string() == ATOM_FORMATTING_BOLD)
            writer.writeStartElement("bold");
        else if (atom->string() == ATOM_FORMATTING_ITALIC)
            writer.writeStartElement("italic");
        else if (atom->string() == ATOM_FORMATTING_UNDERLINE)
            writer.writeStartElement("underline");
        else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT)
            writer.writeStartElement("subscript");
        else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT)
            writer.writeStartElement("superscript");
        else if (atom->string() == ATOM_FORMATTING_TELETYPE)
            writer.writeStartElement("teletype");
        else if (atom->string() == ATOM_FORMATTING_PARAMETER)
            writer.writeStartElement("argument");
        else if (atom->string() == ATOM_FORMATTING_INDEX)
            writer.writeStartElement("index");
    } break;

    case Atom::FormattingRight: {
        if (atom->string() == ATOM_FORMATTING_BOLD)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_ITALIC)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_UNDERLINE)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_SUBSCRIPT)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_SUPERSCRIPT)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_TELETYPE)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_PARAMETER)
            writer.writeEndElement();
        else if (atom->string() == ATOM_FORMATTING_INDEX)
            writer.writeEndElement();
    }
        if (inLink) {
            writer.writeEndElement(); // link
            inLink = false;
        }
        break;

    case Atom::GeneratedList:
        writer.writeStartElement("generatedlist");
        writer.writeAttribute("contents", atom->string());
        writer.writeEndElement();
        break;
    case Atom::Image:
        writer.writeStartElement("image");
        writer.writeAttribute("href", imageFileName(relative, atom->string()));
        writer.writeEndElement();
        break;

    case Atom::InlineImage:
        writer.writeStartElement("inlineimage");
        writer.writeAttribute("href", imageFileName(relative, atom->string()));
        writer.writeEndElement();
        break;

    case Atom::ImageText:
        break;

    case Atom::ImportantLeft:
        writer.writeStartElement("para");
        writer.writeTextElement("bold", "Important:");
        writer.writeCharacters(" ");
        break;

    case Atom::ImportantRight:
        writer.writeEndElement(); // para
        break;

    case Atom::LegaleseLeft:
        writer.writeStartElement("legalese");
        break;

    case Atom::LegaleseRight:
        writer.writeEndElement(); // legalese
        break;

    case Atom::Link:
    case Atom::LinkNode:
        if (!inLink) {
            const Node *node = nullptr;
            QString link = getLink(atom, relative, &node);
            if (!link.isEmpty())
                startLink(writer, atom, node, link);
        }
        break;

    case Atom::ListLeft:
        writer.writeStartElement("list");

        if (atom->string() == ATOM_LIST_BULLET)
            writer.writeAttribute("type", "bullet");
        else if (atom->string() == ATOM_LIST_TAG)
            writer.writeAttribute("type", "definition");
        else if (atom->string() == ATOM_LIST_VALUE) {
            if (relative->isEnumType())
                writer.writeAttribute("type", "enum");
            else
                writer.writeAttribute("type", "definition");
        } else {
            writer.writeAttribute("type", "ordered");
            if (atom->string() == ATOM_LIST_UPPERALPHA)
                writer.writeAttribute("start", "A");
            else if (atom->string() == ATOM_LIST_LOWERALPHA)
                writer.writeAttribute("start", "a");
            else if (atom->string() == ATOM_LIST_UPPERROMAN)
                writer.writeAttribute("start", "I");
            else if (atom->string() == ATOM_LIST_LOWERROMAN)
                writer.writeAttribute("start", "i");
            else // (atom->string() == ATOM_LIST_NUMERIC)
                writer.writeAttribute("start", "1");
        }
        break;

    case Atom::ListItemNumber:
        break;
    case Atom::ListTagLeft: {
        writer.writeStartElement("definition");

        writer.writeTextElement(
                "term", plainCode(marker->markedUpEnumValue(atom->next()->string(), relative)));
    } break;

    case Atom::ListTagRight:
        writer.writeEndElement(); // definition
        break;

    case Atom::ListItemLeft:
        writer.writeStartElement("item");
        break;

    case Atom::ListItemRight:
        writer.writeEndElement(); // item
        break;

    case Atom::ListRight:
        writer.writeEndElement(); // list
        break;

    case Atom::NoteLeft:
        writer.writeStartElement("para");
        writer.writeTextElement("bold", "Note:");
        writer.writeCharacters(" ");
        break;

    case Atom::NoteRight:
        writer.writeEndElement(); // para
        break;

    case Atom::Nop:
        break;

    case Atom::ParaLeft:
        writer.writeStartElement("para");
        break;

    case Atom::ParaRight:
        writer.writeEndElement(); // para
        break;

    case Atom::QuotationLeft:
        writer.writeStartElement("quote");
        break;

    case Atom::QuotationRight:
        writer.writeEndElement(); // quote
        break;

    case Atom::RawString:
        writer.writeCharacters(atom->string());
        break;

    case Atom::SectionLeft:
        writer.writeStartElement("section");
        writer.writeAttribute("id", Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
        break;

    case Atom::SectionRight:
        writer.writeEndElement(); // section
        break;

    case Atom::SectionHeadingLeft: {
        writer.writeStartElement("heading");
        int unit = atom->string().toInt(); // + hOffset(relative)
        writer.writeAttribute("level", QString::number(unit));
        inSectionHeading = true;
    } break;

    case Atom::SectionHeadingRight:
        writer.writeEndElement(); // heading
        inSectionHeading = false;
        break;

    case Atom::SidebarLeft:
    case Atom::SidebarRight:
        break;

    case Atom::SnippetCommand:
        if (quoting_) {
            writer.writeStartElement(atom->string());
        }
        break;

    case Atom::SnippetIdentifier:
        if (quoting_) {
            writer.writeAttribute("identifier", atom->string());
            writer.writeEndElement();
            keepQuoting = true;
        }
        break;

    case Atom::SnippetLocation:
        if (quoting_) {
            const QString location = atom->string();
            writer.writeAttribute("location", location);
            const QString resolved = Doc::resolveFile(Location(), location);
            if (!resolved.isEmpty())
                writer.writeAttribute("path", resolved);
        }
        break;

    case Atom::String:
        writer.writeCharacters(atom->string());
        break;
    case Atom::TableLeft:
        writer.writeStartElement("table");
        if (atom->string().contains("%"))
            writer.writeAttribute("width", atom->string());
        break;

    case Atom::TableRight:
        writer.writeEndElement(); // table
        break;

    case Atom::TableHeaderLeft:
        writer.writeStartElement("header");
        break;

    case Atom::TableHeaderRight:
        writer.writeEndElement(); // header
        break;

    case Atom::TableRowLeft:
        writer.writeStartElement("row");
        break;

    case Atom::TableRowRight:
        writer.writeEndElement(); // row
        break;

    case Atom::TableItemLeft: {
        writer.writeStartElement("item");
        QStringList spans = atom->string().split(",");
        if (spans.size() == 2) {
            if (spans.at(0) != "1")
                writer.writeAttribute("colspan", spans.at(0).trimmed());
            if (spans.at(1) != "1")
                writer.writeAttribute("rowspan", spans.at(1).trimmed());
        }
    } break;
    case Atom::TableItemRight:
        writer.writeEndElement(); // item
        break;

    case Atom::Target:
        writer.writeStartElement("target");
        writer.writeAttribute("name", Doc::canonicalTitle(atom->string()));
        writer.writeEndElement();
        break;

    case Atom::UnhandledFormat:
    case Atom::UnknownCommand:
        writer.writeCharacters(atom->typeString());
        break;
    default:
        break;
    }

    hasQuotingInformation = keepQuoting;
    return atom->next();
}

void WebXMLGenerator::startLink(QXmlStreamWriter &writer, const Atom *atom, const Node *node,
                                const QString &link)
{
    QString fullName = link;
    if (node)
        fullName = node->fullName();
    if (!fullName.isEmpty() && !link.isEmpty()) {
        writer.writeStartElement("link");
        if (!atom->string().isEmpty())
            writer.writeAttribute("raw", atom->string());
        else
            writer.writeAttribute("raw", fullName);
        writer.writeAttribute("href", link);
        writer.writeAttribute("type", targetType(node));
        if (node) {
            switch (node->nodeType()) {
            case Node::Enum:
                writer.writeAttribute("enum", fullName);
                break;
            case Node::Example: {
                const ExampleNode *en = static_cast<const ExampleNode *>(node);
                QString fileTitle = exampleFileTitle(en, atom->string());
                if (!fileTitle.isEmpty()) {
                    writer.writeAttribute("page", fileTitle);
                    break;
                }
            }
                Q_FALLTHROUGH();
            case Node::Page:
                writer.writeAttribute("page", fullName);
                break;
            case Node::Property: {
                const PropertyNode *propertyNode = static_cast<const PropertyNode *>(node);
                if (propertyNode->getters().size() > 0)
                    writer.writeAttribute("getter", propertyNode->getters().at(0)->fullName());
            } break;
            default:
                break;
            }
        }
        inLink = true;
    }
}

void WebXMLGenerator::endLink(QXmlStreamWriter &writer)
{
    if (inLink) {
        writer.writeEndElement(); // link
        inLink = false;
    }
}

void WebXMLGenerator::generateRelations(QXmlStreamWriter &writer, const Node *node)
{
    if (node && !node->links().empty()) {
        QPair<QString, QString> anchorPair;
        const Node *linkNode;

        for (auto it = node->links().cbegin(); it != node->links().cend(); ++it) {

            linkNode = qdb_->findNodeForTarget(it.value().first, node);

            if (!linkNode)
                linkNode = node;

            if (linkNode == node)
                anchorPair = it.value();
            else
                anchorPair = anchorForNode(linkNode);

            writer.writeStartElement("relation");
            writer.writeAttribute("href", anchorPair.first);
            writer.writeAttribute("type", targetType(linkNode));

            switch (it.key()) {
            case Node::StartLink:
                writer.writeAttribute("meta", "start");
                break;
            case Node::NextLink:
                writer.writeAttribute("meta", "next");
                break;
            case Node::PreviousLink:
                writer.writeAttribute("meta", "previous");
                break;
            case Node::ContentsLink:
                writer.writeAttribute("meta", "contents");
                break;
            default:
                writer.writeAttribute("meta", "");
            }
            writer.writeAttribute("description", anchorPair.second);
            writer.writeEndElement(); // link
        }
    }
}

void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer, const Node *relative,
                                            const NodeMap &nodeMap)
{
    generateAnnotatedList(writer, relative, nodeMap.values());
}

void WebXMLGenerator::generateAnnotatedList(QXmlStreamWriter &writer, const Node *relative,
                                            const NodeList &nodeList)
{
    writer.writeStartElement("table");
    writer.writeAttribute("width", "100%");

    for (const auto *node : nodeList) {
        writer.writeStartElement("row");
        writer.writeStartElement("item");
        writer.writeStartElement("para");
        const QString link = linkForNode(node, relative);
        startLink(writer, node->doc().body().firstAtom(), node, link);
        endLink(writer);
        writer.writeEndElement(); // para
        writer.writeEndElement(); // item

        writer.writeStartElement("item");
        writer.writeStartElement("para");
        writer.writeCharacters(node->doc().briefText().toString());
        writer.writeEndElement(); // para
        writer.writeEndElement(); // item
        writer.writeEndElement(); // row
    }
    writer.writeEndElement(); // table
}

QT_END_NAMESPACE
