rstudio / bookdown

Authoring Books and Technical Documents with R Markdown
https://pkgs.rstudio.com/bookdown/
GNU General Public License v3.0
3.74k stars 1.26k forks source link

References at the end of each chapter in pdf book #1400

Open dppalomar opened 1 year ago

dppalomar commented 1 year ago

When generating a pdf book (via latex), the references are included at the end of the book. I wonder how one could include the references on a chapter basis, i.e., at the end of each chapter. (In fact, when generating an html book, they are placed at the end of each section.)

I could not find an automatic way to accomplish did with bookdown. Then I thought of doing it by hand from the tex files, but that would require one tex file per chapter, which bookdown does not seem to generate (instead it generates one single tex file).

Anybody has any suggestion?

One thousand thanks!!

cderv commented 1 year ago

I don't think this is made possible by Pandoc if you use its citation system.

If you are using LaTeX citation engine like natbib maybe you can do that using some tools like [chapterbib]( from what I see in https://texfaq.org/FAQ-chapbib and http://wiki.davidhaberthuer.ch/latex#chapterbib but using that would required some heavy tweak the Pandoc template probably so that requires some customization. but seems possible.

(In fact, when generating an html book, they are placed at the end of each section.)

This is because we do a specific post processing for HTML after Pandoc has generated the bibliography at the end to move everything in each chapter. We don't do that in LaTeX... yet.

If you find a way to do this somehow and it is easy enough to add in our package, we could provide this feature. But it does not see that easy in LaTeX already, so research and Proof of Concept should happen there first.

Hope it helps

dppalomar commented 1 year ago

Dear @cderv , thanks for your prompt reply. I found a way to do it and it could be easily be incorporated into bookdown for the future.

I found the solution in this 5-year old link: https://stackoverflow.com/questions/45028623/is-there-a-way-to-add-chapter-bibliographies-using-bookdown

Two solutions were proposed as discussed next.

1) One solution is based on natbib with the option sectionbib in combination with the package chapterbib. However, this doesn’t really work because chapterbib needs each chapter in a separate tex file with a main tex file including these tex files. Unfortunately, bookdown doesn’t do that… But it could easily do that with some option in the YAML header (please @yihui, I know you want to make things easier and transparent to the user, but this wouldn’t change that aspect and it would allow others to really do much more in the production of a pdf book, please reconsider).

BTW, in passing, let me mention from this link https://stackoverflow.com/questions/44770287/adding-natbib-options-for-pdf-output that the YAML option natbiboptions does not really work yet. It’s not critical as it can still be achieved with a hack (basically by loading the package natbib in the preamble with the desired options, the next time that bookdown includes the package without options the original options should prevail, I believe).

