Skip to content
This repository has been archived by the owner on Apr 30, 2021. It is now read-only.

Hanging indent #410

Closed
njbart opened this issue Aug 14, 2019 · 24 comments
Closed

Hanging indent #410

njbart opened this issue Aug 14, 2019 · 24 comments

Comments

@njbart
Copy link
Contributor

njbart commented Aug 14, 2019

Currently, pandoc-citeproc ignores the hanging-indent="true" flag in .csl style files. While it is almost trivial to obtain hanging indentation in the references section in html (via css), there is no easy way to do this if the output format is latex or pdf.

(So far, I have been using this filter for tweaking the latex output by wrapping the references section in a references latex list environment, complemented by a suitable definition of the environment in the latex template.)

It seems difficult to simplify this setup since pandoc’s latex output currently does not provide hooks of any kind in connection with the references section, e.g., a latex enviroment analogous to <div id="refs" class="references"> in html output.

So, I’d like to suggest, as a minimum, to start wrapping the references section (excluding its header) in a latex environment, e.g., \begin{references}\end{references} (or possibly, for maximal clarity, \begin{pandocreferences}\end{pandocreferences}).

Of course this would have to be defined in the latex template. As a minimum, this could be set up to do nothing:

\newenvironment{references}{}{}

… and users would be able to redefine this as they see fit.

A further step could be to provide a suitable definition for hanging indentation in the template. This would make hanging indentation the default, but since a large majority of CSL styles calls for hanging indentation anyway, pandoc’s latex output would actually be correct more often than it is currently.

One option would be to add, in the template, \usepackage{hanging}, and define \newenvironment{references}{\hangparas{2em}{1}}{\endhangparas}. Of course, one could avoid loading an additional package by providing a functionally equivalent definition in a few lines of latex code.

A final step would be to actually honour CSL’s hanging-indent flag by having pandoc-citeproc read this from the .csl file, setting a pandoc variable (which could be called hanging-indent as well), and adding a suitable if-then-else construct to the latex template.

@jgm
Copy link
Owner

jgm commented Aug 20, 2019

Currently reference are wrapped in

,Div ("refs",["references"],[])

One solution would be to add the hanging-indent class if hanging-indent is set in the CSL style.

,Div ("refs",["references","hanging-indent"],[])

Then we could add a CSS rule for hanging-indent to the default HTML template.
For LaTeX, we could react to this class by surrounding the contents of the div by

\hangindent=\parindent
...
\hangindent=0

Other writers could also be modified to be sensitive to this class.

@njbart
Copy link
Contributor Author

njbart commented Aug 21, 2019

As to html: sounds fine.

