bibcite_footnotes-8.x-1.0-beta3/src/Plugin/BibCiteProcessor/CiteprocPhpInline.php
src/Plugin/BibCiteProcessor/CiteprocPhpInline.php
<?php
namespace Drupal\bibcite_footnotes\Plugin\BibCiteProcessor;
use Seboettg\CiteProc\CiteProc;
use Seboettg\CiteProc\Data\DataList;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\bibcite\Plugin\BibCiteProcessorBase;
use Drupal\bibcite\Plugin\BibCiteProcessorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a style provider based on citeproc-php library.
*
* Extended to support inline citation links based on the CSL.
*
* @BibCiteProcessor(
* id = "citeproc-php-inline",
* label = @Translation("Citeproc PHP"),
* )
*/
class CiteprocPhpInline extends BibCiteProcessorBase implements BibCiteProcessorInterface, ContainerFactoryPluginInterface {
/**
* Config factory service.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
protected $filterSettings = [];
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory')
);
}
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->configFactory = $config_factory;
}
/**
* {@inheritdoc}
*/
public function getDescription() {
return $this->t('Render citation by citeproc-php library');
}
/**
* {@inheritdoc}
*/
public function render($data, $csl, $lang, $mode = 'citation', $citation_items = False)
{
// Use filter settings with defaults
$enableBidirectional = $this->filterSettings['enable_bidirectional_links'] ?? TRUE;
$backlinkSymbol = $this->filterSettings['backlink_symbol'] ?? '↑';
$backlinkPosition = $this->filterSettings['backlink_position'] ?? 'after';
// Static variables to track citation instances and counts
static $citationCounters = [];
static $citationInstanceMap = [];
$additionalMarkup = [
"bibliography" => [
"csl-entry" => function ($cslItem, $renderedText) use (&$citationInstanceMap, $enableBidirectional, $backlinkSymbol, $backlinkPosition) {
$entryId = $cslItem->{'id'};
$backlinks = '';
if ($enableBidirectional) {
// Find all citation instances for this bibliography item
$citationLinks = [];
if (isset($citationInstanceMap[$entryId])) {
foreach ($citationInstanceMap[$entryId] as $citationInstanceId) {
$citationLinks[] = '<a href="#' . $citationInstanceId . '" class="bibcite-backlink">' . $backlinkSymbol . '</a>';
}
}
if (!empty($citationLinks)) {
$backlinks = ' <span class="bibcite-backlinks">[' . implode(' ', $citationLinks) . ']</span>';
}
}
$entryContent = '<a id="' . $entryId . '" href="#' . $entryId . '"></a>' . $renderedText;
if ($backlinkPosition === 'before' && $backlinks) {
return $backlinks . ' ' . $entryContent;
} else {
return $entryContent . $backlinks;
}
}
],
"citation" => [
"csl-entry" => function ($cslItem, $renderedText) use (&$citationCounters, &$citationInstanceMap, $enableBidirectional) {
$entryId = $cslItem->{'id'};
if ($enableBidirectional) {
// Initialize counter for this entry if not exists
if (!isset($citationCounters[$entryId])) {
$citationCounters[$entryId] = 0;
}
// Increment counter and create unique instance ID
$citationCounters[$entryId]++;
$citationInstanceId = $entryId . '_cite_' . $citationCounters[$entryId];
// Track this citation instance
if (!isset($citationInstanceMap[$entryId])) {
$citationInstanceMap[$entryId] = [];
}
$citationInstanceMap[$entryId][] = $citationInstanceId;
return '<a id="' . $citationInstanceId . '" href="#' . $entryId . '">' . $renderedText . '</a>';
} else {
// If bidirectional links are disabled, use simple linking
return '<a href="#' . $entryId . '">' . $renderedText . '</a>';
}
}
]
];
$cite_proc = new CiteProc($csl, $lang, $additionalMarkup);
if (!$data instanceof \stdClass) {
$data = json_decode(json_encode($data));
}
if ($data instanceof \stdClass) {
$data = [$data];
}
if (is_array($citation_items)) {
$citation_items = json_decode(json_encode($citation_items));
return preg_replace('/(\\n|\r)( *)/', '', $cite_proc->render($data, $mode, $citation_items));
} else {
return preg_replace('/(\\n|\r)( *)/', '', $cite_proc->render($data, $mode));
}
}
public function renderCssStyles($csl, $lang) {
$cite_proc = new CiteProc($csl, $lang);
return $cite_proc->renderCssStyles();
}
public function setFilterSettings(array $settings) {
$this->filterSettings = $settings;
}
}
