2019-11-28 14:39:11 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Cite;
|
|
|
|
|
2024-06-08 21:31:42 +00:00
|
|
|
use MediaWiki\Parser\Parser;
|
2023-12-10 22:18:51 +00:00
|
|
|
use MediaWiki\Parser\Sanitizer;
|
2019-11-28 14:39:11 +00:00
|
|
|
|
2019-11-29 14:00:39 +00:00
|
|
|
/**
|
2023-12-15 13:27:58 +00:00
|
|
|
* Footnote markers in the context of the Cite extension are the numbers in the article text, e.g.
|
|
|
|
* [1], that can be hovered or clicked to be able to read the attached footnote.
|
|
|
|
*
|
2019-11-29 14:00:39 +00:00
|
|
|
* @license GPL-2.0-or-later
|
|
|
|
*/
|
2019-11-28 14:39:11 +00:00
|
|
|
class FootnoteMarkFormatter {
|
|
|
|
|
2023-12-12 12:07:53 +00:00
|
|
|
/** @var array<string,string[]> In-memory cache for the cite_link_label_group-… link label lists */
|
2023-06-05 14:36:03 +00:00
|
|
|
private array $linkLabels = [];
|
2023-12-12 12:07:53 +00:00
|
|
|
|
2023-06-05 14:36:03 +00:00
|
|
|
private AnchorFormatter $anchorFormatter;
|
|
|
|
private ReferenceMessageLocalizer $messageLocalizer;
|
2019-12-05 08:37:17 +00:00
|
|
|
|
2019-11-28 14:39:11 +00:00
|
|
|
public function __construct(
|
2019-12-09 16:08:57 +00:00
|
|
|
AnchorFormatter $anchorFormatter,
|
2019-12-05 08:37:17 +00:00
|
|
|
ReferenceMessageLocalizer $messageLocalizer
|
2019-11-28 14:39:11 +00:00
|
|
|
) {
|
2019-12-09 16:08:57 +00:00
|
|
|
$this->anchorFormatter = $anchorFormatter;
|
2019-12-05 08:37:17 +00:00
|
|
|
$this->messageLocalizer = $messageLocalizer;
|
2019-11-28 14:39:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a link (<sup ...) for the <ref> element from a key
|
|
|
|
* and return XHTML ready for output
|
|
|
|
*
|
|
|
|
* @suppress SecurityCheck-DoubleEscaped
|
2019-12-11 14:03:09 +00:00
|
|
|
* @param Parser $parser
|
2023-12-22 22:46:54 +00:00
|
|
|
* @param ReferenceStackItem $ref
|
2019-11-28 14:39:11 +00:00
|
|
|
*
|
2024-06-21 19:09:31 +00:00
|
|
|
* @return string HTML
|
2019-11-28 14:39:11 +00:00
|
|
|
*/
|
2024-06-21 19:18:25 +00:00
|
|
|
public function linkRef( Parser $parser, ReferenceStackItem $ref ): string {
|
2024-10-23 09:29:14 +00:00
|
|
|
$label = $this->makeLabel( $ref->group, $ref->number, $ref->extendsIndex );
|
2019-12-03 09:00:58 +00:00
|
|
|
|
2023-12-22 22:46:54 +00:00
|
|
|
$key = $ref->name ?? $ref->key;
|
2024-01-06 01:18:51 +00:00
|
|
|
// TODO: Use count without decrementing.
|
2023-12-22 22:46:54 +00:00
|
|
|
$count = $ref->name ? $ref->key . '-' . ( $ref->count - 1 ) : null;
|
|
|
|
$subkey = $ref->name ? '-' . $ref->key : null;
|
2019-11-29 23:26:58 +00:00
|
|
|
|
2019-12-11 14:03:09 +00:00
|
|
|
return $parser->recursiveTagParse(
|
2019-12-05 08:37:17 +00:00
|
|
|
$this->messageLocalizer->msg(
|
2019-11-28 14:39:11 +00:00
|
|
|
'cite_reference_link',
|
2023-12-04 07:28:22 +00:00
|
|
|
$this->anchorFormatter->backLinkTarget( $key, $count ),
|
|
|
|
$this->anchorFormatter->jumpLink( $key . $subkey ),
|
2019-12-03 09:00:58 +00:00
|
|
|
Sanitizer::safeEncodeAttribute( $label )
|
2019-12-05 08:37:17 +00:00
|
|
|
)->plain()
|
2019-11-28 14:39:11 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-10-23 09:29:14 +00:00
|
|
|
public function makeLabel( string $group, int $number, ?int $extendsIndex = null ): string {
|
|
|
|
$label = $this->fetchCustomizedLinkLabel( $group, $number ) ??
|
|
|
|
$this->makeDefaultLabel( $group, $number );
|
|
|
|
if ( $extendsIndex !== null ) {
|
|
|
|
// TODO: design better behavior, especially when using custom group markers.
|
|
|
|
$label .= '.' . $this->messageLocalizer->localizeDigits( (string)$extendsIndex );
|
2024-06-21 19:09:31 +00:00
|
|
|
}
|
|
|
|
return $label;
|
|
|
|
}
|
|
|
|
|
2024-10-23 09:29:14 +00:00
|
|
|
public function makeDefaultLabel( string $group, int $number ): string {
|
|
|
|
$label = $this->messageLocalizer->localizeDigits( (string)$number );
|
|
|
|
return $group === Cite::DEFAULT_GROUP ? $label : "$group $label";
|
2024-06-21 19:09:31 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 14:39:11 +00:00
|
|
|
/**
|
|
|
|
* Generate a custom format link for a group given an offset, e.g.
|
|
|
|
* the second <ref group="foo"> is b if $this->mLinkLabels["foo"] =
|
|
|
|
* [ 'a', 'b', 'c', ...].
|
|
|
|
* Return an error if the offset > the # of array items
|
|
|
|
*
|
2024-10-23 09:29:14 +00:00
|
|
|
* @param string $group
|
|
|
|
* @param int $number
|
2019-11-28 14:39:11 +00:00
|
|
|
*
|
2024-10-23 09:29:14 +00:00
|
|
|
* @return ?string Returns null if no custom label can be found
|
2019-11-28 14:39:11 +00:00
|
|
|
*/
|
2024-10-23 09:29:14 +00:00
|
|
|
private function fetchCustomizedLinkLabel( string $group, int $number ): ?string {
|
2023-12-12 12:07:53 +00:00
|
|
|
if ( $group === Cite::DEFAULT_GROUP ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-11-28 14:39:11 +00:00
|
|
|
$message = "cite_link_label_group-$group";
|
2023-12-12 12:07:53 +00:00
|
|
|
if ( !array_key_exists( $group, $this->linkLabels ) ) {
|
2019-12-05 08:37:17 +00:00
|
|
|
$msg = $this->messageLocalizer->msg( $message );
|
2019-12-03 09:00:58 +00:00
|
|
|
$this->linkLabels[$group] = $msg->isDisabled() ? [] : preg_split( '/\s+/', $msg->plain() );
|
2019-11-28 14:39:11 +00:00
|
|
|
}
|
2019-12-03 09:00:58 +00:00
|
|
|
|
2023-12-12 12:07:53 +00:00
|
|
|
// Expected behavior for groups without custom labels
|
2019-12-03 09:00:58 +00:00
|
|
|
if ( !$this->linkLabels[$group] ) {
|
|
|
|
return null;
|
2019-11-28 14:39:11 +00:00
|
|
|
}
|
|
|
|
|
2023-12-12 12:07:53 +00:00
|
|
|
// Error message in case we run out of custom labels
|
2024-10-23 09:29:14 +00:00
|
|
|
return $this->linkLabels[$group][$number - 1] ?? null;
|
2019-11-28 14:39:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|