Skip to content

Commit f629e9e

Browse files
committed
Fix text block in bibliography (#94)
1 parent 3821395 commit f629e9e

22 files changed

+5403
-20
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"editor.tabSize": 2
77
},
88
"[lua]": {
9-
"editor.tabSize": 2
9+
"editor.tabSize": 2,
10+
"editor.formatOnSaveMode": "file"
1011
},
1112
"busted-test-explorer.args": [
1213
"-lua=texlua",

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Add support for grouping bibliography by authors ([#94](https://github.com/zepinglee/citeproc-lua/issues/94)).
13+
- Add `bib-name-sep` and `bib-after-name-sep` options to control the vertical space of author groups ([#94](https://github.com/zepinglee/citeproc-lua/issues/94)).
14+
1015
### Fixed
1116

1217
- Fix missing `keyword` field when converted from BibTeX ([#97](https://github.com/zepinglee/citeproc-lua/issues/97)).

citeproc/citeproc-engine.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ local Position = util.Position
111111
---@field requires_sorting boolean
112112
---@field widest_label string
113113
---@field maxoffset integer
114+
---@field second_field_align string | boolean
114115
local Registry = {}
115116

116117

@@ -182,6 +183,7 @@ function CiteProc.new(sys, style, lang, force_lang)
182183
requires_sorting = false,
183184
widest_label = "",
184185
maxoffset = 0,
186+
second_field_align = false,
185187
},
186188

187189
cite_first_note_numbers = {},
@@ -486,7 +488,7 @@ function CiteProc:makeBibliography(bibsection)
486488

487489
local params = {
488490
hangingindent = self.style.bibliography.hanging_indent,
489-
["second-field-align"] = self.style.bibliography.second_field_align or false,
491+
["second-field-align"] = self.style.bibliography.second_field_align or self.registry.second_field_align or false,
490492
linespacing = self.style.bibliography.line_spacing,
491493
entryspacing = self.style.bibliography.entry_spacing,
492494
maxoffset = self.registry.maxoffset,

citeproc/citeproc-manager.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,10 @@ function CslCitationManager:make_bibliography(filter_str)
822822
value = "{" .. table.concat(value, ", ") .. "}"
823823
else
824824
value = tostring(value)
825+
if string.match(value, ",") or string.match(value, "^%s")
826+
or string.match(value, "%s$") then
827+
value = "{" .. value .. "}"
828+
end
825829
end
826830
if value ~= "" then
827831
table.insert(bib_option_list, string.format("%s = %s", option, value))

citeproc/citeproc-node-group.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ else
2121
util = require("citeproc.util")
2222
end
2323

24-
local Element = element.Element
2524

25+
local Element = element.Element
2626

2727
---@class Group: Element
2828
---@field delimiter string?
@@ -50,6 +50,9 @@ function Group:build_ir(engine, state, context)
5050
ir.formatting = util.clone(self.formatting)
5151
ir.affixes = util.clone(self.affixes)
5252
ir.display = self.display
53+
if self.display == "left-margin" then
54+
engine.registry.second_field_align = "flush"
55+
end
5356
end
5457
return ir
5558
end

citeproc/citeproc-node-text.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ function Text:from_node(node)
7979
o:set_quotes_attribute(node)
8080
o:set_strip_periods_attribute(node)
8181
o:set_text_case_attribute(node)
82+
-- `apa-annotated-bibliography.csl` uses `display="block"` for annotation.
83+
-- Use display="indent" instead
84+
if o.display == "block" and (o.variable == "note" or o.variable == "abstract") then
85+
o.display = "indent"
86+
end
8287
return o
8388
end
8489

@@ -196,6 +201,9 @@ function Text:build_year_suffix_ir(engine, state, context)
196201
ir.group_var = group_var
197202
ir.affixes = util.clone(self.affixes)
198203
ir.display = self.display
204+
if self.display == "left-margin" then
205+
engine.registry.second_field_align = "flush"
206+
end
199207
ir.formatting = util.clone(self.formatting)
200208
if self.quotes then
201209
ir.quotes = context:get_localized_quotes()

citeproc/citeproc-output.lua

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,17 +1965,16 @@ LatexWriter.markups = {
19651965
["@vertical-align/baseline"] = false,
19661966
["@cite/entry"] = false,
19671967
["@bibliography/entry"] = function (str, context)
1968-
if string.match(str, "\\bibitem") then
1969-
str = str .. "\n"
1970-
else
1971-
str = "\\bibitem{" .. context.id .. "}\n" .. str .. "\n"
1968+
if not string.match(str, "\\bibitem") then
1969+
str = "\\bibitem{" .. context.id .. "}\n" .. str
19721970
end
1971+
str = str .. "\n"
19731972
return str
19741973
end,
1975-
-- ["@display/block"] = false,
1974+
["@display/block"] = "\\cslblock{%s}\n\n",
19761975
-- ["@display/left-margin"] = '\n <div class="csl-left-margin">%s</div>',
1977-
-- ["@display/right-inline"] = '<div class="csl-right-inline">%s</div>',
1978-
-- ["@display/indent"] = '<div class="csl-indent">%s</div>\n ',
1976+
["@display/right-inline"] = "%s",
1977+
["@display/indent"] = "\n\n%s",
19791978
}
19801979

19811980
local latex_escape_table = {
@@ -2038,12 +2037,19 @@ function LatexWriter:write_display(inline, context)
20382037
end
20392038
res = string.format("\\bibitem[%s]{%s}\n", res, context.id)
20402039

2041-
elseif inline.div == "right-inline" then
2042-
return res
2043-
2044-
elseif inline.div == "block" then
2045-
res = "\n\n" .. res
2046-
return res
2040+
else
2041+
local key = string.format("@display/%s", inline.div)
2042+
if inline.div == "right-inline" then
2043+
-- Strip trailing spaces
2044+
-- variables_ContainerTitleShort.txt
2045+
res = string.gsub(res, "%s+$", "")
2046+
end
2047+
local format_str = self.markups[key]
2048+
if format_str then
2049+
res = string.format(format_str, res)
2050+
else
2051+
util.error("Unknown display type: " .. inline.div)
2052+
end
20472053
end
20482054
return res
20492055
end

docs/citation-style-language-doc.tex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,20 @@ \section{Package setup}
251251
\cslsetup{bib-item-sep = 8 pt plus 4 pt minus 2 pt}
252252
\end{LaTeXdemo}
253253

254+
\DescribeOption{bib-name-sep}
255+
Vertical space to be inserted between two name groups in a per-author reference
256+
list.
257+
The default value is zero.
258+
Note that this option only takes effect when its value is larger than
259+
\opt{bib-item-sep} because it's used with \cs{addvspace}.
260+
261+
\DescribeOption{bib-after-name-sep}
262+
Vertical space to be inserted between the author block and the following
263+
entries in a per-author reference list.
264+
The default value is zero.
265+
Note that this option only takes effect when its value is larger than
266+
\opt{bib-item-sep} because it's used with \cs{addvspace}.
267+
254268
\DescribeOption{bib-hang}
255269
The \opt{bib-hang} option sets the hanging indentation length which is
256270
usually used for author-date style references.

latex/citation-style-language-bib.sty

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@
242242
}
243243
}
244244
{ \skip_set:Nn \itemsep { \l__csl_bib_item_sep_tl } }
245+
\bool_set_true:N \l_csl_bib_first_block_bool
245246
}
246247

247248

@@ -283,6 +284,26 @@
283284
\par
284285
}
285286

287+
% Used for per-author publication listing
288+
\bool_new:N \l_csl_bib_first_block_bool
289+
290+
\cs_new:Npn \cslblock #1
291+
{
292+
\bool_if:NF \l_csl_bib_first_block_bool
293+
{
294+
\skip_set:NV \l_tmpa_skip { \l__csl_bib_name_sep_tl }
295+
\addvspace { \l_tmpa_skip }
296+
}
297+
\bool_set_false:N \l_csl_bib_first_block_bool
298+
\item [ ]
299+
\skip_horizontal:n { - \leftmargin }
300+
% \hskip - \leftmargin \relax
301+
#1
302+
\par
303+
\skip_set:NV \l_tmpa_skip { \l__csl_bib_after_name_sep_tl }
304+
\addvspace { \l_tmpa_skip }
305+
}
306+
286307
\cs_new:Npn \__csl_print_back_refs:n #1
287308
% #1: list of {<page>}{<label>}{anchor}
288309
{

latex/citation-style-language.sty

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
\tl_new:N \l__csl_bib_font_tl
7777
\bool_new:N \l__csl_bib_entry_page_break_bool
7878
\tl_new:N \l__csl_bib_item_sep_tl
79+
\tl_new:N \l__csl_bib_name_sep_tl
80+
\tl_new:N \l__csl_bib_block_sep_tl
7981
\tl_new:N \l__csl_bib_par_indent_tl
8082
\tl_new:N \l__csl_bib_hang_tl
8183
\str_new:N \l__csl_bib_ref_section_str
@@ -112,6 +114,8 @@
112114
bib-font .tl_set:N = \l__csl_bib_font_tl ,
113115
bib-entry-page-break .bool_set:N = \l__csl_bib_entry_page_break_bool ,
114116
bib-item-sep .tl_set:N = \l__csl_bib_item_sep_tl ,
117+
bib-name-sep .tl_set:N = \l__csl_bib_name_sep_tl ,
118+
bib-after-name-sep .tl_set:N = \l__csl_bib_after_name_sep_tl ,
115119
bib-par-indent .tl_set:N = \l__csl_bib_par_indent_tl ,
116120
bib-hang .tl_set:N = \l__csl_bib_hang_tl ,
117121
% ref section
@@ -141,6 +145,8 @@
141145
prefix-separator = { ~ } ,
142146
suffix-separator = { , ~ } ,
143147
bib-entry-page-break = true ,
148+
bib-name-sep = { 0 pt } ,
149+
bib-after-name-sep = { 0 pt } ,
144150
bib-par-indent = { \parindent } ,
145151
bib-hang = { 1 em } ,
146152
ref-section = none ,

0 commit comments

Comments
 (0)