LAview.LaTeX-Struct/src/latex-struct/TabularParser.vala

138 lines
4.1 KiB
Vala

namespace LAview {
namespace Parsers {
using Table;
class TabularParser : TableParser {
public TabularParser (Array<Link> links) {
base (links);
}
public override IDoc parse (string contents, size_t line, long position) throws ParseError {
/* create empty tabular */
var tabular = new Tabular ();
/* set TeX tabular contents */
this.contents = contents;
this.line = line;
this.position = position;
/* get parameters string */
var PARAM_REGEX_FIGBRANCHES = "\\{[^{}]*([^{}]*\\{[^{}]*\\}[^{}]*)*\\}";
var param_regex = "^(\\[(t|b)])?" + PARAM_REGEX_FIGBRANCHES + "("
+ PARAM_REGEX_FIGBRANCHES + ")?";
string params = "";
uint start_pos = 0, stop_pos = 0;
try {
var regex = new Regex (param_regex);
MatchInfo match_info;
regex.match (contents, 0, out match_info);
if (match_info.matches ()) {
match_info.fetch_pos (0, out start_pos, out stop_pos);
params = match_info.fetch (0);
} else {
/// Translators: please leave the '%s' construction without any changes.
prefix_error (subdoc_start,
_("Incorrect tabular parameters doesn't match '%s' regexp."),
param_regex);
throw new ParseError.SUBDOC (err_str);
}
} catch (RegexError e) {}
/* tabular align: [t], [b] */
if (params[0] == '[') {
tabular.align = params[1];
params = params.offset (3);
}
/* width */
try {
if (Regex.match_simple (PARAM_REGEX_FIGBRANCHES + PARAM_REGEX_FIGBRANCHES, params)) {
var regex = new Regex (PARAM_REGEX_FIGBRANCHES);
MatchInfo match_info;
regex.match (params, 0, out match_info);
match_info.fetch_pos (0, out start_pos, out stop_pos);
var tmps = match_info.fetch (0);
tmps = tmps[1:tmps.length - 1];
tmps = tmps.compress ();
tabular.width = tmps;
params = params.offset (stop_pos);
}
} catch (RegexError e) {}
/* remove bound '{' '}' from params */
params = params[1:params.length - 1];
var col_params = new ColParams ();
/* match reversed params so '|' will be snapped to the right column */
try {
var regex = new Regex ("("
+ "\\|*}[^{}]+{(p\\|*|m\\|*|b\\|*)(}[^{}]+{>(\\|+$|\\||)|\\|)?"
+ "|"
+ "\\|*(r|c|l)(}[^{}]+{@(p\\|*|m\\|*|b\\|*) (r|c|l))?(\\|+$|\\||)"
+ ")");
params = params.reverse ();
MatchInfo match_info;
regex.match_full (params, -1, 0, 0, out match_info);
while (match_info.matches ()) {
var col_param = new ColParam.with_params (0, "", 0);
var word = match_info.fetch (0).reverse ().compress ();
int nllines, nrlines;
for (nllines = 0; '|' == word[nllines]; ++nllines);
for (nrlines = word.length - 1; nrlines != 0 && '|' == word[nrlines]; --nrlines);
var wlen = word.length;
word = word[0:nrlines + 1];
col_param.align = word.offset (nllines);
col_param.nllines = nllines;
col_param.nrlines = wlen - 1 - nrlines;
col_params.insert (0, col_param);
match_info.next ();
}
} catch (RegexError e) {}
/* === Parsing subtables === */
tabular.params = col_params;
/* set TeX document contents */
this.contents = contents.offset (stop_pos);
/* feed in the text */
scanner.input_text (this.contents, this.contents.length);
row_abs_pos = 0;
row = new Row ();
subtable = new Subtable ();
clines = new List<int> ();
cell_abs_pos = 0;
TokenType expected_token = TokenType.NONE;
/* scanning loop, we scan the input until it's end is reached,
* the self encountered a lexing err, or our sub routine came
* across invalid syntax
*/
do {
expected_token = scan_tex_symbol (tabular);
} while (expected_token == TokenType.NONE
&& fifo_peek_head ().token != TokenType.EOF
&& fifo_peek_head ().token != TokenType.ERROR);
/* give an err message upon syntax errors */
if (expected_token == TokenType.ERROR)
scanner.unexp_token (expected_token, null, "symbol", null, null, true);
return tabular;
}
}
}
}