From 3f276388bffb67034d76795b8f130b2143ecea55 Mon Sep 17 00:00:00 2001 From: Adam Wight Date: Sat, 30 Nov 2019 00:10:11 +0100 Subject: [PATCH] Split ref.number field This was carrying the entire footnote marker, but subreferences need to extract just the first (group ref sequence) part. Storing number and extendsIndex in two separate fields gives us more flexibility during rendering, for example these might use two different symbol sets. Change-Id: I75bd6644c336036f9e84ba91e1c35e05bc1ca7f3 --- src/FootnoteBodyFormatter.php | 3 +- src/ReferenceStack.php | 38 ++++++++------- tests/parser/bookReferencing.txt | 10 ++-- tests/phpunit/unit/ReferenceStackTest.php | 56 +++++++++++++---------- 4 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/FootnoteBodyFormatter.php b/src/FootnoteBodyFormatter.php index 1b5eef8c5..8c67f2773 100644 --- a/src/FootnoteBodyFormatter.php +++ b/src/FootnoteBodyFormatter.php @@ -175,7 +175,8 @@ class FootnoteBodyFormatter { 'cite_references_link_many_format', $this->citeKeyFormatter->refKey( $key, $val['key'] . '-' . $i ), $this->referencesFormatEntryNumericBacklinkLabel( - $val['number'], + $val['number'] . + ( isset( $val['extendsIndex'] ) ? '.' . $val['extendsIndex'] : '' ), $i, $val['count'] ), diff --git a/src/ReferenceStack.php b/src/ReferenceStack.php index dd9e8311f..4c7702618 100644 --- a/src/ReferenceStack.php +++ b/src/ReferenceStack.php @@ -165,27 +165,13 @@ class ReferenceStack { return null; } - if ( $extends !== null ) { - if ( isset( $this->refs[$group][$extends] ) ) { - $this->extendsCount[$group][$extends] = - ( $this->extendsCount[$group][$extends] ?? 0 ) + 1; - - $ref['extends'] = $this->groupRefSequence[$group] . '.' . $this->extendsCount[$group][$extends]; - } else { - // TODO: check parent existence in a second, pre-render stage of validation. - // This should be an error, not silent degradation. - $extends = null; - } - } - if ( !$name ) { // This is an anonymous reference, which will be given a numeric index. - $this->refs[$group][] = $ref; + $this->refs[$group][] =& $ref; $action = 'new'; } elseif ( !isset( $this->refs[$group][$name] ) ) { // Valid key with first occurrence - $ref['number'] = $ref['extends'] ?? ++$this->groupRefSequence[$group]; - $this->refs[$group][$name] = $ref; + $this->refs[$group][$name] =& $ref; $action = 'new'; } else { // Change an existing entry. @@ -215,11 +201,29 @@ class ReferenceStack { $action = 'increment'; } } + + $ref['number'] = $ref['number'] ?? ++$this->groupRefSequence[$group]; + + if ( $extends ) { + if ( isset( $this->refs[$group][$extends] ) ) { + $ref['extends'] = $extends; + $ref['extendsIndex'] = $this->extendsCount[$group][$extends] = + ( $this->extendsCount[$group][$extends] ?? 0 ) + 1; + + $ref['number'] = $this->refs[$group][$extends]['number']; + } else { + // TODO: check parent existence in a second, pre-render stage of validation. + // This should be an error, not silent degradation. + $extends = null; + } + } + $this->refCallStack[] = [ $action, $argv, $text, $name, $extends, $group, $ref['key'] ]; return [ $name ?? $ref['key'], $name ? $ref['key'] . '-' . $ref['count'] : null, - $ref['extends'] ?? $ref['number'] ?? ++$this->groupRefSequence[$group], + $ref['number'] . + ( isset( $ref['extendsIndex'] ) ? '.' . $ref['extendsIndex'] : '' ), $name ? '-' . $ref['key'] : null ]; } diff --git a/tests/parser/bookReferencing.txt b/tests/parser/bookReferencing.txt index c66686928..44c5e6f56 100644 --- a/tests/parser/bookReferencing.txt +++ b/tests/parser/bookReferencing.txt @@ -152,11 +152,11 @@ wgCiteBookReferencing=true !! html/php

[1] [1.1] -[1.1] +[1.2]

  1. book -
    1. 1.1.0 1.1.1 page 2 Cite error: Invalid <ref> tag; name "b" defined multiple times with different content +
      1. 1.2.0 1.2.1 page 2 Cite error: Invalid <ref> tag; name "b" defined multiple times with different content
@@ -454,9 +454,9 @@ Extends defined in called with #tag

  1. BAR +
    1. p. 10
    2. -
    3. p. 10 -
    4. +
!! end @@ -534,7 +534,7 @@ wgCiteBookReferencing=true !! html/php

[1] [2] -[2.1] +[1.1]

  1. book diff --git a/tests/phpunit/unit/ReferenceStackTest.php b/tests/phpunit/unit/ReferenceStackTest.php index 0e9d94875..9b95bfa7b 100644 --- a/tests/phpunit/unit/ReferenceStackTest.php +++ b/tests/phpunit/unit/ReferenceStackTest.php @@ -62,7 +62,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text', null, '', null, null, [], 'rtl' ] ], [ - [ 1, null, 1, null ] + [ 1, null, '1', null ] ], [ '' => [ @@ -72,6 +72,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 1, 'name' => null, 'text' => 'text', + 'number' => 1, ] ] ], @@ -84,7 +85,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text', null, 'foo', null, null, [], 'rtl' ] ], [ - [ 1, null, 1, null ] + [ 1, null, '1', null ] ], [ 'foo' => [ @@ -94,6 +95,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 1, 'name' => null, 'text' => 'text', + 'number' => 1, ] ] ], @@ -106,7 +108,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text', null, 'foo', null, null, [], 'rtl' ] ], [ - [ 1, null, 1, null ] + [ 1, null, '1', null ] ], [ 'foo' => [ @@ -116,6 +118,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 1, 'name' => null, 'text' => 'text', + 'number' => 1, ] ] ], @@ -128,7 +131,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text', 'name', 'foo', null, null, [], 'rtl' ] ], [ - [ 'name', '1-0', 1, '-1' ] + [ 'name', '1-0', '1', '-1' ] ], [ 'foo' => [ @@ -152,7 +155,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-b', 'b', 'foo', null, 'a', [], 'rtl' ] ], [ - [ 'a', '1-0', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], null ], [ @@ -201,9 +204,9 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-c', 'c', 'foo', null, null, [], 'rtl' ] ], [ - [ 'a', '1-0', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], null, - [ 'c', '3-0', 2, '-3' ], + [ 'c', '3-0', '2', '-3' ], ], [ 'foo' => [ @@ -245,8 +248,8 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ null, 'a', 'foo', null, null, [], 'rtl' ] ], [ - [ 'a', '1-0', 1, '-1' ], - [ 'a', '1-1', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], + [ 'a', '1-1', '1', '-1' ], ], [ 'foo' => [ @@ -271,8 +274,8 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text', 'a', 'foo', null, null, [], 'rtl' ] ], [ - [ 'a', '1-0', 1, '-1' ], - [ 'a', '1-1', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], + [ 'a', '1-1', '1', '-1' ], ], [ 'foo' => [ @@ -297,8 +300,8 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-2', 'a', 'foo', null, null, [], 'rtl' ] ], [ - [ 'a', '1-0', 1, '-1' ], - [ 'a', '1-1', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], + [ 'a', '1-1', '1', '-1' ], ], [ 'foo' => [ @@ -322,7 +325,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-a', 'a', 'foo', 'b', null, [], 'rtl' ], ], [ - [ 'a', '1-0', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], ], [ 'foo' => [ @@ -346,8 +349,8 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-b', 'b', 'foo', null, null, [], 'rtl' ], ], [ - [ 'a', '1-0', 1, '-1' ], - [ 'b', '2-0', 2, '-2' ], + [ 'a', '1-0', '1', '-1' ], + [ 'b', '2-0', '2', '-2' ], ], [ 'foo' => [ @@ -380,7 +383,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-b', 'b', 'foo', 'a', null, [], 'rtl' ], ], [ - [ 'a', '1-0', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], [ 'b', '2-0', '1.1', '-2' ], ], [ @@ -399,8 +402,9 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 2, 'name' => 'b', 'text' => 'text-b', - 'extends' => '1.1', - 'number' => '1.1', + 'number' => 1, + 'extends' => 'a', + 'extendsIndex' => 1, ] ] ], @@ -414,7 +418,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-a', null, 'foo', 'b', null, [], 'rtl' ], ], [ - [ 1, null, 1, null ], + [ 1, null, '1', null ], ], [ 'foo' => [ @@ -424,6 +428,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 1, 'name' => null, 'text' => 'text-a', + 'number' => 1, ], ] ], @@ -437,8 +442,8 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-b', 'b', 'foo', null, null, [], 'rtl' ], ], [ - [ 1, null, 1, null ], - [ 'b', '2-0', 2, '-2' ], + [ 1, null, '1', null ], + [ 'b', '2-0', '2', '-2' ], ], [ 'foo' => [ @@ -448,6 +453,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 1, 'name' => null, 'text' => 'text-a', + 'number' => 1, ], 'b' => [ 'count' => 0, @@ -470,7 +476,7 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { [ 'text-b', null, 'foo', 'a', null, [], 'rtl' ], ], [ - [ 'a', '1-0', 1, '-1' ], + [ 'a', '1-0', '1', '-1' ], [ 2, null, '1.1', null ], ], [ @@ -489,7 +495,9 @@ class ReferenceStackTest extends MediaWikiUnitTestCase { 'key' => 2, 'name' => null, 'text' => 'text-b', - 'extends' => '1.1', + 'number' => 1, + 'extends' => 'a', + 'extendsIndex' => 1, ] ] ],