Skip to content

Commit 956fbd6

Browse files
arlolrajenkins-bot
authored andcommitted
Rely on HeadingPFragment to set the index when inTemplate
Many tests are made metadata/integrated which will run in both the legacy parser and Parsoid in integrated mode. A test is added for T387374#12059186 to show that if a template subsumes a non-templated region with headings, the headings will still be given the appropriate indices. A test is added for T384490#10731504 to show that if the preprocessor didn't assign an index for a heading because it was on a line with leading or trailing include directives, Parsoid doesn't fill it in post-expansion. A test is added for T387520#10985986 to show that if the preprocessor didn't assign an index for a heading because it was from a parser function returning wikitext, Parsoid doesn't fill it in post-expansion. A test could be written for T387521#12060718 where a heading is generated by a Scribunto module and not assigned an index in the preprocessor but Parsoid was filling one in, but it seems the same in kind as the above and belongs more in the extension's repo if anything. Bug: T430367 Bug: T387374 Change-Id: I377e4cb8effd43ec19d891c6104973acbca14a26
1 parent 75e1c4e commit 956fbd6

7 files changed

Lines changed: 469 additions & 396 deletions

File tree

src/Fragments/HeadingPFragment.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function __construct(
3333
public function asDom( ParsoidExtensionAPI $extApi, bool $release = false ): DocumentFragment {
3434
$df = $extApi->wikitextToDOM(
3535
$this->wt,
36-
[ 'parseOpts' => [ 'expandTemplates' => false ] ],
36+
[ 'parseOpts' => [ 'expandTemplates' => false, 'inTemplate' => true ] ],
3737
true
3838
);
3939
if ( DOMUtils::isHeading( $df->firstChild ) ) {

src/Wt2Html/DOM/Processors/WrapSectionsState.php

Lines changed: 8 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
namespace Wikimedia\Parsoid\Wt2Html\DOM\Processors;
55

66
use Wikimedia\Assert\Assert;
7-
use Wikimedia\Assert\UnreachableException;
87
use Wikimedia\Parsoid\Config\Env;
98
use Wikimedia\Parsoid\Core\DOMCompat;
109
use Wikimedia\Parsoid\Core\DomSourceRange;
@@ -24,7 +23,6 @@
2423
use Wikimedia\Parsoid\Utils\DOMUtils;
2524
use Wikimedia\Parsoid\Utils\PHPUtils;
2625
use Wikimedia\Parsoid\Utils\TokenUtils;
27-
use Wikimedia\Parsoid\Utils\Utils;
2826
use Wikimedia\Parsoid\Utils\WTUtils;
2927
use Wikimedia\Parsoid\Wt2Html\Frame;
3028

@@ -92,55 +90,11 @@ private function computeSectionMetadata(
9290
$this->oldLevel = $newLevel;
9391
$dp = DOMDataUtils::getDataParsoid( $heading );
9492

95-
// Cases where the legacy preprocessor didn't tokenize a heading
96-
// don't get section edit links
97-
if ( !isset( $dp->tmp->headingIndex ) ) {
98-
$metadata->fromTitle = null;
99-
$metadata->index = '';
100-
$metadata->codepointOffset = null;
101-
} elseif ( isset( $dp->tmp->headingData ) ) {
93+
if ( isset( $dp->tmp->headingData ) ) {
10294
$metadata->fromTitle = $dp->tmp->headingData[0]->getPrefixedDBKey();
10395
$metadata->index = 'T-' . $dp->tmp->headingData[1];
10496
$metadata->codepointOffset = null;
105-
} elseif ( $this->tplInfo !== null ) {
106-
$dmw = DOMDataUtils::getDataMw( $this->tplInfo->first );
107-
$metadata->index = ''; // Match legacy parser
108-
if ( !isset( $dmw->parts ) ) {
109-
// Extension or language-variant
110-
// Need to determine what the output should be here
111-
$metadata->fromTitle = null;
112-
} elseif ( count( $dmw->parts ) > 1 ) {
113-
// Multi-part content -- cannot pick a title
114-
$metadata->fromTitle = null;
115-
} else {
116-
$p0 = $dmw->parts[0];
117-
if ( !( $p0 instanceof TemplateInfo ) ) {
118-
throw new UnreachableException(
119-
"a single part will always be a TemplateInfo not a string"
120-
);
121-
}
122-
if ( $p0->type === 'templatearg' ) {
123-
// Since we currently don't process templates in Parsoid,
124-
// this has to be a top-level {{{...}}} and so the content
125-
// comes from the current page. But, legacy parser returns 'false'
126-
// for this, so we'll return null as well instead of current title.
127-
$metadata->fromTitle = null;
128-
} elseif ( $p0->href !== null ) {
129-
// Pick template title, but strip leading "./" prefix
130-
$tplHref = Utils::decodeURIComponent( $p0->href );
131-
$metadata->fromTitle = PHPUtils::stripPrefix( $tplHref, './' );
132-
if ( $this->sectionNumber >= 0 ) {
133-
// Legacy parser sets this to '' in some cases
134-
// See "Templated sections (heading from template arg)" parser test
135-
$metadata->index = 'T-' . $this->sectionNumber;
136-
}
137-
} else {
138-
// Legacy parser return null here
139-
$metadata->fromTitle = null;
140-
}
141-
}
142-
$metadata->codepointOffset = null;
143-
} else {
97+
} elseif ( isset( $dp->tmp->headingIndex ) ) {
14498
$title = $this->env->getContextTitle();
14599
// Use the dbkey (underscores) instead of text (spaces)
146100
$metadata->fromTitle = $title->getPrefixedDBKey();
@@ -149,6 +103,12 @@ private function computeSectionMetadata(
149103
// interface expects *codepoint* counts. We are going to convert
150104
// these in a batch (for efficiency) in ::convertTOCOffsets() below
151105
$metadata->codepointOffset = $dp->dsr->start ?? null;
106+
} else {
107+
// Cases where the legacy preprocessor didn't tokenize a heading
108+
// don't get section edit links
109+
$metadata->fromTitle = null;
110+
$metadata->index = '';
111+
$metadata->codepointOffset = null;
152112
}
153113

154114
$metadata->anchor = DOMCompat::getAttribute( $heading, 'id' );

src/Wt2Html/Grammar.pegphp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ heading_preproc =
536536
spc:( space / sol_transparent )*
537537
&eolf
538538
headingIndex:<&headingIndex>
539+
noHeadingIndex:<noHeadingIndex>
539540
preproc:<&preproc>
540541
{
541542
$c = null;
@@ -600,10 +601,19 @@ heading_preproc =
600601
if (
601602
!$this->hasSOLTransparentAtStart &&
602603
!$hasSOLTransparentAtEnd &&
603-
!$hasOpenPreproc
604+
!$hasOpenPreproc &&
605+
// Don't record an index when we're in a template,
606+
// we rely on the preprocessor to add the metadata
607+
// to the HeadingPFragment
608+
empty( $this->pipelineOpts['inTemplate'] )
604609
) {
605610
$headingIndex++;
606-
$tagDP->getTemp()->headingIndex = $headingIndex;
611+
// Headings occurring in arguments to templates and
612+
// templateargs increase the heading index but don't
613+
// result in sections
614+
if ( !$noHeadingIndex ) {
615+
$tagDP->getTemp()->headingIndex = $headingIndex;
616+
}
607617
}
608618

609619
$res = [ new TagTk( 'h' . $level, [], $tagDP ) ];
@@ -1088,10 +1098,10 @@ template_param =
10881098
}
10891099

10901100
template_param_name =
1091-
template_param_text<equal> / (&'=' @"")
1101+
template_param_text<equal, noHeadingIndex> / (&'=' @"")
10921102

10931103
template_param_value =
1094-
tpt:template_param_text<equal=false>
1104+
tpt:template_param_text<equal=false, noHeadingIndex>
10951105
{
10961106
return [ 'tokens' => $tpt, 'srcOffsets' => $this->tsrOffsets() ];
10971107
}

0 commit comments

Comments
 (0)