seboettg / citeproc-php

Full-featured CSL 1.0.1 processor for PHP
MIT License
75 stars 39 forks source link

Extra field (CSL note) is not parsed for addional variables #164

Open glorieux-f opened 1 year ago

glorieux-f commented 1 year ago

Bug reports:

CSL format allow lots of variables: https://github.com/seboettg/citeproc-php/blob/develop/src/Util/Variables.php. Production clients for records, especially Zotero, has not a specific input for all variables. It is advised in Zotero forums to add such variables in the “Extra” field, exported as the "note" variable in CSL. It seems that citeproc-php do not parse the Zotero “Extra” field.

Bad Fix

Pre-parse the “note” variable before sending json to CiteProc.

Good fix

Correct the CSL export of Zotero if these practices are officially recommended. A post has been submitted https://forums.zotero.org/discussion/106757/translators-csljson-export-csl-variables-from-extra-field

Nice fix

citeproc-php may parse the note field for known variables, like the CSL processor of Zotero.

Used CSL stylesheet:

apa.csl

Used CSL metadata

[
    {
        "id": "n1",
        "type": "article-journal",
        "container-title": "Journal",
        "note": "genre: Genre\nreviewed-title: A well known book",
        "title": "Review, produced with Zotero (extra field)",
        "author": [
            {
                "family": "Reviewer",
                "given": "Given"
            }
        ],
        "reviewed-author": [
            {
                "family": "Author",
                "given": "Reviewed"
            }
        ]
    },
    {
        "id": "n2",
        "type": "article-journal",
        "container-title": "Journal",
        "genre": "genre",
        "reviewed-title": "A well known book",
        "title": "Review with structured fields",
        "author": [
            {
                "family": "Reviewer",
                "given": "Given"
            }
        ],
        "reviewed-author": [
            {
                "family": "Author",
                "given": "Reviewed"
            }
        ]
    }
]
glorieux-f commented 1 year ago

Bad fix, prepocess the note variable before submitting to citeproc-php

<?php
include "vendor/autoload.php";
use Seboettg\CiteProc\StyleSheet;
use Seboettg\CiteProc\CiteProc;
use Seboettg\CiteProc\Util\Variables;
// build dictionary of variables to extract from extra
$variables = array_flip(array_merge(Variables::NUMBER_VARIABLES, Variables::STANDARD_VARIABLE));
unset($variables['note']);
function extraVariables($item)
{
    global $variables;
    if (!isset($item->note)) return;
    $extra = $item->note;
    $note = '';
    // preg_split keep empty lines (not strtok)
    foreach(preg_split("/((\r?\n)|(\r\n?))/", $extra) as $line){
        $pos = strpos($line, ':');
        $var = trim(substr($line,0, $pos));
        if (isset($variables[$var])) {
            $item->{$var} = trim(substr($line, $pos + 1));
        }
        else {
            $note .= $line . "\n";
        }
    }
    $note = trim($note);
    if (!$note) {
        unset($item->note);
    }
    else {
        $item->note = $note;
    }
}

$data = json_decode($json);
foreach($data as $item) {
    extraVariables($item);
}
$style = StyleSheet::loadStyleSheet("apa");
$citeProc = new CiteProc($style, "en-US", $additionalMarkup);
echo $citeProc->render($data, "bibliography");