@@ -91,6 +91,9 @@ class SpLatex
9191 // ! Process % TABULAR commands
9292 void tabular (size_t ln, size_t indent, const std::string& cmdline);
9393
94+ // ! Process % tab separated (TABSEP) commands
95+ void tabsep (size_t ln, size_t indent, const std::string& cmdline);
96+
9497 // ! Process % DEFMACRO commands
9598 void defmacro (size_t ln, size_t indent, const std::string& cmdline);
9699
@@ -463,6 +466,88 @@ void SpLatex::tabular(size_t ln, size_t indent, const std::string& cmdline)
463466 }
464467}
465468
469+ // ! Process % TABSEP commands
470+ void SpLatex::tabsep (size_t ln, size_t indent, const std::string& cmdline)
471+ {
472+ std::string query = cmdline;
473+
474+ // find REFORMAT, parse format and remove clause from query
475+ Reformat reformat;
476+ reformat.parse_query (query);
477+
478+ // execute query
479+ SqlQuery sql = g_db->query (query);
480+
481+ sql->read_complete ();
482+
483+ // prepare reformatting
484+ reformat.prepare (sql);
485+
486+ // calculate width of columns data
487+ std::vector<size_t > cwidth (sql->num_cols (), 0 );
488+
489+ for (unsigned int i = 0 ; i < sql->num_rows (); ++i)
490+ {
491+ for (unsigned int j = 0 ; j < sql->num_cols (); ++j)
492+ {
493+ cwidth[j] = std::max (
494+ cwidth[j],
495+ reformat.format (i,j, sql->text (i,j)).size ()
496+ );
497+ }
498+ }
499+
500+ // generate output
501+ std::vector<std::string> tlines;
502+ for (unsigned int i = 0 ; i < sql->num_rows (); ++i)
503+ {
504+ std::ostringstream out;
505+ for (unsigned j = 0 ; j < sql->num_cols (); ++j)
506+ {
507+ if (j != 0 ) out << " \t " ;
508+ out << std::setw (cwidth[j])
509+ << reformat.format (i, j, sql->text (i,j));
510+ }
511+ tlines.push_back (out.str ());
512+ }
513+
514+ // scan lines forward till next comment directive
515+ size_t eln = ln;
516+ while (eln < m_lines.size () && is_comment_line (eln) < 0 )
517+ ++eln;
518+
519+ static const boost::regex
520+ re_endtabsep (" [[:blank:]]*% END TABSEP .*" );
521+
522+ if (eln < m_lines.size () &&
523+ boost::regex_match (m_lines[eln], re_endtabsep))
524+ {
525+ // found END TABSEP
526+ size_t rln = ln;
527+ size_t entry = 0 ;
528+
529+ static const boost::regex re_tabsep (" .*?\\\\\\\\ (.*)" );
530+ boost::smatch rm;
531+
532+ // iterate over tabsep lines, copy styles to replacement
533+ while (entry < tlines.size () && rln < eln &&
534+ boost::regex_match (m_lines[rln], rm, re_tabsep))
535+ {
536+ tlines[entry++] += rm[1 ];
537+ ++rln;
538+ }
539+
540+ tlines.push_back (shorten (" % END TABSEP " + query));
541+ m_lines.replace (ln, eln+1 , indent, tlines, " TABSEP" );
542+ }
543+ else
544+ {
545+ // could not find END TABSEP: insert whole table.
546+ tlines.push_back (shorten (" % END TABSEP " + query));
547+ m_lines.replace (ln, ln, indent, tlines, " TABSEP" );
548+ }
549+ }
550+
466551// ! Process % DEFMACRO commands
467552void SpLatex::defmacro (size_t ln, size_t indent, const std::string& cmdline)
468553{
@@ -566,6 +651,11 @@ SpLatex::SpLatex(TextLines& lines)
566651 OUT (ln << " % " << cmd);
567652 tabular (ln, indent, cmd.substr (space_pos+1 ));
568653 }
654+ else if (first_word == " TABSEP" )
655+ {
656+ OUT (ln << " % " << cmd);
657+ tabsep (ln, indent, cmd.substr (space_pos+1 ));
658+ }
569659 else if (first_word == " DEFMACRO" )
570660 {
571661 OUT (ln << " % " << cmd);
0 commit comments