summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahoogol <ahoogol@gmail.com>2017-06-25 07:32:35 (GMT)
committerahoogol <ahoogol@gmail.com>2017-06-25 07:32:35 (GMT)
commit5885c89d6b30ca607f84794d0de6800f49dd327b (patch)
tree4005066c10fd003cd6d93697b92a6cf7ba206266
parente7e62101a1a659740223c32cdd525b1e66b1cf09 (diff)
downloadDoxygen-5885c89d6b30ca607f84794d0de6800f49dd327b.zip
Doxygen-5885c89d6b30ca607f84794d0de6800f49dd327b.tar.gz
Doxygen-5885c89d6b30ca607f84794d0de6800f49dd327b.tar.bz2
Added support for RTL(right to left) languages like Arabic and Persian in HTML output
-rw-r--r--.gitignore1
-rw-r--r--qtools/qstring.cpp95
-rw-r--r--qtools/qstring.h37
-rw-r--r--src/config.xml13
-rw-r--r--src/docparser.cpp123
-rw-r--r--src/docparser.h160
-rw-r--r--src/dot.cpp32
-rw-r--r--src/htmldocvisitor.cpp79
-rw-r--r--src/htmlgen.cpp16
-rw-r--r--src/htmlgen.h2
-rw-r--r--src/index.cpp19
-rw-r--r--src/outputgen.h2
-rw-r--r--src/outputlist.h4
-rw-r--r--src/pagedef.cpp4
-rw-r--r--src/util.cpp5
-rw-r--r--src/util.h3
-rw-r--r--templates/html/doxygen.css200
17 files changed, 609 insertions, 186 deletions
diff --git a/.gitignore b/.gitignore
index 21ebe47..440769b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@
/doxygen_docs
/doxygen.tag
+/build
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
index d831cb1..698efcf 100644
--- a/qtools/qstring.cpp
+++ b/qtools/qstring.cpp
@@ -11614,32 +11614,83 @@ static inline bool is_neutral(unsigned short dir) {
#endif
/*!
- This function returns the basic directionality of the string (QChar::DirR for
- right to left and QChar::DirL for left to right). Useful to find the right
- alignment.
- */
-QChar::Direction QString::basicDirection()
+This function returns the directionality of the string.
+
+\returns a value of DirLTR, DirRTL, DirMixed or DirNeutral that indicates
+if the entire text represented by this text is unidirectional,
+and which direction, or if it is mixed-directional or all characters are neutral.
+*/
+QString::Direction QString::direction() const
{
#ifndef QT_NO_UNICODETABLES
- // find base direction
- unsigned int pos = 0;
- while ((pos < length()) &&
- (at(pos) != RLE) &&
- (at(pos) != LRE) &&
- (at(pos) != RLO) &&
- (at(pos) != LRO) &&
- (at(pos).direction() > 1) &&
- (at(pos).direction() != QChar::DirAL)) // not R and not L
- pos++;
-
- if ((at(pos).direction() == QChar::DirR) ||
- (at(pos).direction() == QChar::DirAL) ||
- (at(pos) == RLE) ||
- (at(pos) == RLO))
- return QChar::DirR;
+ // find direction
+ unsigned char resultDir = DirNeutral;
+ for (unsigned int pos = 0; pos < length(); pos++)
+ {
+ if ((at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)) // not R and not L
+ continue;
+
+ if ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO))
+ resultDir |= DirRTL;
+ else
+ resultDir |= DirLTR;
+ if (resultDir == DirMixed)
+ return DirMixed;
+ }
+ return static_cast<Direction>(resultDir);
+#else
+ return DirLTR;
#endif
+}
+
+/*!
+This function returns the basic directionality of the string. Useful to find the right
+alignment.
- return QChar::DirL;
+The base direction is derived from the first character in the string
+with bidirectional character type L, R, or AL.
+If the first such character has type L, DirLTR is returned.
+If the first such character has type R or AL, DirRTL is returned.
+If the string does not contain any character of these types, then DirNeutral is returned.
+This is a lightweight function for use when only the base direction is needed and
+no further bidi processing of the text is needed.
+
+\returns DirRTL, DirLTR or DirNeutral
+*/
+QString::Direction QString::basicDirection() const
+{
+#ifndef QT_NO_UNICODETABLES
+ // find base direction
+ unsigned int pos = 0;
+ while ((pos < length()) &&
+ (at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)) // not R and not L
+ pos++;
+
+ if (pos == length())
+ return DirNeutral;
+
+ if ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO))
+ return DirRTL;
+ return DirLTR;
+#else
+ return DirLTR;
+#endif
}
#ifndef QT_NO_UNICODETABLES
diff --git a/qtools/qstring.h b/qtools/qstring.h
index df3873d..5fcff29 100644
--- a/qtools/qstring.h
+++ b/qtools/qstring.h
@@ -369,6 +369,38 @@ public:
QString &operator=( QChar c );
QString &operator=( char c );
+ enum Direction
+ {
+ /// No strongly directional text.
+ /*!
+ * As return value for direction() or baseDirection(), it means that the source string
+ * is missing or empty, or contains neither left-to-right nor right-to-left characters.
+ */
+ DirNeutral = 0x0,
+ /// Left-to-right text.
+ /*!
+ * - As return value for direction(), it means that the source string
+ * contains no right-to-left characters.
+ * - As return value for basicDirection(), it means that the first strong character
+ * of the source string has a left-to-right direction.
+ */
+ DirLTR = 0b01,
+ /// Right-to-left text.
+ /*!
+ * - As return value for direction(), it means that the source string
+ * contains no left-to-right characters.
+ * - As return value for basicDirection(), it means that the first strong character
+ * of the source string has a right-to-left direction.
+ */
+ DirRTL = 0b10,
+ /// Mixed-directional text
+ /*!
+ * As return value for direction(), it means that the source string
+ * contains both left-to-right and right-to-left characters.
+ */
+ DirMixed = 0b11
+ };
+
//QT_STATIC_CONST QString null;
//bool isNull() const;
@@ -535,8 +567,9 @@ public:
#endif
// new functions for BiDi
void compose();
- QChar::Direction basicDirection();
- QString visual(int index = 0, int len = -1);
+ QString::Direction direction() const;
+ QString::Direction basicDirection() const;
+ QString visual(int index = 0, int len = -1);
#ifndef QT_NO_COMPAT
const char* data() const { return latin1(); }
diff --git a/src/config.xml b/src/config.xml
index 8bb6add..69b4464 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -343,6 +343,19 @@ Go to the <a href="commands.html">next</a> section or return to the
<value name='Ukrainian'/>
<value name='Vietnamese'/>
</option>
+ <option type='enum' id='OUTPUT_TEXT_DIRECTION' defval='None'>
+ <docs>
+<![CDATA[
+ The \c OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+ documentation generated by doxygen is written. Doxygen will use this
+ information to generate all generated output in the proper direction.
+]]>
+ </docs>
+ <value name='None'/>
+ <value name='LTR'/>
+ <value name='RTL'/>
+ <value name='Context'/>
+ </option>
<option type='bool' id='BRIEF_MEMBER_DESC' defval='1'>
<docs>
<![CDATA[
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 2602f78..0cd27c0 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -7218,8 +7218,129 @@ static QCString processCopyDoc(const char *data,uint &len)
buf.addChar(0);
return buf.get();
}
+//---------------------------------------------------------------------------
+QString::Direction getTextDirByConfig(const QString &text)
+{
+ auto configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION);
+ if (configDir == "None")
+ return QString::DirNeutral;
+ if (configDir == "Context")
+ return text.basicDirection();
+ if (configDir == "LTR")
+ {
+ auto textDir = text.direction();
+ if (textDir == QString::DirMixed)
+ return QString::DirLTR;
+ return textDir;
+ }
+ if (configDir == "RTL")
+ {
+ auto textDir = text.direction();
+ if (textDir == QString::DirMixed)
+ return QString::DirRTL;
+ return textDir;
+ }
+ return QString::DirNeutral;
+}
-//--------------------------------------------------------------------------
+QString::Direction getTextDirByConfig(const DocNode *node)
+{
+ auto configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION);
+ if (configDir == "None")
+ return QString::DirNeutral;
+ if (configDir == "Context")
+ return node->getTextBasicDir();
+ if (configDir == "LTR")
+ {
+ auto textDir = node->getTextDir();
+ if (textDir == QString::DirMixed)
+ return QString::DirLTR;
+ return textDir;
+ }
+ if (configDir == "RTL")
+ {
+ auto textDir = node->getTextDir();
+ if (textDir == QString::DirMixed)
+ return QString::DirRTL;
+ return textDir;
+ }
+ return QString::DirNeutral;
+}
+
+QString::Direction getTextDirByConfig(const DocPara *para, int nodeIndex)
+{
+ auto configDir = Config_getEnum(OUTPUT_TEXT_DIRECTION);
+ if (configDir == "None")
+ return QString::DirNeutral;
+ if (configDir == "Context")
+ return para->getTextBasicDir(nodeIndex);
+ if (configDir == "LTR")
+ {
+ auto textDir = para->getTextDir(nodeIndex);
+ if (textDir == QString::DirMixed)
+ return QString::DirLTR;
+ return textDir;
+ }
+ if (configDir == "RTL")
+ {
+ auto textDir = para->getTextDir(nodeIndex);
+ if (textDir == QString::DirMixed)
+ return QString::DirRTL;
+ return textDir;
+ }
+ return QString::DirNeutral;
+}
+
+QCString getDirHtmlClassOfNode(QString::Direction textDir, const char *initValue)
+{
+ QCString classFromDir;
+ if (textDir == QString::DirLTR)
+ classFromDir = "DocNodeLTR";
+ else if (textDir == QString::DirRTL)
+ classFromDir = "DocNodeRTL";
+ else
+ classFromDir = "";
+
+ if (initValue != nullptr && !classFromDir.isEmpty())
+ return QCString(" class=\"") + initValue + " " + classFromDir + "\"";
+ if (initValue != nullptr)
+ return QCString(" class=\"") + initValue + "\"";
+ if (!classFromDir.isEmpty())
+ return QCString(" class=\"") + classFromDir + "\"";
+ return "";
+}
+
+QCString getDirHtmlClassOfPage(QCString pageTitle)
+{
+ QCString result = "";
+ result += " class=\"PageDoc";
+ auto titleDir = getTextDirByConfig(pageTitle);
+ if (titleDir == QString::DirLTR)
+ result += " PageDocLTR-title";
+ else if (titleDir == QString::DirRTL)
+ result += " PageDocRTL-title";
+ result += "\"";
+ return result;
+}
+
+QCString getHtmlDirEmbedingChar(QString::Direction textDir)
+{
+ if (textDir == QString::DirLTR)
+ return "&#x202A;";
+ if (textDir == QString::DirRTL)
+ return "&#x202B;";
+ return "";
+}
+
+QCString getJsDirEmbedingChar(QString::Direction textDir)
+{
+ if (textDir == QString::DirLTR)
+ return "\\u202A";
+ if (textDir == QString::DirRTL)
+ return "\\u202B";
+ return "";
+}
+//---------------------------------------------------------------------------
DocRoot *validatingParseDoc(const char *fileName,int startLine,
Definition *ctx,MemberDef *md,
diff --git a/src/docparser.h b/src/docparser.h
index f5167dc..c6b3b23 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -34,6 +34,14 @@ class MemberGroup;
class SectionDict;
//---------------------------------------------------------------------------
+QString::Direction getTextDirByConfig(const QString &text);
+QString::Direction getTextDirByConfig(const DocNode *node);
+QString::Direction getTextDirByConfig(const DocPara *para, int nodeIndex);
+QCString getDirHtmlClassOfNode(QString::Direction textDir, const char *initValue = nullptr);
+QCString getDirHtmlClassOfPage(QCString pageTitle);
+QCString getHtmlDirEmbedingChar(QString::Direction textDir);
+QCString getJsDirEmbedingChar(QString::Direction textDir);
+//---------------------------------------------------------------------------
/*! Main entry point for the documentation parser.
@@ -157,6 +165,9 @@ class DocNode
/*! Returns TRUE iff this node is inside a preformatted section */
bool isPreformatted() const { return m_insidePre; }
+ virtual QString::Direction getTextDir() const { return QString::DirNeutral; }
+ virtual QString::Direction getTextBasicDir() const { return QString::DirNeutral; }
+
protected:
/*! Sets whether or not this item is inside a preformatted section */
void setInsidePreformatted(bool p) { m_insidePre = p; }
@@ -169,13 +180,13 @@ class DocNode
/** Default accept implementation for compound nodes in the abstract
* syntax tree.
*/
-template<class T> class CompAccept
+template<class T> class CompAccept : public DocNode
{
public:
CompAccept() { m_children.setAutoDelete(TRUE); }
- virtual ~CompAccept() {}
- void accept(T *obj, DocVisitor *v)
- {
+ void accept(DocVisitor *v)
+ {
+ T *obj = dynamic_cast<T *>(this);
v->visitPre(obj);
QListIterator<DocNode> cli(m_children);
DocNode *n;
@@ -184,6 +195,38 @@ template<class T> class CompAccept
}
const QList<DocNode> &children() const { return m_children; }
QList<DocNode> &children() { return m_children; }
+ QString::Direction getTextDir(int nodeIndex) const
+ {
+ unsigned char resultDir = QString::DirNeutral;
+ for (int i = nodeIndex; i < m_children.count(); i++)
+ {
+ auto node = m_children.at(i);
+ auto nodeDir = node->getTextDir();
+ resultDir |= nodeDir;
+ if (resultDir == QString::DirMixed)
+ return QString::DirMixed;
+ }
+ return static_cast<QString::Direction>(resultDir);
+ }
+ QString::Direction getTextBasicDir(int nodeIndex) const
+ {
+ for (int i = nodeIndex; i < m_children.count(); i++)
+ {
+ auto node = m_children.at(i);
+ auto nodeDir = node->getTextBasicDir();
+ if (nodeDir != QString::DirNeutral)
+ return nodeDir;
+ }
+ return QString::DirNeutral;
+ }
+ QString::Direction getTextDir() const override
+ {
+ return getTextDir(0);
+ }
+ QString::Direction getTextBasicDir() const override
+ {
+ return getTextBasicDir(0);
+ }
protected:
QList<DocNode> m_children;
@@ -199,6 +242,8 @@ class DocWord : public DocNode
QCString word() const { return m_word; }
Kind kind() const { return Kind_Word; }
void accept(DocVisitor *v) { v->visit(this); }
+ QString::Direction getTextDir() const override { return QString(word()).direction(); };
+ QString::Direction getTextBasicDir() const override { return QString(word()).basicDirection(); };
private:
QCString m_word;
@@ -220,6 +265,8 @@ class DocLinkedWord : public DocNode
QCString anchor() const { return m_anchor; }
QCString tooltip() const { return m_tooltip; }
void accept(DocVisitor *v) { v->visit(this); }
+ QString::Direction getTextDir() const override { return QString(word()).direction(); };
+ QString::Direction getTextBasicDir() const override { return QString(word()).basicDirection(); };
private:
QCString m_word;
@@ -240,6 +287,8 @@ class DocURL : public DocNode
Kind kind() const { return Kind_URL; }
void accept(DocVisitor *v) { v->visit(this); }
bool isEmail() const { return m_isEmail; }
+ QString::Direction getTextDir() const override { return QString::DirLTR; };
+ QString::Direction getTextBasicDir() const override { return QString::DirLTR; };
private:
QCString m_url;
@@ -614,7 +663,7 @@ class DocCopy : public DocNode
};
/** Node representing an auto List */
-class DocAutoList : public CompAccept<DocAutoList>, public DocNode
+class DocAutoList : public CompAccept<DocAutoList>
{
public:
DocAutoList(DocNode *parent,int indent,bool isEnumList,int depth);
@@ -622,7 +671,6 @@ class DocAutoList : public CompAccept<DocAutoList>, public DocNode
bool isEnumList() const { return m_isEnumList; }
int indent() const { return m_indent; }
int depth() const { return m_depth; }
- void accept(DocVisitor *v) { CompAccept<DocAutoList>::accept(this,v); }
int parse();
private:
@@ -632,13 +680,12 @@ class DocAutoList : public CompAccept<DocAutoList>, public DocNode
};
/** Node representing an item of a auto list */
-class DocAutoListItem : public CompAccept<DocAutoListItem>, public DocNode
+class DocAutoListItem : public CompAccept<DocAutoListItem>
{
public:
DocAutoListItem(DocNode *parent,int indent,int num);
Kind kind() const { return Kind_AutoListItem; }
int itemNumber() const { return m_itemNum; }
- void accept(DocVisitor *v) { CompAccept<DocAutoListItem>::accept(this,v); }
int parse();
private:
@@ -649,20 +696,19 @@ class DocAutoListItem : public CompAccept<DocAutoListItem>, public DocNode
/** Node representing a simple section title */
-class DocTitle : public CompAccept<DocTitle>, public DocNode
+class DocTitle : public CompAccept<DocTitle>
{
public:
DocTitle(DocNode *parent) { m_parent = parent; }
void parse();
void parseFromString(const QCString &title);
Kind kind() const { return Kind_Title; }
- void accept(DocVisitor *v) { CompAccept<DocTitle>::accept(this,v); }
private:
};
/** Node representing an item of a cross-referenced list */
-class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
+class DocXRefItem : public CompAccept<DocXRefItem>
{
public:
DocXRefItem(DocNode *parent,int id,const char *key);
@@ -672,7 +718,6 @@ class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
QCString title() const { return m_title; }
QCString relPath() const { return m_relPath; }
QCString key() const { return m_key; }
- void accept(DocVisitor *v) { CompAccept<DocXRefItem>::accept(this,v); }
bool parse();
private:
@@ -685,7 +730,7 @@ class DocXRefItem : public CompAccept<DocXRefItem>, public DocNode
};
/** Node representing an image */
-class DocImage : public CompAccept<DocImage>, public DocNode
+class DocImage : public CompAccept<DocImage>
{
public:
enum Type { Html, Latex, Rtf, DocBook };
@@ -700,7 +745,6 @@ class DocImage : public CompAccept<DocImage>, public DocNode
QCString relPath() const { return m_relPath; }
QCString url() const { return m_url; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocImage>::accept(this,v); }
void parse();
private:
@@ -714,7 +758,7 @@ class DocImage : public CompAccept<DocImage>, public DocNode
};
/** Node representing a dot file */
-class DocDotFile : public CompAccept<DocDotFile>, public DocNode
+class DocDotFile : public CompAccept<DocDotFile>
{
public:
DocDotFile(DocNode *parent,const QCString &name,const QCString &context);
@@ -727,7 +771,6 @@ class DocDotFile : public CompAccept<DocDotFile>, public DocNode
QCString width() const { return m_width; }
QCString height() const { return m_height; }
QCString context() const { return m_context; }
- void accept(DocVisitor *v) { CompAccept<DocDotFile>::accept(this,v); }
private:
QCString m_name;
QCString m_file;
@@ -738,7 +781,7 @@ class DocDotFile : public CompAccept<DocDotFile>, public DocNode
};
/** Node representing a msc file */
-class DocMscFile : public CompAccept<DocMscFile>, public DocNode
+class DocMscFile : public CompAccept<DocMscFile>
{
public:
DocMscFile(DocNode *parent,const QCString &name,const QCString &context);
@@ -751,7 +794,6 @@ class DocMscFile : public CompAccept<DocMscFile>, public DocNode
QCString width() const { return m_width; }
QCString height() const { return m_height; }
QCString context() const { return m_context; }
- void accept(DocVisitor *v) { CompAccept<DocMscFile>::accept(this,v); }
private:
QCString m_name;
QCString m_file;
@@ -762,7 +804,7 @@ class DocMscFile : public CompAccept<DocMscFile>, public DocNode
};
/** Node representing a dia file */
-class DocDiaFile : public CompAccept<DocDiaFile>, public DocNode
+class DocDiaFile : public CompAccept<DocDiaFile>
{
public:
DocDiaFile(DocNode *parent,const QCString &name,const QCString &context);
@@ -775,7 +817,6 @@ class DocDiaFile : public CompAccept<DocDiaFile>, public DocNode
QCString width() const { return m_width; }
QCString height() const { return m_height; }
QCString context() const { return m_context; }
- void accept(DocVisitor *v) { CompAccept<DocDiaFile>::accept(this,v); }
private:
QCString m_name;
QCString m_file;
@@ -786,19 +827,18 @@ class DocDiaFile : public CompAccept<DocDiaFile>, public DocNode
};
/** Node representing a VHDL flow chart */
-class DocVhdlFlow : public CompAccept<DocVhdlFlow>, public DocNode
+class DocVhdlFlow : public CompAccept<DocVhdlFlow>
{
public:
DocVhdlFlow(DocNode *parent);
void parse();
Kind kind() const { return Kind_VhdlFlow; }
bool hasCaption() { return !m_children.isEmpty(); }
- void accept(DocVisitor *v) { CompAccept<DocVhdlFlow>::accept(this,v); }
private:
};
/** Node representing a link to some item */
-class DocLink : public CompAccept<DocLink>, public DocNode
+class DocLink : public CompAccept<DocLink>
{
public:
DocLink(DocNode *parent,const QCString &target);
@@ -808,7 +848,6 @@ class DocLink : public CompAccept<DocLink>, public DocNode
QCString relPath() const { return m_relPath; }
QCString ref() const { return m_ref; }
QCString anchor() const { return m_anchor; }
- void accept(DocVisitor *v) { CompAccept<DocLink>::accept(this,v); }
private:
QCString m_file;
@@ -819,7 +858,7 @@ class DocLink : public CompAccept<DocLink>, public DocNode
};
/** Node representing a reference to some item */
-class DocRef : public CompAccept<DocRef>, public DocNode
+class DocRef : public CompAccept<DocRef>
{
public:
DocRef(DocNode *parent,const QCString &target,const QCString &context);
@@ -835,7 +874,6 @@ class DocRef : public CompAccept<DocRef>, public DocNode
bool refToSection() const { return m_refType==Section; }
bool refToTable() const { return m_refType==Table; }
bool isSubPage() const { return m_isSubPage; }
- void accept(DocVisitor *v) { CompAccept<DocRef>::accept(this,v); }
private:
enum RefType { Unknown, Anchor, Section, Table };
@@ -849,7 +887,7 @@ class DocRef : public CompAccept<DocRef>, public DocNode
};
/** Node representing an internal reference to some item */
-class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
+class DocInternalRef : public CompAccept<DocInternalRef>
{
public:
DocInternalRef(DocNode *parent,const QCString &target);
@@ -858,7 +896,6 @@ class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
QCString file() const { return m_file; }
QCString relPath() const { return m_relPath; }
QCString anchor() const { return m_anchor; }
- void accept(DocVisitor *v) { CompAccept<DocInternalRef>::accept(this,v); }
private:
QCString m_file;
@@ -867,7 +904,7 @@ class DocInternalRef : public CompAccept<DocInternalRef>, public DocNode
};
/** Node representing a Hypertext reference */
-class DocHRef : public CompAccept<DocHRef>, public DocNode
+class DocHRef : public CompAccept<DocHRef>
{
public:
DocHRef(DocNode *parent,const HtmlAttribList &attribs,const QCString &url,
@@ -877,7 +914,6 @@ class DocHRef : public CompAccept<DocHRef>, public DocNode
QCString url() const { return m_url; }
QCString relPath() const { return m_relPath; }
Kind kind() const { return Kind_HRef; }
- void accept(DocVisitor *v) { CompAccept<DocHRef>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
private:
@@ -887,7 +923,7 @@ class DocHRef : public CompAccept<DocHRef>, public DocNode
};
/** Node Html heading */
-class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode
+class DocHtmlHeader : public CompAccept<DocHtmlHeader>
{
public:
DocHtmlHeader(DocNode *parent,const HtmlAttribList &attribs,int level) :
@@ -895,7 +931,6 @@ class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode
int level() const { return m_level; }
Kind kind() const { return Kind_HtmlHeader; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlHeader>::accept(this,v); }
int parse();
private:
@@ -904,14 +939,13 @@ class DocHtmlHeader : public CompAccept<DocHtmlHeader>, public DocNode
};
/** Node representing a Html description item */
-class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>, public DocNode
+class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>
{
public:
DocHtmlDescTitle(DocNode *parent,const HtmlAttribList &attribs) :
m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlDescTitle; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlDescTitle>::accept(this,v); }
int parse();
private:
@@ -919,14 +953,13 @@ class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>, public DocNode
};
/** Node representing a Html description list */
-class DocHtmlDescList : public CompAccept<DocHtmlDescList>, public DocNode
+class DocHtmlDescList : public CompAccept<DocHtmlDescList>
{
public:
DocHtmlDescList(DocNode *parent,const HtmlAttribList &attribs) :
m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlDescList; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlDescList>::accept(this,v); }
int parse();
private:
@@ -934,7 +967,7 @@ class DocHtmlDescList : public CompAccept<DocHtmlDescList>, public DocNode
};
/** Node representing a normal section */
-class DocSection : public CompAccept<DocSection>, public DocNode
+class DocSection : public CompAccept<DocSection>
{
public:
DocSection(DocNode *parent,int level,const QCString &id) :
@@ -945,7 +978,6 @@ class DocSection : public CompAccept<DocSection>, public DocNode
QCString anchor() const { return m_anchor; }
QCString id() const { return m_id; }
QCString file() const { return m_file; }
- void accept(DocVisitor *v) { CompAccept<DocSection>::accept(this,v); }
int parse();
private:
@@ -957,7 +989,7 @@ class DocSection : public CompAccept<DocSection>, public DocNode
};
/** Node representing a reference to a section */
-class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode
+class DocSecRefItem : public CompAccept<DocSecRefItem>
{
public:
DocSecRefItem(DocNode *parent,const QCString &target) :
@@ -966,7 +998,6 @@ class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode
QCString target() const { return m_target; }
QCString file() const { return m_file; }
QCString anchor() const { return m_anchor; }
- void accept(DocVisitor *v) { CompAccept<DocSecRefItem>::accept(this,v); }
void parse();
private:
@@ -976,56 +1007,52 @@ class DocSecRefItem : public CompAccept<DocSecRefItem>, public DocNode
};
/** Node representing a list of section references */
-class DocSecRefList : public CompAccept<DocSecRefList>, public DocNode
+class DocSecRefList : public CompAccept<DocSecRefList>
{
public:
DocSecRefList(DocNode *parent) { m_parent = parent; }
void parse();
Kind kind() const { return Kind_SecRefList; }
- void accept(DocVisitor *v) { CompAccept<DocSecRefList>::accept(this,v); }
private:
};
/** Node representing an internal section of documentation */
-class DocInternal : public CompAccept<DocInternal>, public DocNode
+class DocInternal : public CompAccept<DocInternal>
{
public:
DocInternal(DocNode *parent) { m_parent = parent; }
int parse(int);
Kind kind() const { return Kind_Internal; }
- void accept(DocVisitor *v) { CompAccept<DocInternal>::accept(this,v); }
private:
};
/** Node representing an block of paragraphs */
-class DocParBlock : public CompAccept<DocParBlock>, public DocNode
+class DocParBlock : public CompAccept<DocParBlock>
{
public:
DocParBlock(DocNode *parent) { m_parent = parent; }
int parse();
Kind kind() const { return Kind_ParBlock; }
- void accept(DocVisitor *v) { CompAccept<DocParBlock>::accept(this,v); }
private:
};
/** Node representing a simple list */
-class DocSimpleList : public CompAccept<DocSimpleList>, public DocNode
+class DocSimpleList : public CompAccept<DocSimpleList>
{
public:
DocSimpleList(DocNode *parent) { m_parent = parent; }
Kind kind() const { return Kind_SimpleList; }
- void accept(DocVisitor *v) { CompAccept<DocSimpleList>::accept(this,v); }
int parse();
private:
};
/** Node representing a Html list */
-class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode
+class DocHtmlList : public CompAccept<DocHtmlList>
{
public:
enum Type { Unordered, Ordered };
@@ -1033,7 +1060,6 @@ class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode
m_type(t), m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlList; }
Type type() const { return m_type; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlList>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
int parseXml();
@@ -1044,7 +1070,7 @@ class DocHtmlList : public CompAccept<DocHtmlList>, public DocNode
};
/** Node representing a simple section */
-class DocSimpleSect : public CompAccept<DocSimpleSect>, public DocNode
+class DocSimpleSect : public CompAccept<DocSimpleSect>
{
public:
enum Type
@@ -1082,7 +1108,7 @@ class DocSimpleSectSep : public DocNode
};
/** Node representing a parameter section */
-class DocParamSect : public CompAccept<DocParamSect>, public DocNode
+class DocParamSect : public CompAccept<DocParamSect>
{
friend class DocParamList;
public:
@@ -1100,7 +1126,6 @@ class DocParamSect : public CompAccept<DocParamSect>, public DocNode
int parse(const QCString &cmdName,bool xmlContext,Direction d);
Kind kind() const { return Kind_ParamSect; }
Type type() const { return m_type; }
- void accept(DocVisitor *v) { CompAccept<DocParamSect>::accept(this,v); }
bool hasInOutSpecifier() const { return m_hasInOutSpecifier; }
bool hasTypeSpecifier() const { return m_hasTypeSpecifier; }
@@ -1111,7 +1136,7 @@ class DocParamSect : public CompAccept<DocParamSect>, public DocNode
};
/** Node representing a paragraph in the documentation tree */
-class DocPara : public CompAccept<DocPara>, public DocNode
+class DocPara : public CompAccept<DocPara>
{
public:
DocPara(DocNode *parent) :
@@ -1119,7 +1144,6 @@ class DocPara : public CompAccept<DocPara>, public DocNode
int parse();
Kind kind() const { return Kind_Para; }
bool isEmpty() const { return m_children.isEmpty(); }
- void accept(DocVisitor *v) { CompAccept<DocPara>::accept(this,v); }
void markFirst(bool v=TRUE) { m_isFirst=v; }
void markLast(bool v=TRUE) { m_isLast=v; }
bool isFirst() const { return m_isFirst; }
@@ -1217,7 +1241,7 @@ class DocSimpleListItem : public DocNode
};
/** Node representing a HTML list item */
-class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode
+class DocHtmlListItem : public CompAccept<DocHtmlListItem>
{
public:
DocHtmlListItem(DocNode *parent,const HtmlAttribList &attribs,int num) :
@@ -1225,7 +1249,6 @@ class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode
Kind kind() const { return Kind_HtmlListItem; }
int itemNumber() const { return m_itemNum; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlListItem>::accept(this,v); }
int parse();
int parseXml();
@@ -1235,13 +1258,12 @@ class DocHtmlListItem : public CompAccept<DocHtmlListItem>, public DocNode
};
/** Node representing a HTML description data */
-class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode
+class DocHtmlDescData : public CompAccept<DocHtmlDescData>
{
public:
DocHtmlDescData(DocNode *parent) { m_parent = parent; }
Kind kind() const { return Kind_HtmlDescData; }
const HtmlAttribList &attribs() const { return m_attribs; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlDescData>::accept(this,v); }
int parse();
private:
@@ -1249,7 +1271,7 @@ class DocHtmlDescData : public CompAccept<DocHtmlDescData>, public DocNode
};
/** Node representing a HTML table cell */
-class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
+class DocHtmlCell : public CompAccept<DocHtmlCell>
{
friend class DocHtmlTable;
public:
@@ -1262,7 +1284,6 @@ class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
bool isFirst() const { return m_isFirst; }
bool isLast() const { return m_isLast; }
Kind kind() const { return Kind_HtmlCell; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlCell>::accept(this,v); }
void markFirst(bool v=TRUE) { m_isFirst=v; }
void markLast(bool v=TRUE) { m_isLast=v; }
const HtmlAttribList &attribs() const { return m_attribs; }
@@ -1286,12 +1307,11 @@ class DocHtmlCell : public CompAccept<DocHtmlCell>, public DocNode
};
/** Node representing a HTML table caption */
-class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode
+class DocHtmlCaption : public CompAccept<DocHtmlCaption>
{
public:
DocHtmlCaption(DocNode *parent,const HtmlAttribList &attribs);
Kind kind() const { return Kind_HtmlCaption; }
- void accept(DocVisitor *v) { CompAccept<DocHtmlCaption>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
bool hasCaptionId() const { return m_hasCaptionId; }
@@ -1306,7 +1326,7 @@ class DocHtmlCaption : public CompAccept<DocHtmlCaption>, public DocNode
};
/** Node representing a HTML table row */
-class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
+class DocHtmlRow : public CompAccept<DocHtmlRow>
{
friend class DocHtmlTable;
public:
@@ -1314,7 +1334,6 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
m_attribs(attribs), m_visibleCells(-1), m_rowIdx(-1) { m_parent = parent; }
Kind kind() const { return Kind_HtmlRow; }
uint numCells() const { return m_children.count(); }
- void accept(DocVisitor *v) { CompAccept<DocHtmlRow>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
int parse();
int parseXml(bool header);
@@ -1343,7 +1362,7 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>, public DocNode
};
/** Node representing a HTML table */
-class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
+class DocHtmlTable : public CompAccept<DocHtmlTable>
{
public:
DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs)
@@ -1372,14 +1391,13 @@ class DocHtmlTable : public CompAccept<DocHtmlTable>, public DocNode
};
/** Node representing an HTML blockquote */
-class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote>, public DocNode
+class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote>
{
public:
DocHtmlBlockQuote(DocNode *parent,const HtmlAttribList &attribs)
: m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlBlockQuote; }
int parse();
- void accept(DocVisitor *v) { CompAccept<DocHtmlBlockQuote>::accept(this,v); }
const HtmlAttribList &attribs() const { return m_attribs; }
private:
@@ -1387,23 +1405,21 @@ class DocHtmlBlockQuote : public CompAccept<DocHtmlBlockQuote>, public DocNode
};
/** Root node of a text fragment */
-class DocText : public CompAccept<DocText>, public DocNode
+class DocText : public CompAccept<DocText>
{
public:
DocText() {}
Kind kind() const { return Kind_Text; }
- void accept(DocVisitor *v) { CompAccept<DocText>::accept(this,v); }
void parse();
bool isEmpty() const { return m_children.isEmpty(); }
};
/** Root node of documentation tree */
-class DocRoot : public CompAccept<DocRoot>, public DocNode
+class DocRoot : public CompAccept<DocRoot>
{
public:
DocRoot(bool indent,bool sl) : m_indent(indent), m_singleLine(sl) {}
Kind kind() const { return Kind_Root; }
- void accept(DocVisitor *v) { CompAccept<DocRoot>::accept(this,v); }
void parse();
bool indent() const { return m_indent; }
bool singleLine() const { return m_singleLine; }
diff --git a/src/dot.cpp b/src/dot.cpp
index 4189748..5c65eef 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -1521,21 +1521,21 @@ void DotNode::setDistance(int distance)
static QCString convertLabel(const QCString &l)
{
- QCString result;
- QCString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
- QCString bAfter(">]),:;|"); // break after character set
- const char *p=l.data();
- if (p==0) return result;
- char c,pc=0;
- char cs[2];
- cs[1]=0;
- int len=l.length();
+ QString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
+ QString bAfter(">]),:;|"); // break after character set
+ QString p(l);
+ if (p.isEmpty()) return QCString();
+ QString result;
+ QChar c,pc=0;
+ int idx = 0;
+ int len=p.length();
int charsLeft=len;
int sinceLast=0;
int foldLen=17; // ideal text length
- while ((c=*p++))
+ while (idx < p.length())
{
- QCString replacement;
+ c = p[idx++];
+ QString replacement;
switch(c)
{
case '\\': replacement="\\\\"; break;
@@ -1546,7 +1546,7 @@ static QCString convertLabel(const QCString &l)
case '{': replacement="\\{"; break;
case '}': replacement="\\}"; break;
case '"': replacement="\\\""; break;
- default: cs[0]=c; replacement=cs; break;
+ default: replacement=c; break;
}
// Some heuristics to insert newlines to prevent too long
// boxes and at the same time prevent ugly breaks
@@ -1564,14 +1564,14 @@ static QCString convertLabel(const QCString &l)
sinceLast=1;
}
else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
- !isupper(c) && isupper(*p))
+ !isupper(c) && p[idx].category()==QChar::Letter_Uppercase)
{
result+=replacement;
result+="\\l";
foldLen = (foldLen+sinceLast+1)/2;
sinceLast=0;
}
- else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || *p!=':'))
+ else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || p[idx]!=':'))
{
result+=replacement;
result+="\\l";
@@ -1586,7 +1586,7 @@ static QCString convertLabel(const QCString &l)
charsLeft--;
pc=c;
}
- return result;
+ return result.utf8();
}
static QCString escapeTooltip(const QCString &tooltip)
@@ -4712,7 +4712,7 @@ void DotGroupCollaboration::writeGraphHeader(FTextStream &t,
}
t << " edge [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\","
"labelfontname=\"" << FONTNAME << "\",labelfontsize=\"" << FONTSIZE << "\"];\n";
- t << " node [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\",shape=record];\n";
+ t << " node [fontname=\"" << FONTNAME << "\",fontsize=\"" << FONTSIZE << "\",shape=box];\n";
t << " rankdir=LR;\n";
}
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index d1fb06c..ab371fe 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -624,6 +624,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
// op->type(),op->isFirst(),op->isLast(),op->text().data());
if (op->isFirst())
{
+ forceStartParagraph(op);
if (!m_hide) m_t << PREFRAG_START;
pushEnabled();
m_hide=TRUE;
@@ -658,6 +659,7 @@ void HtmlDocVisitor::visit(DocIncOperator *op)
{
popEnabled();
if (!m_hide) m_t << PREFRAG_END;
+ forceStartParagraph(op);
}
else
{
@@ -776,12 +778,13 @@ void HtmlDocVisitor::visitPre(DocAutoList *l)
// A.
// 1. (repeat)...
//
- m_t << "<ol type=\"" << types[l->depth() % NUM_HTML_LIST_TYPES] << "\">";
+ m_t << "<ol type=\"" << types[l->depth() % NUM_HTML_LIST_TYPES] << "\"";
}
else
{
- m_t << "<ul>";
+ m_t << "<ul";
}
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(l)) << ">";
if (!l->isPreformatted()) m_t << "\n";
}
@@ -1021,6 +1024,7 @@ void HtmlDocVisitor::visitPre(DocPara *p)
// if the first element of a paragraph is something that should be outside of
// the paragraph (<ul>,<dl>,<table>,..) then that will already started the
// paragraph and we don't need to do it here
+ auto paragraphAlreadyStarted = false;
uint nodeIndex = 0;
if (p && nodeIndex<p->children().count())
{
@@ -1034,6 +1038,7 @@ void HtmlDocVisitor::visitPre(DocPara *p)
DocNode *n = p->children().at(nodeIndex);
if (mustBeOutsideParagraph(n))
{
+ paragraphAlreadyStarted = true;
needsTag = FALSE;
}
}
@@ -1044,13 +1049,13 @@ void HtmlDocVisitor::visitPre(DocPara *p)
// fix the otherwise ugly spacing.
int t;
static const char *contexts[7] =
- { "", // 0
- " class=\"startli\"", // 1
- " class=\"startdd\"", // 2
- " class=\"endli\"", // 3
- " class=\"enddd\"", // 4
- " class=\"starttd\"", // 5
- " class=\"endtd\"" // 6
+ { "", // 0
+ "startli", // 1
+ "startdd", // 2
+ "endli", // 3
+ "enddd", // 4
+ "starttd", // 5
+ "endtd" // 6
};
bool isFirst;
bool isLast;
@@ -1060,7 +1065,10 @@ void HtmlDocVisitor::visitPre(DocPara *p)
//printf(" needsTag=%d\n",needsTag);
// write the paragraph tag (if needed)
- if (needsTag) m_t << "<p" << contexts[t] << ">";
+ if (needsTag)
+ m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(p), contexts[t]) << ">";
+ else if(!paragraphAlreadyStarted)
+ m_t << getHtmlDirEmbedingChar(getTextDirByConfig(p));
}
void HtmlDocVisitor::visitPost(DocPara *p)
@@ -1136,7 +1144,8 @@ void HtmlDocVisitor::visitPre(DocSimpleSect *s)
{
if (m_hide) return;
forceEndParagraph(s);
- m_t << "<dl class=\"section " << s->typeString() << "\"><dt>";
+ m_t << "<dl" << getDirHtmlClassOfNode(getTextDirByConfig(s), "section " + s->typeString())
+ << "><dt>";
switch(s->type())
{
case DocSimpleSect::See:
@@ -1232,7 +1241,7 @@ void HtmlDocVisitor::visitPre(DocSection *s)
{
if (m_hide) return;
forceEndParagraph(s);
- m_t << "<h" << s->level() << ">";
+ m_t << "<h" << s->level() << getDirHtmlClassOfNode(getTextDirByConfig(s->title())) << ">";
m_t << "<a class=\"anchor\" id=\"" << s->anchor();
m_t << "\"></a>" << endl;
filter(convertCharEntitiesToUTF8(s->title().data()));
@@ -1250,12 +1259,13 @@ void HtmlDocVisitor::visitPre(DocHtmlList *s)
forceEndParagraph(s);
if (s->type()==DocHtmlList::Ordered)
{
- m_t << "<ol" << htmlAttribsToString(s->attribs()) << ">\n";
+ m_t << "<ol" << htmlAttribsToString(s->attribs());
}
else
{
- m_t << "<ul" << htmlAttribsToString(s->attribs()) << ">\n";
+ m_t << "<ul" << htmlAttribsToString(s->attribs());
}
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(s)) << ">\n";
}
void HtmlDocVisitor::visitPost(DocHtmlList *s)
@@ -1303,7 +1313,9 @@ void HtmlDocVisitor::visitPost(DocHtmlDescList *dl)
void HtmlDocVisitor::visitPre(DocHtmlDescTitle *dt)
{
if (m_hide) return;
- m_t << "<dt" << htmlAttribsToString(dt->attribs()) << ">";
+ m_t << "<dt" << htmlAttribsToString(dt->attribs())
+ << getDirHtmlClassOfNode(getTextDirByConfig(dt))
+ << ">";
}
void HtmlDocVisitor::visitPost(DocHtmlDescTitle *)
@@ -1315,7 +1327,9 @@ void HtmlDocVisitor::visitPost(DocHtmlDescTitle *)
void HtmlDocVisitor::visitPre(DocHtmlDescData *dd)
{
if (m_hide) return;
- m_t << "<dd" << htmlAttribsToString(dd->attribs()) << ">";
+ m_t << "<dd" << htmlAttribsToString(dd->attribs())
+ << getDirHtmlClassOfNode(getTextDirByConfig(dd))
+ << ">";
}
void HtmlDocVisitor::visitPost(DocHtmlDescData *)
@@ -1338,11 +1352,21 @@ void HtmlDocVisitor::visitPre(DocHtmlTable *t)
QString attrs = htmlAttribsToString(t->attribs());
if (attrs.isEmpty())
{
- m_t << "<table class=\"doxtable\">\n";
+ m_t << "<table";
+ if(t->hasCaption())
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(t->caption()), "doxtable");
+ else
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(t), "doxtable");
+ m_t << ">\n";
}
else
{
- m_t << "<table" << htmlAttribsToString(t->attribs()) << ">\n";
+ m_t << "<table";
+ if (t->hasCaption())
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(t->caption()));
+ else
+ m_t << getDirHtmlClassOfNode(getTextDirByConfig(t));
+ m_t << htmlAttribsToString(t->attribs()) << ">\n";
}
}
@@ -1435,7 +1459,9 @@ void HtmlDocVisitor::visitPre(DocHtmlHeader *header)
if (m_hide) return;
forceEndParagraph(header);
m_t << "<h" << header->level()
- << htmlAttribsToString(header->attribs()) << ">";
+ << htmlAttribsToString(header->attribs())
+ << getDirHtmlClassOfNode(getTextDirByConfig(header))
+ << ">";
}
void HtmlDocVisitor::visitPost(DocHtmlHeader *header)
@@ -1500,6 +1526,7 @@ void HtmlDocVisitor::visitPre(DocImage *img)
if (img->hasCaption())
{
m_t << "<div class=\"caption\">" << endl;
+ m_t << getHtmlDirEmbedingChar(getTextDirByConfig(img));
}
}
else // other format -> skip
@@ -1862,11 +1889,13 @@ void HtmlDocVisitor::visitPre(DocHtmlBlockQuote *b)
QString attrs = htmlAttribsToString(b->attribs());
if (attrs.isEmpty())
{
- m_t << "<blockquote class=\"doxtable\">\n";
+ m_t << "<blockquote" << getDirHtmlClassOfNode(getTextDirByConfig(b), "doxtable")
+ << ">\n";
}
else
{
- m_t << "<blockquote" << htmlAttribsToString(b->attribs()) << ">\n";
+ m_t << "<blockquote" << getDirHtmlClassOfNode(getTextDirByConfig(b))
+ << htmlAttribsToString(b->attribs()) << ">\n";
}
}
@@ -2201,13 +2230,17 @@ void HtmlDocVisitor::forceStartParagraph(DocNode *n)
return; // only whitespace at the end!
}
+ bool needsTag = TRUE;
bool isFirst;
bool isLast;
getParagraphContext(para,isFirst,isLast);
//printf("forceStart first=%d last=%d\n",isFirst,isLast);
- if (isFirst && isLast) return;
+ if (isFirst && isLast) needsTag = FALSE;
- m_t << "<p>";
+ if (needsTag)
+ m_t << "<p" << getDirHtmlClassOfNode(getTextDirByConfig(para, nodeIndex)) << ">";
+ else
+ m_t << getHtmlDirEmbedingChar(getTextDirByConfig(para, nodeIndex));
}
}
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 12b71e1..af8c9e0 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -374,8 +374,8 @@ static QCString substituteHtmlKeywords(const QCString &s,
// first substitute generic keywords
QCString result = substituteKeywords(s,title,
- convertToHtml(Config_getString(PROJECT_NAME)),
- convertToHtml(Config_getString(PROJECT_NUMBER)),
+ convertToHtml(Config_getString(PROJECT_NAME)),
+ convertToHtml(Config_getString(PROJECT_NUMBER)),
convertToHtml(Config_getString(PROJECT_BRIEF)));
// additional HTML only keywords
@@ -479,6 +479,8 @@ void HtmlCodeGenerator::codify(const char *str)
void HtmlCodeGenerator::docify(const char *str)
{
+ m_t << getHtmlDirEmbedingChar(getTextDirByConfig(str));
+
if (str && m_streamSet)
{
const char *p=str;
@@ -2310,6 +2312,16 @@ void HtmlGenerator::endContents()
t << "</div><!-- contents -->" << endl;
}
+void HtmlGenerator::startPageDoc(const char *pageTitle)
+{
+ t << "<div" << getDirHtmlClassOfPage(pageTitle) << ">";
+}
+
+void HtmlGenerator::endPageDoc()
+{
+ t << "</div><!-- PageDoc -->" << endl;
+}
+
void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
{
writeDefaultQuickLinks(t,compact,hli,file,relPath);
diff --git a/src/htmlgen.h b/src/htmlgen.h
index 70e4b5f..82f0c17 100644
--- a/src/htmlgen.h
+++ b/src/htmlgen.h
@@ -271,6 +271,8 @@ class HtmlGenerator : public OutputGenerator
void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first);
void startContents();
void endContents();
+ void startPageDoc(const char *pageTitle);
+ void endPageDoc();
void writeNonBreakableSpace(int);
void startDescTable(const char *title);
diff --git a/src/index.cpp b/src/index.cpp
index 10c1dcb..375bdeb 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -3829,6 +3829,18 @@ static void writeIndex(OutputList &ol)
ol.writeSplitBar(indexName);
ol.writeSearchInfo();
bool headerWritten=FALSE;
+ if (Doxygen::mainPage)
+ {
+ if (!Doxygen::mainPage->title().isEmpty())
+ {
+ if (Doxygen::mainPage->title().lower() != "notitle")
+ ol.startPageDoc(Doxygen::mainPage->title());
+ else
+ ol.startPageDoc("");
+ }
+ else
+ ol.startPageDoc(projectName);
+ }
if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
{
if (Doxygen::mainPage->title().lower()!="notitle")
@@ -3876,6 +3888,7 @@ static void writeIndex(OutputList &ol)
Doxygen::mainPage->documentation(),TRUE,FALSE
/*,Doxygen::mainPage->sectionDict*/);
ol.endTextBlock();
+ ol.endPageDoc();
Doxygen::insideMainPage=FALSE;
}
@@ -4333,7 +4346,7 @@ void renderMemberIndicesAsJs(FTextStream &t,
firstMember=FALSE;
}
t << endl << "{text:\"" << convertToJSString(getInfo(i)->title) << "\",url:\""
- << convertToJSString(getInfo(i)->fname+Doxygen::htmlFileExtension) << "\"";
+ << convertToJSString(getInfo(i)->fname+Doxygen::htmlFileExtension, false) << "\"";
// Check if we have many members, then add sub entries per letter...
// quick alphabetical index
@@ -4363,7 +4376,7 @@ void renderMemberIndicesAsJs(FTextStream &t,
else // other pages of multi page index
anchor=fullName+"_"+is+extension+"#index_";
t << "{text:\"" << convertToJSString(ci) << "\",url:\""
- << convertToJSString(anchor+is) << "\"}";
+ << convertToJSString(anchor+is, false) << "\"}";
firstLetter=FALSE;
}
t << "]";
@@ -4399,7 +4412,7 @@ static bool renderQuickLinksAsJs(FTextStream &t,LayoutNavEntry *root,bool first)
firstChild=FALSE;
QCString url = entry->url();
t << "{text:\"" << convertToJSString(entry->title()) << "\",url:\""
- << convertToJSString(url) << "\"";
+ << convertToJSString(url, false) << "\"";
bool hasChildren=FALSE;
if (entry->kind()==LayoutNavEntry::NamespaceMembers)
{
diff --git a/src/outputgen.h b/src/outputgen.h
index 7e28bac..68356b4 100644
--- a/src/outputgen.h
+++ b/src/outputgen.h
@@ -446,6 +446,8 @@ class OutputGenerator : public BaseOutputDocInterface
virtual void writeSummaryLink(const char *file,const char *anchor,const char *title,bool first) = 0;
virtual void startContents() = 0;
virtual void endContents() = 0;
+ virtual void startPageDoc(const char *pageTitle) {};
+ virtual void endPageDoc() {};
virtual void startTextBlock(bool) = 0;
virtual void endTextBlock(bool) = 0;
virtual void lastIndexPage() = 0;
diff --git a/src/outputlist.h b/src/outputlist.h
index 5cec439..0738ed1 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -366,6 +366,10 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startContents); }
void endContents()
{ forall(&OutputGenerator::endContents); }
+ void startPageDoc(const char *pageTitle)
+ { forall(&OutputGenerator::startPageDoc, pageTitle); }
+ void endPageDoc()
+ { forall(&OutputGenerator::endPageDoc); }
void writeNonBreakableSpace(int num)
{ forall(&OutputGenerator::writeNonBreakableSpace,num); }
void startDescTable(const char *title)
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index 1210305..203acf5 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -183,6 +183,7 @@ void PageDef::writeDocumentation(OutputList &ol)
ol.disable(OutputGenerator::Man);
if (!title().isEmpty() && !name().isEmpty() && si!=0)
{
+ ol.startPageDoc(si->title);
//ol.startSection(si->label,si->title,si->type);
startTitle(ol,getOutputFileBase(),this);
ol.generateDoc(docFile(),docLine(),this,0,si->title,TRUE,FALSE,0,TRUE,FALSE);
@@ -192,6 +193,8 @@ void PageDef::writeDocumentation(OutputList &ol)
//ol.endSection(si->label,si->type);
endTitle(ol,getOutputFileBase(),name());
}
+ else
+ ol.startPageDoc("");
ol.startContents();
ol.popGeneratorState();
//2.}
@@ -202,6 +205,7 @@ void PageDef::writeDocumentation(OutputList &ol)
}
writePageDocumentation(ol);
+ ol.endPageDoc();
if (generateTreeView && getOuterScope()!=Doxygen::globalScope && !Config_getBool(DISABLE_INDEX))
{
diff --git a/src/util.cpp b/src/util.cpp
index e44f825..33562c8 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -5851,6 +5851,7 @@ QCString convertToHtml(const char *s,bool keepEntities)
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
+ growBuf.addStr(getHtmlDirEmbedingChar(getTextDirByConfig(s)));
const char *p=s;
char c;
while ((c=*p++))
@@ -5892,11 +5893,13 @@ QCString convertToHtml(const char *s,bool keepEntities)
return growBuf.get();
}
-QCString convertToJSString(const char *s)
+QCString convertToJSString(const char *s, bool applyTextDir)
{
static GrowBuf growBuf;
growBuf.clear();
if (s==0) return "";
+ if (applyTextDir)
+ growBuf.addStr(getJsDirEmbedingChar(getTextDirByConfig(s)));
const char *p=s;
char c;
while ((c=*p++))
diff --git a/src/util.h b/src/util.h
index af8a3b4..c14c8f7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -26,7 +26,6 @@
#include <ctype.h>
#include "types.h"
#include "sortdict.h"
-#include "docparser.h"
//--------------------------------------------------------------------
@@ -283,7 +282,7 @@ QCString convertToLaTeX(const QCString &s,bool insideTabbing=FALSE,bool keepSpac
QCString convertToXML(const char *s);
-QCString convertToJSString(const char *s);
+QCString convertToJSString(const char *s, bool applyTextDir = true);
QCString getOverloadDocs();
diff --git a/templates/html/doxygen.css b/templates/html/doxygen.css
index 26169de..3bb7316 100644
--- a/templates/html/doxygen.css
+++ b/templates/html/doxygen.css
@@ -163,6 +163,12 @@ dl.el {
margin-left: -1cm;
}
+.fragment
+{
+ text-align: left;
+ direction:ltr;
+}
+
pre.fragment {
border: 1px solid #C4CFE5;
background-color: #FBFCFD;
@@ -402,6 +408,13 @@ blockquote {
padding: 0 12px 0 16px;
}
+blockquote.DocNodeRTL {
+ border-left: 0;
+ border-right: 2px solid #9CAFD4;
+ margin: 0 4px 0 24px;
+ padding: 0 16px 0 12px;
+}
+
/* @end */
/*
@@ -1081,6 +1094,11 @@ div.headertitle
padding: 5px 5px 5px 10px;
}
+.PageDocRTL-title div.headertitle {
+ text-align: right;
+ direction: rtl;
+}
+
dl
{
padding: 0 0 0 10px;
@@ -1093,60 +1111,128 @@ dl.section
padding-left: 0px;
}
-dl.note
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #D0C000;
+dl.section.DocNodeRTL {
+ margin-right: 0px;
+ padding-right: 0px;
}
-dl.warning, dl.attention
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #FF0000;
+dl.note {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #D0C000;
}
-dl.pre, dl.post, dl.invariant
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #00D000;
+dl.note.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #D0C000;
+}
+
+dl.warning, dl.attention {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #FF0000;
}
-dl.deprecated
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #505050;
+dl.warning.DocNodeRTL, dl.attention.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #FF0000;
}
-dl.todo
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #00C0E0;
+dl.pre, dl.post, dl.invariant {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #00D000;
}
-dl.test
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #3030E0;
+dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #00D000;
}
-dl.bug
-{
- margin-left:-7px;
- padding-left: 3px;
- border-left:4px solid;
- border-color: #C08050;
+dl.deprecated {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #505050;
+}
+
+dl.deprecated.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #505050;
+}
+
+dl.todo {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #00C0E0;
+}
+
+dl.todo.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #00C0E0;
+}
+
+dl.test {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #3030E0;
+}
+
+dl.test.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #3030E0;
+}
+
+dl.bug {
+ margin-left: -7px;
+ padding-left: 3px;
+ border-left: 4px solid;
+ border-color: #C08050;
+}
+
+dl.bug.DocNodeRTL {
+ margin-left: 0;
+ padding-left: 0;
+ border-left: 0;
+ margin-right: -7px;
+ padding-right: 3px;
+ border-right: 4px solid;
+ border-color: #C08050;
}
dl.section dd {
@@ -1263,6 +1349,10 @@ div.toc {
width: 200px;
}
+.PageDocRTL-title .toc {
+ float: left !important;
+}
+
div.toc li {
background: url("bdwn.png") no-repeat scroll 0 5px transparent;
font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
@@ -1592,5 +1682,31 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter {
text-align: center
}
+.DocNodeRTL {
+ text-align: right;
+ direction: rtl;
+}
+
+.DocNodeLTR {
+ text-align: left;
+ direction: ltr;
+}
+
+table.DocNodeRTL {
+ width: auto;
+ margin-right: 0;
+ margin-left: auto;
+}
+table.DocNodeLTR {
+ width: auto;
+ margin-right: auto;
+ margin-left: 0;
+}
+
+tt, code, kbd, samp
+{
+ display: inline-block;
+ direction:ltr;
+}
/* @end */