larsgw / citation.js

Citation.js converts formats like BibTeX, Wikidata JSON and ContentMine JSON to CSL-JSON to convert to other formats like APA, Vancouver and back to BibTeX.
https://citation.js.org/
MIT License
219 stars 30 forks source link

Formatting bibliography #220

Open artt opened 2 years ago

artt commented 2 years ago

I have a Cite object bibtex and would like to format the bibliography myself.

This works:

bibtex.format('bibliography', {
    format: 'html',
    template: 'citation-apa',
    entry: Array.from(allEntries),
})

For format field, html and text work. However, when I tried other formats (e.g. object, json) I get the following error:

Cannot read properties of undefined (reading 'text_escape')

  TypeError: Cannot read properties of undefined (reading 'text_escape')

  - citeproc_commonjs.js:1069 Object.getSafeEscape
    [repo]/[citeproc]/citeproc_commonjs.js:1069:59

  - citeproc_commonjs.js:5393 CSL.Output.Queue.string
    [repo]/[citeproc]/citeproc_commonjs.js:5393:23

  - citeproc_commonjs.js:7923 CSL.Engine.CSL.getAmbiguousCite
    [repo]/[citeproc]/citeproc_commonjs.js:7923:27

  - citeproc_commonjs.js:23108 CSL.Registry.doinserts
    [repo]/[citeproc]/citeproc_commonjs.js:23108:41

  - citeproc_commonjs.js:9211 CSL.Engine.updateItems
    [repo]/[citeproc]/citeproc_commonjs.js:9211:19

  - bibliography.js:27 bibliography
    [repo]/[@citation-js]/plugin-csl/lib/bibliography.js:27:30

  - output.js:53 format
    [repo]/[@citation-js]/core/lib/plugins/output.js:53:28

  - get.js:21 Cite.format
    [repo]/[@citation-js]/core/lib/Cite/get.js:21:29
larsgw commented 2 years ago

The object and json formats are not supported for formatted bibliographies. Those are html (HTML), text (plain text), rtf (Rich Text Format), asciidoc (AsciiDoc), and fo (XSL-FO). To get the underlying data in CSL format you can use the following:

bibtex.format('data', {
    format: 'object', // 'object' for a JS Object, 'text' for a JSON string
    entry: Array.from(allEntries),
})
artt commented 2 years ago

Thanks! Is there a way to get the bibliography items sorted appropriately? Getting data, the items would be in the same order as in bibtex file.

Use case: I'm trying to customize the formatting function (add links etc.) Right now append does the trick, but asking this just in case (let's say I want to customize the color of the title). Another way is to allow a function to be passed in as format. That would be super flexible.

larsgw commented 2 years ago

Is there a way to get the bibliography items sorted appropriately?

Not directly but something like this should work to get a sorted list of IDs:

// Format entries normally but with the asEntryArray option
const formattedEntries = bibtex.format('bibliography', {
    format: 'html',
    template: 'apa', // not citation-apa btw
    entry: Array.from(allEntries),
    asEntryArray: true,
})

// Get sorted ids from sorted entries
const sortedIds = formattedEntries.map(function () {
    // entry[0] is the id, entry[1] is the formatted entry
    return entry[0]
})

// Look up the original entries
const data = bibtex.format('data', { type: 'object' }) // (or bibtex.data but then you miss some processing)
const dataById = data.reduce((ids, entry) => { ids[entry.id] = entry }, {})
const sortedData = sortedIds.map(id => dataById[id])

let's say I want to customize the color of the title

There is some interest among the CSL and citeproc-js maintainers to make those things possible but nobody has started to implement it. There is a way to do something similar, a development mode made for https://editor.citationstyles.org/visualEditor/ I think but when I looked at it last time it seemed insufficient. But I will check again, it would be very useful.