Skip to content

Commit d0bc2d9

Browse files
authored
Fix Google Scholar references for a bare YAML bibliography (#15128)
A YAML bibliography not wrapped in --- delimiters produced no citation_reference tags with google-scholar enabled, so its references were missing from the Scholar output. Pandoc has no reader for YAML bibliographies, so the file was read as markdown, which only finds references in a delimited metadata block. Read .yaml and .yml files the way --bibliography does, from the first YAML document: - A references: map goes through --metadata-file, so Pandoc's YAML reader handles it unchanged. - A top-level list is wrapped as {references: ...} on stdin, since --metadata-file needs a map. - The shape check accepts any YAML tag and keeps the last value of a duplicate key, as Pandoc does, so delimited files that worked before still do. See #15125 for the CSL JSON case of the same conversion.
1 parent cbd0349 commit d0bc2d9

10 files changed

Lines changed: 152 additions & 7 deletions

File tree

‎news/changelog-1.11.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ All changes included in 1.11:
6767
- ([#15115](https://github.com/quarto-dev/quarto-cli/pull/15115)): Fix Google Scholar writing two `citation_reference` tags for a reference defined in two bibliography files. The tag now describes the entry Pandoc renders.
6868
- ([#15118](https://github.com/quarto-dev/quarto-cli/pull/15118)): Fix Google Scholar metadata missing the first and last page of bibliography entries, and giving wrong pages for a citation `page` written with an en-dash or as a page list.
6969
- ([#15125](https://github.com/quarto-dev/quarto-cli/pull/15125)): Fix Google Scholar metadata failing the render with a CSL JSON (`.json`) bibliography.
70+
- ([#15128](https://github.com/quarto-dev/quarto-cli/pull/15128)): Fix Google Scholar metadata missing references with a YAML bibliography not wrapped in `---` delimiters.
7071

7172
### `pdf`
7273

‎src/core/bibliography.ts‎

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,23 @@ import { Metadata } from "../config/types.ts";
1313
import { asArray } from "./array.ts";
1414
import { CSL } from "./csl.ts";
1515

16+
import { FAILSAFE_SCHEMA, loadAll, Type } from "yaml";
17+
1618
import { execProcess } from "./process.ts";
1719
import { pandocBinaryPath } from "./resources.ts";
1820

21+
// Keeps every scalar as written and, like pandoc, accepts any tag (!!int,
22+
// !custom, ...) by keeping the untagged value
23+
const kBibliographyYamlSchema = FAILSAFE_SCHEMA.extend(
24+
(["scalar", "sequence", "mapping"] as const).map((kind) =>
25+
new Type("", {
26+
kind,
27+
multi: true,
28+
construct: (data: unknown) => data ?? "",
29+
})
30+
),
31+
);
32+
1933
export async function bibliographyCslJson(input: string, metadata: Metadata) {
2034
const bibliography = metadata[kBibliography] as string | string[];
2135
if (bibliography) {
@@ -84,15 +98,36 @@ export async function renderToCSLJSON(
8498
// The bibliopath might end up as an absolute path
8599
// in which case just leave it alone (otherwise it is cwd relative)
86100
const biblioPath = join(dir, biblio);
101+
const absBiblioPath = isAbsolute(biblioPath)
102+
? biblioPath
103+
: join(Deno.cwd(), biblioPath);
104+
const ext = extname(biblioPath).toLowerCase();
87105
const cmd = [pandocBinaryPath()];
88-
// Without -f, pandoc reads a .json input as its own JSON AST
89-
if (extname(biblioPath).toLowerCase() === ".json") {
90-
cmd.push("-f");
91-
cmd.push("csljson");
106+
let stdin: string | undefined;
107+
if (ext === ".json") {
108+
// Without -f, pandoc reads a .json input as its own JSON AST
109+
cmd.push("-f", "csljson", absBiblioPath);
110+
} else if (ext === ".yaml" || ext === ".yml") {
111+
// Pandoc has no reader for a YAML bibliography: read as markdown, it
112+
// only works when wrapped in --- delimiters. Like --bibliography, use
113+
// the first YAML document, either a references: map or a bare array.
114+
// json: true lets a duplicate key win last, as pandoc does.
115+
const firstDoc = loadAll(Deno.readTextFileSync(absBiblioPath), null, {
116+
schema: kBibliographyYamlSchema,
117+
json: true,
118+
})?.[0];
119+
if (Array.isArray(firstDoc)) {
120+
// --metadata-file needs a map, so wrap the array in a metadata block
121+
// for pandoc's YAML reader to parse its fields as it would the map
122+
cmd.push("-f", "markdown");
123+
stdin = `---\n${JSON.stringify({ references: firstDoc })}\n---\n`;
124+
} else {
125+
cmd.push("-f", "markdown", `--metadata-file=${absBiblioPath}`);
126+
stdin = "";
127+
}
128+
} else {
129+
cmd.push(absBiblioPath);
92130
}
93-
cmd.push(
94-
isAbsolute(biblioPath) ? biblioPath : join(Deno.cwd(), biblioPath),
95-
);
96131
cmd.push("-t");
97132
cmd.push("csljson");
98133
cmd.push("--citeproc");
@@ -105,6 +140,7 @@ export async function renderToCSLJSON(
105140
stderr: "piped",
106141
cwd: dir,
107142
},
143+
stdin,
108144
);
109145
if (result.success) {
110146
if (result.stdout) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Scholar metadata for a top-level array YAML bibliography
3+
format: html
4+
google-scholar: true
5+
bibliography: references-array.yaml
6+
_quarto:
7+
tests:
8+
html:
9+
ensureHtmlElements:
10+
- ['meta[name="citation_reference"][content*="citation_title=Formatted reference;"][content*="citation_volume=1.10;"][content*="citation_issue=7;"]']
11+
---
12+
13+
The bibliography is a YAML file holding a top-level list of references, with no `references:` key, which pandoc accepts for `--bibliography`. The fields still go through pandoc's YAML reader: the markdown title is parsed and the unquoted volume keeps its text.
14+
15+
This article cites one work [@cited].
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Scholar metadata for a bare YAML bibliography
3+
format: html
4+
google-scholar: true
5+
bibliography: references-bare.yaml
6+
_quarto:
7+
tests:
8+
html:
9+
ensureHtmlElements:
10+
- ['meta[name="citation_reference"][content*="citation_author=Alice Smith;"]']
11+
---
12+
13+
The bibliography is a YAML file with a `references:` list and no `---` delimiters, which pandoc accepts for `--bibliography`. Pandoc has no input format that reads such a file, so the Scholar reference tags need it handled explicitly.
14+
15+
This article cites one work [@cited].
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Scholar metadata for a delimited YAML bibliography
3+
format: html
4+
google-scholar: true
5+
bibliography: references-delimited.yaml
6+
_quarto:
7+
tests:
8+
html:
9+
ensureHtmlElements:
10+
- ['meta[name="citation_reference"][content*="citation_title=Cited reference;"]']
11+
---
12+
13+
The bibliography is a YAML file wrapped in `---` delimiters, with a duplicated `title` key. Pandoc warns and keeps the last value, so the Scholar reference tags do too.
14+
15+
This article cites one work [@cited].
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
- id: cited
2+
type: article-journal
3+
title: "*Formatted* reference"
4+
volume: 1.10
5+
issue: !!int 7
6+
author:
7+
- family: Smith
8+
given: Alice
9+
issued:
10+
date-parts:
11+
- [2024]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
references:
2+
- id: cited
3+
type: article-journal
4+
title: Cited reference
5+
author:
6+
- family: Smith
7+
given: Alice
8+
issued:
9+
date-parts:
10+
- [2024]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
references:
3+
- id: cited
4+
type: article-journal
5+
title: Superseded title
6+
title: Cited reference
7+
author:
8+
- family: Smith
9+
given: Alice
10+
issued:
11+
date-parts:
12+
- [2024]
13+
---
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
references:
3+
- id: cited
4+
type: article-journal
5+
title: Cited reference
6+
volume: !!int 2
7+
issue: !custom 7
8+
author:
9+
- family: Smith
10+
given: Alice
11+
issued:
12+
date-parts:
13+
- [!!int 2024]
14+
---
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Scholar metadata for a YAML bibliography with explicit tags
3+
format: html
4+
google-scholar: true
5+
bibliography: references-tagged.yaml
6+
_quarto:
7+
tests:
8+
html:
9+
ensureHtmlElements:
10+
- ['meta[name="citation_reference"][content*="citation_publication_date=2024;"][content*="citation_volume=2;"][content*="citation_issue=7;"]']
11+
---
12+
13+
The bibliography is a delimited YAML file whose values carry explicit tags, standard (`!!int`) and custom (`!custom`). Pandoc accepts any tag and keeps the value's text, so the Scholar reference tags do too.
14+
15+
This article cites one work [@cited].

0 commit comments

Comments
 (0)