xianzhe18/bibtex-handler

BibTex 解析器提供了一个 API,用于以编程方式读取 .bib 文件(从 renanbr/bibtex-parser 分支出来)

2.0.8 2019-11-12 05:47 UTC

This package is auto-updated.

Last update: 2024-09-12 16:45:01 UTC


README

这是从 renanbr/bibtex-parser 分支出来的。

这是一个用 PHP 编写的 BibTeX 处理器。

BibTeX logo PHP logo

目录

安装

composer require xianzhe18/bibtex-handler

用法

use Xianzhe18\BibTexParser\Listener;
use Xianzhe18\BibTexParser\Parser;

require 'vendor/autoload.php';

$bibtex = <<<BIBTEX
@article{einstein1916relativity,
  title={Relativity: The Special and General Theory},
  author={Einstein, Albert},
  year={1916}
}
BIBTEX;

$parser = new Parser();          // Create a Parser
$listener = new Listener();      // Create and configure a Listener
$parser->addListener($listener); // Attach the Listener to the Parser
$parser->parseString($bibtex);   // or parseFile('/path/to/file.bib')
$entries = $listener->export();  // Get processed data from the Listener

print_r($entries);

这将输出

Array
(
    [0] => Array
        (
            [type] => article
            [citation-key] => einstein1916relativity
            [title] => Relativity: The Special and General Theory
            [author] => Einstein, Albert
            [year] => 1916
        )
)

词汇表

BibTeX 主要关于 "条目"、"标签名称" 和 "标签内容"。

BibTeX 条目 由类型(@后面的词)、一个引用键和定义特定 BibTeX 条目各种特性的多个标签组成。(...) BibTeX 标签 由其 名称 后跟一个等号和 内容 指定。

来源:http://www.bibtex.org/Format/

注意:此库将 "类型" 和 "引用键" 视为标签。此行为可以通过实现自己的监听器来更改(更多信息请参阅本文档末尾)。

处理器

Processor 是一个接收条目作为参数并返回修改后条目的 可调用

此库包含三个主要部分

  • Parser 类,负责检测 BibTeX 输入中的单元;
  • Listener 类,负责收集单元并将它们转换为条目列表;
  • Processor 类,负责操作条目。

尽管您不能配置 Parser,但您可以通过 Listener::addProcessor() 在导出内容之前将任意数量的 Processor 添加到 Listener 中。请注意,Listener 默认提供以下功能

  • 通过 Listener::export() 方法可访问找到的条目;
  • 标签内容连接;
    • 例如,hello # " world" 标签的内容将生成 hello world 字符串
  • 标签内容缩写处理;
    • 例如,@string{foo="bar"} @misc{bar=foo} 将使 $entries[1]['bar'] 假设 bar 为值
  • 出版物类型作为 type 标签公开;
  • 引用键作为 citation-key 标签公开;
  • 原始条目文本作为 _original 标签公开。

此项目附带了一些有用的处理器。

标签名称大小写

BibTeX 中标签名称不区分大小写。此库以 数组 的形式公开条目,其中键区分大小写。为了避免这种误解,您可以使用 TagNameCaseProcessor 强制标签名称字符大小写。

use Xianzhe18\BibTexParser\Processor\TagNameCaseProcessor;

$listener->addProcessor(new TagNameCaseProcessor(CASE_UPPER)); // or CASE_LOWER
@article{
  title={BibTeX rocks}
}
Array
(
    [0] => Array
        (
            [TYPE] => article
            [TITLE] => BibTeX rocks
        )
)

作者和编辑者

BibTeX 识别作者姓名的四个部分:First Von Last Jr. 如果您想解析包含在条目中的 authoreditor 标签,可以使用 NamesProcessor 类。

use Xianzhe18\BibTexParser\Processor\NamesProcessor;

$listener->addProcessor(new NamesProcessor());
@article{
  title={Relativity: The Special and General Theory},
  author={Einstein, Albert}
}
Array
(
    [0] => Array
        (
            [type] => article
            [title] => Relativity: The Special and General Theory
            [author] => Array
                (
                    [0] => Array
                        (
                            [first] => Albert
                            [von] =>
                            [last] => Einstein
                            [jr] =>
                        )
                )
        )
)

关键词

keywords 标签包含表示为 字符串 的表达式列表,您可能希望将它们读取为 数组

use Xianzhe18\BibTexParser\Processor\KeywordsProcessor;

