RE: Customizing an Asciidoctor PDF so it looks like an InfoQ Mini-Book
Last week, I wrote about customizing an Asciidoctor PDF so it looks like an InfoQ Mini-Book. Shortly after writing that blog post, Dan Allen responded to my questions and showed me how to customize Asciidoctor's PDF generation. I ended up using both techniques he described: creating a custom theme and using Ruby to override methods. To recap, here are the changes I was hoping to make:
- The colophon is not aligned to the bottom of the page.
- The title page (first one after the cover) and colophon pages should be merged.
- The dedication and acknowledgement headers are not center-aligned and underlined like InfoQ's format.
- The main sections don't have whole-page delimiters.
- The table of contents comes right after the title page, rather than after the dedication and acknowledgement.
I'm happy to report that I was able to fix most these issues, except for the second one and last one. There is a pull request to allow changing the location of the table of contents, but I was unable to make it work. I spent a good hour building the asciidoctor-pdf gem and trying to modify AsciidoctorJ to use it. In the end, I decided to mark this as a bug in the JHipster book and we'll fix it when Asciidoctor supports moving the table of contents.
To customize the output, I created an src/main/ruby/asciidoctor-pdf-extensions.rb
file and added the following code to it:
require 'asciidoctor-pdf' unless defined? ::Asciidoctor::Pdf module AsciidoctorPdfExtensions def layout_title_page doc # no title page end def layout_chapter_title node, title if node.id == "dedication" || node.id == "acknowledgements" layout_heading_custom title, align: :center elsif node.id.include? "mini-book" # colophon move_down 470 layout_heading title, size: @theme.base_font_size elsif node.id.include? "jhipster" #chapters puts 'Processing ' + node.id + '...' move_down 120 # set Akkurat font for all custom headings font 'Akkurat' layout_heading 'PART', align: :right, size: 120, color: [91, 54, 8, 13], style: :normal move_up 40 part_number = "ONE" if node.id.include? "ui-components" part_number = "TWO" elsif node.id.include? "api" part_number = "THREE" end layout_heading part_number, align: :right, size: 120, color: [42, 1, 83, 1], style: :bold layout_heading title, align: :right, color: [42, 1, 83, 1], style: :normal, size: 30 move_up 30 start_new_page else # delegate to default implementation super end end def layout_heading_custom string, opts = {} move_down 100 typeset_text string, calc_line_metrics((opts.delete :line_height) || @theme.heading_line_height), { inline_format: true }.merge(opts) move_up 5 $i = 0 underline = '' while $i < string.length do if string == 'Dedication' underline += '/////' else underline += '//////' end $i += 1 end if string == 'Dedication' underline += '////' end typeset_text underline, calc_line_metrics((opts.delete :line_height) || @theme.heading_line_height), { inline_format: true, color: 'B0B0B0', size: 8, style: :italic }.merge(opts) move_down 20 end end Asciidoctor::Pdf::Converter.prepend AsciidoctorPdfExtensions
Then I modified build.gradle
to use this file.
asciidoctor { backends 'html5', 'pdf', 'epub3' attributes 'sourcedir': '../../../main/webapp', 'source-highlighter': 'coderay', 'imagesdir': './images', toc: 'left', icons: 'font', linkattrs: true, encoding: 'utf-8', 'setanchors': true, 'idprefix': '', 'idseparator': '-', 'docinfo1': 'true' requires file('src/main/ruby/asciidoctor-pdf-extensions.rb') }
After getting this to work, we're very close to publishing the JHipster Mini-Book! Thanks to Dan for creating Asciidoctor and supporting this great open source project. It's been a pleasure to write with it and the editing process with Git and pull requests has been wonderful.
Update: The JHipster Mini-Book has been released!