2) The other solution is instead based on biblatex (this is not ideal for me as I had a .bst file to use which only works with natbib, but well). I managed to make it work with a few minor hacks. @cderv: I believe this method could be easily incorporated in bookdown. These are the hacks in the different files (I just realized that the same hacks were used in https://github.com/rstub/bookdown-chapterbib):

Finally, since bookdown automatically includes the reference list at the end of the book (again, this could be controlled by some YAML option), I have to do a small hack to remove it: after all the chapters, I need to include the command:

\def\printbibliography{}

For completeness, there seems to be another solution here with a lua filter that I didn’t explore: https://community.rstudio.com/t/one-bibliography-per-chapter-when-using-pandoc-for-citations/117105/3

Best, Daniel

cderv commented 1 year ago

Wow @dppalomar thanks a lot ! I wasn't aware of rstub/bookdown-chapterbib - that is cool !

I see there are several solutions. I forgot about the lua filter one - I wonder if that would not be the cleanest. See here for the new filter. https://github.com/pandoc-ext/section-bibliographies I wonder if this works out of the box, and maybe we could bundle it to be easily opt-in. I'll have a look

Finally, since bookdown automatically includes the reference list at the end of the book

Yes this is added by Pandoc's template (https://github.com/jgm/pandoc/blob/4db5b05abc4f1509f17f029017016b48cebd2f1f/data/templates/default.latex#L539-L547) - It would require to provide a modified template without this. It is not really possible with an option in Bookdown, unless to pre process the template to modify it.

cderv commented 1 year ago

I wonder if this works out of the box,

Ok so I tested quickly and it works.

Add the filter to your project, then add the lua filter to your PDF format

bookdown::pdf_book:
  includes:
    in_header: preamble.tex
  latex_engine: xelatex
  citation_package: natbib
  keep_tex: yes
  pandoc_args: ['--lua-filter=section-bibliographies.lua']

in index.Rmd add this field for specific variable to give a name to the section in each chapter

reference-section-title: References

To remove the bibliography at the end you would still need to modify the template before rendering. You can download the template on Github, or export it for your pandoc version at command line (or using this R function which is a helper for that pandoc::pandoc_export_template()

@yihui I believe this filter would also work for HTML and citeproc. We could replace our tricks to move the bibliography with R code using regex by using this filter probably. Could worth the work on the long term if we want to support split_bib option for HTML and PDF.

yihui commented 1 year ago

@yihui I believe this filter would also work for HTML and citeproc. We could replace our tricks to move the bibliography with R code using regex by using this filter probably. Could worth the work on the long term if we want to support split_bib option for HTML and PDF.

Sounds like a good idea!

dppalomar commented 1 year ago

@cderv Thanks for the lua based solution. I implemented it as you describe and it works. However, I get a problem. For some reason, the chapter references do not follow the style indicated in biblio-style (e.g., biblio-style: apalike or some other .bst file). Perhaps there is another way to indicate the style?

Also, I noticed that the separation between the section header and the text is smaller than in other sections. Weird.

Thanks.

cderv commented 1 year ago

Interesting. It could be some issue or missing feature with the filter. At least interesting feedback for the filter.

You could maybe open your feedback there and we can discuss with the author who know it better.

HenrikEckermann commented 3 months ago

Dear @cderv , thanks for your prompt reply. I found a way to do it and it could be easily be incorporated into bookdown for the future.

I found the solution in this 5-year old link: https://stackoverflow.com/questions/45028623/is-there-a-way-to-add-chapter-bibliographies-using-bookdown

Two solutions were proposed as discussed next.

  1. One solution is based on natbib with the option sectionbib in combination with the package chapterbib. However, this doesn’t really work because chapterbib needs each chapter in a separate tex file with a main tex file including these tex files. Unfortunately, bookdown doesn’t do that… But it could easily do that with some option in the YAML header (please @yihui, I know you want to make things easier and transparent to the user, but this wouldn’t change that aspect and it would allow others to really do much more in the production of a pdf book, please reconsider).

BTW, in passing, let me mention from this link https://stackoverflow.com/questions/44770287/adding-natbib-options-for-pdf-output that the YAML option natbiboptions does not really work yet. It’s not critical as it can still be achieved with a hack (basically by loading the package natbib in the preamble with the desired options, the next time that bookdown includes the package without options the original options should prevail, I believe).

  1. The other solution is instead based on biblatex (this is not ideal for me as I had a .bst file to use which only works with natbib, but well). I managed to make it work with a few minor hacks. @cderv: I believe this method could be easily incorporated in bookdown. These are the hacks in the different files (I just realized that the same hacks were used in https://github.com/rstub/bookdown-chapterbib):
  • In _output.yml:
citation_package: biblatex
  • In the YAML header of index.Rmd:
biblio-style: apa
biblatexoptions: [refsegment=chapter]
  • Then, at the end of each chapter file chapterXX.Rmd:
\printbibliography[segment=\therefsegment,heading=subbibliography]

Or with a few more options:

\phantomsection
\clearpage\markright{}
\addcontentsline{toc}{section}{References}
\setlength\bibitemsep{0.5\baselineskip}
\printbibliography[segment=\therefsegment,heading=subbibliography]

Finally, since bookdown automatically includes the reference list at the end of the book (again, this could be controlled by some YAML option), I have to do a small hack to remove it: after all the chapters, I need to include the command:

\def\printbibliography{}

For completeness, there seems to be another solution here with a lua filter that I didn’t explore: https://community.rstudio.com/t/one-bibliography-per-chapter-when-using-pandoc-for-citations/117105/3

Best, Daniel

Thanks so much for sharing this solution. This almost works for me. The only thing that does not work is that:

\def\printbibliography{}

Without this command all looks fine except that I have a ref list at the very end again. With this command, only the first chapter works fine and then all others have something like this [segment=7,heading=subbibliography] printed instead of the ref list.

If you have any idea what the cause of that is please share. I am still looking for a solution to this issue.