$listener->addProcessor(new KeywordsProcessor());
@misc{
  title={The End of Theory: The Data Deluge Makes the Scientific Method Obsolete},
  keywords={big data, data deluge, scientific method}
}
Array
(
    [0] => Array
        (
            [type] => misc
            [title] => The End of Theory: The Data Deluge Makes the Scientific Method Obsolete
            [keywords] => Array
                (
                    [0] => big data
                    [1] => data deluge
                    [2] => scientific method
                )
        )
)

LaTeX 到 Unicode

BibTeX文件存储LaTeX内容。你可能希望以Unicode格式读取它们。 LatexToUnicodeProcessor类解决了这个问题,但在将处理器添加到监听器之前,你必须

use Xianzhe18\BibTexParser\Processor\LatexToUnicodeProcessor;

$listener->addProcessor(new LatexToUnicodeProcessor());
@article{
  title={Caf\\'{e}s and bars}
}
Array
(
    [0] => Array
        (
            [type] => article
            [title] => Cafés and bars
        )
)

注意:顺序很重要,请将此处理器作为最后一个添加。

自定义

Listener::addProcessor()方法期望一个可调用参数。在下面的示例中,我们将文本with laser追加到所有条目的title标签中。

$listener->addProcessor(function (array $entry) {
    $entry['title'] .= ' with laser';
    return $entry;
});
@article{
  title={BibTeX rocks}
}
Array
(
    [0] => Array
        (
            [type] => article
            [title] => BibTeX rocks with laser
        )
)

将条目转换回 bibTex

此库可以将条目转换回bibTex格式。

$parser = new Parser();          // Create a Parser
$listener = new Listener();      // Create and configure a Listener

$listener->addProcessor(function (array $entry) { // Custom processor
    $entry['some-key'] = 'some-value';
    return $entry;
});

$parser->addListener($listener); // Attach the Listener to the Parser
$parser->parseString($bibtex);   // or parseFile('/path/to/file.bib')
$entries = $listener->export();  // Get processed data from the Listener

$newBibtex = $parser->convertIntoBibTex($entries);

echo $newBibtex;
Array
(
    [0] => Array
        (
            [type] => article
            [citation-key] => STEEL081011
            [author] => Steel
        )
)

$parser = new Parser();          // Create a Parser

$bibtex = $parser->convertIntoBibTex($entries);

echo $newBibtex;
@article{STEEL081011,
  author={Steel}
}

处理错误

此库抛出两种类型的异常:ParserExceptionProcessorException。第一种异常可能在数据提取期间发生。当它发生时,可能意味着解析的BibTeX无效。第二种异常可能在数据处理期间抛出。当它发生时,意味着监听器的处理器不能正确处理找到的数据。两者都实现了ExceptionInterface

use Xianzhe18\BibTexParser\Exception\ExceptionInterface;
use Xianzhe18\BibTexParser\Exception\ParserException;
use Xianzhe18\BibTexParser\Exception\ProcessorException;

try {
    // ... parser and listener configuration

    $parser->parseFile('/path/to/file.bib');
    $entries = $listener->export();
} catch (ParserException $exception) {
    // The BibTeX isn't valid
} catch (ProcessorException $exception) {
    // Listener's processors aren't able to handle data found
} catch (ExceptionInterface $exception) {
    // Alternatively, you can use this exception to catch all of them at once
}

高级用法

此库的核心由以下类组成

  • Xianzhe18\BibTexParser\Parser:负责检测BibTeX输入内的单元;
  • Xianzhe18\BibTexParser\ListenerInterface:负责处理找到的单元。

您可以通过Parser::addListener()将监听器附加到解析器上。解析器能够检测BibTeX单元,例如“类型”、“标签名称”、“标签内容”。当解析器找到一个单元时,会触发监听器。

您可以编写自己的监听器!您需要做的只是处理单元。

interface Xianzhe18\BibTexParser\ListenerInterface
{
    /**
     * Called when an unit is found.
     *
     * @param string $text    The original content of the unit found.
     *                        Escape character will not be sent.
     * @param string $type    The type of unit found.
     *                        It can assume one of Parser's constant value.
     * @param array  $context Contains details of the unit found.
     */
    public function bibTexUnitFound($text, $type, array $context);
}

$type可能具有以下值之一

  • Parser::TYPE
  • Parser::CITATION_KEY
  • Parser::TAG_NAME
  • Parser::RAW_TAG_CONTENT
  • Parser::BRACED_TAG_CONTENT
  • Parser::QUOTED_TAG_CONTENT
  • Parser::ENTRY

$context是一个具有以下键的数组

  • offset包含$text的开始位置。例如,它可以用于在文件指针上定位
  • length包含原始$text的长度。它可能与发送给监听器的字符串长度不同,因为可能存在转义字符。