56 std::ostream& output,
bool wide,
57 const std::string& endSentenceTag)
const
61 setlocale(LC_CTYPE,
"fr_FR.UTF-8");
65 size_t nbNewLines = 0;
68 enum RetVal {SUCCESS, INVALID_OPENING_TAG_CHAR, INVALID_CLOSING_TAG_CHAR,
69 DUPLICATED_OPENING_TAG_CHAR, DUPLICATED_CLOSING_TAG_CHAR,
70 UNCLOSED_OPENING_TAG_CHAR};
71 RetVal retVal = SUCCESS;
73 enum Etat {TEXT, DEBCOL, FINCOL, BLANC, DEBBLANC, FINBLANC, BEGENTITY, ENTITY};
80 std::ostringstream txt;
81 std::ostringstream tag;
82 std::ostringstream tagValue;
83 std::ostringstream entity;
89 if (input.eof())
continue;
101 LDEBUG <<
"TEXT-> DEBCOL";
106 status <<
"Invalid '>' character at " << position << std::endl;
107 retVal = INVALID_CLOSING_TAG_CHAR;
113 LDEBUG <<
"TEXT -> BEGENTITY;";
116 case ' ':
case '\t':
case '\n':
117 output << txt.str();;
131 case 'A':;
case 'B':;
case 'C':;
case 'D':;
case 'E':;
case 'F':;
case 'G':;
132 case 'H':;
case 'I':;
case 'J':;
case 'K':;
case 'L':;
case 'M':;
case 'N':;
133 case 'O':;
case 'P':;
case 'Q':;
case 'R':;
case 'S':;
case 'T':;
case 'U':;
134 case 'V':;
case 'W':;
case 'X':;
case 'Y':;
case 'Z':;
135 case 'a':;
case 'b':;
case 'c':;
case 'd':;
case 'e':;
case 'f':;
case 'g':;
136 case 'h':;
case 'i':;
case 'j':;
case 'k':;
case 'l':;
case 'm':;
case 'n':;
137 case 'o':;
case 'p':;
case 'q':;
case 'r':;
case 's':;
case 't':;
case 'u':;
138 case 'v':;
case 'w':;
case 'x':;
case 'y':;
case 'z':
140 LDEBUG <<
"BEGENTITY-> ENTITY";
149 LDEBUG <<
"BEGENTITY-> DEBCOL";
152 case ' ':
case '\t':
case '\n':
157 LDEBUG <<
"BEGENTITY-> BLANC";
165 LDEBUG <<
"BEGENTITY-> TEXT";
173 case 'A':;
case 'B':;
case 'C':;
case 'D':;
case 'E':;
case 'F':;
case 'G':;
174 case 'H':;
case 'I':;
case 'J':;
case 'K':;
case 'L':;
case 'M':;
case 'N':;
175 case 'O':;
case 'P':;
case 'Q':;
case 'R':;
case 'S':;
case 'T':;
case 'U':;
176 case 'V':;
case 'W':;
case 'X':;
case 'Y':;
case 'Z':;
177 case 'a':;
case 'b':;
case 'c':;
case 'd':;
case 'e':;
case 'f':;
case 'g':;
178 case 'h':;
case 'i':;
case 'j':;
case 'k':;
case 'l':;
case 'm':;
case 'n':;
179 case 'o':;
case 'p':;
case 'q':;
case 'r':;
case 's':;
case 't':;
case 'u':;
180 case 'v':;
case 'w':;
case 'x':;
case 'y':;
case 'z':
184 for (uint64_t i = 0; i < entity.str().size(); i++)
192 LDEBUG <<
"ENTITY-> DEBCOL";
195 case ' ':
case '\t':
case '\n':
196 for (uint64_t i = 0; i < entity.str().size(); i++)
203 LDEBUG <<
"ENTITY-> BLANC";
207 for (uint64_t i = 0; i < entity.str().size()+1; i++)
213 LDEBUG <<
"ENTITY-> TEXT";
217 for (uint64_t i = 0; i < entity.str().size(); i++)
224 LDEBUG <<
"ENTITY-> TEXT";
236 status <<
"Invalid '<' character at " << position << std::endl;
237 retVal = DUPLICATED_OPENING_TAG_CHAR;
242 LDEBUG <<
"DEBCOL-> FINCOL";
245 case ' ':
case '\t':
case '\n':
249 LDEBUG <<
"Looking at " << carLu;
250 char buf[MB_LEN_MAX];
252 input.rdbuf()-> sgetn(buf+1, 9);
254 int transRes = mbtowc(&mbc, buf, MB_LEN_MAX);
255 LDEBUG <<
"transres value is " << transRes;
258 LDEBUG <<
"Got a multibyte char inside tag: " << mbc;
259 for (
int i = 1; i < transRes; i++)
276 LDEBUG <<
"FINCOL-> DEBCOL";
283 status <<
"Invalid '>' character at " << position << std::endl;
284 retVal = DUPLICATED_CLOSING_TAG_CHAR;
286 case ' ':
case '\t':
case '\n':
287 putTag(status, output, wide, endSentenceTag, tag, tagValue);
289 LDEBUG <<
"FINCOL-> BLANC";
293 putTag(status, output, wide, endSentenceTag, tag, tagValue);
295 LDEBUG <<
"FINCOL -> BEGENTITY;";
299 putTag(status, output, wide, endSentenceTag, tag, tagValue);
302 LDEBUG <<
"FINCOL-> TEXT";
312 LDEBUG <<
"BLANC -> BEGENTITY;";
319 LDEBUG <<
"BLANC-> DEBBLANC";
324 status <<
"Invalid '>' character at " << position << std::endl;
325 retVal = INVALID_CLOSING_TAG_CHAR;
329 case ' ':
case '\t':
case '\n':
345 status <<
"Duplicated '<' character at " << position << std::endl;
346 retVal = DUPLICATED_OPENING_TAG_CHAR;
350 LDEBUG <<
"DEBBLANC-> FINBLANC";
357 LDEBUG <<
"Looking at " << carLu;
358 char buf[MB_LEN_MAX];
360 std::streamsize got = input.rdbuf()-> sgetn(buf+1, 9);
361 for (std::streamsize i = 0; i < got ; i++)
362 input.rdbuf()-> sungetc();
363 for (uint64_t i = 0; i<MB_LEN_MAX; i++)
367 int transRes = mbtowc(&mbc, buf, MB_LEN_MAX);
368 LDEBUG <<
"transres is " << transRes;
371 LDEBUG <<
"Got a multibyte char inside tag: " << mbc;
372 for (
int i = 1; i < transRes; i++)
387 LDEBUG <<
"FINBLANC-> DEBBLANC";
391 status <<
"Duplicated '>' character at " << position << std::endl;
392 retVal = DUPLICATED_CLOSING_TAG_CHAR;
393 putWhites(status, output, wide,endSentenceTag, tagValue,
394 output, carLu,
' ', nb, nbNewLines);
395 LDEBUG <<
"FINBLANC-> TEXT";
398 case ' ':
case '\t':
case '\n':
399 putWhites(status, output, wide,endSentenceTag, tagValue,
400 output, carLu,
' ', nb, nbNewLines);
401 LDEBUG <<
"FINBLANC-> BLANC";
407 putWhites(status, output, wide,endSentenceTag, tagValue,
408 entity, carLu,
' ', nb, nbNewLines);
409 LDEBUG <<
"FINBLANC -> BEGENTITY;";
415 putWhites(status, output, wide,endSentenceTag, tagValue,
416 txt, carLu,
' ', nb, nbNewLines);
417 LDEBUG <<
"FINBLANC-> TEXT";
423 throw std::runtime_error((std::string(
"unknown state %d.\n",
int(etat))).c_str());
427 if ( (etat == DEBCOL) || (etat == DEBBLANC) )
429 status <<
"Unclosed tag at EOF (" << position <<
")" << std::endl;
430 retVal = UNCLOSED_OPENING_TAG_CHAR;
438 s = std::string(nb/2,
' ');
439 s.append(nbNewLines,
'\n');
441 if (nb%2 == 0) s.append(nb/2,
' ');
443 else s.append(nb/2 + 1,
' ');
450 else if ((etat == FINCOL) || (etat == FINBLANC))
455 else if (etat == TEXT)