PageRenderTime 68ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/TODO/srcOld/Reader.cpp

https://bitbucket.org/floba/markintuitive
C++ | 2460 lines | 1938 code | 315 blank | 207 comment | 557 complexity | aa4099a39f71084def466fc9c0357655 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #include "Reader.h"
  2. //READ
  3. void Reader::read(const QString& sourceFilePath)
  4. {
  5. //preprocess
  6. currentPosition = 0;
  7. preprocess();
  8. //process
  9. currentPosition = 0;
  10. buffers.clear();
  11. enter(Document);
  12. process();
  13. //post process
  14. postprocess();
  15. }
  16. //PREPROCESS
  17. void Reader::preprocess()
  18. {
  19. while(!eof())
  20. {
  21. //ignore everything in script and style
  22. if(isLast("\n") && (is("@@") || is("!!")))
  23. {
  24. skip(2);
  25. skipWhileIsSpaceOrTab();
  26. bool inCurlyBraces = false;
  27. if(is("{"))
  28. {
  29. skip();
  30. inCurlyBraces = true;
  31. }
  32. while(true)
  33. {
  34. if(inCurlyBraces)
  35. {
  36. static int braceDepth = 1;
  37. if(is("{")) braceDepth++;
  38. else if(is("}"))
  39. {
  40. //!!!!WHAT IS IF BRACE IS IN A "" OR IF IT IS COMMENTED?!?!?!
  41. braceDepth--;
  42. if(braceDepth == 0)
  43. {
  44. next();
  45. break;
  46. }
  47. }
  48. }
  49. else //indented
  50. if(isNext("\n") && !(isNext("\n ") || isNext("\n\t") || isNext("\n\n")))
  51. break;
  52. next();
  53. }
  54. continue;
  55. }
  56. //ignore everything in code
  57. if(is("\\´"))
  58. {
  59. text.replace(currentPosition, 1, "");
  60. skip();
  61. continue;
  62. }
  63. if(is("´"))
  64. {
  65. skip();
  66. while(!is("´") && !eof()) next();
  67. skip();
  68. continue;
  69. }
  70. //single line commands
  71. if(is("\\//"))
  72. {
  73. text.replace(currentPosition, 1, "");
  74. skip(2);
  75. continue;
  76. }
  77. if(!(isLast("http:") || isLast("https:") || isLast("ftp:"))
  78. && is("//"))
  79. {
  80. int i = 2; while(!is("\n", i) && !eof(i)) i++;
  81. text.replace(currentPosition, i, "");
  82. continue;
  83. }
  84. //multiline comments
  85. if(is("\\/*"))
  86. {
  87. text.replace(currentPosition, 1, "");
  88. skip(2);
  89. continue;
  90. }
  91. if(is("/*"))
  92. {
  93. int i = 2; while(!is("*/", i) && !eof(i)) i++;
  94. text.replace(currentPosition, i + 2, "");
  95. }
  96. //newline escape
  97. if(is("\\\n"))
  98. {
  99. text.replace(currentPosition, 2, "");
  100. continue;
  101. }
  102. //file include (to be interpreted)
  103. if(is("\n") && isNext("\\<=="))
  104. {
  105. skip();
  106. text.replace(currentPosition, 1, "");
  107. skip(3);
  108. continue;
  109. }
  110. if(isLast("\n") && is("<=="))
  111. {
  112. int i = lookAheadWhileIsSpaceOrTabAt(3);
  113. QString filePath;
  114. while(!eof(i))
  115. {
  116. int j = lookAheadWhileIsSpaceOrTabAt(i);
  117. if(is("\n", j))
  118. {
  119. i = j;
  120. break;
  121. }
  122. filePath += c(i);
  123. i++;
  124. }
  125. if(!filePath.startsWith("/")) filePath = sourceDirPath + filePath;
  126. QFile file(filePath);
  127. if(file.open(QIODevice::ReadOnly))
  128. {
  129. text.replace(currentPosition, i, QString::fromUtf8(file.readAll()));
  130. file.close();
  131. continue;
  132. }
  133. // else
  134. // ; //!!!ERROR
  135. }
  136. //next
  137. next();
  138. }
  139. }
  140. //PROCESS
  141. void Reader::process()
  142. {
  143. while(!eof())
  144. {
  145. //not to be interpreted file inclusions
  146. if(includeFileWithoutInterpretation()) continue;
  147. //ordinary document elements
  148. if(inlineMakro()) continue;
  149. if(style()) continue;
  150. if(script()) continue;
  151. if(head()) continue;
  152. if(body()) continue;
  153. if(characterReplace()) continue;
  154. //append character to current buffer
  155. if(!isLast(Document) && !isLast(Head) && !isLast(Body) && !isLast(Matter) && !isLast(Part)
  156. && !isLast(BulletList) && !isLast(ListItem)
  157. && !isLast(TableRow)
  158. )
  159. {
  160. //enter text if needed
  161. if(!isIn(Text)) enter(Text);
  162. append(c());
  163. }
  164. //next
  165. next();
  166. }
  167. //tie document buffer
  168. while(!buffers.last()->is(Document) && !buffers.empty()) leave(buffers.last()->type());
  169. _documentBuffer = buffers.takeLast();
  170. }
  171. bool Reader::includeFileWithoutInterpretation()
  172. {
  173. //enter and insert the file
  174. if(isLast("\n") && is("<--"))
  175. {
  176. skip(3);
  177. skipWhileIsSpaceOrTab();
  178. QString filePath;
  179. while(!is("\n") && !eof())
  180. {
  181. skipWhileIsSpaceOrTab();
  182. filePath += c();
  183. next();
  184. }
  185. if(!filePath.startsWith("/")) filePath = sourceDirPath + filePath;
  186. QFile file(filePath);
  187. if(file.open(QIODevice::ReadOnly))
  188. {
  189. enter(NotInterpretedText);
  190. append(QString::fromUtf8(file.readAll()));
  191. file.close();
  192. leave(NotInterpretedText);
  193. }
  194. // else
  195. // ; //!!!ERROR
  196. }
  197. //continue searching
  198. return false;
  199. }
  200. bool Reader::inlineMakro()
  201. {
  202. //enter
  203. if(is("!{"))
  204. {
  205. enter(InlineMakro);
  206. skip(2);
  207. return true;
  208. }
  209. //append character
  210. if(isIn(InlineMakro))
  211. {
  212. if(is("}"))
  213. {
  214. skip();
  215. leave(InlineMakro);
  216. return true;
  217. }
  218. else
  219. {
  220. append(c());
  221. next();
  222. return true;
  223. }
  224. }
  225. //continue searching
  226. return false;
  227. }
  228. bool Reader::style()
  229. {
  230. //enter
  231. static bool inBraces = false;
  232. if(isLast("\n") && is("@@"))
  233. {
  234. enter(XmlStyle);
  235. skip(2);
  236. if(is("{"))
  237. {
  238. inBraces = true;
  239. skip();
  240. }
  241. return true;
  242. }
  243. //append character or leave
  244. if(isIn(XmlStyle))
  245. {
  246. if(inBraces) //is in braces
  247. {
  248. static int braceDepth = 1;
  249. if(is("{")) braceDepth++;
  250. else if(is("}"))
  251. {
  252. //!!!!WHAT IS IF BRACE IS IN A "" OR IF IT IS COMMENTED?!?!?!
  253. // EASIEST IDEA: dont use braces, only allow indenting for a style block
  254. braceDepth--;
  255. if(braceDepth == 0)
  256. {
  257. inBraces = false;
  258. skip();
  259. leave(XmlStyle);
  260. return true;
  261. }
  262. }
  263. }
  264. else //is indented
  265. if(is("\n") && !(isNext(" ") || isNext("\t") || isNext("\n")))
  266. {
  267. skip();
  268. leave(XmlStyle);
  269. return true;
  270. }
  271. append(c());
  272. next();
  273. return true;
  274. }
  275. //continue searching
  276. return false;
  277. }
  278. bool Reader::script()
  279. {
  280. //enter
  281. static bool inBraces = false;
  282. if(isLast("\n") && is("!!"))
  283. {
  284. enter(Xml_Script);
  285. skip(2);
  286. if(is("{"))
  287. {
  288. inBraces = true;
  289. skip();
  290. }
  291. return true;
  292. }
  293. //append character or leave
  294. if(isIn(Xml_Script))
  295. {
  296. if(inBraces) //is in braces
  297. {
  298. static int braceDepth = 1;
  299. if(is("{")) braceDepth++;
  300. else if(is("}"))
  301. {
  302. //!!!!WHAT IS IF BRACE IS IN A "" OR IF IT IS COMMENTED?!?!?!
  303. // EASIEST IDEA: dont use braces, only allow indenting for a style block
  304. braceDepth--;
  305. if(braceDepth == 0)
  306. {
  307. inBraces = false;
  308. skip();
  309. leave(Xml_Script);
  310. return true;
  311. }
  312. }
  313. }
  314. else //is indented
  315. if(is("\n") && !(isNext(" ") || isNext("\t") || isNext("\n")))
  316. {
  317. skip();
  318. leave(Xml_Script);
  319. return true;
  320. }
  321. append(c());
  322. next();
  323. return true;
  324. }
  325. //continue searching
  326. return false;
  327. }
  328. bool Reader::body()
  329. {
  330. //body elements
  331. if(isIn(Body))
  332. {
  333. if(xmlClass()) return true;
  334. if(label()) return true;
  335. if(inlineStyle()) return true;
  336. if(makro()) return true;
  337. if(inlineScript()) return true;
  338. if(inlineListing()) return true;
  339. if(matter()) return true;
  340. if(part()) return true;
  341. if(imageFigure()) return true;
  342. if(heading()) return true;
  343. if(horizontalLine()) return true;
  344. if(list()) return true;
  345. if(definitionList()) return true;
  346. if(quote()) return true;
  347. if(texMath()) return true;
  348. if(texMathInline()) return true;
  349. if(footnote()) return true;
  350. if(span()) return true;
  351. if(sub()) return true;
  352. if(sup()) return true;
  353. if(strongEmphasised()) return true;
  354. if(strong()) return true;
  355. if(emphasise()) return true;
  356. if(table()) return true;
  357. if(url()) return true;
  358. if(ref()) return true;
  359. if(titleRef()) return true;
  360. if(pageRef()) return true;
  361. if(bibRef()) return true;
  362. if(paragraph()) return true;
  363. }
  364. //continue searching
  365. return false;
  366. }
  367. bool Reader::xmlClass()
  368. {
  369. //hold
  370. static Hold hold = None;
  371. //enter
  372. if(!isIn(XmlClass) && is(".") && (!isNext(" ") && !isNext("\t") && !isNext(".") && !isNext(":")))
  373. {
  374. bool enterClass = false;
  375. if(isIn(Text) && (isLast(" ") || isLast("\t") || isLast("\n")))
  376. enterClass = true;
  377. if(enterClass)
  378. {
  379. if(isLast(Body) || isLast(Part)) enter(Paragraph);
  380. enter(XmlClass);
  381. skip();
  382. if(is("'")) {hold = Quote; skip();}
  383. else if(is("\"")) {hold = DoubleQuote; skip();}
  384. else if(is("{")) {hold = CurlyBracket; skip();}
  385. else hold = None;
  386. return true;
  387. }
  388. }
  389. //append character or leave
  390. if(isIn(XmlClass))
  391. {
  392. bool toBeLeft = false;
  393. switch(hold)
  394. {
  395. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  396. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  397. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  398. case None:
  399. default: if(is(" ") || is("\t")) toBeLeft = true;
  400. }
  401. if(is("\n"))
  402. toBeLeft = true;
  403. if(!toBeLeft) {append(c()); next();}
  404. else leave(XmlClass);
  405. return true;
  406. }
  407. //continue searching
  408. return false;
  409. }
  410. bool Reader::label()
  411. {
  412. //hold
  413. static Hold hold = None;
  414. //enter
  415. if(canEnter(Label) && is("<-") && !(is("<- ") || is("<-\t") || is("<-\n") || is("<->")))
  416. {
  417. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  418. enter(Label);
  419. skip(2);
  420. if(is("'")) {hold = Quote; skip();}
  421. else if(is("\"")) {hold = DoubleQuote; skip();}
  422. else if(is("{")) {hold = CurlyBracket; skip();}
  423. else hold = None;
  424. return true;
  425. }
  426. //append character or leave
  427. if(isIn(Label))
  428. {
  429. bool toBeLeft = false;
  430. switch(hold)
  431. {
  432. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  433. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  434. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  435. case None:
  436. default: if(is(" ") || is("\t")) toBeLeft = true;
  437. }
  438. if(is("\n"))
  439. toBeLeft = true;
  440. if(!toBeLeft) {append(c()); next();}
  441. else leave(Label);
  442. return true;
  443. }
  444. //continue searching
  445. return false;
  446. }
  447. bool Reader::inlineStyle()
  448. {
  449. //hold
  450. static Hold hold = None;
  451. //enter
  452. if(canEnter(XmlInlineStyle) && (isLast(" ") || isLast("\t") || isLast("\n")) && is("@"))
  453. {
  454. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  455. enter(XmlInlineStyle);
  456. skip();
  457. if(is("'")) {hold = Quote; skip();}
  458. else if(is("\"")) {hold = DoubleQuote; skip();}
  459. else if(is("{")) {hold = CurlyBracket; skip();}
  460. else hold = None;
  461. return true;
  462. }
  463. //append character or leave
  464. if(isIn(XmlInlineStyle))
  465. {
  466. bool toBeLeft = false;
  467. switch(hold)
  468. {
  469. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  470. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  471. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  472. case None:
  473. default: if(is(" ") || is("\t")) toBeLeft = true;
  474. }
  475. if(is("\n"))
  476. toBeLeft = true;
  477. if(!toBeLeft) {append(c()); next();}
  478. else leave(XmlInlineStyle);
  479. return true;
  480. }
  481. //continue searching
  482. return false;
  483. }
  484. bool Reader::makro()
  485. {
  486. //enter
  487. static bool inBraces = false;
  488. if(isLast("\n") && is("!"))
  489. {
  490. enter(Makro);
  491. skip();
  492. if(is("{"))
  493. {
  494. skip();
  495. inBraces = true;
  496. }
  497. return true;
  498. }
  499. //append character or leave
  500. if(isIn(Makro))
  501. {
  502. if(inBraces) //braced
  503. {
  504. if(is("}"))
  505. {
  506. skip();
  507. inBraces = false;
  508. leave(Makro);
  509. return true;
  510. }
  511. }
  512. else //indented
  513. {
  514. if(is("\n") && !(isNext(" ") || isNext("\t") || isNext("\n")))
  515. {
  516. skip();
  517. leave(Makro);
  518. return true;
  519. }
  520. }
  521. append(c());
  522. next();
  523. return true;
  524. }
  525. //continue searching
  526. return false;
  527. }
  528. bool Reader::inlineScript()
  529. {
  530. // //enter
  531. // static bool inBraces = false;
  532. // if(isLast("\n") && is("!!"))
  533. // {
  534. // enter(Script);
  535. // skip(2);
  536. // if(is("{"))
  537. // {
  538. // inBraces = true;
  539. // skip();
  540. // }
  541. // return true;
  542. // }
  543. // //append character or leave
  544. // if(isIn(Script))
  545. // {
  546. // if(inBraces) //is in braces
  547. // {
  548. // static int braceDepth = 1;
  549. // if(is("{")) braceDepth++;
  550. // else if(is("}"))
  551. // {
  552. // //!!!!WHAT IS IF BRACE IS IN A "" OR IF IT IS COMMENTED?!?!?!
  553. // // EASIEST IDEA: dont use braces, only allow indenting for a style block
  554. // braceDepth--;
  555. // if(braceDepth == 0)
  556. // {
  557. // inBraces = false;
  558. // skip();
  559. // leave(Script);
  560. // return true;
  561. // }
  562. // }
  563. // }
  564. // else //is indented
  565. // if(is("\n") && !(isNext(" ") || isNext("\t") || isNext("\n")))
  566. // {
  567. // skip();
  568. // leave(Script);
  569. // return true;
  570. // }
  571. // append(c());
  572. // next();
  573. // return true;
  574. // }
  575. //continue searching
  576. return false;
  577. }
  578. bool Reader::inlineListing()
  579. {
  580. //enter
  581. if(canEnter(InlineListing) && (is("´") || is("`")))
  582. {
  583. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  584. enter(InlineListing);
  585. skip();
  586. return true;
  587. }
  588. //leave
  589. if(isIn(InlineListing))
  590. {
  591. if(is("´") || is("`"))
  592. {
  593. skip();
  594. leave(InlineListing);
  595. }
  596. else
  597. {
  598. append(c());
  599. next();
  600. }
  601. return true;
  602. }
  603. //continue searching
  604. return false;
  605. }
  606. bool Reader::matter()
  607. {
  608. //enter
  609. if(isLast("\n") && is("::"))
  610. {
  611. if(isIn(Part)) leave(Part);
  612. if(isIn(Matter)) leave(Matter);
  613. int i = 2; while((is(":", i) || is(" ", i) || is("\t", i)) && !eof(i)) i++;
  614. if(!is("\n", i))
  615. {
  616. enter(Matter);
  617. enter(MatterName);
  618. }
  619. skip(i);
  620. return true;
  621. }
  622. //leave
  623. if(isIn(MatterName))
  624. {
  625. if(is(":") || is(" ") || is("\t")) next();
  626. else if(is("\n")) leave(MatterName);
  627. else {append(c()); next();}
  628. return true;
  629. }
  630. //continue searching
  631. return false;
  632. }
  633. bool Reader::part()
  634. {
  635. //enter
  636. if(isLast("\n") && (is(".") || is(":")))
  637. {
  638. int dots = 0;
  639. int colons = 0;
  640. int i = 0;
  641. while((c(i) == '.' || c(i) == ':' || c(i) == ' ' || c(i) == '\t') && !eof(i))
  642. {
  643. if(c(i) == '.') dots++;
  644. if(c(i) == ':') colons++;
  645. i++;
  646. }
  647. if(dots > 0 && colons > 0)
  648. {
  649. if(isIn(Part)) leave(Part);
  650. if(!is("\n", i))
  651. {
  652. enter(Part);
  653. enter(PartName);
  654. }
  655. skip(i);
  656. return true;
  657. }
  658. }
  659. //leave
  660. if(isIn(PartName))
  661. {
  662. int i = lookAheadWhileIsSpaceOrTabAt(0);
  663. if((c(i) == ':' || c(i) == '.') || (c(i) == '.' && c(i + 1) == ':') || (c(i) == '.' && c(i + 1) == '.'))
  664. {
  665. skip(i + 1);
  666. while((is(":") || is(".")) && !eof()) next();
  667. }
  668. if(is("\n")) leave(PartName);
  669. else {append(c()); next();}
  670. return true;
  671. }
  672. //continue searching
  673. return false;
  674. }
  675. //!!!check
  676. bool Reader::imageFigure()
  677. {
  678. //enter image or subimage
  679. if(isLast("\n"))
  680. {
  681. int i = lookAheadWhileIsSpaceOrTabAt();
  682. if(is("<=", i) && !is("<=>", i))
  683. {
  684. //enter image figure, if not already in
  685. if(!isIn(ImageFigure)) enter(ImageFigure);
  686. //check if this is an subimage; if so enter subimage
  687. int j = i + 2; while(c(j) != '\n') {j++; if(eof(j)) return false;}
  688. j++; j = lookAheadWhileIsSpaceOrTabAt(j);
  689. if(is("##", j) || is("#.#", j) || is("<=", j))
  690. {
  691. if(isIn(Subimage)) leave(Subimage);
  692. enter(Subimage);
  693. }
  694. //finally enter the image (path)
  695. enter(Image);
  696. skip(i + 2);
  697. skipWhileIsSpaceOrTab();
  698. return true;
  699. }
  700. }
  701. //leave image
  702. if(isIn(Image) && is("\n"))
  703. {
  704. int i = lookAheadWhileIsSpaceOrTabAt(1);
  705. if(is("#.#", i) || is("##", i))
  706. {
  707. leave(Image);
  708. enter(Caption);
  709. if(is("#.#", i)) skip(i + 3);
  710. else if(is("##", i)) skip(i + 2);
  711. skipWhileIsSpaceOrTab();
  712. return true;
  713. }
  714. else if(is("<=", i))
  715. {
  716. leave(Image);
  717. leave(Subimage);
  718. enter(Subimage);
  719. enter(Image);
  720. skip(i + 2);
  721. skipWhileIsSpaceOrTab();
  722. return true;
  723. }
  724. }
  725. //enter image caption
  726. if(isIn(ImageFigure) && is("\n"))
  727. {
  728. int i = lookAheadWhileIsSpaceOrTabAt(1);
  729. if(is("#", i))
  730. {
  731. if(isIn(Subimage)) leave(Subimage);
  732. if(isIn(Image)) leave(Image);
  733. enter(Caption);
  734. skip(i + 1);
  735. skipWhileIsSpaceOrTab();
  736. return true;
  737. }
  738. }
  739. //leave image figure
  740. if(isIn(ImageFigure) && is("\n"))
  741. {
  742. int i = lookAheadWhileIsSpaceOrTabAt(1);
  743. if(!is("#", i) && !is("<=", i))
  744. leave(ImageFigure);
  745. }
  746. //continue searching
  747. return false;
  748. }
  749. //!!!check
  750. void Reader::enterTablePart()
  751. {
  752. //if there is not only a table body, enter table head
  753. //go to next line
  754. int i = 1; while(c(i) != '\n' && !eof(i)) i++;
  755. //find one time "\n[ \t]*|?=" and there is a head
  756. while(true)
  757. {
  758. if(eof(i)) break;
  759. if(c(i) == '\n')
  760. {
  761. //skip indenting spaces and tabs
  762. int k = i + 1; while((c(k) == ' ' || c(k) == '\t') && !eof(k)) k++;
  763. //if now again a \n comes, table ends
  764. if(c(k) == '\n') break;
  765. //else if now a "\n[ \t]*|?=" comes, there could be a head ...
  766. else if(c(k) == '=' || (c(k) == '|' && c(k + 1) == '='))
  767. {
  768. //... if right after that line ...
  769. int j = k + 1; while(c(j) != '\n' && !eof(j)) j++;
  770. //... and indenting spaces and tabs ...
  771. j++; while((c(j) == ' ' || c(j) == '\t') && !eof(j)) j++;
  772. //...again a row comes
  773. if(c(j) == '|')
  774. {
  775. enter(TableHead);
  776. break;
  777. }
  778. }
  779. }
  780. i++;
  781. }
  782. //else enter table body
  783. if(!isIn(TableHead))
  784. enter(TableBody);
  785. }
  786. //!!!check
  787. bool Reader::table()
  788. {
  789. //!!!INDENT
  790. //!!!WATCH FOR ARROWS
  791. //!!!DONT USE c()
  792. //!!!also in enterTablePart()
  793. //enter table
  794. if(!isIn(TableFigure) && isLast("\n"))
  795. {
  796. //caption does not come first
  797. if(is("|") || (is("=") && !is("=>") && !is("==>")) || (is("-") && !is("->"))) //!!!!EVERYWHERE (arrows!)
  798. {
  799. enter(TableFigure);
  800. enter(Table);
  801. enterTablePart();
  802. enter(TableRow);
  803. if(is("=") || is("|="))
  804. {
  805. skip();
  806. if(is("=")) while(is("=") && !eof()) skip();
  807. else if(is("-")) while(is("-") && !eof()) skip();
  808. }
  809. else
  810. {
  811. enter(TableCell);
  812. skip();
  813. skipWhileIsSpaceOrTab();
  814. }
  815. return true;
  816. }
  817. //caption comes first?
  818. else if(is("#"))
  819. {
  820. int i = 1; while(c(i) != '\n' && !eof(i)) i++; i++;
  821. i = lookAheadWhileIsSpaceOrTabAt(i);
  822. //tables begins, and caption comes first?
  823. if(c(i) == '|' || c(i) == '=' || c(i) == '-')
  824. {
  825. enter(TableFigure);
  826. enter(Caption);
  827. skip();
  828. skipWhileIsSpaceOrTab();
  829. return true;
  830. }
  831. }
  832. }
  833. //leave table caption (mondatory if caption comes above the table)
  834. if(isIn(Caption) && is("\n"))
  835. {
  836. leave(Caption);
  837. //only if caption comes before table, enter table head (or body repectively) and table row
  838. int i = 1; while((c(i) == ' ' || c(i) == '\t') && !eof(i)) i++;
  839. if(c(i) == '|' || c(i) == '=' || c(i) == '-')
  840. {
  841. enter(Table);
  842. enterTablePart();
  843. enter(TableRow);
  844. i++;
  845. if(is("=", i) || is("|=", i))
  846. {
  847. skip(i);
  848. if(is("=")) while(is("=") && !eof()) skip();
  849. else if(is("-")) while(is("-") && !eof()) skip();
  850. }
  851. else
  852. {
  853. enter(TableCell);
  854. skip(i);
  855. skipWhileIsSpaceOrTab();
  856. }
  857. return true;
  858. }
  859. }
  860. //leave/enter body and foot
  861. if(isIn(Table) && isLast("\n") && (is("|=") || is("=")))
  862. {
  863. int i = 1; while(c(i) != '\n' && !eof(i)) i++;
  864. i++; while((c(i) == ' ' || c(i) == '\t') && !eof(i)) i++;
  865. if(c(i) == '|')
  866. {
  867. if(isIn(TableHead))
  868. {
  869. leave(TableHead);
  870. enter(TableBody);
  871. enter(TableRow);
  872. }
  873. else if(isIn(TableBody))
  874. {
  875. leave(TableBody);
  876. enter(TableFoot);
  877. enter(TableRow);
  878. }
  879. skip(); while(is("=") && !eof()) skip();
  880. return true;
  881. }
  882. skip(); while(is("=") && !eof()) skip();
  883. return true;
  884. }
  885. //table row
  886. if(isIn(TableRow) && isLast("\n") && (is("|-") || is("-")))
  887. {
  888. int i = 1; while(c(i) != '\n' && !eof(i)) i++;
  889. i++; while((c(i) == ' ' || c(i) == '\t') && !eof(i)) i++;
  890. if(c(i) == '|')
  891. {
  892. leave(TableRow);
  893. enter(TableRow);
  894. skip(); while(is("-") && !eof()) skip();
  895. return true;
  896. }
  897. skip(); while(is("-") && !eof()) skip();
  898. return true;
  899. }
  900. //table cell
  901. if(isIn(TableRow) && is("|"))
  902. {
  903. if(isIn(TableCell))
  904. leave(TableCell);
  905. enter(TableCell);
  906. skip();
  907. skipWhileIsSpaceOrTab();
  908. return true;
  909. }
  910. //width
  911. if(isIn(TableCell) /*&& isLast("|")*/ && is("<>"))
  912. {
  913. skip(2);
  914. enter(Width);
  915. return true;
  916. }
  917. if(isIn(Width))
  918. {
  919. if(is(" ") || is("\t") || is("\n"))
  920. {
  921. leave(Width);
  922. if(is(" ") || is("\t"))
  923. return true;
  924. }
  925. else
  926. {
  927. append(c()); next();
  928. return true;
  929. }
  930. }
  931. //col span
  932. if(isIn(TableCell) /*&& isLast("|")*/ && is(">"))
  933. {
  934. enter(ColSpan);
  935. skip();
  936. return true;
  937. }
  938. if(isIn(ColSpan))
  939. {
  940. if(is(" ") || is("\t") || is("\n"))
  941. {
  942. leave(ColSpan);
  943. if(is(" ") || is("\t"))
  944. return true;
  945. }
  946. else
  947. {
  948. append(c()); next();
  949. return true;
  950. }
  951. }
  952. //row span
  953. if(isIn(TableCell) /*&& isLast("|")*/ && is("^"))
  954. {
  955. enter(RowSpan);
  956. skip();
  957. return true;
  958. }
  959. if(isIn(RowSpan))
  960. {
  961. if(is(" ") || is("\t") || is("\n"))
  962. {
  963. leave(RowSpan);
  964. if(is(" ") || is("\t"))
  965. return true;
  966. }
  967. else
  968. {
  969. append(c()); next();
  970. return true;
  971. }
  972. }
  973. //start caption (if caption comes after the table)
  974. if(isIn(Table) && isLast("\n"))
  975. {
  976. //skip indenting spaces and tabs
  977. int i = 0; while((c(i) == ' ' || c(i) == '\t') && !eof(i)) i++;
  978. //if now a # comes, caption starts
  979. if(c(i) == '#')
  980. {
  981. leave(Table);
  982. enter(Caption);
  983. skip(i);
  984. skip(); //#
  985. skipWhileIsSpaceOrTab();
  986. return true;
  987. }
  988. }
  989. //leave table (independendly from whether caption comes first or not)
  990. if(isIn(TableFigure) && is("\n"))
  991. {
  992. //skip indenting spaces and tabs
  993. int i = 1; while((c(i) == ' ' || c(i) == '\t') && !eof(i)) i++;
  994. //comes again a newline?
  995. if(c(i) == '\n')
  996. {
  997. leave(TableFigure);
  998. skip(i);
  999. return true;
  1000. }
  1001. }
  1002. //continue searching
  1003. return false;
  1004. }
  1005. bool Reader::heading()
  1006. {
  1007. //Heading6
  1008. if(isLast("\n\n") && is("######"))
  1009. {
  1010. enter(Heading6);
  1011. skip(6);
  1012. skipWhileIsSpaceOrTab();
  1013. return true;
  1014. }
  1015. else if(isLast("\n\n") && is("#.#.#.#.#.#"))
  1016. {
  1017. enter(Heading6);
  1018. skip(11);
  1019. skipWhileIsSpaceOrTab();
  1020. return true;
  1021. }
  1022. if(isIn(Heading6) && is("\n"))
  1023. leave(Heading6);
  1024. //Heading5
  1025. if(isLast("\n\n") && is("#####"))
  1026. {
  1027. enter(Heading5);
  1028. skip(5);
  1029. skipWhileIsSpaceOrTab();
  1030. return true;
  1031. }
  1032. else if(isLast("\n\n") && is("#.#.#.#.#"))
  1033. {
  1034. enter(Heading5);
  1035. skip(9);
  1036. skipWhileIsSpaceOrTab();
  1037. return true;
  1038. }
  1039. if(isIn(Heading5) && is("\n"))
  1040. leave(Heading5);
  1041. //Heading4
  1042. if(isLast("\n\n") && is("####"))
  1043. {
  1044. enter(Heading4);
  1045. skip(4);
  1046. skipWhileIsSpaceOrTab();
  1047. return true;
  1048. }
  1049. else if(isLast("\n\n") && is("#.#.#.#"))
  1050. {
  1051. enter(Heading4);
  1052. skip(7);
  1053. skipWhileIsSpaceOrTab();
  1054. return true;
  1055. }
  1056. if(isIn(Heading4) && is("\n"))
  1057. leave(Heading4);
  1058. //Heading3
  1059. if(isLast("\n\n") && is("###"))
  1060. {
  1061. enter(Heading3);
  1062. skip(3);
  1063. skipWhileIsSpaceOrTab();
  1064. return true;
  1065. }
  1066. else if(isLast("\n\n") && is("#.#.#"))
  1067. {
  1068. enter(Heading3);
  1069. skip(5);
  1070. skipWhileIsSpaceOrTab();
  1071. return true;
  1072. }
  1073. if(isIn(Heading3) && is("\n"))
  1074. leave(Heading3);
  1075. //Heading2
  1076. if(isLast("\n\n") && is("##"))
  1077. {
  1078. enter(Heading2);
  1079. skip(2);
  1080. skipWhileIsSpaceOrTab();
  1081. return true;
  1082. }
  1083. else if(isLast("\n\n") && is("#.#"))
  1084. {
  1085. enter(Heading2);
  1086. skip(3);
  1087. skipWhileIsSpaceOrTab();
  1088. return true;
  1089. }
  1090. if(isIn(Heading2) && is("\n"))
  1091. leave(Heading2);
  1092. //Heading1
  1093. if(isLast("\n\n") && is("#"))
  1094. {
  1095. enter(Heading1);
  1096. skip();
  1097. skipWhileIsSpaceOrTab();
  1098. return true;
  1099. }
  1100. if(isIn(Heading1) && is("\n"))
  1101. leave(Heading1);
  1102. //continue searching
  1103. return false;
  1104. }
  1105. bool Reader::horizontalLine()
  1106. {
  1107. //enter
  1108. if(!isIn(ImageFigure) && !isIn(TableFigure)
  1109. && isLast("\n") && (is("___") || is("~~~")))
  1110. {
  1111. enter(HorizontalLine);
  1112. skip(3);
  1113. return true;
  1114. }
  1115. //leave
  1116. if(isIn(HorizontalLine))
  1117. {
  1118. if(!is("\n")) next();
  1119. else leave(HorizontalLine);
  1120. return true;
  1121. }
  1122. //continue searching
  1123. return false;
  1124. }
  1125. bool Reader::list()
  1126. {
  1127. //indentation depth
  1128. static int currentIndentationDepth = 0;
  1129. START:
  1130. //enter new bullet list
  1131. if(!isLast(BulletList) && isLast("\n") && (is(spaces(currentIndentationDepth)) || is(tabs(currentIndentationDepth))))
  1132. {
  1133. int spacesOrTabs = lookAheadWhileIsSpaceOrTabAt(0);
  1134. if((is("*", spacesOrTabs) || is("o", spacesOrTabs) || is("-", spacesOrTabs))
  1135. && (isNext(" ", spacesOrTabs) || isNext("\t", spacesOrTabs)))
  1136. enter(BulletList);
  1137. }
  1138. //enter new list item in same depth
  1139. if(isLast(BulletList) && (is(spaces(currentIndentationDepth)) || is(tabs(currentIndentationDepth))))
  1140. {
  1141. int spacesOrTabs = lookAheadWhileIsSpaceOrTabAt(0);
  1142. if((is("*", spacesOrTabs) || is("o", spacesOrTabs) || is("-", spacesOrTabs))
  1143. && (isNext(" ", spacesOrTabs) || isNext("\t", spacesOrTabs)))
  1144. {
  1145. enter(ListItem);
  1146. currentIndentationDepth++;
  1147. skip(spacesOrTabs);
  1148. skip();
  1149. skipWhileIsSpaceOrTab();
  1150. enter(Paragraph); //!!!?!?!?!?!?!?!?!?!?!?! WHAT IS IF A TABLE OR BLOCKQUOTE OR NEW LIST OR ... COMES?!?!
  1151. return true;
  1152. }
  1153. }
  1154. //leave bullet list item
  1155. if(isIn(ListItem) && is("\n"))
  1156. {
  1157. // int i = 1;
  1158. // while((is("\n", i)/* || is(spaces(currentIndentationDepth), i) || is(tabs(currentIndentationDepth), i)*/) && !eof(i))
  1159. // i++;
  1160. // int spacesOrTabs = lookAheadWhileIsSpaceOrTabAt(1);
  1161. // if(!is("\n", spacesOrTabs))
  1162. // {
  1163. leave(ListItem);
  1164. currentIndentationDepth--;
  1165. goto START;
  1166. // }
  1167. }
  1168. //leave bullet list
  1169. if(isLast(BulletList) && is("\n"))
  1170. {
  1171. int spacesOrTabs = lookAheadWhileIsSpaceOrTabAt(1);
  1172. if(!is("\n", spacesOrTabs) && !((is("*", spacesOrTabs) || is("o", spacesOrTabs) || is("-", spacesOrTabs))
  1173. && (isNext(" ", spacesOrTabs) || isNext("\t", spacesOrTabs))))
  1174. {
  1175. leave(BulletList);
  1176. // int nextIndentationDepth = currentIndentationDepth;
  1177. // while(!(isNext(spaces(nextIndentationDepth)) || isNext(tabs(nextIndentationDepth))) && nextIndentationDepth >= 0)
  1178. // nextIndentationDepth--;
  1179. // for(int i = 0; i < currentIndentationDepth - nextIndentationDepth; i++) leave(BulletList);
  1180. // if(isIn(ListItem)) leave(ListItem);
  1181. // currentIndentationDepth = nextIndentationDepth;
  1182. }
  1183. }
  1184. //continue searching
  1185. return false;
  1186. }
  1187. bool Reader::definitionList()
  1188. {
  1189. //enter
  1190. if(isLast("\n"))
  1191. {
  1192. int i = 0; while(!is("\n", i) && !is(":", i) && !eof(i)) i++;
  1193. if(is(":", i))
  1194. {
  1195. i++;
  1196. if(is("\n ", i) || is("\n\t", i) || is(":", i))
  1197. {
  1198. if(!isIn(DefinitionList)) enter(DefinitionList);
  1199. enter(Term);
  1200. }
  1201. }
  1202. }
  1203. //leave Term, enter Definition
  1204. if(isIn(Term) && is(":"))
  1205. {
  1206. skip();
  1207. if(is(":")) skip();
  1208. leave(Term);
  1209. enter(Definition);
  1210. return true;
  1211. }
  1212. //leave Definition
  1213. if(isIn(Definition) && is("\n") && !isNext(" ") && !isNext("\t"))
  1214. {
  1215. leave(Definition);
  1216. if(is("\n\n")) leave(DefinitionList);
  1217. }
  1218. //continue searching
  1219. return false;
  1220. }
  1221. bool Reader::quote()
  1222. {
  1223. //enter
  1224. if(!isIn(BlockQuote) && isLast("\n"))
  1225. {
  1226. int i = lookAheadWhileIsSpaceOrTabAt(0);
  1227. if((is("\"", i) || is(">", i)) && (is(" ", i + 1) || is("\t", i + 1)))
  1228. {
  1229. enter(BlockQuote);
  1230. skip(i + 1);
  1231. skipWhileIsSpaceOrTab();
  1232. return true;
  1233. }
  1234. }
  1235. //leave
  1236. if(isIn(BlockQuote) && is("\n"))
  1237. {
  1238. //int i = lookAheadWhileIsSpaceOrTabAt(1);
  1239. //if(c(i) == '\n')
  1240. //{
  1241. leave(BlockQuote);
  1242. //skip(i);
  1243. //return true;
  1244. //}
  1245. }
  1246. //continue searching
  1247. return false;
  1248. }
  1249. bool Reader::texMath()
  1250. {
  1251. //enter
  1252. if(!isIn(TexMath) && isLast("\n"))
  1253. {
  1254. int i = lookAheadWhileIsSpaceOrTabAt(0);
  1255. if(is("$", i))
  1256. {
  1257. enter(TexMath);
  1258. skip(i + 1);
  1259. skipWhileIsSpaceOrTab();
  1260. return true;
  1261. }
  1262. }
  1263. //leave
  1264. if(isIn(TexMath))
  1265. {
  1266. if(is("\n") && !(isNext(" ") || isNext("\t") /*|| isNext("\n")*/))
  1267. {
  1268. skip();
  1269. leave(TexMath);
  1270. return true;
  1271. }
  1272. append(c());
  1273. next();
  1274. return true;
  1275. }
  1276. //continue searching
  1277. return false;
  1278. }
  1279. bool Reader::texMathInline()
  1280. {
  1281. //enter
  1282. if(!isIn(TexMathInline) && is("$") && !isLast("\\"))
  1283. {
  1284. enter(TexMathInline);
  1285. skip();
  1286. return true;
  1287. }
  1288. //leave
  1289. if(isIn(TexMathInline))
  1290. {
  1291. if(is("$") && !isLast("\\"))
  1292. {
  1293. skip();
  1294. leave(TexMathInline);
  1295. return true;
  1296. }
  1297. else
  1298. {
  1299. append(c());
  1300. next();
  1301. return true;
  1302. }
  1303. }
  1304. //continue searching
  1305. return false;
  1306. }
  1307. bool Reader::span()
  1308. {
  1309. //enter
  1310. if(!isIn(Span) && is("__"))
  1311. {
  1312. if(isLast(Body)) enter(Paragraph);
  1313. enter(Span);
  1314. skip(2);
  1315. return true;
  1316. }
  1317. //leave
  1318. if(isIn(Span) && is("__"))
  1319. {
  1320. skip(2);
  1321. leave(Span);
  1322. return true;
  1323. }
  1324. //continue searching
  1325. return false;
  1326. }
  1327. bool Reader::footnote()
  1328. {
  1329. //hold
  1330. static Hold hold = None;
  1331. //enter
  1332. if(!isIn(Footnote) && is("^^") && (c(2) == '\'' || c(2) == '"' || c(2) == '{'))
  1333. {
  1334. enter(Footnote);
  1335. skip(2);
  1336. if(is("'")) {hold = Quote; skip();}
  1337. else if(is("\"")) {hold = DoubleQuote; skip();}
  1338. else if(is("{")) {hold = CurlyBracket; skip();}
  1339. return true;
  1340. }
  1341. //leave
  1342. if(isIn(Footnote))
  1343. {
  1344. switch(hold)
  1345. {
  1346. case Quote: if(is("'")) {skip(); leave(Footnote); return true;} break;
  1347. case DoubleQuote: if(is("\"")) {skip(); leave(Footnote); return true;} break;
  1348. case CurlyBracket: if(is("}")) {skip(); leave(Footnote); return true;} break;
  1349. default: break;
  1350. }
  1351. }
  1352. //continue searching
  1353. return false;
  1354. }
  1355. bool Reader::sub()
  1356. {
  1357. //hold
  1358. static Hold hold = None;
  1359. //enter
  1360. if(!isIn(Sub) && is("_"))
  1361. {
  1362. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  1363. enter(Sub);
  1364. skip();
  1365. if(is("'")) {hold = Quote; skip();}
  1366. else if(is("\"")) {hold = DoubleQuote; skip();}
  1367. else if(is("{")) {hold = CurlyBracket; skip();}
  1368. else hold = None;
  1369. return true;
  1370. }
  1371. //leave
  1372. if(isIn(Sub))
  1373. {
  1374. switch(hold)
  1375. {
  1376. case Quote: if(is("'")) {skip(); leave(Sub); return true;} break;
  1377. case DoubleQuote: if(is("\"")) {skip(); leave(Sub); return true;} break;
  1378. case CurlyBracket: if(is("}")) {skip(); leave(Sub); return true;} break;
  1379. case None:
  1380. default:
  1381. //!!!!!!
  1382. if(!isLast("_") /*&& (buffers.last()->type == Sup
  1383. || (buffers.size() - 2 >= 0
  1384. && buffers.at(buffers.size() - 2).type == Sup
  1385. && buffers.last()->type == Text))*/)
  1386. leave(Sub);
  1387. }
  1388. }
  1389. //continue searching
  1390. return false;
  1391. }
  1392. bool Reader::sup()
  1393. {
  1394. //hold
  1395. static Hold hold = None;
  1396. //enter
  1397. if(!isIn(Sup) && !isLast("^") && is("^") && !is("^^"))
  1398. {
  1399. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  1400. enter(Sup);
  1401. skip();
  1402. if(is("'")) {hold = Quote; skip();}
  1403. else if(is("\"")) {hold = DoubleQuote; skip();}
  1404. else if(is("{")) {hold = CurlyBracket; skip();}
  1405. else hold = None;
  1406. return true;
  1407. }
  1408. //leave
  1409. if(isIn(Sup))
  1410. {
  1411. switch(hold)
  1412. {
  1413. case Quote: if(is("'")) {skip(); leave(Sup); return true;} break;
  1414. case DoubleQuote: if(is("\"")) {skip(); leave(Sup); return true;} break;
  1415. case CurlyBracket: if(is("}")) {skip(); leave(Sup); return true;} break;
  1416. case None:
  1417. default:
  1418. if(!isLast("^") && (buffers.last()->is(Sup)
  1419. || (buffers.size() - 2 >= 0
  1420. && buffers.at(buffers.size() - 2)->is(Sup)
  1421. && buffers.last()->is(Text))))
  1422. leave(Sup);
  1423. }
  1424. }
  1425. //continue searching
  1426. return false;
  1427. }
  1428. bool Reader::strongEmphasised()
  1429. {
  1430. //enter
  1431. if(!isIn(StrongEmphasised) && is("***"))
  1432. {
  1433. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  1434. enter(StrongEmphasised);
  1435. skip(3);
  1436. return true;
  1437. }
  1438. //leave
  1439. if(isIn(StrongEmphasised) && is("***"))
  1440. {
  1441. skip(3);
  1442. leave(StrongEmphasised);
  1443. return true;
  1444. }
  1445. //continue searching
  1446. return false;
  1447. }
  1448. bool Reader::strong()
  1449. {
  1450. //enter
  1451. if(!isIn(Strong) && is("**"))
  1452. {
  1453. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  1454. enter(Strong);
  1455. skip(2);
  1456. return true;
  1457. }
  1458. //leave
  1459. if(isIn(Strong) && is("**"))
  1460. {
  1461. skip(2);
  1462. leave(Strong);
  1463. return true;
  1464. }
  1465. //continue searching
  1466. return false;
  1467. }
  1468. bool Reader::emphasise()
  1469. {
  1470. //enter
  1471. if(!isIn(Emphasise) && is("*"))
  1472. {
  1473. if(isLast(Body) || isLast(Matter) || isLast(Part)) enter(Paragraph);
  1474. enter(Emphasise);
  1475. skip();
  1476. return true;
  1477. }
  1478. //leave
  1479. if(isIn(Emphasise) && is("*"))
  1480. {
  1481. skip();
  1482. leave(Emphasise);
  1483. return true;
  1484. }
  1485. //continue searching
  1486. return false;
  1487. }
  1488. bool Reader::url()
  1489. {
  1490. //hold
  1491. static Hold hold = None;
  1492. //enter url
  1493. if(!isIn(Url) && !is(" ") && !is("\t") && !is("\n"))
  1494. {
  1495. if(is("'")) hold = Quote;
  1496. else if(is("\"")) hold = DoubleQuote;
  1497. else if(is("{")) hold = CurlyBracket;
  1498. else hold = None;
  1499. int i = 0;
  1500. while(true)
  1501. {
  1502. i++;
  1503. if(is("\n", i) || (hold == None && (is(" ", i) || is("\t", i))) || eof(i)) break;
  1504. if((((hold == Quote && is("'", i))
  1505. || (hold == DoubleQuote && is("\"", i))
  1506. || (hold == CurlyBracket && is("}", i))
  1507. )
  1508. && is("==>", i+1) && !(is("==> ", i+1) || is("==>\t", i+1) || is("==>\n", i+1))
  1509. )
  1510. || (hold == None && is("==>", i) && !(is("==> ", i) || is("==>\t", i) || is("==>\n", i)))
  1511. )
  1512. {
  1513. enter(Url);
  1514. if(hold != None) skip();
  1515. }
  1516. }
  1517. }
  1518. //prepare to enter url link
  1519. if(isIn(Url) && !isIn(UrlLink))
  1520. {
  1521. if((hold == Quote && is("'"))
  1522. || (hold == DoubleQuote && is("\""))
  1523. || (hold == CurlyBracket && is("}")))
  1524. skip();
  1525. }
  1526. //enter url link
  1527. if(!isIn(UrlLink) && is("==>") && !(is("==> ") || is("==>\t") || is("==>\n")))
  1528. {
  1529. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  1530. if(!isIn(Url)) enter(Url);
  1531. enter(UrlLink);
  1532. skip(3);
  1533. if(is("'")) {hold = Quote; skip();}
  1534. else if(is("\"")) {hold = DoubleQuote; skip();}
  1535. else if(is("{")) {hold = CurlyBracket; skip();}
  1536. else hold = None;
  1537. return true;
  1538. }
  1539. //append character or leave url link
  1540. if(isIn(UrlLink))
  1541. {
  1542. bool toBeLeft = false;
  1543. switch(hold)
  1544. {
  1545. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  1546. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  1547. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  1548. case None:
  1549. default: if(is(" ") || is("\t")) toBeLeft = true;
  1550. }
  1551. if(is("\n"))
  1552. toBeLeft = true;
  1553. if(!toBeLeft) {append(c()); next();}
  1554. else leave(Url);
  1555. return true;
  1556. }
  1557. //continue searching
  1558. return false;
  1559. }
  1560. bool Reader::ref()
  1561. {
  1562. //hold
  1563. static Hold hold = None;
  1564. //enter
  1565. if(!isIn(Ref) && !isLast("<") && is("->") && !(is("-> ") || is("->\t") || is("->\n")))
  1566. {
  1567. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  1568. enter(Ref);
  1569. skip(2);
  1570. if(is("'")) {hold = Quote; skip();}
  1571. else if(is("\"")) {hold = DoubleQuote; skip();}
  1572. else if(is("{")) {hold = CurlyBracket; skip();}
  1573. else hold = None;
  1574. return true;
  1575. }
  1576. //append character or leave
  1577. if(isIn(Ref))
  1578. {
  1579. bool toBeLeft = false;
  1580. switch(hold)
  1581. {
  1582. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  1583. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  1584. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  1585. case None:
  1586. default: if(is(" ") || is("\t")) toBeLeft = true;
  1587. }
  1588. if(is("\n"))
  1589. toBeLeft = true;
  1590. if(!toBeLeft) {append(c()); next();}
  1591. else leave(Ref);
  1592. return true;
  1593. }
  1594. //continue searching
  1595. return false;
  1596. }
  1597. bool Reader::titleRef()
  1598. {
  1599. //hold
  1600. static Hold hold = None;
  1601. //enter
  1602. if(!isIn(TitleRef) && is("~>") && !(is("~> ") || is("~>\t") || is("~>\n")))
  1603. {
  1604. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  1605. enter(TitleRef);
  1606. skip(2);
  1607. if(is("'")) {hold = Quote; skip();}
  1608. else if(is("\"")) {hold = DoubleQuote; skip();}
  1609. else if(is("{")) {hold = CurlyBracket; skip();}
  1610. else hold = None;
  1611. return true;
  1612. }
  1613. //append character or leave
  1614. if(isIn(TitleRef))
  1615. {
  1616. bool toBeLeft = false;
  1617. switch(hold)
  1618. {
  1619. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  1620. case DoubleQuote: if(is("\"")) {skip(); toBeLeft = true;} break;
  1621. case CurlyBracket: if(is("}")) {skip(); toBeLeft = true;} break;
  1622. case None:
  1623. default: if(is(" ") || is("\t")) toBeLeft = true;
  1624. }
  1625. if(is("\n"))
  1626. toBeLeft = true;
  1627. if(!toBeLeft) {append(c()); next();}
  1628. else leave(TitleRef);
  1629. return true;
  1630. }
  1631. //continue searching
  1632. return false;
  1633. }
  1634. bool Reader::pageRef()
  1635. {
  1636. //hold
  1637. static Hold hold = None;
  1638. //enter
  1639. if(!isIn(PageRef) && !isLast("<") && is("=>") && !(is("=> ") || is("=>\t") || is("=>\n")))
  1640. {
  1641. if(isLast(Body) || isLast(Matter)) enter(Paragraph);
  1642. enter(PageRef);
  1643. skip(2);
  1644. if(is("'")) {hold = Quote; skip();}
  1645. else if(is("\"")) {hold = DoubleQuote; skip();}
  1646. else if(is("{")) {hold = CurlyBracket; skip();}
  1647. else hold = None;
  1648. return true;
  1649. }
  1650. //append character or leave
  1651. if(isIn(PageRef))
  1652. {
  1653. bool toBeLeft = false;
  1654. switch(hold)
  1655. {
  1656. case Quote: if(is("'")) {skip(); toBeLeft = true;} break;
  1657. case DoubleQuote: if(

Large files files are truncated, but you can click here to view the full file