diff --git a/config.yaml b/config.yaml index f21fc84d01fa3fabec4e323a35c2f12bb824d831..b2ef663d3122d828e9d67fb1bc0f50c0c0a5f61e 100755 --- a/config.yaml +++ b/config.yaml @@ -50,3 +50,4 @@ markup: tabWidth: 2 theme: - hugo-activitystreams + - hugo-cite diff --git a/content/articles/2021-07-23-our-new-digital-home/bib.json b/content/articles/2021-07-23-our-new-digital-home/bib.json new file mode 100644 index 0000000000000000000000000000000000000000..32ac4a5789ff245a9d5db9db9d3d2b76fcbd70a4 --- /dev/null +++ b/content/articles/2021-07-23-our-new-digital-home/bib.json @@ -0,0 +1,13 @@ +[{ + "id": "example", + "type": "article", + "title": "Example CSL-JSON file", + "author": [{ + "family": "Willighagen", + "given": "Lars" + }], + "issued": { + "date-parts": [[2020, 5, 2]] + }, + "publisher": "GitHub Gist" +}] diff --git a/content/articles/2021-07-23-our-new-digital-home/index.Rmd b/content/articles/2021-07-23-our-new-digital-home/index.Rmd index 49df75d067033219f50b1484081c068f17c015b7..7775b08e045a1b25fdb05335e46a1d52bdd6d36f 100644 --- a/content/articles/2021-07-23-our-new-digital-home/index.Rmd +++ b/content/articles/2021-07-23-our-new-digital-home/index.Rmd @@ -158,3 +158,16 @@ And of course error notices. {{< error >}} Danger will robinson, danger! {{< /error >}} + +## Citations and bibliographies + +It is possible to add a citation to something in the bibliography inline like so{{< cite "example" >}}; cool +huh? You can also do the same citation as a numbered margin citations like so{{<sn>}}{{< cite "example" >}} +{{</sn>}}. Neat huh? + +By adding a CL-JSON bibliography file of the format `*bib*.json` inside an articles directory it is +possible to render the bibliography like so. + +### Bibliography + +{{< bibliography >}} \ No newline at end of file diff --git a/themes/hugo-cite/.gitignore b/themes/hugo-cite/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6325e67786c5ffe60b631e5de847acdd598c50e --- /dev/null +++ b/themes/hugo-cite/.gitignore @@ -0,0 +1,8 @@ +# https://git-scm.com/docs/gitignore +# https://help.github.com/articles/ignoring-files +# Example .gitignore files: https://github.com/github/gitignore +/bower_components/ +/node_modules/ +.DS_Store +docs +.idea diff --git a/themes/hugo-cite/LICENSE b/themes/hugo-cite/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..5a8e332545f667aab9bf3a17f11dba27c70b656a --- /dev/null +++ b/themes/hugo-cite/LICENSE @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/themes/hugo-cite/README.md b/themes/hugo-cite/README.md new file mode 100644 index 0000000000000000000000000000000000000000..189a92129fb4b0c657e22e41287dfa8a9f855b20 --- /dev/null +++ b/themes/hugo-cite/README.md @@ -0,0 +1,285 @@ +# Hugo Cite + +📠Easily manage your bibliography and in-text citations with [Hugo](https://gohugo.io), the popular static-site generator. + +[**Documentation site + demo →**](https://labs.loupbrun.ca/hugo-cite/) + +--- + +âš ï¸ **Important note: APA is the only citation style currently available, and you must be aware that it does not match the entire APA spec.** +More styles may be added eventually (contributions welcome!), but given that they are extremely verbose to implement, this is unlikely to happen in a near future. + +--- + +## Install + +### 1. Download + +Download Hugo Cite in the `themes/hugo-cite` directory, either by [cloning with Git](https://github.com/loup-brun/hugo-cite) (the preferred method) or by [downloading as a ZIP file](https://github.com/alex-shpak/hugo-book/archive/master.zip). + +The Git way: + +```bash +git submodule add https://github.com/loup-brun/hugo-cite.git themes/hugo-cite +``` + +Your project directory should then look like this: + +```bash +# Your Hugo project directory +├── config.yml +└── themes + └── hugo-cite +``` + +### 2. Configure + +Edit the `theme` parameter in your Hugo config file and add `hugo-cite` after your theme. + +```yaml +# config.yml +theme: +- <your-theme> +- hugo-cite +``` + +### 3. Add CSS + +Reference the CSS somewhere in your HTML templates: + +```html +<link rel="stylesheet" type="text/css" href="{{ "/hugo-cite.css" | relURL }}" /> +``` + +## Usage + +You must first provide a **[CSL-JSON](https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html) bibliography file**. +(Other formats, such as BiBTeX, are _not_ supported.) +In Zotero for instance, this can be accomplished by selecting the CSL-JSON format when exporting a collection. +Just include `bib` in the filename (such as `bibliography.json`,`oh-my-bib.json`, or simply `bib.json`) and save it inside your Hugo project directory. + +Here is an example: + +```bash +# Your Hugo project directory +├── content +│ ├── article1 +│ │ ├── bib.json +│ │ └── index.md +│ ├── article2 +│ │ ├── image.jpg +│ │ ├── index.md +│ │ └── mr-bib.json +│ └── article3 +│ ├── index.md +│ └── oh-my-bib.json +└── path + └── to + └── bib.json +``` + +### Shortcodes + +There are two shortcodes you can use in your content: + +- **`{{< bibliography >}}`**: display a list of works. +- **`{{< cite >}}`**: render an in-text citation. + +### Display a bibliography + +#### Basic Example + +By default, the `{{< bibliography >}}` shortcode will render all entries from a `bib.json` included in a [leaf bundle](https://gohugo.io/content-management/page-bundles/#leaf-bundles) (see directory example above). + +```markdown +<!-- Markdown --> + +{{< bibliography >}} +``` + +#### Cited Works + +You can restrict the list only to works cited on the page (with the use of in-text citations, see below): + +```markdown +<!-- Markdown --> + +{{< bibliography cited >}} +``` + +#### File Defined in Front Matter + +You can specify the path to a JSON file located *inside* the Hugo project directory in the content page’s **front matter** using the `bibFile` parameter. +This is especially useful when working with `cited` entries: + +```markdown +--- +title: My Article +bibFile: path/to/bib.json # path relative to project root +--- + +## Bibliography + +<!-- The bibliography will display works from path/to/bib.json --> +{{< bibliography >}} +``` + +#### File Defined in Shortcode + +Alternatively, you can specify the path to the CSL-JSON file at the shortcode level: + +```markdown +<!-- Markdown --> + +{{< bibliography "path/to/bib.json" >}} +``` + +#### Combine Options + +You can also **combine both options** (the path to the JSON file must come first): + +```markdown +<!-- Markdown --> + +{{< bibliography "path/to/bib.json" cited >}} +``` + +**Note**: if you are working with a `cited` bibliography, you’ll have to specify the path to the JSON file in the front matter for in-text citations to access the same file. + +#### Named Params + +You can chose to use **named params** for clarity (the order does not matter here): + +```markdown +<!-- Markdown --> + +{{< bibliography src="path/to/bib.json" cited="true" >}} +``` + +#### File From a URL + +Thanks to Hugo’s [`getJSON`](https://gohugo.io/templates/data-templates/#data-driven-content) function, the path can also be a **URL**. +*Note however that this method may have some drawbacks if you are [reloading often](https://gohugo.io/templates/data-templates/#livereload-with-data-files), see the Hugo docs regarding potential issues.* + +```markdown +<!-- Markdown --> + +{{< bibliography "http://example.com/my/bib.json" >}} +``` + +### Render in-text citations + +Use the `{{< cite >}}` shortcode to render rich in-text citations. + +Example: + +```markdown +<!-- Markdown --> + +{{< cite "Lessig 2002" >}} +``` + +The citation key (in the above example, `Lessig 2002`) must match the `id` field of a reference in your CSL-JSON file. +You can make it look like an author-date format, or anything else. + +Here’s an excerpt of a CSL-JSON file: + +```json +[ + { + "id": "Lessig 2002", + "author": [ + { + "family": "Lessig", + "given": "Lawrence" + } + ] + } +] +``` + +Using the citation key defined in the CSL-JSON, you can reference your entry in content files: + +```markdown +<!-- Markdown --> + +Our generation has a philosopher. +He is not an artist, or a professional writer. +He is a programmer. {{< cite "Lessig 2002" >}} +``` + +#### Suppress Author + +For an abbreviated in-text citation form, you can add a **dash** (`-`) at the beginning of your citation key: + +```markdown +<!-- Markdown --> + +{{< cite "-Lessig 2002" >}} +``` + +The above would render `(2002)` rather than `(Lessig, 2002)`. + +#### Cite a Page + +You can also provide a **page** as the second positional parameter: + +```markdown +<!-- Markdown --> + +{{< cite "Lessig 2002" 5 >}} +``` + +The example above will render `(Lessig, 2002, p. 5)` (note the `p.` was added by hugo-cite; you need not to add it). + +#### Cite a Page Range + +You can instead specify a **range of pages** using a **dash** `-`, which will output `pp.` before the page range (ensure there is no space between the page numbers): + +```markdown +<!-- Markdown --> + +{{< cite "Lessig 2002" 5-6 >}} +``` + +The example above will render `(Lessig, 2002, pp. 5-6)`. + + +#### Combine Multiple Citations + +You can combine **multiple citations** in a single block, using the **semi-colon** (`;`) separator (no spaces around the semi-colon): + +```markdown +<!-- Markdown --> + +{{< cite "Lessig2002;Nussbaum2011;Dewey1938" >}} +``` + +The above would render `(Lessig, 2002; Nussbaum, 2011; Dewey, 1938)`. + +Works with pagination too, **in the matching order** of the citation keys: + +```markdown +<!-- Markdown --> + +{{< cite "Lessig2002;Nussbaum2011;Dewey1938" "5-6;;25" >}} +``` + +The above would render `(Lessig, 2002, pp. 5-6; Nussbaum, 2011; Dewey, 1938, p. 25)`. + +## Cited Works + +```markdown +<!-- Include the list of cited works on the page --> +{{< bibliography cited >}} +``` + +## Demo + +Check out a working [online demo →](https://labs.loupbrun.ca/hugo-cite/demo/) + +[](https://labs.loupbrun.ca/hugo-cite/demo/) + +## License + +[WTFPL](LICENSE) diff --git a/themes/hugo-cite/config.yml b/themes/hugo-cite/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..4fe09d7e3a23f0e310601757eaa2bb5eeef46213 --- /dev/null +++ b/themes/hugo-cite/config.yml @@ -0,0 +1,11 @@ +module: + proxy: direct + hugoVersion: + min: "0.55.0" + mounts: + - source: layouts + target: layouts + - source: i18n + target: i18n + - source: static + target: static diff --git a/themes/hugo-cite/go.mod b/themes/hugo-cite/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..04e758cc82fcb46ffb1def3acb7c7c7df4176243 --- /dev/null +++ b/themes/hugo-cite/go.mod @@ -0,0 +1,3 @@ +module github.com/loup-brun/hugo-cite + +go 1.16 diff --git a/themes/hugo-cite/i18n/en.yaml b/themes/hugo-cite/i18n/en.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6f8dcd8cfb3203877d2507c5eae6f62de4cca80f --- /dev/null +++ b/themes/hugo-cite/i18n/en.yaml @@ -0,0 +1,17 @@ +# APA Style Localization +# EN + +apa_available_from: + other: "Available from" + +apa_in: + other: "In" + +apa_no_author_abbr: + other: "n.a." + +apa_no_date_abbr: + other: "n.d." + +apa_retrieved_from: + other: "Retrieved from" diff --git a/themes/hugo-cite/i18n/fr.yaml b/themes/hugo-cite/i18n/fr.yaml new file mode 100644 index 0000000000000000000000000000000000000000..09e8cf03b67c4bd0d9a2b230f6441f54b4c488c4 --- /dev/null +++ b/themes/hugo-cite/i18n/fr.yaml @@ -0,0 +1,17 @@ +# APA Style Localization +# FR + +apa_available_from: + other: "Disponible à l’adresse" + +apa_in: + other: "Dans" + +apa_no_author_abbr: + other: "s.a." + +apa_no_date_abbr: + other: "s.d." + +apa_retrieved_from: + other: "Consulté à l’adresse" diff --git a/themes/hugo-cite/layouts/partials/bibliography/apa-style.html b/themes/hugo-cite/layouts/partials/bibliography/apa-style.html new file mode 100644 index 0000000000000000000000000000000000000000..86f46b48d062e9abea2d73f5bdea3a287f652188 --- /dev/null +++ b/themes/hugo-cite/layouts/partials/bibliography/apa-style.html @@ -0,0 +1,419 @@ +{{/* + APA-Style Citation + + + Book Template : + + Author Surname, First Initial. Second Initial. (Year). <i>Book title: Subtitle</i>. Place of Publication: Publisher. [DOI] + + Journal Template: + + Author, I. N. (Year). Title of the article. <i>Title of the Journal or Periodical, volume number(issue number)</i>, page numbers. [DOI] + + https://apastyle.apa.org/style-grammar-guidelines/references/examples + +*/}} + +{{/* BEGIN author */}} +{{- define "authorPart" }} + {{- $authors := .author }} + {{- if $authors -}} + {{- $totalAuthors := len $authors -}} + {{- range $authorIndex, $author := $authors -}} + <span itemprop="author" itemscope itemtype="https://schema.org/Person"> + {{- with $author.family -}} + <span itemprop="familyName">{{ . }}</span> + {{- end -}} + {{- with $author.given -}},  + <meta itemprop="givenName" content="{{ . }}" /> + {{ substr . 0 1 }}. + {{- end -}}{{/* First letter (initial). */}} + {{- with $author.secondInitial -}}  + <meta itemprop="additionalName" content="{{ . }}" /> + {{- substr . 0 1 -}}.{{- end -}} + </span> + {{- if and (gt $totalAuthors 1) (lt (add $authorIndex 2) $totalAuthors) -}},  + {{ end -}} + {{ if eq $totalAuthors (add $authorIndex 2) -}} & {{ end -}}{{/* Last name has ampersand */}} + {{- end -}} + {{- else -}}{{/* Fallback if no authors are specified */}} + ({{- i18n "apa_no_author_abbr" | default "n.a." | upper -}}). + {{- end -}} +{{- end -}}{{/* END author */}} + +{{/* BEGIN editor */}} +{{- define "editorPart" }} + {{- $editors := .editor }} + {{- if $editors -}} + {{- $totalEditors := len $editors -}} + {{- range $editorIndex, $editor := $editors -}} + <span itemprop="editor" itemscope itemtype="https://schema.org/Person"> + {{- with $editor.family -}} + <span itemprop="familyName">{{ . }}</span> + {{- end -}} + {{- with $editor.given -}},  + <meta itemprop="givenName" content="{{ . }}" /> + {{ substr . 0 1 }}. + {{- end -}}{{/* First letter (initial). */}} + {{- with $editor.secondInitial -}}  + <meta itemprop="additionalName" content="{{ . }}" /> + {{- substr . 0 1 -}}.{{- end -}} + </span> + {{- if and (gt $totalEditors 1) (lt (add $editorIndex 2) $totalEditors) -}},  + {{ end -}} + {{ if eq $totalEditors (add $editorIndex 2) -}} & {{ end -}}{{/* Last name has ampersand */}} + {{- end -}} + {{- end -}} +{{- end -}}{{/* END editor */}} + +{{/* BEGIN issued (year of publication) */}} +{{- define "issuedPart" }} + {{- if and (isset . "issued") (isset .issued "date-parts") -}} + {{/* range of dates */}} + (<span itemprop="datePublished"> + {{- range $index, $dateParts := (index .issued "date-parts") -}} + {{- if gt $index 0 -}}, {{ end -}}{{/* Separate other years by comma */}} + {{- range first 1 $dateParts -}}{{/* First element in date-part is the year */}} + {{- . -}} + {{- end -}} + {{- end -}} + </span>) + {{- else }} + ({{ i18n "apa_no_date_abbr" | default "n.d." }}){{/* no date */}} + {{- end }} +{{- end }}{{/* END issued */}} + +{{/* BEGIN full issued (year, month day) */}} +{{- define "issuedFullPart" }} + {{- if and (isset . "issued") (isset .issued "date-parts") -}} + (<span itemprop="datePublished"> + {{- range (index .issued "date-parts") -}} + {{- index . 0 -}}{{/* year */}} + {{- if (index . 1) -}} + , {{- index . 1 -}}{{/* month */}} + {{- end }} + {{- with index . 2 -}} + /{{- . }}{{/* day */}} + {{- end -}} + {{- end -}} + </span>) + {{- else }} + (s.d.){{/* no date */}} + {{- end }} +{{- end }}{{/* END issued */}} + +{{/* BEGIN DOI */}} +{{- define "DOIPart" }} + {{- if .DOI }} + <a href="https://doi.org/{{ .DOI }}" + itemprop="identifier" + itemtype="https://schema.org/URL">https://doi.org/{{- .DOI -}}</a> + {{- else if .URL }}  + {{- i18n "apa_retrieved_from" | default "Retrieved from" -}}  + <a href="{{ .URL }}" + itemprop="identifier" + itemtype="https://schema.org/URL">{{ .URL }}</a> + {{- end -}} +{{- end -}} +{{- /* END DOI*/ -}} + +{{/* BEGIN ArchivalID */}} +{{- define "ArchivalID" }} + {{ if isset . "archive" -}} {{ i18n "archive_available_from" | default "Available from" }} + <meta itemprop="Organization" itemtype="http://schema.org/Organization" itemscope> + <span itemprop="name">{{- echoParam . "archive" -}}</span>. + {{- if isset . "archive_location" -}}  ({{- echoParam . "archive_location" -}}){{- end }}. + {{- end }} +{{- end -}} +{{- /* END ArchivalID */ -}} + +{{/* -------------------- BEGIN TYPES -------------------- */}} +{{/* -------------------- BEGIN BOOK TYPE -------------------- */}} +{{- if eq .type "book" -}} +<span itemscope + itemtype="https://schema.org/Book" + data-type="book"> + {{- if .author -}} + {{- template "authorPart" . -}} +   + {{- else if .editor -}}{{/* Display editors if no authors*/}} + {{- template "editorPart" . -}} +   + {{- end -}} + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + <i>{{/* italicize title */}} + {{- .title | markdownify -}} + {{- if .subtitle }}: {{ .subtitle | markdownify }}{{- end -}} + </i></span>{{/* close to avoid space */}} + {{- end -}} + {{- if or (isset . "edition") (isset . "page") }} ( + {{- with .edition -}} + <span>{{ . }}</span> + {{- end -}} + {{- if and (isset . "edition") (isset . "page") -}}, {{ end -}} + {{- if isset . "page" -}} + <meta itemprop="numberOfPages" content="{{ .page }}"> + {{- end -}} + ){{- end -}}. + {{ if isset . "publisher-place" -}} + <meta itemprop="contentLocation" + value="{{- echoParam . "publisher-place" -}}"> + {{- end -}} + {{- with .publisher -}}  + <span itemprop="publisher" + itemtype="http://schema.org/Organization" + itemscope=""> + <span itemprop="name"> + {{- . -}} + </span></span>. + {{- end }} + + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END BOOK TYPE -------------------- */}} + +{{/* -------------------- BEGIN CHAPTER TYPE -------------------- */}} +{{- else if eq .type "chapter" -}} +<span itemscope + itemtype="https://schema.org/Chapter" + data-type="chapter"> + {{ template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + {{- .title | markdownify -}} + {{- if .subtitle }}: {{ .subtitle | markdownify }}{{- end -}} + </span>. + {{- end -}} + + {{- if isset . "container-title" -}} +  {{- i18n "apa_in" | default "In" -}} + {{- if .editor -}} + {{- template "editorPart" . }} (Eds.),  + {{- end -}} + + <span itemprop="about"> + <i>{{/* italicize title */}} + {{- echoParam . "container-title" -}} + </i></span>.{{/* close to avoid space */}} + {{- end -}} + {{- if or (isset . "edition") (isset . "page") -}} ( + {{- if isset . "edition" -}} + <span itemprop="workExample">{{ .edition }}</span> + {{- if isset . "page" -}}, {{ end -}} + {{- end -}} + {{- if isset . "page" -}} + <span>pp. {{ replace .page "-" "–" }}</span> + {{- end -}} + ){{- end -}}. + {{ if isset . "publisher-place" -}} + <meta itemprop="contentLocation" + value="{{- echoParam . "publisher-place" -}}"> + {{- end -}} + {{- with .publisher -}} +  <span itemprop="publisher" + itemtype="http://schema.org/Organization" + itemscope=""> + <span itemprop="name"> + {{- . -}} + </span></span>. + {{- end }} + + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END CHAPTER TYPE -------------------- */}} + +{{/* -------------------- BEGIN ARTICLE TYPE -------------------- */}} +{{- else if or (eq .type "article-journal") (eq .type "article") -}} +<span itemscope + itemtype="https://schema.org/Article" + data-type="article"> + {{- template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + {{- .title | markdownify -}} + </span>. + {{- end -}} + + {{- if isset . "container-title" -}} + {{- if .editor -}}{{/* Add `In` before name of Eds. and title*/}} +  {{- i18n "apa_in" | default "In" -}}  + {{- template "editorPart" . }} (Eds.),  + {{- end -}} + + <i>{{/* italicize journal title */}} + <span itemprop="about"> + {{- echoParam . "container-title" -}}</span> + {{- if isset . "volume" -}} + , {{- .volume -}} + {{- end -}} + {{- if isset . "issue" }}({{ .issue }}) + {{- end -}} + </i>.{{- end -}} + {{- if isset . "page" -}} +  <span itemprop="pagination">{{ replace .page "-" "–" }}</span>. + {{- end -}} + + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END ARTICLE TYPE -------------------- */}} + +{{/* -------------------- BEGIN WEBPAGE TYPE -------------------- */}} +{{- else if eq .type "webpage" -}} +<span itemscope + itemtype="https://schema.org/WebPage" + data-type="webpage"> + {{- template "authorPart" . -}} + + {{- template "issuedFullPart" . -}}. + + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END WEBPAGE TYPE -------------------- */}} + +{{/* -------------------- BEGIN BLOGPOST TYPE -------------------- */}} +{{- else if eq .type "post-weblog" -}} +<span itemscope + itemtype="https://schema.org/BlogPosting" + data-type="blog"> + {{- template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + {{- .title | markdownify -}} + </span> + {{- end -}} +{{- if isset . "genre" -}}<span itemprop="genre"> [{{- echoParam . "genre" -}}]</span> + {{- end -}}. + + {{- if isset . "container-title" -}} + {{- if .editor -}}{{/* Add `In` before name of Eds. and title*/}} +  {{- i18n "apa_in" | default "In" -}}  + {{- template "editorPart" . }} (Eds.),  + {{- end -}} + +<span itemprop="isPartOf"> + {{- echoParam . "container-title" -}}</span> + {{- if isset . "volume" -}} + , {{- .volume -}} + {{- end -}} + {{- if isset . "issue" }}({{ .issue }}) + {{- end -}} +.{{- end -}} + {{- if isset . "page" -}} +  <span itemprop="pagination">{{ replace .page "-" "–" }}</span>. + {{- end -}} + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END BLOGPOST TYPE -------------------- */}} + +{{/* -------------------- BEGIN DEGREE WORK TYPE -------------------- */}} +{{- else if eq .type "thesis" -}} +<span itemscope + itemtype="https://schema.org/Thesis" + data-type="thesis"> + {{- template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + <i>{{- .title | markdownify -}}</i> + </span> + {{- end -}} +{{- if isset . "genre" -}}<span itemprop="inSupportOf"> ({{- echoParam . "genre" -}})</span> + {{- end -}}.  +{{- if isset . "publisher-place" -}} + <meta itemprop="locationCreated" + value="{{- echoParam . "publisher-place" -}}"> + {{- end -}} + {{- with .publisher -}} + <span itemprop="publisher" + itemtype="http://schema.org/EducationalOrganization" + itemscope> + <span itemprop="name">{{- . -}}{{- end -}} + </span>{{ if isset . "publisher-place" -}},  <span itemprop="location">{{- echoParam . "publisher-place" -}}</span></span>. + {{- end }} + {{- template "ArchivalID" . -}} + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END DEGREE WORK TYPE -------------------- */}} + +{{/* -------------------- BEGIN REPORT TYPE -------------------- */}} +{{- else if eq .type "report" -}} +<span itemscope + itemtype="https://schema.org/Report" + data-type="report"> + {{- template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + <i>{{- .title | markdownify -}}</i> + </span> + {{- end -}} + {{- if isset . "number" -}}<span itemprop="reportNumber"> ({{- echoParam . "number" -}})</span> + {{- end -}}. + {{- if isset . "publisher-place" -}} + <meta itemprop="contentLocation" + value="{{- echoParam . "publisher-place" -}}"> + {{- end -}} + {{- with .publisher -}} + <span itemprop="Organization" + itemtype="http://schema.org/Organization" + itemscope> + <span itemprop="name"> + {{- . -}}{{- end -}} + </span> {{ if isset . "publisher-place" -}}:  <span itemprop="location">{{- echoParam . "publisher-place" -}}</span></span>. + {{- end }} + {{- template "ArchivalID" . -}} + {{- template "DOIPart" . -}} +</span> +{{/* -------------------- END REPORT TYPE -------------------- */}} + +{{/* -------------------- BEGIN DEFAULT APA -------------------- */}} +{{- else -}} +<span itemscope + itemtype="https://schema.org/CreativeWork" + data-type="{{ .type | default "default" }}"> + {{- template "authorPart" . }} +   + {{- template "issuedPart" . }}. +   + {{- if .title -}} + <span itemprop="name"> + <i>{{/* italicize title */}} + {{- .title | markdownify -}} + {{- if .subtitle }}: {{ .subtitle | markdownify }}{{- end -}} + </i></span>{{/* close to avoid space */}} + {{- end -}} + {{- if isset . "edition" }} ( + <span span itemprop="workExample">{{ .edition }}</span> + ){{- end -}}. + {{ if isset . "publisher-place" -}} + <meta itemprop="contentLocation" + content="{{- echoParam . "publisher-place" -}}"> + {{- end -}} + {{- with .publisher -}}  + <span itemprop="publisher" itemtype="http://schema.org/Organization" itemscope=""> + <span itemprop="name"> + {{- . -}} + </span></span>. + {{- end }} + + {{- template "DOIPart" . -}} +</span> +{{- end -}} +{{/* -------------------- END DEFAULT APA -------------------- */}} +{{/* -------------------- END TYPES -------------------- */}} diff --git a/themes/hugo-cite/layouts/partials/bibliography/bibliography-list.html b/themes/hugo-cite/layouts/partials/bibliography/bibliography-list.html new file mode 100644 index 0000000000000000000000000000000000000000..56543b3bf8be0c6b9b4abbd71c08908dd802ff7e --- /dev/null +++ b/themes/hugo-cite/layouts/partials/bibliography/bibliography-list.html @@ -0,0 +1,98 @@ +{{/* + Bibliography List + + - You can change the citationStyle in the site's `config.yml` file. + - Citation template files must match the name of the style + (e.g. `apa` => `apa-style.html`) and must be located inside the + `layouts/partials/bibliography/` directory. + - This partial expects a map with the following property: + + references: references + + CSL-JSON spec: + https://citeproc-js.readthedocs.io/en/latest/csl-json/markup.html +*/}} + +{{- $errorMissingPartialStyle := dict "Style de citation" "q-cite" "message" "Aucun modèle ne correspond au style de citation entré. Assurez-vous que le style explicité dans `.Site.params` se trouve dans `partials/bibliography`. Par exemple : " "example" "citationStyle: apa" -}} + +{{/* -------------------- 1. BEGIN CITATION STYLE BLOCK -------------------- */}} +{{/* APA style by default */}} +{{- $citationStyle := "apa" }} + +{{/* If the citationStyle is specified in the site config, use it. */}} +{{- if $.Site.Params.citationStyle }} +{{- $citationStyle = $.Site.Params.citationStyle }} +{{- end }} + +{{/* Catch if there is no matching template for the style */}} +{{- if not (templates.Exists (printf "partials/bibliography/%s-style.html" $citationStyle)) }} + {{- errorf "The provided citationStyle does not exist: `%s`. Please make sure that a file named `%s-style.html` file exists in your layouts/partials/bibliography directory." $citationStyle $citationStyle }} +{{- else }} +{{/* -------------------- END CITATION STYLE BLOCK -------------------- */}} + +{{/* -------------------- 2. BEGIN REFERENCES BLOCK -------------------- */}} +{{- $references := .references }} + +{{ if $references }} +<section class="hugo-cite-bibliography"> + <dl> + {{/* -------------------- BEGIN RANGE BIBLIOGRAPHY -------------------- */}} + {{- range $refIndex, $refObject := $references -}} + {{- $currentRef := index $references $refIndex }} + + {{- $partialPath := string (printf "bibliography/%s-style.html" $citationStyle) }} + + <div id="{{ $currentRef.id | urlize }}"> + <dt> + {{/* + Author-date in-text citation + */}} + + {{- $displayAuthors := $currentRef.author -}} + {{- if not $currentRef.author -}} + {{- $displayAuthors = $currentRef.editor -}} + {{- end -}} + {{- if not $displayAuthors -}}{{/* Fallback if no authors/Eds are specified */}} + ({{- i18n "apa_no_author_abbr" | default "n.a." | upper -}}) + {{- else -}} + + {{- $totalAuthors := len $displayAuthors -}} + {{- range $authorIndex, $author := $displayAuthors -}}{{/* BEGIN authors loop */}} + + {{- with $author.family -}} + {{ . }} + {{- end }} + {{- if and (gt $totalAuthors 1) (lt (add $authorIndex 2) $totalAuthors) -}},  + {{ end -}} + {{ if eq $totalAuthors (add $authorIndex 2) -}} & {{ end -}}{{/* Last name has ampersand */}} + {{- end -}} + + {{- end -}}{{/* END authors loop */}} + + {{/* Begin Issued */}} + ({{- if and (isset $currentRef "issued") (isset .issued "date-parts") -}} + {{- range $index, $dateParts := (index $currentRef.issued "date-parts") -}} + {{- if gt $index 0 -}}, {{ end -}} + {{- range first 1 $dateParts -}}{{- . -}}{{- end -}} + {{- end -}} + {{- else -}}{{/* Fallback if no date */}} + {{- i18n "apa_no_date_abbr" | default "n.d." -}} + {{- end -}}){{/* End Issued */}}</dt> + + <dd> + {{/* + Full bibliographic notice + */}} + + {{- partial $partialPath $currentRef -}}</dd> + + </div> + {{- end -}} + {{/* -------------------- END RANGE BIBLIOGRAPHY -------------------- */}} + </dl> +</section> +{{- else }} +{{ printf "Bibliography called, but no references" }} +{{- end }} +{{- end }} +{{/* -------------------- END REFERENCES BLOCK -------------------- */}} diff --git a/themes/hugo-cite/layouts/shortcodes/bibliography.html b/themes/hugo-cite/layouts/shortcodes/bibliography.html new file mode 100644 index 0000000000000000000000000000000000000000..999c55e66aa24523a45e630d2960e98420aa0069 --- /dev/null +++ b/themes/hugo-cite/layouts/shortcodes/bibliography.html @@ -0,0 +1,100 @@ +{{/* + + This shortcode renders entries from a CSL-JSON file. + + Examples: + + 1. Render all works from a `bib.json` file located + in a page leaf bundle: + + {{< bibliography >}} + + + 2. Render all works from a specified JSON file, + located *inside* the Hugo project directory: + + {{< bibliography "path/to/bib.json" >}} + + + 3. Render only cited works cited in the page + (with the use of `{{< cite >}}` shortcode): + + {{< bibliography cited >}} + + + 4. Combine both options: + + {{< bibliography "path/to/bib.json" cited >}} + + + 5. You can also use named params for clarity: + + {{< bibliography src="path/to/bib.json" cited="true" >}} + + + 6. Bibliography file may be located at a URL, thanks to Hugo’s + `getJSON` function. + *Note however that this method may have some drawbacks if you are reloading + often, see the Hugo docs regarding potential issues:* + https://gohugo.io/templates/data-templates/#livereload-with-data-files + + {{< bibliography "https://example.com/my/bib.json" >}} + + + The first positional param points to the bibliography file. + It is optional if you have a `bib.json` in a page leaf bundle. + It must be relative to the root of the Hugo project. + + By default, all entries of the bibliography file are rendered; you can chose + to render only those cited on the page (using the {{< cite >}} shortcode) by + including the `cited` parameter (or `cited="true"` if using named params). + +*/}} + +{{- $src := "" }} +{{- $citedOnly := false }} +{{- $references := false }} + +{{- if .IsNamedParams }} + {{- with .Get "src" }}{{ $src = . }}{{ end }} + {{- if .Get "cited" }}{{ $citedOnly = true }}{{ end }} +{{- else }} + {{- with .Get 0 }} + {{- if eq . "cited" }} + {{- $citedOnly = true }} + {{- else }}{{/* assume path to bib */}} + {{- $src = . }} + {{ end }} + {{ end }} + {{- if eq (.Get 1) "cited" }}{{- $citedOnly = true }}{{ end }} +{{- end }} + +{{- if $citedOnly }}{{/* Render cited references only */}} + + {{ $references = $.Page.Scratch.Get "citedBib" }} + +{{- else }}{{/* Render the full bibliography */}} + + {{- $bibliographyPath := "" }} + {{- $pageResource := $.Page.Resources.GetMatch "*bib*.json" -}} + + {{/* Specified in shortcode */}} + {{- if gt (len $src) 1 }} + {{- $bibliographyPath = $src }} + + {{/* 2. Specified in page front-matter */}} + {{- else if $.Page.Params.bibFile }} + {{- $bibliographyPath = $.Page.Params.bibFile }} + + {{/* 3. Page resource bib.json */}} + {{- else if $pageResource }} + {{- $constructedBibResource := printf "content/%s%s" $.Page.File.Dir $pageResource.Name }} + {{- $bibliographyPath = $constructedBibResource }} + {{- end }} + + {{- $references = getJSON $bibliographyPath }} + +{{- end }} + +{{- $bibParams := dict "references" $references }} +{{- partial "bibliography/bibliography-list.html" $bibParams }} diff --git a/themes/hugo-cite/layouts/shortcodes/cite.html b/themes/hugo-cite/layouts/shortcodes/cite.html new file mode 100644 index 0000000000000000000000000000000000000000..77786bebe6d841c7ad89382be721c1f872360e09 --- /dev/null +++ b/themes/hugo-cite/layouts/shortcodes/cite.html @@ -0,0 +1,194 @@ +{{/* + + This shortcode adds a linked Author Date citation reference to the text, and a + hover pop-up with the full citation text. It also adds the citation to a map + of cited works, which can then be output as a page-level bibliography using + the {{< bibliography >}} shortcode. + + Example: + + {{< cite "Faure1909" "304" >}} + + The first positional parameter is a short form citation that should match one + ID in the bib.json file (or the file specified on the content page). + The second, optional parameter is a page reference. Given there is one author + in the work with key "Faure1909", named Faure, with issued year of 1909, the + above would output as: + + (Faure 1909, 54) + + with a link to the complete reference. + + The bibliography file must be a CSL-JSON, specified either in page’s front- + matter with the `bibFile` parameter, or in a leaf bundle, with "bib" in + the file name. + +*/}} + +{{- $errorMissingValue := "1 or 2 values must be supplied with this shortcode. You provided %d params. The first is required and should match an ID in the CSL-JSON bibliography file, the second is optional, and should be a page number or range of page numbers. Example: {{< cite \"Faure 1909\" \"304\" >}}" -}} +{{- $errorMissingNamedParams := "You must at least provide a citation key. It is required and should match an ID in the CSL-JSON bibliography file. Example: {{< cite key=\"Faure 1909\" >}}" -}} + +{{- $defaultErrString := "No matching key was found for `%s` in the references. Please make sure to provide an available ID in your `bib.json` file." -}} + +{{/* Set variables*/}} +{{- $key := "" -}} +{{- $keys := slice "" ";" -}} +{{- $pages := slice "" ";" -}} +{{- $suppressAuthor := false -}} +{{- $keySeparator := ";" -}} + +{{/* -------------------- Named/Positional Params -------------------- */}} +{{- if .IsNamedParams }} + {{/* -------------------- a) Named -------------------- */}} + {{- if not (.Get "key") -}} + {{- errorf $errorMissingNamedParams -}} + {{- else -}} + {{- $key = .Get "key" -}} + {{- $pages = split (.Get "pages" | string) ";" -}} + {{- if .Get "suppressAuthor" }} + {{- $suppressAuthor = true -}} + {{- end -}} + {{- end -}} +{{- else -}} + {{/* -------------------- b) Positional -------------------- */}} + {{- if lt (len .Params) 1 -}} + {{- errorf $errorMissingValue (len .Params) -}} + {{- else -}} + {{- $key = (.Get 0) | replaceRE "^-(.+)" "$1" -}} + {{ $keys = split $key $keySeparator -}} + {{- $pages = string (.Get 1) -}} + {{- if $pages -}} + {{- $pages = split $pages ";" -}} + {{- end -}} + {{- if (findRE "^-(.+)" (.Get 0) 1) -}} + {{- $suppressAuthor = true -}} + {{- end -}} +{{- end -}} + +{{- $totalRefs := len $keys -}} + + +{{/* -------------------- BEGIN Citation style -------------------- */}} +{{- $citationStyle := "apa" }} +{{- if $.Site.Params.citationStyle }} + {{- if templates.Exists (printf "partials/bibliography/%s-style.html" $.Site.Params.citationStyle) }} + {{- $citationStyle = $.Site.Params.citationStyle }} + {{- end }} +{{- end }} +{{- $partialPath := string (printf "bibliography/%s-style.html" $citationStyle) }} +{{/* -------------------- END Citation style -------------------- */}} + +{{/* -------------------- BEGIN Bibliography path -------------------- */}} +{{- $bibliographyPath := "" }} + +{{/* Default: check for a JSON file in the leaf bundle. */}} +{{- $pageResource := $.Page.Resources.GetMatch "*bib*.json" -}} +{{- if $pageResource }} +{{- $constructedBibResource := printf "content/%s%s" $.Page.File.Dir $pageResource.Name }} +{{- $bibliographyPath = $constructedBibResource }} +{{- end }} + +{{- /* If a `bibFile` is specified in the page front-matter, it takes precedence + over a page resource. */ -}} +{{- /* `specifiedBib` must be relative to project root */ -}} +{{- if $.Page.Params.bibFile }} +{{- $bibliographyPath = $.Page.Params.bibFile -}} +{{- end }} + +{{- if gt (len $bibliographyPath) 0 -}}{{/* Begin Bibliography Loop */}} +{{- $bibliography := getJSON $bibliographyPath -}} +{{- /* -------------------- END Bibliography path -------------------- */ -}} + + <span class="hugo-cite-intext" + itemprop="citation">( + + {{- /* Range over citation keys */ -}} + + {{- range $keyIndex, $key := $keys -}} + + {{- range where $bibliography "id" "eq" $key -}} + {{- $currentRef := . -}} + <span class="hugo-cite-group"> + + {{/* Add to the collection of cited references */}} + {{- $.Page.Scratch.SetInMap "citedBib" $key $currentRef -}} + + {{/* Add to the collection of cited references */}} + {{- $.Page.Scratch.SetInMap "citedBib" $key $currentRef -}} + + <a href="#{{- $key | urlize -}}"><span class="visually-hidden">Citation: </span> + {{- $reference := . -}} + + {{- /* -------------------- BEGIN Display authors -------------------- */ -}} + {{- if not $suppressAuthor -}} + {{- $displayAuthors := $reference.author -}} + {{- if not $reference.author -}} + {{- $displayAuthors = $reference.editor -}} + {{- end -}} + {{- if not $displayAuthors -}} + <span rel="noauthor"> + {{- i18n "apa_no_author_abbr" | default "n.a." | upper -}} + </span> + {{- else -}} + {{- range $authorIndex, $author := $displayAuthors | first 2 -}} + <span itemprop="author" itemscope itemtype="https://schema.org/Person"> + {{- with $author.given -}} + <meta itemprop="givenName" content="{{ . }}"> + {{- end -}} + {{- with $author.family -}} + <span itemprop="familyName">{{ . | markdownify }}</span> + {{- end -}} + </span> + {{- if and (eq $authorIndex 0) (gt (len $displayAuthors) 2) -}} + ,  + {{- end -}} + {{- if and (eq (len $displayAuthors) 2) (eq $authorIndex 0) -}} &  + {{- end -}} + {{- end -}} + {{ if gt (len $displayAuthors) 2 }} + <em>& al.</em> + {{- end -}} + {{- end -}},  + {{- end -}} + {{- /* -------------------- END Display authors -------------------- */ -}} + + {{- if and (isset $reference "issued") (isset $reference.issued "date-parts") -}} + {{- range $index, $dateParts := (index .issued "date-parts") -}}{{/* range of dates */}} + {{- range first 1 $dateParts -}}{{/* First element in date-part is the year */ -}} + <span itemprop="datePublished"> + {{- . -}} + </span> + {{- end -}} + {{- end -}} + {{- end -}} + {{- $currentPages := index $pages $keyIndex -}} + {{- with $currentPages -}},  + {{- $formatedPages := (printf "p. %s" $currentPages) | safeHTML -}} + {{- if gt (findRE "-" $currentPages) 0 -}}{{/* If `$pages` contains a dash */}} + {{- $formatedPages = (printf "pp. %s" $currentPages) | safeHTML -}} + {{- end -}} + {{- $formatedPages }}{{- end -}} + </a> + + {{- /* Eliminate space between css-hidden citation hover block */ -}} + + <span class="hugo-cite-citation"> {{ partial $partialPath $reference }}</span></span> + + {{- if lt (add 1 $keyIndex) $totalRefs -}}; {{- end -}} + + {{- else -}} + + {{- /* + Did not find reference with matching key + */ -}} + {{- $particularKeyErr := printf $defaultErrString $key -}} + {{- $errorNoMatchingKey := $particularKeyErr -}} + <span style="background-color: #f00; color: #fff;">{{- $errorNoMatchingKey -}}</span> + + {{- end }} + {{- end }} + {{- end -}}{{/* End Bibliography Loop */ -}} + + {{- end -}} + {{- /* END loop over keys*/ -}} + )</span> diff --git a/themes/hugo-cite/static/hugo-cite.css b/themes/hugo-cite/static/hugo-cite.css new file mode 100644 index 0000000000000000000000000000000000000000..92346571944265e3b3f0254a68c7b0b04ba10dc5 --- /dev/null +++ b/themes/hugo-cite/static/hugo-cite.css @@ -0,0 +1,49 @@ +/* ============================================================================= +/* Hugo-Cite.css +/* ----------------------------------------------------------------------------- */ + +.hugo-cite-group { + display: inline-block; + vertical-align: baseline; /*compensate for lower height */ + position: relative; + font-size: .85em; /* reduce to avoid some breaks */ +} +.hugo-cite-group + .hugo-cite-citation { + visibility: hidden; + background-color: #ffffff; + color: inherit; + border: 1px solid currentColor; + padding: 1rem; + position: absolute; + width: 350px; + max-width: 100vw; + z-index: 1; + bottom: 140%; + left: 0; + margin-left: -50px; + + z-index: 2; + transition: + visibility 0s .3s, + transform .3s ease 0s, + opacity .3s ease 0s; + opacity: 0; + transform: translateY(-8px); +} +.hugo-cite-group:hover + .hugo-cite-citation { + visibility: visible; + transition: visibility 0s 0s, transform .3s, opacity .3s; + opacity: 1; + transform: translateY(0); +} + +/* Visually Hidden utility class */ +.visually-hidden { + clip: rect(1px, 1px, 1px, 1px); + height: 1px; + overflow: hidden; + position: absolute; + width: 1px; +}