| OLD | NEW |
| (Empty) |
| 1 #include <cstdlib> | |
| 2 #include <cstring> | |
| 3 #include <cstdio> | |
| 4 #include <ctype.h> | |
| 5 | |
| 6 #include "../hunspell/csutil.hxx" | |
| 7 #include "latexparser.hxx" | |
| 8 | |
| 9 #ifndef W32 | |
| 10 using namespace std; | |
| 11 #endif | |
| 12 | |
| 13 static struct { | |
| 14 const char * pat[2]; | |
| 15 int arg; | |
| 16 } PATTERN[] = { | |
| 17 { { "\\(", "\\)" } , 0 }, | |
| 18 { { "$$", "$$" } , 0 }, | |
| 19 { { "$", "$" } , 0 }, | |
| 20 { { "\\begin{math}", "\\end{math}" } , 0 }, | |
| 21 { { "\\[", "\\]" } , 0 }, | |
| 22 { { "\\begin{displaymath}", "\\end{displaymath}" } , 0 }, | |
| 23 { { "\\begin{equation}", "\\end{equation}" } , 0 }, | |
| 24 { { "\\begin{equation*}", "\\end{equation*}" } , 0 }, | |
| 25 { { "\\cite", NULL } , 1 }, | |
| 26 { { "\\nocite", NULL } , 1 }, | |
| 27 { { "\\index", NULL } , 1 }, | |
| 28 { { "\\label", NULL } , 1 }, | |
| 29 { { "\\ref", NULL } , 1 }, | |
| 30 { { "\\pageref", NULL } , 1 }, | |
| 31 { { "\\parbox", NULL } , 1 }, | |
| 32 { { "\\begin{verbatim}", "\\end{verbatim}" } , 0 }, | |
| 33 { { "\\verb+", "+" } , 0 }, | |
| 34 { { "\\verb|", "|" } , 0 }, | |
| 35 { { "\\verb#", "#" } , 0 }, | |
| 36 { { "\\verb*", "*" } , 0 }, | |
| 37 { { "\\documentstyle", "\\begin{document}" } , 0 }, | |
| 38 { { "\\documentclass", "\\begin{document}" } , 0 }, | |
| 39 // { { "\\documentclass", NULL } , 1 }, | |
| 40 { { "\\usepackage", NULL } , 1 }, | |
| 41 { { "\\includeonly", NULL } , 1 }, | |
| 42 { { "\\include", NULL } , 1 }, | |
| 43 { { "\\input", NULL } , 1 }, | |
| 44 { { "\\vspace", NULL } , 1 }, | |
| 45 { { "\\setlength", NULL } , 2 }, | |
| 46 { { "\\addtolength", NULL } , 2 }, | |
| 47 { { "\\settowidth", NULL } , 2 }, | |
| 48 { { "\\rule", NULL } , 2 }, | |
| 49 { { "\\hspace", NULL } , 1 } , | |
| 50 { { "\\vspace", NULL } , 1 } , | |
| 51 { { "\\\\[", "]" } , 0 }, | |
| 52 { { "\\pagebreak[", "]" } , 0 } , | |
| 53 { { "\\nopagebreak[", "]" } , 0 } , | |
| 54 { { "\\enlargethispage", NULL } , 1 } , | |
| 55 { { "\\begin{tabular}", NULL } , 1 } , | |
| 56 { { "\\addcontentsline", NULL } , 2 } , | |
| 57 { { "\\begin{thebibliography}", NULL } , 1 } , | |
| 58 { { "\\bibliography", NULL } , 1 } , | |
| 59 { { "\\bibliographystyle", NULL } , 1 } , | |
| 60 { { "\\bibitem", NULL } , 1 } , | |
| 61 { { "\\begin", NULL } , 1 } , | |
| 62 { { "\\end", NULL } , 1 } , | |
| 63 { { "\\pagestyle", NULL } , 1 } , | |
| 64 { { "\\pagenumbering", NULL } , 1 } , | |
| 65 { { "\\thispagestyle", NULL } , 1 } , | |
| 66 { { "\\newtheorem", NULL } , 2 }, | |
| 67 { { "\\newcommand", NULL } , 2 }, | |
| 68 { { "\\renewcommand", NULL } , 2 }, | |
| 69 { { "\\setcounter", NULL } , 2 }, | |
| 70 { { "\\addtocounter", NULL } , 1 }, | |
| 71 { { "\\stepcounter", NULL } , 1 }, | |
| 72 { { "\\selectlanguage", NULL } , 1 }, | |
| 73 { { "\\inputencoding", NULL } , 1 }, | |
| 74 { { "\\hyphenation", NULL } , 1 }, | |
| 75 { { "\\definecolor", NULL } , 3 }, | |
| 76 { { "\\color", NULL } , 1 }, | |
| 77 { { "\\textcolor", NULL } , 1 }, | |
| 78 { { "\\pagecolor", NULL } , 1 }, | |
| 79 { { "\\colorbox", NULL } , 2 }, | |
| 80 { { "\\fcolorbox", NULL } , 2 }, | |
| 81 { { "\\declaregraphicsextensions", NULL } , 1 }, | |
| 82 { { "\\psfig", NULL } , 1 }, | |
| 83 { { "\\url", NULL } , 1 }, | |
| 84 { { "\\eqref", NULL } , 1 }, | |
| 85 { { "\\vskip", NULL } , 1 }, | |
| 86 { { "\\vglue", NULL } , 1 }, | |
| 87 { { "\'\'", NULL } , 1 } | |
| 88 }; | |
| 89 | |
| 90 #define PATTERN_LEN (sizeof(PATTERN) / sizeof(PATTERN[0])) | |
| 91 | |
| 92 LaTeXParser::LaTeXParser(const char * wordchars) | |
| 93 { | |
| 94 init(wordchars); | |
| 95 } | |
| 96 | |
| 97 LaTeXParser::LaTeXParser(unsigned short * wordchars, int len) | |
| 98 { | |
| 99 init(wordchars, len); | |
| 100 } | |
| 101 | |
| 102 LaTeXParser::~LaTeXParser() | |
| 103 { | |
| 104 } | |
| 105 | |
| 106 int LaTeXParser::look_pattern(int col) | |
| 107 { | |
| 108 for (unsigned int i = 0; i < PATTERN_LEN; i++) { | |
| 109 char * j = line[actual] + head; | |
| 110 const char * k = PATTERN[i].pat[col]; | |
| 111 if (! k) continue; | |
| 112 while ((*k != '\0') && (tolower(*j) == *k)) { | |
| 113 j++; | |
| 114 k++; | |
| 115 } | |
| 116 if (*k == '\0') return i; | |
| 117 } | |
| 118 return -1; | |
| 119 } | |
| 120 | |
| 121 /* | |
| 122 * LaTeXParser | |
| 123 * | |
| 124 * state 0: not wordchar | |
| 125 * state 1: wordchar | |
| 126 * state 2: comments | |
| 127 * state 3: commands | |
| 128 * state 4: commands with arguments | |
| 129 * state 5: % comment | |
| 130 * | |
| 131 */ | |
| 132 | |
| 133 | |
| 134 char * LaTeXParser::next_token() | |
| 135 { | |
| 136 int i; | |
| 137 int slash = 0; | |
| 138 int apostrophe; | |
| 139 for (;;) { | |
| 140 // fprintf(stderr,"depth: %d, state: %d, , arg: %d, token: %s\n"
,depth,state,arg,line[actual]+head); | |
| 141 | |
| 142 switch (state) | |
| 143 { | |
| 144 case 0: // non word chars | |
| 145 if ((pattern_num = look_pattern(0)) != -1) { | |
| 146 if (PATTERN[pattern_num].pat[1]) { | |
| 147 state = 2; | |
| 148 } else { | |
| 149 state = 4; | |
| 150 depth = 0; | |
| 151 arg = 0; | |
| 152 opt = 1; | |
| 153 } | |
| 154 head += strlen(PATTERN[pattern_num].pat[0]) - 1; | |
| 155 } else if ((line[actual][head] == '%')) { | |
| 156 state = 5; | |
| 157 } else if (is_wordchar(line[actual] + head)) { | |
| 158 state = 1; | |
| 159 token = head; | |
| 160 } else if (line[actual][head] == '\\') { | |
| 161 if (line[actual][head + 1] == '\\' || // \\ (li
nebreak) | |
| 162 (line[actual][head + 1] == '$') || // \$
(dollar sign) | |
| 163 (line[actual][head + 1] == '%')) { // \%
(percent) | |
| 164 head++; | |
| 165 break; | |
| 166 } | |
| 167 state = 3; | |
| 168 } else if (line[actual][head] == '%') { | |
| 169 if ((head==0) || (line[actual][head - 1] != '\\'
)) state = 5; | |
| 170 } | |
| 171 break; | |
| 172 case 1: // wordchar | |
| 173 apostrophe = 0; | |
| 174 if (! is_wordchar(line[actual] + head) || | |
| 175 (line[actual][head] == '\'' && line[actual][head+1] ==
'\'' && ++apostrophe)) { | |
| 176 state = 0; | |
| 177 char * t = alloc_token(token, &head); | |
| 178 if (apostrophe) head += 2; | |
| 179 if (t) return t; | |
| 180 } | |
| 181 break; | |
| 182 case 2: // comment, labels, etc | |
| 183 if (((i = look_pattern(1)) != -1) && | |
| 184 (strcmp(PATTERN[i].pat[1],PATTERN[pattern_num].p
at[1]) == 0)) { | |
| 185 state = 0; | |
| 186 head += strlen(PATTERN[pattern_num].pat[
1]) - 1; | |
| 187 } | |
| 188 break; | |
| 189 case 3: // command | |
| 190 if ((tolower(line[actual][head]) < 'a') || (tolower(line
[actual][head]) > 'z')) { | |
| 191 state = 0; | |
| 192 head--; | |
| 193 } | |
| 194 break; | |
| 195 case 4: // command with arguments | |
| 196 if (slash && (line[actual][head] != '\0')) { | |
| 197 slash = 0; | |
| 198 head++; | |
| 199 break; | |
| 200 } else if (line[actual][head]=='\\') { | |
| 201 slash = 1; | |
| 202 } else if ((line[actual][head] == '{') || | |
| 203 ((opt) && (line[actual][head] == '['))) { | |
| 204 depth++; | |
| 205 opt = 0; | |
| 206 } else if (line[actual][head] == '}') { | |
| 207 depth--; | |
| 208 if (depth == 0) { | |
| 209 opt = 1; | |
| 210 arg++; | |
| 211 } | |
| 212 if (((depth == 0) && (arg == PATTERN[pattern_num
].arg)) || | |
| 213 (depth < 0) ) { | |
| 214 state = 0; // XXX not handles th
e last optional arg. | |
| 215 } | |
| 216 } else if (line[actual][head] == ']') depth--; | |
| 217 } // case | |
| 218 if (next_char(line[actual], &head)) { | |
| 219 if (state == 5) state = 0; | |
| 220 return NULL; | |
| 221 } | |
| 222 } | |
| 223 } | |
| OLD | NEW |