summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ftvhelp.cpp1
-rw-r--r--src/htmldocvisitor.cpp18
-rw-r--r--src/latexdocvisitor.cpp136
-rw-r--r--src/latexdocvisitor.h84
-rw-r--r--templates/html/doxygen.css4
-rw-r--r--templates/latex/doxygen.sty8
6 files changed, 180 insertions, 71 deletions
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index e2774a9..a70e243 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -171,6 +171,7 @@ void FTVHelp::decContentsDepth()
/*! Add a list item to the contents file.
* \param isDir TRUE if the item is a directory, FALSE if it is a text
+ * \param name The name of the item.
* \param ref the URL of to the item.
* \param file the file containing the definition of the item
* \param anchor the anchor within the file.
diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp
index 296a957..2e9795e 100644
--- a/src/htmldocvisitor.cpp
+++ b/src/htmldocvisitor.cpp
@@ -1301,6 +1301,11 @@ void HtmlDocVisitor::visitPre(DocHtmlTable *t)
forceEndParagraph(t);
+ if (t->hasCaption())
+ {
+ m_t << "<a class=\"anchor\" id=\"" << t->caption()->anchor() << "\"></a>\n";
+ }
+
QString attrs = htmlAttribsToString(t->attribs());
if (attrs.isEmpty())
{
@@ -1353,21 +1358,11 @@ void HtmlDocVisitor::visitPost(DocHtmlCell *c)
void HtmlDocVisitor::visitPre(DocHtmlCaption *c)
{
if (m_hide) return;
- if (c->hasCaptionId())
- {
- m_t << "<a class=\"anchor\" id=\"" << c->anchor() << "\"></a>\n";
- }
bool hasAlign = FALSE;
HtmlAttribListIterator li(c->attribs());
HtmlAttrib *att;
QCString id;
- for (li.toFirst();(att=li.current());++li)
- {
- if (att->name=="align") hasAlign=TRUE;
- }
- m_t << "<caption" << htmlAttribsToString(c->attribs());
- if (!hasAlign) m_t << " align=\"bottom\"";
- m_t << ">";
+ m_t << "<caption" << htmlAttribsToString(c->attribs()) << ">";
}
void HtmlDocVisitor::visitPost(DocHtmlCaption *)
@@ -1813,7 +1808,6 @@ void HtmlDocVisitor::visitPre(DocHtmlBlockQuote *b)
{
if (m_hide) return;
forceEndParagraph(b);
-
QString attrs = htmlAttribsToString(b->attribs());
if (attrs.isEmpty())
{
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index 22b3b32..5e7278c 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -172,10 +172,9 @@ LatexDocVisitor::LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci,
const char *langExt,bool insideTabbing)
: DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE),
m_insideItem(FALSE), m_hide(FALSE), m_hideCaption(FALSE), m_insideTabbing(insideTabbing),
- m_insideTable(FALSE), m_langExt(langExt), m_currentColumn(0),
- m_inRowspan(FALSE), m_inColspan(FALSE), m_firstRow(FALSE)
+ m_langExt(langExt)
{
- m_rowSpans.setAutoDelete(TRUE);
+ m_tableStateStack.setAutoDelete(TRUE);
}
//--------------------------------------
@@ -890,7 +889,7 @@ void LatexDocVisitor::visitPost(DocHtmlDescData *)
{
}
-static const char *getTableName(const DocNode *n)
+static bool tableIsNested(const DocNode *n)
{
bool isNested=FALSE;
while (n && !isNested)
@@ -898,14 +897,39 @@ static const char *getTableName(const DocNode *n)
isNested = n->kind()==DocNode::Kind_HtmlTable || n->kind()==DocNode::Kind_ParamSect;
n = n->parent();
}
- return isNested ? "TabularNC" : "TabularC";
+ return isNested;
+}
+
+static void writeStartTableCommand(FTextStream &t,const DocNode *n,int cols)
+{
+ if (tableIsNested(n))
+ {
+ t << "\\begin{tabularx}{\\linewidth}{|*{" << cols << "}{>{\\raggedright\\arraybackslash}X|}}";
+ }
+ else
+ {
+ t << "\\tabulinesep=1mm\n\\begin{longtabu} spread 0pt [c]{*" << cols << "{|X[-1]}|}\n";
+ }
+ //return isNested ? "TabularNC" : "TabularC";
+}
+
+static void writeEndTableCommand(FTextStream &t,const DocNode *n)
+{
+ if (tableIsNested(n))
+ {
+ t << "\\end{tabularx}\n";
+ }
+ else
+ {
+ t << "\\end{longtabu}\n";
+ }
+ //return isNested ? "TabularNC" : "TabularC";
}
void LatexDocVisitor::visitPre(DocHtmlTable *t)
{
- m_rowSpans.clear();
- m_insideTable=TRUE;
if (m_hide) return;
+ pushTableState();
if (t->hasCaption())
{
DocHtmlCaption *c = t->caption();
@@ -918,7 +942,7 @@ void LatexDocVisitor::visitPre(DocHtmlTable *t)
m_t << endl;
}
- m_t << "\\begin{" << getTableName(t->parent()) << "}{" << t->numColumns() << "}\n";
+ writeStartTableCommand(m_t,t->parent(),t->numColumns());
if (t->hasCaption())
{
@@ -930,7 +954,7 @@ void LatexDocVisitor::visitPre(DocHtmlTable *t)
m_t << "\\\\\n";
}
- m_numCols = t->numColumns();
+ setNumCols(t->numColumns());
m_t << "\\hline\n";
// check if first row is a heading and then render the row already here
@@ -939,17 +963,17 @@ void LatexDocVisitor::visitPre(DocHtmlTable *t)
DocHtmlRow *firstRow = t->firstRow();
if (firstRow && firstRow->isHeading())
{
- m_firstRow=TRUE;
+ setFirstRow(TRUE);
firstRow->accept(this);
- m_firstRow=FALSE;
+ setFirstRow(FALSE);
}
}
void LatexDocVisitor::visitPost(DocHtmlTable *t)
{
- m_insideTable=FALSE;
if (m_hide) return;
- m_t << "\\end{" << getTableName(t->parent()) << "}\n";
+ writeEndTableCommand(m_t,t->parent());
+ popTableState();
}
void LatexDocVisitor::visitPre(DocHtmlCaption *c)
@@ -965,7 +989,7 @@ void LatexDocVisitor::visitPost(DocHtmlCaption *c)
void LatexDocVisitor::visitPre(DocHtmlRow *r)
{
- m_currentColumn = 0;
+ setCurrentColumn(0);
if (r->isHeading()) m_t << "\\rowcolor{\\tableheadbgcolor}";
}
@@ -973,15 +997,15 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row)
{
if (m_hide) return;
- int c=m_currentColumn;
- while (c<=m_numCols) // end of row while inside a row span?
+ int c=currentColumn();
+ while (c<=numCols()) // end of row while inside a row span?
{
uint i;
- for (i=0;i<m_rowSpans.count();i++)
+ for (i=0;i<rowSpans().count();i++)
{
- ActiveRowSpan *span = m_rowSpans.at(i);
- //printf(" founc row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d\n",
- // span->column, span->rowSpan,span->colSpan,row->rowIndex(),span->cell->rowIndex());
+ ActiveRowSpan *span = rowSpans().at(i);
+ //printf(" found row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d i=%d c=%d\n",
+ // span->column, span->rowSpan,span->colSpan,row->rowIndex(),span->cell->rowIndex(),i,c);
if (span->rowSpan>0 && span->column==c && // we are at a cell in a row span
row->rowIndex()>span->cell->rowIndex() // but not the row that started the span
)
@@ -991,9 +1015,9 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row)
{
m_t << "\\multicolumn{" << span->colSpan << "}{";
m_t << "p{(\\linewidth-\\tabcolsep*"
- << m_numCols << "-\\arrayrulewidth*"
+ << numCols() << "-\\arrayrulewidth*"
<< row->visibleCells() << ")*"
- << span->colSpan <<"/"<< m_numCols << "}|}{}";
+ << span->colSpan <<"/"<< numCols() << "}|}{}";
}
else // solitary row span
{
@@ -1008,9 +1032,9 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row)
int col = 1;
uint i;
- for (i=0;i<m_rowSpans.count();i++)
+ for (i=0;i<rowSpans().count();i++)
{
- ActiveRowSpan *span = m_rowSpans.at(i);
+ ActiveRowSpan *span = rowSpans().at(i);
if (span->rowSpan>0) span->rowSpan--;
if (span->rowSpan<=0)
{
@@ -1027,16 +1051,16 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row)
}
}
- if (col <= m_numCols)
+ if (col <= numCols())
{
- m_t << "\\cline{" << col << "-" << m_numCols << "}";
+ m_t << "\\cline{" << col << "-" << numCols() << "}";
}
m_t << "\n";
if (row->isHeading() && row->rowIndex()==1)
{
- if (m_firstRow)
+ if (firstRow())
{
m_t << "\\endfirsthead" << endl;
m_t << "\\hline" << endl;
@@ -1059,32 +1083,32 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c)
{
row = (DocHtmlRow*)c->parent();
}
-
- m_currentColumn++;
+
+ setCurrentColumn(currentColumn()+1);
//Skip columns that span from above.
uint i;
- for (i=0;i<m_rowSpans.count();i++)
+ for (i=0;i<rowSpans().count();i++)
{
- ActiveRowSpan *span = m_rowSpans.at(i);
- if (span->rowSpan>0 && span->column==m_currentColumn)
+ ActiveRowSpan *span = rowSpans().at(i);
+ if (span->rowSpan>0 && span->column==currentColumn())
{
if (row && span->colSpan>1)
{
m_t << "\\multicolumn{" << span->colSpan << "}{";
- if (m_currentColumn /*c->columnIndex()*/==1) // add extra | for first column
+ if (currentColumn() /*c->columnIndex()*/==1) // add extra | for first column
{
m_t << "|";
}
m_t << "p{(\\linewidth-\\tabcolsep*"
- << m_numCols << "-\\arrayrulewidth*"
+ << numCols() << "-\\arrayrulewidth*"
<< row->visibleCells() << ")*"
- << span->colSpan <<"/"<< m_numCols << "}|}{}";
- m_currentColumn+=span->colSpan;
+ << span->colSpan <<"/"<< numCols() << "}|}{}";
+ setCurrentColumn(currentColumn()+span->colSpan);
}
else
{
- m_currentColumn++;
+ setCurrentColumn(currentColumn()+1);
}
m_t << "&";
}
@@ -1093,23 +1117,26 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c)
int cs = c->colSpan();
if (cs>1 && row)
{
- m_inColspan = TRUE;
+ setInColSpan(TRUE);
m_t << "\\multicolumn{" << cs << "}{";
if (c->columnIndex()==1) // add extra | for first column
{
m_t << "|";
}
m_t << "p{(\\linewidth-\\tabcolsep*"
- << m_numCols << "-\\arrayrulewidth*"
+ << numCols() << "-\\arrayrulewidth*"
<< row->visibleCells() << ")*"
- << cs <<"/"<< m_numCols << "}|}{";
+ << cs <<"/"<< numCols() << "}|}{";
if (c->isHeading()) m_t << "\\cellcolor{\\tableheadbgcolor}";
}
int rs = c->rowSpan();
if (rs>0)
{
- m_inRowspan = TRUE;
- m_rowSpans.append(new ActiveRowSpan(c,rs,cs,m_currentColumn));
+ setInRowSpan(TRUE);
+ //printf("adding row span: cell={r=%d c=%d rs=%d cs=%d} curCol=%d\n",
+ // c->rowIndex(),c->columnIndex(),c->rowSpan(),c->colSpan(),
+ // currentColumn());
+ addRowSpan(new ActiveRowSpan(c,rs,cs,currentColumn()));
m_t << "\\multirow{" << rs << "}{\\linewidth}{";
}
int a = c->alignment();
@@ -1127,7 +1154,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c)
}
if (cs>1)
{
- m_currentColumn+=cs-1;
+ setCurrentColumn(currentColumn()+cs-1);
}
}
@@ -1138,14 +1165,14 @@ void LatexDocVisitor::visitPost(DocHtmlCell *c)
{
m_t << "}";
}
- if (m_inRowspan)
+ if (inRowSpan())
{
- m_inRowspan = FALSE;
+ setInRowSpan(FALSE);
m_t << "}";
}
- if (m_inColspan)
+ if (inColSpan())
{
- m_inColspan = FALSE;
+ setInColSpan(FALSE);
m_t << "}";
}
if (!c->isLast()) m_t << "&";
@@ -1603,15 +1630,22 @@ void LatexDocVisitor::filter(const char *str)
void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const QCString &anchor,bool refToTable)
{
static bool pdfHyperLinks = Config_getBool("PDF_HYPERLINKS");
- if (ref.isEmpty() && pdfHyperLinks) // internal PDF link
+ if (ref.isEmpty() && pdfHyperLinks) // internal PDF link
{
- m_t << "\\hyperlink{";
+ if (refToTable)
+ {
+ m_t << "\\doxytablelink{";
+ }
+ else
+ {
+ m_t << "\\hyperlink{";
+ }
if (!file.isEmpty()) m_t << stripPath(file);
if (!file.isEmpty() && !anchor.isEmpty()) m_t << "_";
if (!anchor.isEmpty()) m_t << anchor;
m_t << "}{";
}
- else if (refToTable)
+ else if (ref.isEmpty() && refToTable)
{
m_t << "\\doxytableref{";
}
@@ -1620,7 +1654,7 @@ void LatexDocVisitor::startLink(const QCString &ref,const QCString &file,const Q
m_t << "\\doxyref{";
}
else // external link
- {
+ {
m_t << "{\\bf ";
}
}
diff --git a/src/latexdocvisitor.h b/src/latexdocvisitor.h
index de797ae..02df1ef 100644
--- a/src/latexdocvisitor.h
+++ b/src/latexdocvisitor.h
@@ -192,15 +192,85 @@ class LatexDocVisitor : public DocVisitor
bool m_hide;
bool m_hideCaption;
bool m_insideTabbing;
- bool m_insideTable;
- int m_numCols;
QStack<bool> m_enabled;
QCString m_langExt;
- RowSpanList m_rowSpans;
- int m_currentColumn;
- bool m_inRowspan;
- bool m_inColspan;
- bool m_firstRow;
+
+ struct TableState
+ {
+ TableState() : numCols(0), currentColumn(0), inRowSpan(FALSE),
+ inColSpan(FALSE), firstRow(FALSE)
+ { rowSpans.setAutoDelete(TRUE); }
+ RowSpanList rowSpans;
+ int numCols;
+ int currentColumn;
+ bool inRowSpan;
+ bool inColSpan;
+ bool firstRow;
+ };
+ QStack<TableState> m_tableStateStack; // needed for nested tables
+ RowSpanList m_emptyRowSpanList;
+
+ void pushTableState()
+ {
+ m_tableStateStack.push(new TableState);
+ }
+ void popTableState()
+ {
+ delete m_tableStateStack.pop();
+ }
+ int currentColumn() const
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->currentColumn : 0;
+ }
+ void setCurrentColumn(int col)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->currentColumn = col;
+ }
+ int numCols() const
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->numCols : 0;
+ }
+ void setNumCols(int num)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->numCols = num;
+ }
+ bool inRowSpan() const
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->inRowSpan : FALSE;
+ }
+ void setInRowSpan(bool b)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->inRowSpan = b;
+ }
+ bool inColSpan() const
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->inColSpan : FALSE;
+ }
+ void setInColSpan(bool b)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->inColSpan = b;
+ }
+ bool firstRow() const
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->firstRow : FALSE;
+ }
+ void setFirstRow(bool b)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->firstRow = b;
+ }
+ const RowSpanList &rowSpans()
+ {
+ return !m_tableStateStack.isEmpty() ? m_tableStateStack.top()->rowSpans : m_emptyRowSpanList;
+ }
+ void addRowSpan(ActiveRowSpan *span)
+ {
+ if (!m_tableStateStack.isEmpty()) m_tableStateStack.top()->rowSpans.append(span);
+ }
+ bool insideTable() const
+ {
+ return !m_tableStateStack.isEmpty();
+ }
+
};
#endif
diff --git a/templates/html/doxygen.css b/templates/html/doxygen.css
index e41b0d7..8383f5a 100644
--- a/templates/html/doxygen.css
+++ b/templates/html/doxygen.css
@@ -832,6 +832,10 @@ address {
color: ##33;
}
+table.doxtable caption {
+ caption-side: top;
+}
+
table.doxtable {
border-collapse:collapse;
margin-top: 4px;
diff --git a/templates/latex/doxygen.sty b/templates/latex/doxygen.sty
index 64fb0f0..803b662 100644
--- a/templates/latex/doxygen.sty
+++ b/templates/latex/doxygen.sty
@@ -11,6 +11,7 @@
\RequirePackage[table]{xcolor}
\RequirePackage{longtable}
\RequirePackage{tabu}
+\RequirePackage{tabularx}
%---------- Internal commands used in this style file ----------------
@@ -421,7 +422,7 @@
\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}%
\newenvironment{TabularC}[1]%
{\tabulinesep=1mm
-\begin{longtabu} spread 0pt [l]{*#1{|X[-1]}|}}%
+\begin{longtabu} spread 0pt [c]{*#1{|X[-1]}|}}%
{\end{longtabu}\par}%
\newenvironment{TabularNC}[1]%
@@ -444,6 +445,11 @@
\textbf{#1} (\textnormal{#2}\,\pageref{#3})%
}
+% Used to link to a table when hyperlinks are turned on
+\newcommand{\doxytablelink}[2]{%
+ \ref{#1}%
+}
+
% Used to link to a table when hyperlinks are turned off
\newcommand{\doxytableref}[3]{%
\ref{#3}%