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;
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc