Index: branches/parser-work/phase3/maintenance/parserTests.txt |
— | — | @@ -3792,9 +3792,10 @@ |
3793 | 3793 | <li class="toclevel-5 tocsection-5"><a href="#Level_5_Heading"><span class="tocnumber">1.1.1.1.1</span> <span class="toctext">Level 5 Heading</span></a> |
3794 | 3794 | <ul> |
3795 | 3795 | <li class="toclevel-6 tocsection-6"><a href="#Level_6_Heading"><span class="tocnumber">1.1.1.1.1.1</span> <span class="toctext">Level 6 Heading</span></a></li> |
3796 | | -<li class="toclevel-6 tocsection-7"><a href="#.3D_Level_7_Heading"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">= Level 7 Heading</span></a></li> |
3797 | | -<li class="toclevel-6 tocsection-8"><a href="#.3D.3D_Level_8_Heading"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">== Level 8 Heading</span></a></li> |
3798 | | -<li class="toclevel-6 tocsection-9"><a href="#.3D.3D.3D_Level_9_Heading"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">=== Level 9 Heading</span></a></li> |
| 3796 | +<li class="toclevel-6 tocsection-7"><a href="#.3D_Level_7_Heading.3D"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">= Level 7 Heading=</span></a></li> |
| 3797 | +<li class="toclevel-6 tocsection-8"><a href="#.3D.3D_Level_8_Heading.3D.3D"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">== Level 8 Heading==</span></a></li> |
| 3798 | +<li class="toclevel-6 tocsection-9"><a href="#.3D.3D.3D_Level_9_Heading.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">=== Level 9 Heading===</span></a></li> |
| 3799 | +<li class="toclevel-6 tocsection-10"><a href="#.3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.5</span> <span class="toctext">==== Level 10 Heading====</span></a></li> |
3799 | 3800 | </ul> |
3800 | 3801 | </li> |
3801 | 3802 | </ul> |
— | — | @@ -3805,13 +3806,7 @@ |
3806 | 3807 | </li> |
3807 | 3808 | </ul> |
3808 | 3809 | </li> |
3809 | | -<li class="toclevel-1"><a href="#.3D"><span class="tocnumber">2</span> <span class="toctext">=</span></a> |
3810 | | -<ul> |
3811 | | -<li class="toclevel-2 tocsection-10"><a href="#.3D.3D.3D.3D_Level_10_Heading"><span class="tocnumber">2.1</span> <span class="toctext">==== Level 10 Heading</span></a></li> |
3812 | 3810 | </ul> |
3813 | | -</li> |
3814 | | -<li class="toclevel-1"><a href="#.3D.3D"><span class="tocnumber">3</span> <span class="toctext">==</span></a></li> |
3815 | | -</ul> |
3816 | 3811 | </td></tr></table><script>if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script> |
3817 | 3812 | <h1><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline" id="Level_1_Heading"> Level 1 Heading</span></h1> |
3818 | 3813 | <h2><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline" id="Level_2_Heading"> Level 2 Heading</span></h2> |
— | — | @@ -3819,16 +3814,10 @@ |
3820 | 3815 | <h4><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline" id="Level_4_Heading"> Level 4 Heading</span></h4> |
3821 | 3816 | <h5><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline" id="Level_5_Heading"> Level 5 Heading</span></h5> |
3822 | 3817 | <h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline" id="Level_6_Heading"> Level 6 Heading</span></h6> |
3823 | | -<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading">= Level 7 Heading</span></h6> |
3824 | | -<p>= |
3825 | | -</p> |
3826 | | -<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading">== Level 8 Heading</span></h6> |
3827 | | -<p>== |
3828 | | -</p> |
3829 | | -<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading">=== Level 9 Heading</span></h6> |
3830 | | -<h1> <span class="mw-headline" id=".3D">=</span></h1> |
3831 | | -<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading">==== Level 10 Heading</span></h6> |
3832 | | -<h1> <span class="mw-headline" id=".3D.3D">==</span></h1> |
| 3818 | +<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span></h6> |
| 3819 | +<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span></h6> |
| 3820 | +<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span></h6> |
| 3821 | +<h6><span class="editsection">[<a href="https://www.mediawiki.org/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span></h6> |
3833 | 3822 | |
3834 | 3823 | !! end |
3835 | 3824 | |
— | — | @@ -5505,6 +5494,16 @@ |
5506 | 5495 | !! end |
5507 | 5496 | |
5508 | 5497 | !! test |
| 5498 | +Invalid header with following text |
| 5499 | +!! input |
| 5500 | += x = y |
| 5501 | +!! result |
| 5502 | +<p>= x = y |
| 5503 | +</p> |
| 5504 | +!! end |
| 5505 | + |
| 5506 | + |
| 5507 | +!! test |
5509 | 5508 | Section extraction test (section 0) |
5510 | 5509 | !! options |
5511 | 5510 | section=0 |
— | — | @@ -5753,18 +5752,43 @@ |
5754 | 5753 | !! end |
5755 | 5754 | |
5756 | 5755 | !! test |
| 5756 | +Section extraction test with bogus heading (section 1) |
| 5757 | +!! options |
| 5758 | +section=1 |
| 5759 | +!! input |
| 5760 | +==a== |
| 5761 | +==bogus== not a legal section |
| 5762 | +==b== |
| 5763 | +!! result |
| 5764 | +==a== |
| 5765 | +==bogus== not a legal section |
| 5766 | +!! end |
| 5767 | + |
| 5768 | +!! test |
5757 | 5769 | Section extraction test with bogus heading (section 2) |
5758 | 5770 | !! options |
5759 | 5771 | section=2 |
5760 | 5772 | !! input |
5761 | 5773 | ==a== |
5762 | | -==b== now a legal section |
| 5774 | +==bogus== not a legal section |
| 5775 | +==b== |
5763 | 5776 | !! result |
5764 | 5777 | ==b== |
5765 | | - now a legal section |
5766 | 5778 | !! end |
5767 | 5779 | |
5768 | 5780 | !! test |
| 5781 | +Section extraction test with comment after heading (section 1) |
| 5782 | +!! options |
| 5783 | +section=1 |
| 5784 | +!! input |
| 5785 | +==a== |
| 5786 | +==b== <!-- --> |
| 5787 | +==c== |
| 5788 | +!! result |
| 5789 | +==a== |
| 5790 | +!! end |
| 5791 | + |
| 5792 | +!! test |
5769 | 5793 | Section extraction test with comment after heading (section 2) |
5770 | 5794 | !! options |
5771 | 5795 | section=2 |
— | — | @@ -5773,8 +5797,20 @@ |
5774 | 5798 | ==b== <!-- --> |
5775 | 5799 | ==c== |
5776 | 5800 | !! result |
| 5801 | +==b== <!-- --> |
| 5802 | +!! end |
| 5803 | + |
| 5804 | +!! test |
| 5805 | +Section extraction test with bogus <nowiki> heading (section 1) |
| 5806 | +!! options |
| 5807 | +section=1 |
| 5808 | +!! input |
| 5809 | +==a== |
| 5810 | +==bogus== <nowiki>not a legal section</nowiki> |
5777 | 5811 | ==b== |
5778 | | - <!-- --> |
| 5812 | +!! result |
| 5813 | +==a== |
| 5814 | +==bogus== <nowiki>not a legal section</nowiki> |
5779 | 5815 | !! end |
5780 | 5816 | |
5781 | 5817 | !! test |
— | — | @@ -5783,10 +5819,10 @@ |
5784 | 5820 | section=2 |
5785 | 5821 | !! input |
5786 | 5822 | ==a== |
5787 | | -==b== <nowiki>now a legal section</nowiki> |
| 5823 | +==bogus== <nowiki>not a legal section</nowiki> |
| 5824 | +==b== |
5788 | 5825 | !! result |
5789 | 5826 | ==b== |
5790 | | - <nowiki>now a legal section</nowiki> |
5791 | 5827 | !! end |
5792 | 5828 | |
5793 | 5829 | |
Index: branches/parser-work/phase3/includes/parser/Parser.php |
— | — | @@ -95,7 +95,7 @@ |
96 | 96 | # Persistent: |
97 | 97 | var $mTagHooks, $mTransparentTagHooks, $mFunctionHooks, $mFunctionSynonyms, $mVariables, |
98 | 98 | $mSubsts, $mImageParams, $mImageParamsMagicArray, $mStripList, $mMarkerIndex, |
99 | | - $mParseEngine, $mPreprocessor, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList, |
| 99 | + $mParseEngine, $mExtLinkBracketedRegex, $mUrlProtocols, $mDefaultStripList, |
100 | 100 | $mVarCache, $mConf, $mFunctionTagHooks; |
101 | 101 | |
102 | 102 | |
— | — | @@ -227,11 +227,6 @@ |
228 | 228 | $this->mDoubleUnderscores = array(); |
229 | 229 | $this->mExpensiveFunctionCount = 0; |
230 | 230 | |
231 | | - # Fix cloning |
232 | | - if ( isset( $this->mPreprocessor ) && $this->mPreprocessor->parser !== $this ) { |
233 | | - $this->mPreprocessor = null; |
234 | | - } |
235 | | - |
236 | 231 | wfRunHooks( 'ParserClearState', array( &$this ) ); |
237 | 232 | wfProfileOut( __METHOD__ ); |
238 | 233 | } |
— | — | @@ -535,16 +530,6 @@ |
536 | 531 | } |
537 | 532 | |
538 | 533 | /** |
539 | | - * Get a preprocessor object |
540 | | - */ |
541 | | - function getPreprocessor() { |
542 | | - if ( !isset( $this->mPreprocessor ) ) { |
543 | | - $this->mPreprocessor = new Preprocessor( $this->mParseEngine ); |
544 | | - } |
545 | | - return $this->mPreprocessor; |
546 | | - } |
547 | | - |
548 | | - /** |
549 | 534 | * Replaces all occurrences of HTML-style comments and the given tags |
550 | 535 | * in the text with a random marker and returns the next text. The output |
551 | 536 | * parameter $matches will be an associative array filled with data in |
— | — | @@ -912,7 +897,7 @@ |
913 | 898 | $flag = 0; |
914 | 899 | else |
915 | 900 | $flag = Parser::PTD_FOR_INCLUSION; |
916 | | - $dom = $this->preprocessToDom( $text, $flag ); |
| 901 | + $dom = $this->mParseEngine->parse($text); |
917 | 902 | $text = $frame->expand( $dom, $flag ); |
918 | 903 | } |
919 | 904 | // if $frame is not provided, then use old-style replaceVariables |
— | — | @@ -2715,33 +2700,6 @@ |
2716 | 2701 | wfProfileOut( __METHOD__ ); |
2717 | 2702 | } |
2718 | 2703 | |
2719 | | - /** |
2720 | | - * Preprocess some wikitext and return the document tree. |
2721 | | - * This is the ghost of replace_variables(). |
2722 | | - * |
2723 | | - * @param string $text The text to parse |
2724 | | - * @param integer flags Bitwise combination of: |
2725 | | - * self::PTD_FOR_INCLUSION Handle <noinclude>/<includeonly> as if the text is being |
2726 | | - * included. Default is to assume a direct page view. |
2727 | | - * |
2728 | | - * The generated DOM tree must depend only on the input text and the flags. |
2729 | | - * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899. |
2730 | | - * |
2731 | | - * Any flag added to the $flags parameter here, or any other parameter liable to cause a |
2732 | | - * change in the DOM tree for a given text, must be passed through the section identifier |
2733 | | - * in the section edit link and thus back to extractSections(). |
2734 | | - * |
2735 | | - * The output of this function is currently only cached in process memory, but a persistent |
2736 | | - * cache may be implemented at a later date which takes further advantage of these strict |
2737 | | - * dependency requirements. |
2738 | | - * |
2739 | | - * @private |
2740 | | - */ |
2741 | | - function preprocessToDom ( $text, $flags = 0 ) { |
2742 | | - $dom = $this->getPreprocessor()->preprocessToObj( $text, $flags ); |
2743 | | - return $dom; |
2744 | | - } |
2745 | | - |
2746 | 2704 | /* |
2747 | 2705 | * Return a three-element array: leading whitespace, string contents, trailing whitespace |
2748 | 2706 | */ |
— | — | @@ -2772,27 +2730,19 @@ |
2773 | 2731 | * @param PPFrame $frame Object describing the arguments passed to the template. |
2774 | 2732 | * Arguments may also be provided as an associative array, as was the usual case before MW1.12. |
2775 | 2733 | * Providing arguments this way may be useful for extensions wishing to perform variable replacement explicitly. |
2776 | | - * @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion |
2777 | 2734 | * @private |
2778 | 2735 | */ |
2779 | | - function replaceVariables( $text, $frame = false, $argsOnly = false ) { |
| 2736 | + function replaceVariables( $text ) { |
2780 | 2737 | # Is there any text? Also, Prevent too big inclusions! |
2781 | 2738 | if ( strlen( $text ) < 1 || strlen( $text ) > $this->mOptions->getMaxIncludeSize() ) { |
2782 | 2739 | return $text; |
2783 | 2740 | } |
2784 | 2741 | wfProfileIn( __METHOD__ ); |
2785 | 2742 | |
2786 | | - if ( $frame === false ) { |
2787 | | - $frame = new PPFrame($this); |
2788 | | - } elseif ( !( $frame instanceof PPFrame ) ) { |
2789 | | - wfDebug( __METHOD__." called using plain parameters instead of a PPFrame instance. Creating custom frame.\n" ); |
2790 | | - $frame = $this->getPreprocessor()->newCustomFrame($frame); |
2791 | | - } |
| 2743 | + $dom = $this->mParseEngine->parse($text); |
| 2744 | + $frame = new PPFrame($this); |
| 2745 | + $text = $frame->expand($dom); |
2792 | 2746 | |
2793 | | - $dom = $this->preprocessToDom( $text ); |
2794 | | - $flags = $argsOnly ? PPFrame::NO_TEMPLATES : 0; |
2795 | | - $text = $frame->expand( $dom, $flags ); |
2796 | | - |
2797 | 2747 | wfProfileOut( __METHOD__ ); |
2798 | 2748 | return $text; |
2799 | 2749 | } |
— | — | @@ -2994,7 +2944,7 @@ |
2995 | 2945 | $text = $result; |
2996 | 2946 | } |
2997 | 2947 | if ( !$noparse ) { |
2998 | | - $text = $this->preprocessToDom( $text, $preprocessFlags ); |
| 2948 | + $text = $this->mParseEngine->parse($text); |
2999 | 2949 | $isChildObj = true; |
3000 | 2950 | } |
3001 | 2951 | } |
— | — | @@ -3063,7 +3013,7 @@ |
3064 | 3014 | } else { |
3065 | 3015 | $text = $this->interwikiTransclude( $title, 'raw' ); |
3066 | 3016 | // Preprocess it like a template |
3067 | | - $text = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION ); |
| 3017 | + $text = $this->mParseEngine->parse($text); |
3068 | 3018 | $isChildObj = true; |
3069 | 3019 | } |
3070 | 3020 | $found = true; |
— | — | @@ -3167,7 +3117,7 @@ |
3168 | 3118 | return array( false, $title ); |
3169 | 3119 | } |
3170 | 3120 | |
3171 | | - $dom = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION ); |
| 3121 | + $dom = $this->mParseEngine->parse($text); |
3172 | 3122 | $this->mTplDomCache[ $titleText ] = $dom; |
3173 | 3123 | |
3174 | 3124 | if (! $title->equals($cacheTitle)) { |
— | — | @@ -3600,7 +3550,7 @@ |
3601 | 3551 | $oldType = $this->mOutputType; |
3602 | 3552 | $this->setOutputType( self::OT_WIKI ); |
3603 | 3553 | $frame = new PPFrame($this); |
3604 | | - $root = $this->preprocessToDom( $origText ); |
| 3554 | + $root = $this->mParseEngine->parse($origText); |
3605 | 3555 | $node = $root->firstChild; |
3606 | 3556 | $byteOffset = 0; |
3607 | 3557 | $tocraw = array(); |
— | — | @@ -4163,7 +4113,7 @@ |
4164 | 4114 | |
4165 | 4115 | $text = preg_replace( $substRegex, $substText, $text ); |
4166 | 4116 | $text = $this->cleanSigInSig( $text ); |
4167 | | - $dom = $this->preprocessToDom( $text ); |
| 4117 | + $dom = $this->mParseEngine->parse($text); |
4168 | 4118 | $frame = new PPFrame($this); |
4169 | 4119 | $text = $frame->expand( $dom ); |
4170 | 4120 | |
— | — | @@ -4748,7 +4698,7 @@ |
4749 | 4699 | * @private |
4750 | 4700 | */ |
4751 | 4701 | function attributeStripCallback( &$text, $frame = false ) { |
4752 | | - $text = $this->replaceVariables( $text, $frame ); |
| 4702 | + $text = $this->replaceVariables( $text ); |
4753 | 4703 | $text = $this->mStripState->unstripBoth( $text ); |
4754 | 4704 | return $text; |
4755 | 4705 | } |
— | — | @@ -4814,7 +4764,7 @@ |
4815 | 4765 | } |
4816 | 4766 | } |
4817 | 4767 | // Preprocess the text |
4818 | | - $root = $this->preprocessToDom( $text, $flags ); |
| 4768 | + $root = $this->mParseEngine->parse($text); |
4819 | 4769 | PPFrame::updateIncTags($root, $flags); |
4820 | 4770 | |
4821 | 4771 | // <h> nodes indicate section breaks |
Index: branches/parser-work/phase3/includes/parser/ParseEngine.php |
— | — | @@ -22,6 +22,8 @@ |
23 | 23 | } |
24 | 24 | |
25 | 25 | function parse($text) { |
| 26 | +//print("Text: $text\n"); |
| 27 | +//foreach (debug_backtrace() as $func) print("{$func["function"]}:{$func["file"]}:{$func["line"]}\n"); |
26 | 28 | global $wgDebugParserLog; |
27 | 29 | if ($wgDebugParserLog != '') { |
28 | 30 | wfErrorLog("==========Start Parsing==========\n", $wgDebugParserLog); |
— | — | @@ -43,20 +45,6 @@ |
44 | 46 | return $doc; |
45 | 47 | } |
46 | 48 | |
47 | | - static function unparse($node) { |
48 | | - $retStr = ""; |
49 | | - if ($node instanceof DOMElement) { |
50 | | - $retStr .= $node->getAttribute("startTag"); |
51 | | - foreach ($node->childNodes as $child) { |
52 | | - $retStr .= ParseEngine::unparse($child); |
53 | | - } |
54 | | - $retStr .= $node->getAttribute("endTag"); |
55 | | - } else { |
56 | | - $retStr .= $node->textContent; |
57 | | - } |
58 | | - return $retStr; |
59 | | - } |
60 | | - |
61 | 49 | private function parseRec($rule, $replaceStr, $saveTags, &$iter, &$text, &$outNode) { |
62 | 50 | global $wgDebugParserLog; |
63 | 51 | if ($wgDebugParserLog != '') { |
— | — | @@ -79,23 +67,23 @@ |
80 | 68 | $retCode = FALSE; |
81 | 69 | if ($rule->nodeName == "Assignment") { |
82 | 70 | $startPat = $rule->getAttribute("tag"); |
83 | | - $startTag = NULL; |
| 71 | + $tag = NULL; |
84 | 72 | if ($rule->getAttribute("regex") != NULL) { |
85 | 73 | if (preg_match("/^$startPat/s", $text, $matches)) { |
86 | | - $startTag = $matches[0]; |
| 74 | + $tag = $matches[0]; |
87 | 75 | if (isset($matches[1])) { |
88 | 76 | $replaceStr = $matches[1]; |
89 | 77 | } |
90 | 78 | } |
91 | 79 | } elseif ($startPat != NULL && strncmp($startPat, $text, strlen($startPat)) == 0) { |
92 | | - $startTag = $startPat; |
| 80 | + $tag = $startPat; |
93 | 81 | } |
94 | | - if ($startTag != NULL || $startPat == NULL) { |
| 82 | + if ($tag != NULL || $startPat == NULL) { |
95 | 83 | $newText = $text; |
96 | | - $newElement = $dom->createElement($rule->getAttribute("name")); |
97 | | - if ($startTag != NULL) { |
98 | | - $newText = substr($newText, strlen($startTag)); |
99 | | - $newElement->setAttribute("startTag", $startTag); |
| 84 | + $newElement = $dom->createElement($rule->getAttribute("tagName")); |
| 85 | + if ($tag != NULL) { |
| 86 | + $newText = substr($newText, strlen($tag)); |
| 87 | + $newElement->setAttribute("tag", $tag); |
100 | 88 | } |
101 | 89 | $retCode = $rule->firstChild == NULL || $this->parseRec($rule->firstChild, $replaceStr, $saveTags, $iter, $newText, $newElement); |
102 | 90 | if ($retCode) { |
— | — | @@ -103,14 +91,6 @@ |
104 | 92 | $text = $newText; |
105 | 93 | } |
106 | 94 | } |
107 | | - } elseif ($rule->nodeName == "EndTag") { |
108 | | - $tag = str_replace("~r", $replaceStr, $rule->getAttribute("tag")); |
109 | | - $tagLength = strlen($tag); |
110 | | - if (strncmp($tag, $text, $tagLength) == 0) { |
111 | | - $text = substr($text, $tagLength); |
112 | | - $outNode->setAttribute("endTag", $tag); |
113 | | - $retCode = TRUE; |
114 | | - } |
115 | 95 | } elseif ($rule->nodeName == "Sequence") { |
116 | 96 | $saveText = $text; |
117 | 97 | $saveNode = $outNode->cloneNode(TRUE); |
— | — | @@ -195,7 +175,7 @@ |
196 | 176 | } |
197 | 177 | $rule->setAttribute("pushInd", $pushInd); |
198 | 178 | } else { |
199 | | - if ($rule->nodeName != "Choice" && $rule->nodeName != "EndTag") { |
| 179 | + if ($rule->nodeName != "Choice") { |
200 | 180 | $rule->setAttribute("saveTags", $tagStr); |
201 | 181 | $tagStr = NULL; |
202 | 182 | if ($rule->nodeName == "Text") { |
— | — | @@ -223,7 +203,7 @@ |
224 | 204 | } |
225 | 205 | $childTags = ""; |
226 | 206 | $failSafe = TRUE; |
227 | | - if ($rule->nodeName == "EndTag" || $rule->nodeName == "Assignment") { |
| 207 | + if ($rule->nodeName == "Assignment") { |
228 | 208 | $childTags = $rule->getAttribute("tag"); |
229 | 209 | if ($rule->nodeName != "Assignment" || $rule->getAttribute("regex") == NULL) { |
230 | 210 | $childTags = preg_quote($childTags, "/"); |
Index: branches/parser-work/phase3/includes/parser/Preprocessor.php |
— | — | @@ -1,117 +1,5 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | /** |
5 | | - * @ingroup Parser |
6 | | - */ |
7 | | -class Preprocessor { |
8 | | - private $mParser, $memoryLimit; |
9 | | - |
10 | | - const CACHE_VERSION = 1; |
11 | | - |
12 | | - function __construct( $parser ) { |
13 | | - $this->mParser = $parser; |
14 | | - $mem = ini_get( 'memory_limit' ); |
15 | | - $this->memoryLimit = false; |
16 | | - if ( strval( $mem ) !== '' && $mem != -1 ) { |
17 | | - if ( preg_match( '/^\d+$/', $mem ) ) { |
18 | | - $this->memoryLimit = $mem; |
19 | | - } elseif ( preg_match( '/^(\d+)M$/i', $mem, $m ) ) { |
20 | | - $this->memoryLimit = $m[1] * 1048576; |
21 | | - } |
22 | | - } |
23 | | - } |
24 | | - |
25 | | - function memCheck() { |
26 | | - if ( $this->memoryLimit === false ) { |
27 | | - return; |
28 | | - } |
29 | | - $usage = memory_get_usage(); |
30 | | - if ( $usage > $this->memoryLimit * 0.9 ) { |
31 | | - $limit = intval( $this->memoryLimit * 0.9 / 1048576 + 0.5 ); |
32 | | - throw new MWException( "Preprocessor hit 90% memory limit ($limit MB)" ); |
33 | | - } |
34 | | - return $usage <= $this->memoryLimit * 0.8; |
35 | | - } |
36 | | - |
37 | | - /** |
38 | | - * Preprocess some wikitext and return the document tree. |
39 | | - * This is the ghost of Parser::replace_variables(). |
40 | | - * |
41 | | - * @param string $text The text to parse |
42 | | - * @param integer flags Bitwise combination of: |
43 | | - * Parser::PTD_FOR_INCLUSION Handle <noinclude>/<includeonly> as if the text is being |
44 | | - * included. Default is to assume a direct page view. |
45 | | - * |
46 | | - * The generated DOM tree must depend only on the input text and the flags. |
47 | | - * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899. |
48 | | - * |
49 | | - * Any flag added to the $flags parameter here, or any other parameter liable to cause a |
50 | | - * change in the DOM tree for a given text, must be passed through the section identifier |
51 | | - * in the section edit link and thus back to extractSections(). |
52 | | - * |
53 | | - * The output of this function is currently only cached in process memory, but a persistent |
54 | | - * cache may be implemented at a later date which takes further advantage of these strict |
55 | | - * dependency requirements. |
56 | | - * |
57 | | - * @private |
58 | | - */ |
59 | | - function preprocessToObj( $text, $flags = 0 ) { |
60 | | - wfProfileIn( __METHOD__ ); |
61 | | - global $wgMemc, $wgPreprocessorCacheThreshold; |
62 | | - |
63 | | - $xml = false; |
64 | | - $cacheable = strlen( $text ) > $wgPreprocessorCacheThreshold; |
65 | | - if ( $cacheable ) { |
66 | | - wfProfileIn( __METHOD__.'-cacheable' ); |
67 | | - |
68 | | - $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags ); |
69 | | - $cacheValue = $wgMemc->get( $cacheKey ); |
70 | | - if ( $cacheValue ) { |
71 | | - $version = substr( $cacheValue, 0, 8 ); |
72 | | - if ( intval( $version ) == self::CACHE_VERSION ) { |
73 | | - $xml = substr( $cacheValue, 8 ); |
74 | | - // From the cache |
75 | | - wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" ); |
76 | | - } |
77 | | - } |
78 | | - } |
79 | | - $dom = false; |
80 | | - if ( $xml === false ) { |
81 | | - if ( $cacheable ) { |
82 | | - wfProfileIn( __METHOD__.'-cache-miss' ); |
83 | | - } |
84 | | - $dom = $this->mParser->parse($text); |
85 | | - if ( $cacheable ) { |
86 | | - $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $dom->saveXML(); |
87 | | - $wgMemc->set( $cacheKey, $cacheValue, 86400 ); |
88 | | - wfProfileOut( __METHOD__.'-cache-miss' ); |
89 | | - wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" ); |
90 | | - } |
91 | | - } else { |
92 | | - wfProfileIn( __METHOD__.'-loadXML' ); |
93 | | - $dom = new DOMDocument; |
94 | | - wfSuppressWarnings(); |
95 | | - $result = $dom->loadXML( $xml ); |
96 | | - wfRestoreWarnings(); |
97 | | - if ( !$result ) { |
98 | | - // Try running the XML through UtfNormal to get rid of invalid characters |
99 | | - $xml = UtfNormal::cleanUp( $xml ); |
100 | | - $result = $dom->loadXML( $xml ); |
101 | | - if ( !$result ) { |
102 | | - throw new MWException( __METHOD__.' generated invalid XML' ); |
103 | | - } |
104 | | - } |
105 | | - wfProfileOut( __METHOD__.'-loadXML' ); |
106 | | - } |
107 | | - if ( $cacheable ) { |
108 | | - wfProfileOut( __METHOD__.'-cacheable' ); |
109 | | - } |
110 | | - wfProfileOut( __METHOD__ ); |
111 | | - return $dom; |
112 | | - } |
113 | | -} |
114 | | - |
115 | | -/** |
116 | 4 | * An expansion frame, used as a context to expand the result of preprocessToObj() |
117 | 5 | * @ingroup Parser |
118 | 6 | */ |
— | — | @@ -141,7 +29,7 @@ |
142 | 30 | |
143 | 31 | /** |
144 | 32 | * Construct a new preprocessor frame. |
145 | | - * @param Preprocessor $parser The parent parser |
| 33 | + * @param Parser $parser The parent parser |
146 | 34 | */ |
147 | 35 | function __construct( $parser ) { |
148 | 36 | $this->parser = $parser; |
— | — | @@ -216,11 +104,11 @@ |
217 | 105 | //print("UpdIn - {$root->ownerDocument->saveXML()}\n"); |
218 | 106 | PPFrame::updateIncTags($root, $flags); |
219 | 107 | |
220 | | -print("ParseIn - {$root->ownerDocument->saveXML()}\n"); |
| 108 | +//print("ParseIn - {$root->ownerDocument->saveXML()}\n"); |
221 | 109 | $headingIndex = 1; |
222 | 110 | $this->expandRec($root->childNodes, $flags, $headingIndex); |
223 | 111 | $output = $root->textContent; |
224 | | -print("ParseOut - {$output}\n"); |
| 112 | +//print("ParseOut - {$output}\n"); |
225 | 113 | |
226 | 114 | --$expansionDepth; |
227 | 115 | wfProfileOut( __METHOD__ ); |
— | — | @@ -228,31 +116,22 @@ |
229 | 117 | } |
230 | 118 | |
231 | 119 | private function expandRec($contextNode, $flags, &$headingIndex) { |
| 120 | + $xpath = new DOMXPath($contextNode->ownerDocument); |
232 | 121 | if ($contextNode instanceof DOMNodeList) { |
233 | | - for ($i = 0; $i < $contextNode->length; $i ++) { |
234 | | - $child = $contextNode->item($i); |
| 122 | + $retStr = ""; |
| 123 | + foreach ($contextNode as $child) { |
235 | 124 | if ($child instanceof DOMElement) { |
236 | | - $this->expandRec($child, $flags, $headingIndex); |
237 | | - $i --; |
| 125 | + $retStr .= $this->expandRec($child, $flags, $headingIndex); |
| 126 | + } else { |
| 127 | + $retstr .= $child->data; |
238 | 128 | } |
239 | 129 | } |
240 | 130 | } else { |
241 | | -print("ParseRecIn - {$contextNode->nodeName}\n"); |
242 | | - if (($contextNode->nodeName == 'template' || $contextNode->nodeName == 'tplarg') && ! ($flags & self::NO_ARGS)) { |
243 | | - foreach ($contextNode->childNodes as $child) { |
244 | | - if ($child->nodeName == "part") { |
245 | | - foreach ($child->childNodes as $partChild) { |
246 | | - $this->expandRec($partChild->childNodes, $flags, $headingIndex); |
247 | | - } |
248 | | - } else { |
249 | | - $this->expandRec($child->childNodes, $flags, $headingIndex); |
250 | | - } |
251 | | - } |
252 | | - if ( $contextNode->nodeName == 'template' ) { |
253 | | - $this->parser->braceSubstitution($contextNode, $this); |
254 | | - } else { |
255 | | - $this->parser->argSubstitution($contextNode, $this); |
256 | | - } |
| 131 | +//print("ParseRecIn - {$contextNode->nodeName}\n"); |
| 132 | + if ($contextNode->nodeName == 'template' && ! ($flags & self::NO_TEMPLATES)) { |
| 133 | + $retStr = $this->parser->braceSubstitution($contextNode, $this); |
| 134 | + } elseif ($contextNode->nodeName == 'tplarg' && ! ($flags & self::NO_ARGS)) { |
| 135 | + $retStr = $this->parser->argSubstitution($contextNode, $this); |
257 | 136 | } elseif ( $contextNode->nodeName == 'comment' ) { |
258 | 137 | $comment = $contextNode->getAttribute("startTag"); |
259 | 138 | # HTML-style comment |
— | — | @@ -277,35 +156,32 @@ |
278 | 157 | else { |
279 | 158 | $contextNode->parentNode->replaceChild($contextNode->ownerDocument->createTextNode($comment), $contextNode); |
280 | 159 | } |
281 | | - } elseif ($contextNode->nodeName == 'ignore') { |
282 | | - # Output suppression used by <includeonly> etc. |
283 | | - # OT_WIKI will only respect <ignore> in substed templates. |
284 | | - # The other output types respect it unless NO_IGNORE is set. |
285 | | - # extractSections() sets NO_IGNORE and so never respects it. |
286 | | - if (($this instanceof PPTemplateFrame || ! $this->parser->ot['wiki']) && ! ($flags & self::NO_IGNORE)) { |
287 | | - $contextNode->parentNode->removeChild($contextNode); |
| 160 | + } elseif ($contextNode->nodeName == "xmltag" || $contextNode->nodeName == "onlyinclude") { |
| 161 | + $tagName = $contextNode->nodeName == "xmltag" ? $xpath->query("name", $contextNode)->item(0)->getAttribute("tag") : "noinclude"; |
| 162 | + if ($tagName == "noinclude" || $tagName == "includeonly") { |
| 163 | + if (((! $this instanceof PPTemplateFrame && $this->parser->ot['wiki']) || ($flags & self::NO_IGNORE)) && |
| 164 | + ((($flags & Parser::PTD_FOR_INCLUSION) && $tagName == "includeonly") || |
| 165 | + (! ($flags & Parser::PTD_FOR_INCLUSION) && $tagName == "noinclude"))) { |
| 166 | + $retStr = "" . $contextNode->getAttribute("tag") . $this->expandRec($contextNode->childNodes, $flags, $headingIndex); |
| 167 | + } |
288 | 168 | } else { |
289 | | - $outText = ParseEngine::unparse($contextNode); |
290 | | - $contextNode->parentNode->replaceChild($contextNode->ownerDocument->createTextNode($outText), $contextNode); |
291 | | - } |
292 | | - } elseif ( $contextNode->nodeName == 'xmltag' ) { |
293 | | - foreach ($contextNode->childNodes as $child) { |
294 | | - $this->expandRec($child->childNodes, $flags, $headingIndex); |
295 | | - } |
296 | | - $tagName = substr($contextNode->getAttribute("startTag"), 1); |
297 | | - $isStripTag = false; |
298 | | - foreach ($this->parser->getStripList() as $stripTag) { |
299 | | - $isStripTag = $tagName == $stripTag; |
| 169 | + foreach ($contextNode->childNodes as $child) { |
| 170 | + $this->expandRec($child->childNodes, $flags, $headingIndex); |
| 171 | + } |
| 172 | + $isStripTag = false; |
| 173 | + foreach ($this->parser->getStripList() as $stripTag) { |
| 174 | + $isStripTag = $tagName == $stripTag; |
| 175 | + if ($isStripTag) { |
| 176 | + break; |
| 177 | + } |
| 178 | + } |
300 | 179 | if ($isStripTag) { |
301 | | - break; |
| 180 | + $outText = $this->parser->extensionSubstitution($contextNode, $this); |
| 181 | + } else { |
| 182 | + $outText = ParseEngine::unparse($contextNode); |
302 | 183 | } |
| 184 | + $contextNode->parentNode->replaceChild($contextNode->ownerDocument->createTextNode($outText), $contextNode); |
303 | 185 | } |
304 | | - if ($isStripTag) { |
305 | | - $outText = $this->parser->extensionSubstitution($contextNode, $this); |
306 | | - } else { |
307 | | - $outText = ParseEngine::unparse($contextNode); |
308 | | - } |
309 | | - $contextNode->parentNode->replaceChild($contextNode->ownerDocument->createTextNode($outText), $contextNode); |
310 | 186 | } elseif ($contextNode->nodeName == 'h' && $contextNode->parentNode->nodeName == 'root' && $this->parser->ot['html']) { |
311 | 187 | # Insert a heading marker only for <h> children of <root> |
312 | 188 | # This is to stop extractSections from going over multiple tree levels |
— | — | @@ -325,70 +201,11 @@ |
326 | 202 | $outText = ParseEngine::unparse($contextNode); |
327 | 203 | $contextNode->parentNode->replaceChild($contextNode->ownerDocument->createTextNode($outText), $contextNode); |
328 | 204 | } |
329 | | -print("ParseRecOut - {$contextNode->ownerDocument->saveXML()}\n"); |
| 205 | +//print("ParseRecOut - {$contextNode->ownerDocument->saveXML()}\n"); |
| 206 | + return retStr; |
330 | 207 | } |
331 | 208 | } |
332 | 209 | |
333 | | - static function updateIncTags($root, $flags = 0) { |
334 | | - if ( $root instanceof DOMDocument ) { |
335 | | - $root = $root->documentElement; |
336 | | - } |
337 | | - $parent = $root; |
338 | | - if ($parent instanceof DOMNodeList) { |
339 | | - $parent = $parent->item(0)->parentNode; |
340 | | - } |
341 | | - $xpath = new DOMXPath( $parent->ownerDocument ); |
342 | | - $forInclusion = $flags & Parser::PTD_FOR_INCLUSION; |
343 | | - $ignoreRest = $forInclusion && $xpath->query("xmltag[@startTag='<onlyinclude']", $parent)->length > 0; |
344 | | - $children = array(); |
345 | | - $ind = -1; |
346 | | - while ($parent->hasChildNodes()) { |
347 | | - $child = $parent->firstChild; |
348 | | - $parent->removeChild($child); |
349 | | - $tagName = $child instanceof DOMElement ? substr($child->getAttribute("startTag"), 1) : ""; |
350 | | - if ($tagName != "onlyinclude" && $ignoreRest) { |
351 | | - if ($ind < 0 || $children[$ind]->nodeName != "ignore") { |
352 | | - $children[] = $parent->ownerDocument->createElement("ignore"); |
353 | | - $ind ++; |
354 | | - } |
355 | | - $children[$ind]->appendChild($child); |
356 | | - } elseif ($tagName == "includeonly" || $tagName == "noinclude" || $tagName == "onlyinclude") { |
357 | | - $leftTag = $parent->ownerDocument->createTextNode("<$tagName>"); |
358 | | - $rightTag = $parent->ownerDocument->createTextNode("</$tagName>"); |
359 | | - $inner = $child->lastChild; |
360 | | - if (($tagName == "includeonly" && ! $forInclusion) || ($tagName == "noinclude" && $forInclusion)) { |
361 | | - $children[] = $parent->ownerDocument->createElement("ignore"); |
362 | | - $ind ++; |
363 | | - $children[$ind]->appendChild($leftTag); |
364 | | - while ($inner->hasChildNodes()) { |
365 | | - $gChild = $inner->firstChild; |
366 | | - $inner->removeChild($gChild); |
367 | | - $children[$ind]->appendChild($gChild); |
368 | | - } |
369 | | - $children[$ind]->appendChild($rightTag); |
370 | | - } else { |
371 | | - $children[] = $parent->ownerDocument->createElement("ignore"); |
372 | | - $ind ++; |
373 | | - $children[$ind]->appendChild($leftTag); |
374 | | - while ($inner->hasChildNodes()) { |
375 | | - $children[] = $inner->firstChild; |
376 | | - $ind ++; |
377 | | - $inner->removeChild($inner->firstChild); |
378 | | - } |
379 | | - $children[] = $parent->ownerDocument->createElement("ignore"); |
380 | | - $ind ++; |
381 | | - $children[$ind]->appendChild($rightTag); |
382 | | - } |
383 | | - } else { |
384 | | - $children[] = $child; |
385 | | - $ind ++; |
386 | | - } |
387 | | - } |
388 | | - foreach ($children as $child) { |
389 | | - $parent->appendChild($child); |
390 | | - } |
391 | | - } |
392 | | - |
393 | 210 | function __toString() { |
394 | 211 | return 'frame{}'; |
395 | 212 | } |
— | — | @@ -551,43 +368,3 @@ |
552 | 369 | } |
553 | 370 | } |
554 | 371 | |
555 | | -/** |
556 | | - * Expansion frame with custom arguments |
557 | | - * @ingroup Parser |
558 | | - */ |
559 | | -class PPCustomFrame extends PPFrame { |
560 | | - private $args; |
561 | | - |
562 | | - function __construct( $args ) { |
563 | | - PPFrame::__construct( ); |
564 | | - $this->args = $args; |
565 | | - } |
566 | | - |
567 | | - function __toString() { |
568 | | - $s = 'cstmframe{'; |
569 | | - $first = true; |
570 | | - foreach ( $this->args as $name => $value ) { |
571 | | - if ( $first ) { |
572 | | - $first = false; |
573 | | - } else { |
574 | | - $s .= ', '; |
575 | | - } |
576 | | - $s .= "\"$name\":\"" . |
577 | | - str_replace( '"', '\\"', $value->__toString() ) . '"'; |
578 | | - } |
579 | | - $s .= '}'; |
580 | | - return $s; |
581 | | - } |
582 | | - |
583 | | - function isEmpty() { |
584 | | - return !count( $this->args ); |
585 | | - } |
586 | | - |
587 | | - function getArgument( $index ) { |
588 | | - if ( !isset( $this->args[$index] ) ) { |
589 | | - return false; |
590 | | - } |
591 | | - return $this->args[$index]; |
592 | | - } |
593 | | -} |
594 | | - |
Index: branches/parser-work/phase3/includes/parser/WikiTextGrammar.xml |
— | — | @@ -2,34 +2,44 @@ |
3 | 3 | <Grammar rootTag="root" startRule="start"> |
4 | 4 | <Sequence name="start" > |
5 | 5 | <Choice failSafe="true"> |
6 | | - <Assignment name="h" tag="(={1,6})" regex="true"> |
| 6 | + <Assignment tagName="noinclude" tag="(?=.*(<onlyinclude>))" regex="true"> |
7 | 7 | <Reference name="endText" /> |
8 | 8 | </Assignment> |
| 9 | + <Reference name="heading" /> |
9 | 10 | </Choice> |
10 | 11 | <Reference name="main" /> |
11 | 12 | </Sequence> |
12 | 13 | <Text name="main"> |
13 | | - <Assignment name="link" tag="[["> |
| 14 | + <Reference name="newLine" /> |
| 15 | + <Assignment tagName="link" tag="[["> |
14 | 16 | <Reference name="endText" var="]]" /> |
15 | 17 | </Assignment> |
16 | | - <Assignment name="h" tag="\n(={1,6})" regex="true"> |
17 | | - <Reference name="endText" /> |
18 | | - </Assignment> |
19 | | - <Assignment name="tplarg" tag="{{{(?!{)" regex="true"> |
| 18 | + <Assignment tagName="tplarg" tag="{{{(?!{)" regex="true"> |
20 | 19 | <Reference name="tplSeq" var="}}}" /> |
21 | 20 | </Assignment> |
22 | | - <Assignment name="template" tag="{{"> |
| 21 | + <Assignment tagName="template" tag="{{"> |
23 | 22 | <Reference name="tplSeq" var="}}" /> |
24 | 23 | </Assignment> |
25 | | - <Assignment name="comment" tag="\n?(?:<!--.*?(?:-->\n?|$))+" regex="true" /> |
26 | | - <Assignment name="xmltag" tag="<(\w+)(?= |>)" regex="true"> |
| 24 | + <Reference name="comment" /> |
| 25 | + <Assignment tagName="onlyinclude" tag="</onlyinclude>"> |
27 | 26 | <Sequence> |
28 | | - <Assignment name="attr"> |
29 | | - <Reference name="main" /> |
30 | | - </Assignment> |
| 27 | + <Reference name="main" /> |
| 28 | + <Choice failSafe="true"> |
| 29 | + <Assignment tagName="endtag" tag="<onlyinclude>" /> |
| 30 | + </Choice> |
| 31 | + </Sequence> |
| 32 | + </Assignment> |
| 33 | + <Assignment tagName="xmltag" tag="<(?=(\w+)[\s\/>])" regex="true"> |
| 34 | + <Sequence> |
| 35 | + <Assignment tagName="name" tag="~r"> |
| 36 | + <Choice failSafe="true"> |
| 37 | + <Assignment tagName="attr" tag="\s+" regex="true"> |
| 38 | + <Reference name="main" /> |
| 39 | + </Assignment> |
| 40 | + </Choice> |
31 | 41 | <Choice> |
32 | | - <EndTag tag="/>" /> |
33 | | - <Assignment name="inner" tag=">"> |
| 42 | + <Assignment tagName="endtag" tag="/>" /> |
| 43 | + <Assignment tagName="inner" tag=">"> |
34 | 44 | <Reference name="endText" var="</~r>" /> |
35 | 45 | </Assignment> |
36 | 46 | </Choice> |
— | — | @@ -38,24 +48,45 @@ |
39 | 49 | </Text> |
40 | 50 | <Sequence name="endText"> |
41 | 51 | <Reference name="main" /> |
42 | | - <EndTag tag="~r" /> |
| 52 | + <Assignment tagName="endtag" tag="~r" /> |
43 | 53 | </Sequence> |
| 54 | + <Choice name="ignoreList" failSafe="true"> |
| 55 | + <Sequence> |
| 56 | + <Choice> |
| 57 | + <Assignment name="whitespace" tag="[ \t]+" regex="true" /> |
| 58 | + <Reference name="comment" /> |
| 59 | + </Choice> |
| 60 | + <Reference name="ignoreList" /> |
| 61 | + </Sequence> |
| 62 | + </Choice> |
| 63 | + <Assignment name="newLine" tag="\n"> |
| 64 | + <Choice failSafe="true"> |
| 65 | + <Reference name="heading" /> |
| 66 | + </Choice> |
| 67 | + </Assignment> |
| 68 | + <Sequence name="heading"> |
| 69 | + <Assignment tagName="h" tag="(={1,6})" regex="true"> |
| 70 | + <Reference name="endText" /> |
| 71 | + </Assignment> |
| 72 | + <Reference name="ignoreList" /> |
| 73 | + <Reference name="newLine" /> |
| 74 | + </Sequence> |
44 | 75 | <Sequence name="tplSeq"> |
45 | | - <Assignment name="title"> |
| 76 | + <Assignment tagName="title"> |
46 | 77 | <Reference name="main" /> |
47 | 78 | </Assignment> |
48 | 79 | <Reference name="partList" /> |
49 | | - <EndTag tag="~r" /> |
| 80 | + <Assignment tagName="endtag" tag="~r" /> |
50 | 81 | </Sequence> |
51 | 82 | <Choice name="partList" failSafe="true"> |
52 | 83 | <Sequence> |
53 | | - <Assignment name="part" tag="|"> |
| 84 | + <Assignment tagName="part" tag="|"> |
54 | 85 | <Sequence> |
55 | | - <Assignment name="first"> |
| 86 | + <Assignment tagName="first"> |
56 | 87 | <Reference name="main" /> |
57 | 88 | </Assignment> |
58 | 89 | <Choice failSafe="true"> |
59 | | - <Assignment name="value" tag="="> |
| 90 | + <Assignment tagName="value" tag="="> |
60 | 91 | <Reference name="main" /> |
61 | 92 | </Assignment> |
62 | 93 | </Choice> |
— | — | @@ -64,4 +95,5 @@ |
65 | 96 | <Reference name="partList" /> |
66 | 97 | </Sequence> |
67 | 98 | </Choice> |
| 99 | + <Assignment name="comment" tagName="comment" tag="<!--.*?(?:-->|$)" regex="true" /> |
68 | 100 | </Grammar> |
Index: branches/parser-work/phase3/includes/AutoLoader.php |
— | — | @@ -443,7 +443,6 @@ |
444 | 444 | 'LinkHolderArray' => 'includes/parser/LinkHolderArray.php', |
445 | 445 | 'LinkMarkerReplacer' => 'includes/parser/Parser_LinkHooks.php', |
446 | 446 | 'OnlyIncludeReplacer' => 'includes/parser/Parser.php', |
447 | | - 'PPCustomFrame' => 'includes/parser/Preprocessor.php', |
448 | 447 | 'PPFrame' => 'includes/parser/Preprocessor.php', |
449 | 448 | 'PPTemplateFrame' => 'includes/parser/Preprocessor.php', |
450 | 449 | 'ParseEngine' => 'includes/parser/ParseEngine.php', |
— | — | @@ -453,7 +452,6 @@ |
454 | 453 | 'ParserOutput' => 'includes/parser/ParserOutput.php', |
455 | 454 | 'Parser_DiffTest' => 'includes/parser/Parser_DiffTest.php', |
456 | 455 | 'Parser_LinkHooks' => 'includes/parser/Parser_LinkHooks.php', |
457 | | - 'Preprocessor' => 'includes/parser/Preprocessor.php', |
458 | 456 | 'StripState' => 'includes/parser/Parser.php', |
459 | 457 | 'MWTidy' => 'includes/parser/Tidy.php', |
460 | 458 | |