This adds a test for numbers like "1.2.0" that appear when an extended
reference (e.g. "1.2.") is reused multiple times.
The first separator is from the extended reference. We decided to never
localize it. However, the second seperator is from reusing a reference.
This was always localized. We believe this is a bug, but haven't fixed
it yet.
The test is documenting the status quo "1.2,0" with a comma. This kind
of makes sense, one could argue, because the "1.2" appears like this up
in the text, but the ",0" is a different indicator for a reuse, which
*never* occurs in the text.
Change-Id: Ie3d26bcadd8929b906bfbcac4806af2150d61f2a
Before, this regular expression was looking for incomplete wikitext
like this:
<ref>unclosed
<ref>closed</ref>
With this change, wikitext like this will trigger the same error:
<ref>unclosed
<references />
incomplete</ref>
This should be much, much more rare. But I feel it's reasonable to mark
this as an error, instead of just rendering the broken inner tag in
plain text.
This patch also replaces `.*?>` with `[^>]*+>`. Both do the exact same.
Instead of doing an "ungreedy search for the first possible closing
bracket", which might cause backtracking, the new syntax consumes all
non-brackets before expecting one. This is guaranteed to never backtrack
(guaranteed by the extra +), and potentially faster because of this.
Change-Id: Ic76a52cd111b28e4522f095ce3984e3583f602c1
The concept "key" already exists in the structure handled by this
function, so to have a $key which means something else was distracting.
Change-Id: I91a76edbb42a1ab6514bc706b75ab89f78539fa5
This partly reverts Ied2e3f5. I haven't properly tested this before.
Rendering a bad extends (that extends a <ref> that's already extended)
not indented messes the order up and rips other extended <ref>s out of
context.
For now it might be better to stick to the previous, "magic" behavior:
Such an extends behaves like it is extending the *parent*, and is
ordered and indented as such. This is still not correct, but I feel
this is much better than rendering such a bad extends on the top level.
This patch also makes the code fail much earlier for a nested extends,
if this decision can be made already. In this case the error message is
rendered in the middle of the text (as other errors also are), not in
the <references> section.
Change-Id: I33c6a763cd6c11df09d10dfab73f955ed15e9d36
This partly reverts Id7a4036e64920acdeccb4dfcf6bef31d0e5657ab.
The message "cite_section_preview_references" says "Preview of references".
This line is not meant to be part of the content, but an interface message.
It should use the users (interface) language, not the content language.
Change-Id: I1b1b5106266606eb0dfaa31f4abd3cee9ba92e8c
This simplifies as well as fixes a series of issues with this regular
expression:
* Before, the wikitext `<REF><REF>` would not trigger the error, but
`<ref><ref>` would. Parser tags are case-insensitive, but the error
check was not.
* Before, the wikitext `<ref><ref name="<">` would not trigger the error.
That's a valid name. The error check should not stop just because it
found a `<`.
* Both the old and the new code do *not* fail with the wikitext
`<ref><ref</ref>` where the inner `<ref` does not have a closing `>`. I
was thinking about changing this, but figured it might be used as a
feature.
* The old code was not able to properly understand HTML comments,
<nowiki> tags and such that contain a line break. That caused
inconsistent and confusing error reporting in some cases, but not in
others. This change *reduces* the amount of errors this code produces.
* The old code was looking for "SGML tags" with names that could be
anything, not just alphanumeric characters. This allowed for strange
edge-cases like `<ref><>><ref></>></ref>` that have not been reported,
but should be. This change *increases* the amount of errors. However,
relevant edge-cases should be extremely rare.
Note the ++ avoids backtracking, speeding up the regex.
Change-Id: I0c61a245f4f743871b4cad886ce239650af2b37c
We never access Language directly, so proxy its method instead of
returning the full object.
I believe I've found a bug, but not fixing here: the footnote body
numeric backlinks like "2.1" behave as if they were decimals rather
than two numbers stuck together with a dot. So they are localized
to "2,1".
Bug: T239725
Change-Id: If386bf96d48cb95c0a287a02bedfe984941efe30
I was able to track this code down to I093d85d from 2012, which was done
right after the ParserAfterParse hook was introduced. I believe the
redundant code path was left to keep the Cite extension compatible with
old MediaWiki versions that did not had this hook yet.
I also noticed this code path is most probably entirely redundant with
the current version of MediaWiki. The *only* thing this code does is
blocking the ParserBeforeTidy hook from doing the same thing a second
time if the ParserAfterParse hook was called before. But it does *not*
block any other compination, e.g. if the two hooks are called the other
way around, or the same hook twice.
In core, it looks like it is impossible for the ParserBeforeTidy hook
being fired without the ParserAfterParse hook being fired before. If this
is true, this is in fact dead code.
Change-Id: Iacf8b600c7abdeaf89c22c2fc31e646f57245e47
Encapsulate the language interfaces, this will be used to replace
global wfMessage calls in future patches.
Change-Id: I7857f3e5154626e0b29977610b81103d91615f65
This makes it obvious that our function isn't sensitive to the input value.
Also rearranges a string concatenation to make the element wrapping clearer.
I probably should have switched to the HTML class here, but I'm not sure what
the advantages would be.
Change-Id: Ife3424ce68588f73f168b10e63e6cd81c4a60084
The new extends="…" feature is using numbers like "1.2". These should be
localized in languages like Hebrew that uses other symbols for the digits.
But the "." should not change.
The existing feature when a <ref> is reused multiple times does have the
same "issue". But it seems this is intentional, because it is covered by
a test. Note this is not visible in German, because German uses custom
labels "a", "b", and so on.
This patch also improves the so called "smoke" tests and makes one cover
numbers up to "1,10" for a <ref> that is reused that often.
Bug: T239725
Change-Id: Iffcb56e1c7be09cefed9dabb1d6391eb6ad995ce
* Don't use string comparisons to compare numbers.
* Avoid isset() for variables that are guaranteed to exist.
* Inline two small "gen…" functions that are only called once.
* Move the fallback code path out of getLinkLabel(). Before it was
always called. Now it's only called when needed.
Change-Id: I42073f57f21d32c7936954da776ef3a393410020
If `extends` is encountered before the parent ref, we reserve the
sequence number and leave a placeholder to record the link between
ref name and number. This is necessary to render a list like,
"[1] [2.1] [2]", or to use subreferencing when the parent ref is
declared in the references tag.
When a placeholder is encountered during references section rendering,
it means that the parent was never declared.
Change-Id: I611cd1d73f775908926a803fae90d039ce122ab6
Pass the full ref structure from ReferenceStack to FootnoteMarkFormatter,
to give it control over the final rendering. This is aligned with how
the FootnoteBodyFormatter directly scans over groupRefs.
Change-Id: I3294fd9366f01daa4250a5d481f4adbae84c72b1
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
This was a bug which would affect book references, if the same group
and parent ref name combination occur twice in an article.
Change-Id: I608f58aac0cec31c8650835fc80195a87bc851d3
This patch does two things:
* Add strict PHP 7 type hints to most code.
* Narrow the interface of the checkRefsNoReferences() method to not
require a ParserOptions object any more.
Change-Id: I91c6a2d9b76915d7677a3f735ee8e054c898fcc5
This fixes a FIXME I left in the code. Previously, I just stripped the
closing </li> to make sure the nested <ol> is *inside* of the <li>.
This relies on (Remex) Tidy to clean the incomplete HTML up.
This patch remembers the stripped </li> and adds it back.
This also makes sure the nested <ol> is closed, even if it was the
last element in the data structure.
Notice how this does not influence any test. I find this a bit
confusing. It looks like (Remex) Tidy is executed, even if the tests
are not marked as "html/php+tidy".
Bug: T237241
Change-Id: Idb804df46dc24406d6bba40414675b6ff4812d48
The "no key" error should have been unreachable, but I'm afraid that
null `$text` and empty string `$text` were reporting slightly different errors.
Unfortunately, we still have to care about `$text = '0'` because PHP, so
the expressions don't reduce to `if ( !$text ...`
Change-Id: Id1028611ec3bc462dca413f31f7f59637bd7cc7b
There was a call in the API that was *not* using normalizeKey(). Now
that the API is gone, we can inline this.
This patch also contains a bunch of cleanups that might already been
resolved in the previous patches.
Change-Id: Id3767b5830268c8cfe9c10efabfa4a31e9dafeb8
Forked from Icd933fc983.
Bugs and unimplemented features are documented as TODOs in the parser test
fixtures.
Bug: T237241
Change-Id: I9427e025ea0bcf2fa24fd539a775429cc64767cc
This API was never used in Wikimedia production, and would have caused
performance problems. Removing the dead code will simplify our refactoring.
Bug: T238195
Change-Id: I7088f257ec034c0d089e0abdaa5a739910598300
This is motivated by I9427e025e, which demonstrates that the existing
logic was hard to integrate into. There's a lot of redundant expressions
which make the function difficult to read, and code paths which have
less effect than they appear to.
Change-Id: Ida9612d1457f2593647b8fc02930d2e9ae824814
We realized the trim() are not needed. This does not leave much behind
in the existing refArg() method, except that it checks for unknown keys.
I tried a few strategies and ended using the pretty new possibility to
have keys in list(), as well as use [] instead of list(). Both is
supported since PHP 7.1.
Change-Id: I569bfa14e68b64402519bd39022c197553881dde
We noticed the group="…" attribute was the only one that was not
trimmed. Does this mean it was possible to have two groups "a" and
" a"? It turns out: no. This was never possible because the parser
already trims all attributes before calling this code.
I tried to come up with the worst possible test case, but it succeeds,
even with very old versions of this codebase.
I suggest to remove the extra trimming from this codebase and rely on
what the parser provides.
Note the content is special and *not* trimmed by default.
Change-Id: Idff015447d7156ba7b5c03a5c423f199a71349f2
Functional changes:
* hasGroup() will return false when a group exists, but is empty. This
is in line with what other methods like getGroups() already do.
Shouldn't have any effect on the existing code, but feels more clean
and consistent.
* getGroupRefs() won't fail any more when asked for an unknown group.
Tests:
* Add missing @covers for the constructor.
* Simplify test setup by always returning a spy. All tests need it
anyway.
* Cover 3 more methods.
Change-Id: Ie93e9af6258b757d842b30b0b059344733aad434
That was annoying me. Since we're passing a bare list, alphabetical
order helps make the code and tests readable.
Change-Id: I6384094e429e0e2a6fa810fdc28ae0643a0ccf7c
This is invalid, because it would allow access to internal, autoindexed,
anonymous refs. These would break when refs are reordered.
Bug: T151305
Change-Id: Ib4bb8270d810b64e4c160f377ce52ce2fc70bab4
This introduces a slight behavior change, but for the better:
* When pointing to the name "0", the non-numeric error will be displayed,
which is correct whereas "no key" is not.
Change-Id: I33467b27cd447812fe67204831909c4d9869db08
Validation logic can be split from arg parsing, default values and
other side-effects.
No behavior was changed.
Change-Id: I2d9904b7631d0d6be13e0aaed0106f186d388c4f
Most of this state is used to manage interactions with other state,
and encapsulation allows us to hide data structures and access behind
self-explanatory function names.
The interface is still much wider than I'd like, but it can be improved in
future work.
There is one small behavior change in here: in the `follows` edge case
demonstrated by I3bdf26fd14, we prepend if the splice point cannot be
used because it has a non-numeric key. I believe this was the original
intention of the logic, and is how the numeric case behaves. I've verified
that when array_splice throws a warning about non-numeric key, it fails to
add anything to the original array, so the broken follows ref disappeared.
Bug: T237241
Change-Id: I091a0b71ee9aa78e841c2e328018e886a7217715