@@ -1256,11 +1256,11 @@ void LatexDocVisitor::writeStartTableCommand(const DocNodeVariant *n,size_t cols
12561256{
12571257 if (isTableNested (n))
12581258 {
1259- m_t << " \n\\ begin{DoxyTableNested}{" << cols << " }\n " ;
1259+ m_t << " \n\\ begin{DoxyTableNested}{" << cols << " }" ;
12601260 }
12611261 else
12621262 {
1263- m_t << " \n\\ begin{DoxyTable}{" << cols << " }\n " ;
1263+ m_t << " \n\\ begin{DoxyTable}{" << cols << " }" ;
12641264 }
12651265 // return isNested ? "TabularNC" : "TabularC";
12661266}
@@ -1294,33 +1294,40 @@ void LatexDocVisitor::operator()(const DocHtmlTable &t)
12941294 m_t << " \n " ;
12951295 }
12961296
1297+ const DocHtmlRow *firstRow = std::get_if<DocHtmlRow>(t.firstRow ());
12971298 writeStartTableCommand (t.parent (),t.numColumns ());
1298-
1299- if (c)
1299+ if (!isTableNested (t.parent ()))
13001300 {
1301- m_t << " \\ caption{" ;
1302- std::visit (*this , *t.caption ());
1301+ // write caption
1302+ m_t << " {" ;
1303+ if (c)
1304+ {
1305+ std::visit (*this , *t.caption ());
1306+ }
1307+ m_t << " }" ;
1308+ // write label
1309+ m_t << " {" ;
1310+ if (c)
1311+ {
1312+ m_t << stripPath (c->file ()) << " _" << c->anchor ();
1313+ }
13031314 m_t << " }" ;
1304- m_t << " \\ label{" << stripPath (c->file ()) << " _" << c->anchor () << " }" ;
1305- m_t << " \\\\\n " ;
13061315 }
1307-
1308- setNumCols (t.numColumns ());
1309- m_t << " \\ hline\n " ;
1310-
1311- // check if first row is a heading and then render the row already here
1312- // and end it with \endfirsthead (triggered via m_firstRow==TRUE)
1313- // then repeat the row as normal and end it with \endhead (m_firstRow==FALSE)
1314- const DocHtmlRow *firstRow = std::get_if<DocHtmlRow>(t.firstRow ());
1316+ // write head row
1317+ m_t << " {" ;
13151318 if (firstRow && firstRow->isHeading ())
13161319 {
1317- setFirstRow (TRUE );
1318- if (!isTableNested (t.parent ()))
1319- {
1320- std::visit (*this ,*t.firstRow ());
1321- }
1322- setFirstRow (FALSE );
1320+ m_t << " 1" ;
1321+ }
1322+ else
1323+ {
1324+ m_t << " 0" ;
13231325 }
1326+ m_t << " }" ;
1327+ m_t << " \n " ;
1328+
1329+ setNumCols (t.numColumns ());
1330+
13241331 visitChildren (t);
13251332 writeEndTableCommand (t.parent ());
13261333 popTableState ();
@@ -1339,32 +1346,6 @@ void LatexDocVisitor::operator()(const DocHtmlRow &row)
13391346
13401347 visitChildren (row);
13411348
1342- size_t c=currentColumn ();
1343- while (c<=numCols ()) // end of row while inside a row span?
1344- {
1345- for (const auto &span : rowSpans ())
1346- {
1347- // printf(" found row span: column=%d rs=%d cs=%d rowIdx=%d cell->rowIdx=%d i=%d c=%d\n",
1348- // span->column, span->rowSpan,span->colSpan,row.rowIndex(),span->cell->rowIndex(),i,c);
1349- if (span.rowSpan >0 && span.column ==c && // we are at a cell in a row span
1350- row.rowIndex ()>span.cell .rowIndex () // but not the row that started the span
1351- )
1352- {
1353- m_t << " &" ;
1354- if (span.colSpan >1 ) // row span is also part of a column span
1355- {
1356- m_t << " \\ multicolumn{" << span.colSpan << " }{" ;
1357- m_t << " }|}{}" ;
1358- }
1359- else // solitary row span
1360- {
1361- m_t << " \\ multicolumn{1}{c|}{}" ;
1362- }
1363- }
1364- }
1365- c++;
1366- }
1367-
13681349 m_t << " \\\\ " ;
13691350
13701351 size_t col = 1 ;
@@ -1377,7 +1358,6 @@ void LatexDocVisitor::operator()(const DocHtmlRow &row)
13771358 }
13781359 else if (span.column >col)
13791360 {
1380- m_t << " \\ cline{" << col << " -" << (span.column -1 ) << " }" ;
13811361 col = span.column +span.colSpan ;
13821362 }
13831363 else
@@ -1386,142 +1366,110 @@ void LatexDocVisitor::operator()(const DocHtmlRow &row)
13861366 }
13871367 }
13881368
1389- if (col <= numCols ())
1390- {
1391- m_t << " \\ cline{" << col << " -" << numCols () << " }" ;
1392- }
1393-
13941369 m_t << " \n " ;
1395-
1396- const DocNodeVariant *n = ::parent (row.parent ());
1397- if (row.isHeading () && row.rowIndex ()==1 && !isTableNested (n))
1398- {
1399- if (firstRow ())
1400- {
1401- m_t << " \\ endfirsthead\n " ;
1402- m_t << " \\ hline\n " ;
1403- m_t << " \\ endfoot\n " ;
1404- m_t << " \\ hline\n " ;
1405- }
1406- else
1407- {
1408- m_t << " \\ endhead\n " ;
1409- }
1410- }
14111370}
14121371
14131372void LatexDocVisitor::operator ()(const DocHtmlCell &c)
14141373{
14151374 if (m_hide) return ;
1416-
1417- const DocHtmlRow *row = std::get_if<DocHtmlRow>(c.parent ());
1375+ // printf("Cell(r=%u,c=%u) rowSpan=%d colSpan=%d currentColumn()=%zu\n",c.rowIndex(),c.columnIndex(),c.rowSpan(),c.colSpan(),currentColumn());
14181376
14191377 setCurrentColumn (currentColumn ()+1 );
14201378
1421- // Skip columns that span from above.
1422- for (const auto &span : rowSpans ())
1379+ QCString cellOpts;
1380+ QCString cellSpec;
1381+ auto appendOpt = [&cellOpts](const QCString &s)
14231382 {
1424- if (span.rowSpan >0 && span.column ==currentColumn ())
1383+ if (!cellOpts.isEmpty ()) cellOpts+=" ," ;
1384+ cellOpts+=s;
1385+ };
1386+ auto appendSpec = [&cellSpec](const QCString &s)
1387+ {
1388+ if (!cellSpec.isEmpty ()) cellSpec+=" ," ;
1389+ cellSpec+=s;
1390+ };
1391+ auto writeCell = [this ,&cellOpts,&cellSpec]()
1392+ {
1393+ if (!cellOpts.isEmpty () || !cellSpec.isEmpty ())
14251394 {
1426- if (row && span.colSpan >1 )
1427- {
1428- m_t << " \\ multicolumn{" << span.colSpan << " }{" ;
1429- if (currentColumn () /* c.columnIndex()*/ ==1 ) // add extra | for first column
1430- {
1431- m_t << " |" ;
1432- }
1433- m_t << " l|}{" << (c.isHeading ()? " \\ columncolor{\\ tableheadbgcolor}" : " " ) << " }" ; // alignment not relevant, empty column
1434- setCurrentColumn (currentColumn ()+span.colSpan );
1435- }
1436- else
1395+ m_t << " \\ SetCell" ;
1396+ if (!cellOpts.isEmpty ())
14371397 {
1438- setCurrentColumn ( currentColumn ()+ 1 ) ;
1398+ m_t << " [ " << cellOpts << " ] " ;
14391399 }
1440- m_t << " & " ;
1400+ m_t << " { " << cellSpec << " } " ;
14411401 }
1442- }
1402+ };
14431403
1444- int cs = c.colSpan ();
1445- int a = c.alignment ();
1446- if (cs>1 && row)
1404+ // skip over columns that have a row span starting at an earlier row
1405+ for (const auto &span : rowSpans ())
14471406 {
1448- setInColSpan (TRUE );
1449- m_t << " \\ multicolumn{" << cs << " }{" ;
1450- if (c.columnIndex ()==1 ) // add extra | for first column
1451- {
1452- m_t << " |" ;
1453- }
1454- switch (a)
1407+ // printf("span(r=%u,c=%u): column=%zu colSpan=%zu,rowSpan=%zu currentColumn()=%zu\n",
1408+ // span.cell.rowIndex(),span.cell.columnIndex(),
1409+ // span.column,span.colSpan,span.rowSpan,
1410+ // currentColumn());
1411+ if (span.rowSpan >0 && span.column ==currentColumn ())
14551412 {
1456- case DocHtmlCell::Right:
1457- m_t << " r|}{" ;
1458- break ;
1459- case DocHtmlCell::Center:
1460- m_t << " c|}{" ;
1461- break ;
1462- default :
1463- m_t << " l|}{" ;
1464- break ;
1413+ setCurrentColumn (currentColumn ()+span.colSpan );
1414+ for (size_t i=0 ;i<span.colSpan ;i++)
1415+ {
1416+ m_t << " &" ;
1417+ }
14651418 }
14661419 }
1420+
1421+ int cs = c.colSpan ();
1422+ int ha = c.alignment ();
14671423 int rs = c.rowSpan ();
14681424 int va = c.valignment ();
1469- if (rs>0 )
1425+
1426+ switch (ha) // horizontal alignment
14701427 {
1471- setInRowSpan (TRUE );
1472- m_t << " \\ multirow" ;
1473- switch (va)
1474- {
1475- case DocHtmlCell::Top:
1476- m_t << " [t]" ;
1477- break ;
1478- case DocHtmlCell::Bottom:
1479- m_t << " [b]" ;
1480- break ;
1481- case DocHtmlCell::Middle:
1482- break ; // No alignment option needed
1483- default :
1484- break ;
1485- }
1486- // printf("adding row span: cell={r=%d c=%d rs=%d cs=%d} curCol=%d\n",
1428+ case DocHtmlCell::Right:
1429+ appendSpec (" r" );
1430+ break ;
1431+ case DocHtmlCell::Center:
1432+ appendSpec (" c" );
1433+ break ;
1434+ default :
1435+ // default
1436+ break ;
1437+ }
1438+ if (rs>0 ) // row span
1439+ {
1440+ appendOpt (" r=" +QCString ().setNum (rs));
1441+ // printf("adding row span: cell={r=%d c=%d rs=%d cs=%d} curCol=%zu\n",
14871442 // c.rowIndex(),c.columnIndex(),c.rowSpan(),c.colSpan(),
14881443 // currentColumn());
14891444 addRowSpan (ActiveRowSpan (c,rs,cs,currentColumn ()));
1490- m_t << " {" << rs << " }{*}{" ;
14911445 }
1492- if (a==DocHtmlCell::Center)
1446+ if (cs> 1 ) // column span
14931447 {
1494- m_t << " \\ PBS\\ centering " ;
1495- }
1496- else if (a==DocHtmlCell::Right)
1497- {
1498- m_t << " \\ PBS\\ raggedleft " ;
1499- }
1500- if (c.isHeading ())
1501- {
1502- m_t << " \\ cellcolor{\\ tableheadbgcolor}\\ textbf{ " ;
1448+ // update column to the end of the span, needs to be done *after* calling addRowSpan()
1449+ setCurrentColumn (currentColumn ()+cs-1 );
1450+ appendOpt (" c=" +QCString ().setNum (cs));
15031451 }
1504- if (cs> 1 )
1452+ switch (va) // vertical alignment
15051453 {
1506- setCurrentColumn (currentColumn ()+cs-1 );
1454+ case DocHtmlCell::Top:
1455+ appendSpec (" h" );
1456+ break ;
1457+ case DocHtmlCell::Bottom:
1458+ appendSpec (" f" );
1459+ break ;
1460+ case DocHtmlCell::Middle:
1461+ // default
1462+ break ;
15071463 }
1464+ writeCell ();
15081465
15091466 visitChildren (c);
15101467
1511- if (c. isHeading () )
1468+ for ( int i= 0 ;i<cs- 1 ;i++ )
15121469 {
1513- m_t << " }" ;
1514- }
1515- if (inRowSpan ())
1516- {
1517- setInRowSpan (FALSE );
1518- m_t << " }" ;
1519- }
1520- if (inColSpan ())
1521- {
1522- setInColSpan (FALSE );
1523- m_t << " }" ;
1470+ m_t << " &" ; // placeholder for invisible cell
15241471 }
1472+
15251473 if (!c.isLast ()) m_t << " &" ;
15261474}
15271475
0 commit comments