As to LaTeX, I’m worried that as is, your proposed solution isn’t suitably configurable:

  • \hangindent=\parindent will not work, since pandoc’s default for \parindent is 0pt (unless the indent variable is set). Also, \hangindent might have to be set to a value different from \parindent.
  • A single \hangindent=... will not work, since the scope of \hangindent is limited to the current paragraph.
    • “When you specify hanging indentation, it applies only to the next paragraph (if you’re in vertical mode) or to the current paragraph (if you’re in horizontal mode).” (http://tug.ctan.org/info/impatient/book.pdf, p. 117)
  • So, e.g., \hangindent=2em would have to be prepended to each paragraph.
    • \hangindent=0 wouldn’t be necessary though.
  • However, users or style guides may require a different amount of hanging indent. The CSL specs do not give a specific length, and style guides vary. MLA 8e (p. 122) says “half an inch”. APA and CMOS don’t give explicit values, but the examples in APA 6e, p. 193 ff. display a hanging indent of about 2em, CMOS 17e shows example bibliographies with about 1em (p. 778), 2em (p. 779), and around 1.5em for individual examples throughout the text.
  • In addition, users might want to format other details in a different way: e.g., linestretch, font, fontsize, etc. This would be comparatively easy to do with an environment but hard with individual \hangindent=... commands.
  • That’s why I continue to feel only a latex environment will provide the required flexibility.

I have run a few tests wrapping all the paragraphs in a reference section of a pandoc-generated latex file in \begin{references} ... \end{references}, and defining:

\newenvironment{references}{\everypar{\setlength{\hangindent}{2em}}}{\par}

or

\newlength{\refhangindent}
\setlength{\refhangindent}{2em}
\newenvironment{references}{\everypar{\setlength{\hangindent}{\refhangindent}}}{\par}

… and both seem to work very well.

@jgm
Copy link
Owner

jgm commented Aug 21, 2019

Just wrapping in a references environment wouldn't give you sensitivity ot the hanging-indent attribute, though. You'd have to modify the template or use a variable to do that separately.

We could use a special hanging environment just in the case where the hanging-indent attribute is used. Or we could have something like

\newenvironment{references}[1][0em]{\everypar{\setlength{\hangindent}{#1}}}{\par}
```
and then emit either
```
\begin{references}[\refhangindent]
```
or just
```
\begin{references}
```

@jgm
Copy link
Owner

jgm commented Aug 21, 2019

Maybe setting it up so you can do

\begin{references}[hanging]

would be cleaner.

@njbart
Copy link
Contributor Author

njbart commented Aug 22, 2019

Just wrapping in a references environment wouldn't give you sensitivity ot the hanging-indent attribute, though. You'd have to modify the template or use a variable to do that separately.

Right. I was thinking along these lines:

  1. pandoc-citeproc checks if the .csl file has hanging-indent set to true.
    If so, it sets the pandoc variable csl-hanging-indent (or so) to true.

  2. default.latex contains

    \newlength{\cslhangindent}       % set up new length
    \setlength{\cslhangindent}{0em}  % set to default value
    \newenvironment{cslreferences}{\everypar{\setlength{\hangindent}{\cslhangindent}}}{\par}
                                     % by default, this env does not change anything
    $if(csl-hanging-indent)$
    \setlength{\cslhangindent}{2em}
    $endif$
    
  3. If pandoc does emit (csl) references, it just wraps them in

    \begin{cslreferences}
    ...
    \end{cslreferences}
    
  4. (optional) Users can override this by inserting (in header-includes or include-before), e.g.:

    • \setlength{\cslhangindent}{0em} (if a .csl says “hanging indent” but they don’t want it)
    • \setlength{\cslhangindent}{7em} (if they want to override a .csl saying “no hanging indent” but they do want it, or simply want a value other than the default.)

ALTERNATIVE:

  1. pandoc-citeproc checks if the .csl file has hanging-indent set to true.
    If so, it sets the pandoc variable csl-hanging-indent to 2em. Else, to 0em.

  2. default.latex contains

    \newlength{\cslhangindent}       % set up new length
    \setlength{\cslhangindent}{0em}  % set to default value
    \newenvironment{cslreferences}{\everypar{\setlength{\hangindent}{\cslhangindent}}}{\par}
                                     % by default, this env does not change anything
    $if(csl-hanging-indent)$
    \setlength{\cslhangindent}{$csl-hanging-indent$}
    $endif$
    
  3. As above.

  4. Users can override this by setting the pandoc variable csl-hanging-indent to any length they are happy with.

NOTES:

  • I think it’s helpful to prefix all CSL things that are written out to a latex file with a string like csl, in order to distinguish them clearly from any natbib or biblatex stuff.
  • I’m not sure whether there is a pandoc variable that is set iff pandoc-citeproc is called. If so, the proposed definitions in default.latex could be made conditional on that variable being set.

@jgm
Copy link
Owner

jgm commented Aug 22, 2019

pandoc-citeproc checks if the .csl file has hanging-indent set to true. If so, it sets the pandoc variable csl-hanging-indent (or so) to true.

This can't be done. pandoc-citeproc simply modifies the pandoc AST. Variables are not part of that (they are part of writer options). pandoc-citeproc could set a metadata field, which would then populate a variable, but I prefer not to mess with metadata, since some output formats will put this in metadata blocks.

Hence my thought that this should not be handled in the template, though the template might need to define a default environment.

@jgm
Copy link
Owner

jgm commented Aug 22, 2019

I suppose the latex writer could be modified to inspect the refs div and set the csl-hanging-indent variable if this div has a hanging-indent class. That would be the way to go if we wanted to push as much as possible to the template.

@njbart
Copy link
Contributor Author

njbart commented Aug 23, 2019

I suppose the latex writer could be modified to inspect the refs div and set the csl-hanging-indent variable if this div has a hanging-indent class. That would be the way to go if we wanted to push as much as possible to the template.

Sounds excellent.

Just to check if I understand this correctly: So pandoc-citeproc (1) cannot set a pandoc variable itself, but (2) it could in principle set a metadata field (though you prefer not to take this route), and (3) it can write pretty much anything into the pandoc AST, which pandoc itself can use to set a pandoc variable? If so, (3) seems it could be made to work without any user intervention, which would be great.

If (3) can be made to work, there’s no need of me arguing in favour of (2), but out of curiosity: Would it really pose a problem if csl-hanging-indent appeared in the metadata, compared to existing user-definable sizes such as linestretch, geometry, papersize, …?

@jgm
Copy link
Owner

jgm commented Aug 23, 2019

Maybe it would be okay to put this in metadata, but it would mean it's included in meta tags in HTML, properties in Word, YAML markdown blocks, ...

@njbart
Copy link
Contributor Author

njbart commented Aug 23, 2019

Again, if (3) can be expected to work just as well, we don’t really need to discuss (2).

FWIW, I tried putting a few random pandoc variables (colorlinks, linestretch, papersize, classoption) into the YAML metadata block of a markdown source file, and these did appear in docx and odt output (where at least the last three don’t make any more sense than csl-hanging-indent would) and of course in the YAML metadata block of markdown output, but they did not show up in epub, html, or docbook (that’s all I tried so far).

jgm added a commit that referenced this issue Sep 3, 2019
This depends on whether the `hanging-indent` attribute of
`<bibliography>` is true.

See #410.
@jgm
Copy link
Owner

jgm commented Sep 3, 2019

I've implemented this. To test, get latest pandoc master and latest pandoc-citeproc master, and change stack.yaml in pandoc so you've got

 packages:
 - '.'
- '../pandoc-citeproc'

Also remove the stanza under extra-deps for pandoc-citeproc. Then stack install pandoc pandoc-citeproc.

@njbart
Copy link
Contributor Author

njbart commented Sep 3, 2019

Excellent, works like a charm for both hanging-indent styles like chicago-author-date.csl and non-hanging-indent styles like harvard-cite-them-right.csl.

One thing I hadn’t considered though is that pandoc’s indent variable might be set. If so, results are not quite right yet. I’d suggest replacing:

$if(csl-refs)$
\newlength{\cslhangindent}       % set up new length
\setlength{\cslhangindent}{$if(csl-hanging-indent)$2em$else$0em$endif$}
\newenvironment{cslreferences}%
  {\everypar{\setlength{\hangindent}{\cslhangindent}}}%
  {\par} % by default, this env does not change anything
$endif$

with

$if(csl-refs)$
\newlength{\cslhangindent}       % set up new length
\setlength{\cslhangindent}{$if(csl-hanging-indent)$1.5em$else$0em$endif$}
\newenvironment{cslreferences}%
  {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}%
  \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}%
  {\par} % by default, this env does not change anything
$endif$
  • Since the default indent of standard LaTeX styles is (or is close to) 1.5em (see e.g. here), I’d suggest using 1.5em for hanging indent, too. (The combination of conventional indent in the text and hanging indent in the references section looks much better this way.)
  • If indent is set, and we want hanging indent we need to set \parindent to zero for the cslreferences environment, hence \setlength{\parindent}{0pt}.
    We wouldn’t want to set it to zero, however, if indent is set, and we don’t want hanging indent, that’s why this is wrapped in $if(csl-hanging-indent)$... $endif$.

@jgm
Copy link
Owner

jgm commented Sep 3, 2019

I've simplified to

$if(csl-refs)$
\newlength{\cslhangindent}
\setlength{\cslhangindent}{1.5em}
\newenvironment{cslreferences}%
  {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}%
  \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}%
  {\par}
$endif$

The thinking is that it's harmless to set \cslhangindent unconditionally, since it's only used when csl-hanging-indent is set. Let me know if you see more room for improvement.

@jgm
Copy link
Owner

jgm commented Sep 3, 2019

We may want to think about adding something to the html-based templates (including e.g. revealjs), the epub default css, and the ms and context templates. This would also require changes to the writers to make sure variables are set.

@jgm
Copy link
Owner

jgm commented Sep 3, 2019

Oh, and it would be nice to make the docx writer sensitive to this, as well.

@njbart
Copy link
Contributor Author

njbart commented Sep 4, 2019

A number of html-based templates share the same style element:

  <style>
      code{white-space: pre-wrap;}
      span.smallcaps{font-variant: small-caps;}
      span.underline{text-decoration: underline;}
      div.column{display: inline-block; vertical-align: top; width: 50%;}
  </style>

All it would seem to take to make hanging indent work is to add one line:

      div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}

Would a PR for the following files be welcome?

data/templates/default.html4
data/templates/default.html5
data/templates/default.s5
data/templates/default.slideous
data/templates/default.slidy
test/s5-basic.html
test/s5-fancy.html
test/s5-inserts.html

@jgm
Copy link
Owner

jgm commented Sep 4, 2019

Yes, sure.

@jgm
Copy link
Owner

jgm commented Sep 5, 2019

I'll do this myself as part of a refactor.

@jgm
Copy link
Owner

jgm commented Sep 5, 2019

See 381654a7043184c0b0ddf1c2e3fe5c35bfb1cd47

@denismaier
Copy link

Very good that this is finally coming! When will this be available in an official release?

Would be great to have this available with ConTeXt as well. What would be needed for this?

@denismaier
Copy link

That could be a start:

$if(csl-refs)$
\newdimen\cslhangindent
\cslhangindent=1.5em
\definestartstop [cslreferences] [
	$if(csl-hanging-indent)$
	before={%
		\setupnarrower[left=\cslhangindent]
    	\startnarrower[left]%
    	\setupindenting[-\leftskip,yes,first]%
    	\setuphead[chapter][indentnext=yes]%
  	},
  	after=\stopnarrower,
	$endif$
]
$endif$

@jgm
Copy link
Owner

jgm commented Sep 25, 2019

This will be in the next pandoc and pandoc-citeproc release (hopefully in the coming month).
If you want to submit a PR for a change to pandoc's context template, you can do that at jgm/pandoc.

@denismaier
Copy link

Ok. I can do this once the new version is out. But I guess we will have to change to context writer as well so that the references are wrapped in \startcslreferences ... \stopcslreferences, but I don't know how to do this.

@jgm
Copy link
Owner

jgm commented Sep 26, 2019

Put a note in your PR and I can handle that part.

jgm pushed a commit to jgm/pandoc that referenced this issue Nov 17, 2019
Define an start-stop-pair `cslreferences` to allow for hanging indents in the bibliography. Analogous to the cslreferences-environment in the default latex template. See here: jgm/pandoc-citeproc#410
For this to work the context writer must be adapted.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants