toc = node->doc().tableOfContents();
if (toc.isEmpty())
return;
QString nodeName = "";
if (node != relative)
nodeName = node->name();
QStringList sectionNumber;
int columnSize = 0;
QString tdTag;
if (numColumns > 1) {
tdTag = ""; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/
out() << "\n"
<< tdTag << "\n";
}
// disable nested links in table of contents
inContents = true;
inLink = true;
for (int i = 0; i < toc.size(); ++i) {
Atom *atom = toc.at(i);
int nextLevel = atom->string().toInt();
if (nextLevel > (int)sectioningUnit)
continue;
if (sectionNumber.size() < nextLevel) {
do {
out() << "";
sectionNumber.append("1");
} while (sectionNumber.size() < nextLevel);
}
else {
while (sectionNumber.size() > nextLevel) {
out() << " \n";
sectionNumber.removeLast();
}
sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
}
int numAtoms;
Text headingText = Text::sectionHeading(atom);
if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) {
out() << "" << tdTag << "\n";
columnSize = 0;
}
out() << "- ";
out() << "";
generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
out() << "
\n";
++columnSize;
}
while (!sectionNumber.isEmpty()) {
out() << " \n";
sectionNumber.removeLast();
}
if (numColumns > 1)
out() << " \n";
inContents = false;
inLink = false;
}
/*!
Revised for the new doc format.
Generates a table of contents beginning at \a node.
*/
void DitaXmlGenerator::generateTableOfContents(const Node *node,
CodeMarker *marker,
QList* sections)
{
QList toc;
if (node->doc().hasTableOfContents())
toc = node->doc().tableOfContents();
if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
return;
QStringList sectionNumber;
int detailsBase = 0;
// disable nested links in table of contents
inContents = true;
inLink = true;
out() << "\n";
out() << " Contents\n";
sectionNumber.append("1");
out() << " \n";
if (node->subType() == Node::Module) {
if (moduleNamespaceMap.contains(node->name())) {
out() << "- Namespaces
\n";
}
if (moduleClassMap.contains(node->name())) {
out() << "- Classes
\n";
}
out() << "- Detailed Description
\n";
for (int i = 0; i < toc.size(); ++i) {
if (toc.at(i)->string().toInt() == 1) {
detailsBase = 1;
break;
}
}
}
else if (sections && (node->type() == Node::Class)) {
QList::ConstIterator s = sections->begin();
while (s != sections->end()) {
if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
out() << "- " << (*s).name
<< "
\n";
}
++s;
}
out() << "- Detailed Description
\n";
for (int i = 0; i < toc.size(); ++i) {
if (toc.at(i)->string().toInt() == 1) {
detailsBase = 1;
break;
}
}
}
for (int i = 0; i < toc.size(); ++i) {
Atom *atom = toc.at(i);
int nextLevel = atom->string().toInt() + detailsBase;
if (sectionNumber.size() < nextLevel) {
do {
sectionNumber.append("1");
} while (sectionNumber.size() < nextLevel);
}
else {
while (sectionNumber.size() > nextLevel) {
sectionNumber.removeLast();
}
sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
}
int numAtoms;
Text headingText = Text::sectionHeading(atom);
QString s = headingText.toString();
out() << "- ";
out() << "";
generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
out() << "
\n";
}
while (!sectionNumber.isEmpty()) {
sectionNumber.removeLast();
}
out() << " \n";
out() << " \n";
inContents = false;
inLink = false;
}
QString DitaXmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
CodeMarker *marker)
{
QList sections;
QList::ConstIterator s;
sections = marker->sections(inner,
CodeMarker::SeparateList,
CodeMarker::Okay);
if (sections.isEmpty())
return QString();
QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
beginSubPage(inner->location(), fileName);
QString title = "List of All Members for " + inner->name();
generateHeader(inner);
generateTitle(title, Text(), SmallSubTitle, inner, marker);
out() << "This is the complete list of members for ";
generateFullName(inner, 0, marker);
out() << ", including inherited members. \n";
Section section = sections.first();
generateSectionList(section, 0, marker, CodeMarker::SeparateList);
endSubPage();
return fileName;
}
QString DitaXmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
CodeMarker *marker,
CodeMarker::Status status)
{
QList sections = marker->sections(inner,
CodeMarker::Summary,
status);
QMutableListIterator j(sections);
while (j.hasNext()) {
if (j.next().members.size() == 0)
j.remove();
}
if (sections.isEmpty())
return QString();
int i;
QString title;
QString fileName;
if (status == CodeMarker::Compat) {
title = "Qt 3 Support Members for " + inner->name();
fileName = fileBase(inner) + "-qt3." + fileExtension(inner);
}
else {
title = "Obsolete Members for " + inner->name();
fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
}
beginSubPage(inner->location(), fileName);
generateHeader(inner);
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
out() << "The following class members are part of the "
"Qt 3 support layer. "
"They are provided to help you port old code to Qt 4. We advise against "
"using them in new code. \n";
}
else {
out() << "The following class members are obsolete. "
<< "They are provided to keep old source code working. "
<< "We strongly advise against using them in new code. \n";
}
out() << "- "
<< protectEnc(inner->name())
<< " class reference
\n";
for (i = 0; i < sections.size(); ++i) {
out() << "" << protectEnc(sections.at(i).name) << "\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
}
sections = marker->sections(inner, CodeMarker::Detailed, status);
for (i = 0; i < sections.size(); ++i) {
out() << " \n";
out() << "" << protectEnc(sections.at(i).name) << "\n";
NodeList::ConstIterator m = sections.at(i).members.begin();
while (m != sections.at(i).members.end()) {
if ((*m)->access() != Node::Private)
generateDetailedMember(*m, inner, marker);
++m;
}
}
endSubPage();
return fileName;
}
void DitaXmlGenerator::generateClassHierarchy(const Node *relative,
CodeMarker *marker,
const QMap &classMap)
{
if (classMap.isEmpty())
return;
NodeMap topLevel;
NodeMap::ConstIterator c = classMap.begin();
while (c != classMap.end()) {
const ClassNode *classe = static_cast(*c);
if (classe->baseClasses().isEmpty())
topLevel.insert(classe->name(), classe);
++c;
}
QStack stack;
stack.push(topLevel);
out() << "\n";
while (!stack.isEmpty()) {
if (stack.top().isEmpty()) {
stack.pop();
out() << " \n";
}
else {
const ClassNode *child =
static_cast(*stack.top().begin());
out() << "";
generateFullName(child, relative, marker);
out() << "\n";
stack.top().erase(stack.top().begin());
NodeMap newTop;
foreach (const RelatedClass &d, child->derivedClasses()) {
if (d.access != Node::Private)
newTop.insert(d.node->name(), d.node);
}
if (!newTop.isEmpty()) {
stack.push(newTop);
out() << "\n";
}
}
}
}
void DitaXmlGenerator::generateAnnotatedList(const Node *relative,
CodeMarker *marker,
const NodeMap &nodeMap)
{
out() << "\n";
int row = 0;
foreach (const QString &name, nodeMap.keys()) {
const Node *node = nodeMap[name];
if (node->status() == Node::Obsolete)
continue;
if (++row % 2 == 1)
out() << "";
else
out() << " ";
out() << "";
generateFullName(node, relative, marker);
out() << " | ";
if (!(node->type() == Node::Fake)) {
Text brief = node->doc().trimmedBriefText(name);
if (!brief.isEmpty()) {
out() << "";
generateText(brief, node, marker);
out() << " | ";
}
}
else {
out() << "";
out() << protectEnc(node->doc().briefText().toString());
out() << " | ";
}
out() << " \n";
}
out() << " \n";
}
/*!
This function finds the common prefix of the names of all
the classes in \a classMap and then generates a compact
list of the class names alphabetized on the part of the
name not including the common prefix. You can tell the
function to use \a comonPrefix as the common prefix, but
normally you let it figure it out itself by looking at
the name of the first and last classes in \a classMap.
*/
void DitaXmlGenerator::generateCompactList(const Node *relative,
CodeMarker *marker,
const NodeMap &classMap,
bool includeAlphabet,
QString commonPrefix)
{
const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
if (classMap.isEmpty())
return;
/*
If commonPrefix is not empty, then the caller knows what
the common prefix is and has passed it in, so just use that
one.
*/
int commonPrefixLen = commonPrefix.length();
if (commonPrefixLen == 0) {
QString first;
QString last;
/*
The caller didn't pass in a common prefix, so get the common
prefix by looking at the class names of the first and last
classes in the class map. Discard any namespace names and
just use the bare class names. For Qt, the prefix is "Q".
Note that the algorithm used here to derive the common prefix
from the first and last classes in alphabetical order (QAccel
and QXtWidget in Qt 2.1), fails if either class name does not
begin with Q.
*/
NodeMap::const_iterator iter = classMap.begin();
while (iter != classMap.end()) {
if (!iter.key().contains("::")) {
first = iter.key();
break;
}
++iter;
}
if (first.isEmpty())
first = classMap.begin().key();
iter = classMap.end();
while (iter != classMap.begin()) {
--iter;
if (!iter.key().contains("::")) {
last = iter.key();
break;
}
}
if (last.isEmpty())
last = classMap.begin().key();
if (classMap.size() > 1) {
while (commonPrefixLen < first.length() + 1 &&
commonPrefixLen < last.length() + 1 &&
first[commonPrefixLen] == last[commonPrefixLen])
++commonPrefixLen;
}
commonPrefix = first.left(commonPrefixLen);
}
/*
Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z,
underscore (_). QAccel will fall in paragraph 10 (A) and
QXtWidget in paragraph 33 (X). This is the only place where we
assume that NumParagraphs is 37. Each paragraph is a NodeMap.
*/
NodeMap paragraph[NumParagraphs+1];
QString paragraphName[NumParagraphs+1];
QSet usedParagraphNames;
NodeMap::ConstIterator c = classMap.begin();
while (c != classMap.end()) {
QStringList pieces = c.key().split("::");
QString key;
int idx = commonPrefixLen;
if (!pieces.last().startsWith(commonPrefix))
idx = 0;
if (pieces.size() == 1)
key = pieces.last().mid(idx).toLower();
else
key = pieces.last().toLower();
int paragraphNr = NumParagraphs - 1;
if (key[0].digitValue() != -1) {
paragraphNr = key[0].digitValue();
}
else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
paragraphNr = 10 + key[0].unicode() - 'a';
}
paragraphName[paragraphNr] = key[0].toUpper();
usedParagraphNames.insert(key[0].toLower().cell());
paragraph[paragraphNr].insert(key, c.value());
++c;
}
/*
Each paragraph j has a size: paragraph[j].count(). In the
discussion, we will assume paragraphs 0 to 5 will have sizes
3, 1, 4, 1, 5, 9.
We now want to compute the paragraph offset. Paragraphs 0 to 6
start at offsets 0, 3, 4, 8, 9, 14, 23.
*/
int paragraphOffset[NumParagraphs + 1]; // 37 + 1
paragraphOffset[0] = 0;
for (int i=0; i";
for (int i = 0; i < 26; i++) {
QChar ch('a' + i);
if (usedParagraphNames.contains(char('a' + i)))
out() << QString("%2 ").arg(ch).arg(ch.toUpper());
}
out() << "\n";
}
/*
Output a element to contain all the elements.
*/
out() << "\n";
for (int i=0; i .
*/
if (curParOffset == 0) {
if (i > 0)
out() << "\n";
if (++numTableRows % 2 == 1)
out() << "";
else
out() << "";
out() << "- ";
if (includeAlphabet) {
QChar c = paragraphName[curParNr][0].toLower();
out() << QString("").arg(c);
}
out() << ""
<< paragraphName[curParNr]
<< "";
out() << "
\n";
}
/*
Output a - for the current offset in the current paragraph.
*/
out() << "
- ";
if ((curParNr < NumParagraphs) &&
!paragraphName[curParNr].isEmpty()) {
NodeMap::Iterator it;
it = paragraph[curParNr].begin();
for (int i=0; i";
QStringList pieces;
if (it.value()->subType() == Node::QmlClass)
pieces << it.value()->name();
else
pieces = fullName(it.value(), relative, marker).split("::");
out() << protectEnc(pieces.last());
out() << "";
if (pieces.size() > 1) {
out() << " (";
generateFullName(it.value()->parent(), relative, marker);
out() << ")";
}
}
out() << "
\n";
curParOffset++;
}
out() << " \n";
out() << " \n";
}
void DitaXmlGenerator::generateFunctionIndex(const Node *relative,
CodeMarker *marker)
{
out() << "";
for (int i = 0; i < 26; i++) {
QChar ch('a' + i);
out() << QString("%2 ").arg(ch).arg(ch.toUpper());
}
out() << " \n";
char nextLetter = 'a';
char currentLetter;
#if 1
out() << "\n";
#endif
QMap::ConstIterator f = funcIndex.begin();
while (f != funcIndex.end()) {
#if 1
out() << "- ";
#else
out() << "
";
#endif
out() << protectEnc(f.key()) << ":";
currentLetter = f.key()[0].unicode();
while (islower(currentLetter) && currentLetter >= nextLetter) {
out() << QString("").arg(nextLetter);
nextLetter++;
}
NodeMap::ConstIterator s = (*f).begin();
while (s != (*f).end()) {
out() << " ";
generateFullName((*s)->parent(), relative, marker, *s);
++s;
}
#if 1
out() << " ";
#else
out() << "";
#endif
out() << "\n";
++f;
}
#if 1
out() << " \n";
#endif
}
void DitaXmlGenerator::generateLegaleseList(const Node *relative,
CodeMarker *marker)
{
QMap::ConstIterator it = legaleseTexts.begin();
while (it != legaleseTexts.end()) {
Text text = it.key();
out() << " \n";
generateText(text, relative, marker);
out() << "\n";
do {
out() << "- ";
generateFullName(it.value(), relative, marker);
out() << "
\n";
++it;
} while (it != legaleseTexts.end() && it.key() == text);
out() << " \n";
}
}
/*void DitaXmlGenerator::generateSynopsis(const Node *node,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style)
{
QString marked = marker->markedUpSynopsis(node, relative, style);
QRegExp templateTag("(<[^@>]*>)");
if (marked.indexOf(templateTag) != -1) {
QString contents = protectEnc(marked.mid(templateTag.pos(1),
templateTag.cap(1).length()));
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
}
marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])@param>"),
"\\1\\2");
marked.replace("<@param>", "");
marked.replace("@param>", "");
if (style == CodeMarker::Summary)
marked.replace("@name>", "b>");
if (style == CodeMarker::SeparateList) {
QRegExp extraRegExp("<@extra>.*@extra>");
extraRegExp.setMinimal(true);
marked.replace(extraRegExp, "");
}
else {
marked.replace("<@extra>", " ");
marked.replace("@extra>", "");
}
if (style != CodeMarker::Detailed) {
marked.replace("<@type>", "");
marked.replace("@type>", "");
}
out() << highlightedCode(marked, marker, relative);
}*/
#ifdef QDOC_QML
void DitaXmlGenerator::generateQmlItem(const Node *node,
const Node *relative,
CodeMarker *marker,
bool summary)
{
QString marked = marker->markedUpQmlItem(node,summary);
QRegExp templateTag("(<[^@>]*>)");
if (marked.indexOf(templateTag) != -1) {
QString contents = protectEnc(marked.mid(templateTag.pos(1),
templateTag.cap(1).length()));
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
}
marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])@param>"),
"\\1\\2");
marked.replace("<@param>", "");
marked.replace("@param>", "");
if (summary)
marked.replace("@name>", "b>");
marked.replace("<@extra>", "");
marked.replace("@extra>", "");
if (summary) {
marked.replace("<@type>", "");
marked.replace("@type>", "");
}
out() << highlightedCode(marked, marker, relative);
}
#endif
void DitaXmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
{
QMap > fakeNodeMap;
QMap groupTitlesMap;
QMap uncategorizedNodeMap;
QRegExp singleDigit("\\b([0-9])\\b");
const NodeList children = myTree->root()->childNodes();
foreach (Node *child, children) {
if (child->type() == Node::Fake && child != relative) {
FakeNode *fakeNode = static_cast(child);
// Check whether the page is part of a group or is the group
// definition page.
QString group;
bool isGroupPage = false;
if (fakeNode->doc().metaCommandsUsed().contains("group")) {
group = fakeNode->doc().metaCommandArgs("group")[0];
isGroupPage = true;
}
// there are too many examples; they would clutter the list
if (fakeNode->subType() == Node::Example)
continue;
// not interested either in individual (Qt Designer etc.) manual chapters
if (fakeNode->links().contains(Node::ContentsLink))
continue;
// Discard external nodes.
if (fakeNode->subType() == Node::ExternalPage)
continue;
QString sortKey = fakeNode->fullTitle().toLower();
if (sortKey.startsWith("the "))
sortKey.remove(0, 4);
sortKey.replace(singleDigit, "0\\1");
if (!group.isEmpty()) {
if (isGroupPage) {
// If we encounter a group definition page, we add all
// the pages in that group to the list for that group.
foreach (Node *member, fakeNode->groupMembers()) {
if (member->type() != Node::Fake)
continue;
FakeNode *page = static_cast(member);
if (page) {
QString sortKey = page->fullTitle().toLower();
if (sortKey.startsWith("the "))
sortKey.remove(0, 4);
sortKey.replace(singleDigit, "0\\1");
fakeNodeMap[const_cast(fakeNode)].insert(sortKey, page);
groupTitlesMap[fakeNode->fullTitle()] = const_cast(fakeNode);
}
}
}
else if (!isGroupPage) {
// If we encounter a page that belongs to a group then
// we add that page to the list for that group.
const FakeNode *groupNode = static_cast(myTree->root()->findNode(group, Node::Fake));
if (groupNode)
fakeNodeMap[groupNode].insert(sortKey, fakeNode);
//else
// uncategorizedNodeMap.insert(sortKey, fakeNode);
}// else
// uncategorizedNodeMap.insert(sortKey, fakeNode);
}// else
// uncategorizedNodeMap.insert(sortKey, fakeNode);
}
}
// We now list all the pages found that belong to groups.
// If only certain pages were found for a group, but the definition page
// for that group wasn't listed, the list of pages will be intentionally
// incomplete. However, if the group definition page was listed, all the
// pages in that group are listed for completeness.
if (!fakeNodeMap.isEmpty()) {
foreach (const QString &groupTitle, groupTitlesMap.keys()) {
const FakeNode *groupNode = groupTitlesMap[groupTitle];
out() << QString("%2\n").arg(
linkForNode(groupNode, relative)).arg(
protectEnc(groupNode->fullTitle()));
if (fakeNodeMap[groupNode].count() == 0)
continue;
out() << "\n";
foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
QString title = fakeNode->fullTitle();
if (title.startsWith("The "))
title.remove(0, 4);
out() << "- "
<< protectEnc(title) << "
\n";
}
out() << " \n";
}
}
if (!uncategorizedNodeMap.isEmpty()) {
out() << QString("Miscellaneous\n");
out() << "\n";
foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
QString title = fakeNode->fullTitle();
if (title.startsWith("The "))
title.remove(0, 4);
out() << "- "
<< protectEnc(title) << "
\n";
}
out() << " \n";
}
}
void DitaXmlGenerator::generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style)
{
bool name_alignment = true;
if (!nl.isEmpty()) {
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
name_alignment = false;
twoColumn = (nl.count() >= 16);
}
else if (nl.first()->type() == Node::Property) {
twoColumn = (nl.count() >= 5);
name_alignment = false;
}
if (name_alignment) {
out() << "\n";
}
else {
if (twoColumn)
out() << "\n"
<< "";
out() << "\n";
}
int i = 0;
NodeList::ConstIterator m = nl.begin();
while (m != nl.end()) {
if ((*m)->access() == Node::Private) {
++m;
continue;
}
if (name_alignment) {
out() << " ";
}
else {
if (twoColumn && i == (int) (nl.count() + 1) / 2)
out() << " | \n";
out() << "- ";
}
generateSynopsis(*m, relative, marker, style, name_alignment);
if (name_alignment)
out() << "
| \n";
else
out() << "\n";
i++;
++m;
}
if (name_alignment)
out() << " | \n";
else {
out() << "\n";
if (twoColumn)
out() << "\n \n";
}
}
}
void DitaXmlGenerator::generateSectionList(const Section& section,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style)
{
bool name_alignment = true;
if (!section.members.isEmpty()) {
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
name_alignment = false;
twoColumn = (section.members.count() >= 16);
}
else if (section.members.first()->type() == Node::Property) {
twoColumn = (section.members.count() >= 5);
name_alignment = false;
}
if (name_alignment) {
out() << "\n";
}
else {
if (twoColumn)
out() << "\n"
<< "";
out() << "\n";
}
int i = 0;
NodeList::ConstIterator m = section.members.begin();
while (m != section.members.end()) {
if ((*m)->access() == Node::Private) {
++m;
continue;
}
if (name_alignment) {
out() << " ";
}
else {
if (twoColumn && i == (int) (section.members.count() + 1) / 2)
out() << " | \n";
out() << "- ";
}
generateSynopsis(*m, relative, marker, style, name_alignment);
if (name_alignment)
out() << "
| \n";
else
out() << "\n";
i++;
++m;
}
if (name_alignment)
out() << " | \n";
else {
out() << "\n";
if (twoColumn)
out() << "\n \n";
}
}
if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
out() << "\n";
generateSectionInheritedList(section, relative, marker, name_alignment);
out() << " \n";
}
}
void DitaXmlGenerator::generateSectionInheritedList(const Section& section,
const Node *relative,
CodeMarker *marker,
bool nameAlignment)
{
QList >::ConstIterator p = section.inherited.begin();
while (p != section.inherited.end()) {
if (nameAlignment)
out() << "- ";
else
out() << "
- ";
out() << (*p).second << " ";
if ((*p).second == 1) {
out() << section.singularMember;
}
else {
out() << section.pluralMember;
}
out() << " inherited from "
<< protectEnc(marker->plainFullName((*p).first, relative))
<< "
\n";
++p;
}
}
void DitaXmlGenerator::generateSynopsis(const Node *node,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style,
bool nameAlignment)
{
QString marked = marker->markedUpSynopsis(node, relative, style);
QRegExp templateTag("(<[^@>]*>)");
if (marked.indexOf(templateTag) != -1) {
QString contents = protectEnc(marked.mid(templateTag.pos(1),
templateTag.cap(1).length()));
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
}
marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])@param>"),
"\\1\\2");
marked.replace("<@param>", "");
marked.replace("@param>", "");
if (style == CodeMarker::Summary) {
marked.replace("<@name>", ""); // was ""
marked.replace("@name>", ""); // was ""
}
if (style == CodeMarker::SeparateList) {
QRegExp extraRegExp("<@extra>.*@extra>");
extraRegExp.setMinimal(true);
marked.replace(extraRegExp, "");
} else {
marked.replace("<@extra>", "");
marked.replace("@extra>", "");
}
if (style != CodeMarker::Detailed) {
marked.replace("<@type>", "");
marked.replace("@type>", "");
}
out() << highlightedCode(marked, marker, relative, style, nameAlignment);
}
QString DitaXmlGenerator::highlightedCode(const QString& markedCode,
CodeMarker *marker,
const Node *relative,
CodeMarker::SynopsisStyle ,
bool nameAlignment)
{
QString src = markedCode;
QString html;
QStringRef arg;
QStringRef par1;
const QChar charLangle = '<';
const QChar charAt = '@';
// replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(@link>)"
static const QString linkTag("link");
bool done = false;
for (int i = 0, n = src.size(); i < n;) {
if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
if (nameAlignment && !done) {// && (i != 0)) Why was this here?
html += " | ";
done = true;
}
i += 2;
if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
html += "";
QString link = linkForNode(
CodeMarker::nodeForString(par1.toString()), relative);
addLink(link, arg, &html);
html += "";
}
else {
html += charLangle;
html += charAt;
}
}
else {
html += src.at(i++);
}
}
if (slow) {
// is this block ever used at all?
// replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(@func>)"
src = html;
html = QString();
static const QString funcTag("func");
for (int i = 0, n = src.size(); i < n;) {
if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
i += 2;
if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
QString link = linkForNode(
marker->resolveTarget(par1.toString(),
myTree,
relative),
relative);
addLink(link, arg, &html);
par1 = QStringRef();
}
else {
html += charLangle;
html += charAt;
}
}
else {
html += src.at(i++);
}
}
}
// replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(@\\2>)" tags
src = html;
html = QString();
static const QString typeTags[] = { "type", "headerfile", "func" };
for (int i = 0, n = src.size(); i < n;) {
if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
i += 2;
bool handled = false;
for (int k = 0; k != 3; ++k) {
if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
par1 = QStringRef();
QString link = linkForNode(
marker->resolveTarget(arg.toString(), myTree, relative),
relative);
addLink(link, arg, &html);
handled = true;
break;
}
}
if (!handled) {
html += charLangle;
html += charAt;
}
}
else {
html += src.at(i++);
}
}
// replace all
// "<@comment>" -> " |