diff options
author | johnk <johnk@arlut.utexas.edu> | 2016-10-05 19:38:51 (GMT) |
---|---|---|
committer | johnk <johnk@arlut.utexas.edu> | 2016-10-05 19:38:51 (GMT) |
commit | 7f35695022d3baa8fc8c8d1b9a9f3368a0963871 (patch) | |
tree | bae5059d7772434969a76e22cd23115f027b7051 /src/markdown.cpp | |
parent | 8074d26746e58056b8aa1444439368b038f1dcd7 (diff) | |
download | Doxygen-7f35695022d3baa8fc8c8d1b9a9f3368a0963871.zip Doxygen-7f35695022d3baa8fc8c8d1b9a9f3368a0963871.tar.gz Doxygen-7f35695022d3baa8fc8c8d1b9a9f3368a0963871.tar.bz2 |
Add support for more CSS formatting and column/row spanning in markdown tables
Diffstat (limited to 'src/markdown.cpp')
-rw-r--r-- | src/markdown.cpp | 181 |
1 files changed, 173 insertions, 8 deletions
diff --git a/src/markdown.cpp b/src/markdown.cpp index d63e149..919fc6e 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -36,6 +36,8 @@ #include <qregexp.h> #include <qfileinfo.h> #include <qdict.h> +#include <qvector.h> +//#define USE_ORIGINAL_TABLES #include "markdown.h" #include "growbuf.h" @@ -81,6 +83,13 @@ struct LinkRef QCString title; }; +struct TableCell +{ + TableCell() : colSpan(false) {} + QCString cellText; + bool colSpan; +}; + typedef int (*action_t)(GrowBuf &out,const char *data,int offset,int size); enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight }; @@ -1578,14 +1587,6 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) i = findTableColumns(data,size,start,end,columns); - out.addStr("<table>"); - - // write table header, in range [start..end] - out.addStr("<tr>"); - - int headerStart = start; - int headerEnd = end; - // read cell alignments int ret = findTableColumns(data+i,size-i,start,end,cc); k=0; @@ -1626,6 +1627,15 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) // proceed to next line i+=ret; +#ifdef USE_ORIGINAL_TABLES + out.addStr("<table>"); + + // write table header, in range [start..end] + out.addStr("<tr>"); + + int headerStart = start; + int headerEnd = end; + int m=headerStart; for (k=0;k<columns;k++) { @@ -1689,6 +1699,161 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size) } out.addStr("</table> "); +#else + // Store the table cell information by row then column. This + // allows us to handle row spanning. + QVector<QVector<TableCell> > tableContents; + tableContents.setAutoDelete(TRUE); + + int headerStart = start; + int headerEnd = end; + + int m=headerStart; + QVector<TableCell> *headerContents = new QVector<TableCell>(columns); + headerContents->setAutoDelete(TRUE); + for (k=0;k<columns;k++) + { + headerContents->insert(k, new TableCell); + while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\'))) + { + headerContents->at(k)->cellText += data[m++]; + } + m++; + // do the column span test before stripping white space + // || is spanning columns, | | is not + headerContents->at(k)->colSpan = headerContents->at(k)->cellText.isEmpty(); + headerContents->at(k)->cellText = headerContents->at(k)->cellText.stripWhiteSpace(); + } + // qvector doesn't have an append like std::vector, so we gotta do + // extra work + tableContents.resize(1); + tableContents.insert(0, headerContents); + + // write table cells + int rowNum = 1; + while (i<size) + { + int ret = findTableColumns(data+i,size-i,start,end,cc); + if (cc!=columns) break; // end of table + + j=start+i; + k=0; + QVector<TableCell> *rowContents = new QVector<TableCell>(columns); + rowContents->setAutoDelete(TRUE); + rowContents->insert(k, new TableCell); + while (j<=end+i) + { + if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + { + // do the column span test before stripping white space + // || is spanning columns, | | is not + rowContents->at(k)->colSpan = rowContents->at(k)->cellText.isEmpty(); + rowContents->at(k)->cellText = rowContents->at(k)->cellText.stripWhiteSpace(); + k++; + rowContents->insert(k, new TableCell); + } // if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) + else + { + rowContents->at(k)->cellText += data[j]; + } // else { if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) } + j++; + } // while (j<=end+i) + // do the column span test before stripping white space + // || is spanning columns, | | is not + rowContents->at(k)->colSpan = rowContents->at(k)->cellText.isEmpty(); + rowContents->at(k)->cellText = rowContents->at(k)->cellText.stripWhiteSpace(); + // qvector doesn't have an append like std::vector, so we gotta do + // extra work + tableContents.resize(tableContents.size()+1); + tableContents.insert(rowNum++, rowContents); + + // proceed to next line + i+=ret; + } + + + out.addStr("<table class=\"markdownTable\">\n"); + QCString cellTag("th"), cellClass("class=\"markdownTableHead"); + for (unsigned row = 0; row < tableContents.size(); row++) + { + out.addStr(" <tr class=\"markdownTable"); + if (row) + { + out.addStr("Body\""); + if (row % 2) + { + out.addStr(" class=\"markdownTableRowOdd\">\n"); + } + else + { + out.addStr(" class=\"markdownTableRowEven\">\n"); + } + } + else + { + out.addStr("Head\">\n"); + } + for (int c = 0; c < columns; c++) + { + // save the cell text for use after column span computation + QCString cellText(tableContents[row]->at(c)->cellText); + + // Row span handling. Spanning rows will contain a caret ('^'). + // If the current cell contains just a caret, this is part of an + // earlier row's span and the cell should not be added to the + // output. + if (tableContents[row]->at(c)->cellText == "^") + continue; + unsigned rowSpan = 1, spanRow = row+1; + while ((spanRow < tableContents.size()) && + (tableContents[spanRow]->at(c)->cellText == "^")) + { + spanRow++; + rowSpan++; + } + + out.addStr(" <" + cellTag + " " + cellClass); + // use appropriate alignment style + switch (columnAlignment[c]) + { + case AlignLeft: out.addStr("Left\""); break; + case AlignRight: out.addStr("Right\""); break; + case AlignCenter: out.addStr("Center\""); break; + case AlignNone: out.addStr("None\""); break; + } + + if (rowSpan > 1) + { + QCString spanStr; + spanStr.setNum(rowSpan); + out.addStr(" rowspan=\"" + spanStr + "\""); + } + // Column span handling, assumes that column spans will have + // empty strings, which would indicate the sequence "||", used + // to signify spanning columns. + unsigned colSpan = 1; + while ((c < columns-1) && + tableContents[row]->at(c+1)->colSpan) + { + c++; + colSpan++; + } + if (colSpan > 1) + { + QCString spanStr; + spanStr.setNum(colSpan); + out.addStr(" colspan=\"" + spanStr + "\""); + } + // need at least one space on either side of the cell text in + // order for doxygen to do other formatting + out.addStr("> " + cellText + " </" + cellTag + ">\n"); + } + cellTag = "td"; + cellClass = "class=\"markdownTableBody"; + out.addStr(" </tr>\n"); + } + out.addStr("</table>\n"); +#endif delete[] columnAlignment; return i; |