/****************************************************************************
**
** 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 "config.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()
{
    HtmlGenerator::initializeGenerator();
}

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");

    if (Config::instance().getBool(CONFIG_LOCATIONINFO)) {
        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");
    if (Config::instance().getBool(CONFIG_LOCATIONINFO)) {
        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
