asciidoctor / asciidoctor-pdf

:page_with_curl: Asciidoctor PDF: A native PDF converter for AsciiDoc based on Asciidoctor and Prawn, written entirely in Ruby.
https://docs.asciidoctor.org/pdf-converter/latest/
MIT License
1.15k stars 499 forks source link

Styling of part pages #671

Closed vogella closed 2 years ago

vogella commented 8 years ago

At the moment the styling of a part page is quite rudimentary. It is only possible to style the h1 element as with:

heading:
  h1:
    font_size: $base_font_size * 1.8
    font_color: 999999
    font_style: italic
    align: right

We would need to style part pages similar like title pages.

title_page:
  align: right
  logo:
    top: 40%
    align: right
    image: image:GrayMagier.png[pdfwidth=17%]
  title:
    top: 55%
    font_size: $heading_h1_font_size * 1.4
    font_color: 999999
    line_height: 0.9
vogella commented 8 years ago

@fap- can you have a look?

mojavelinux commented 8 years ago

This seems pretty reasonable. In the meantime, you can override the layout_part_title node, title, opts method similar to what Matt Raible did for the InfoQ minibook.

https://github.com/mraible/infoq-mini-book/blob/master/src/main/ruby/asciidoctor-pdf-extensions.rb

mojavelinux commented 8 years ago

If we do this, we should probably abstract away a generic method that handles a configuration-driven, full-page layout.

fapdash commented 7 years ago

I'd like to start working on this. Do you have some suggestions how this generic method should work? Do you mean a generic abstraction above all the layout_ methods and/or would you like to extend customizability above the level that the title page currently allows?

fapdash commented 7 years ago

@mojavelinux I thought about this for a while and I'd really like to make the layout more extendable. The way the theme gets loaded into an OpenStruct instead of an Hash makes it harder to utilize the structured nature of Yaml to make this possible. Is there a reason for the decision to load it this way?

I'd propose a structure likes this. The new flexible parts are highlighted with a # comment.

pages:
  title:
    align: right
    images:                                                 # insert arbitrary images without asciidoctor knowing about them beforehand
      logo:
        top: 40%
        align: right
        image: image:GrayMagier.png[pdfwidth=17%]
    title:
      top: 55%
      font_size: $heading_h1_font_size * 1.4
      font_color: 999999
      line_height: 0.9
    subtitle:
      font_size: $heading_h3_font_size
      font_style: bold_italic
      line_height: 1
    authors:
      margin_top: $base_font_size * 1.25
      font_size: $base_font_size_large
      font_color: 181818
  chapter:
    # default case, special chapters inherit these
    title:
      top: 55%
      font_size: $heading_h1_font_size * 1.4
      font_color: 999999
      line_height: 0.9
    images:
      logo:
        top: 40%
        align: right
        image: image:GrayMagier.png[pdfwidth=17%]
    chapters:
      colophon:                                               # special layout for certain chapter pages, gets matched with section_title.downcase
        align: left
        title:
          top: 50%
        images:                                               # insert arbitrary images without asciidoctor knowing about them beforehand
          flower:
            top: 60%
            align: right
            image: image:FlowerPower.png
        texts:                                                # makes it possible to insert arbitrary text to specific positions on chapter page
          underline:
            top: 50%
            text: "/////////"                                 # I'd rather have a way to give an id to a line of text in the asciidoc and reference it here than to have this in the theme
            margin_top: $base_font_size * 1.25

There should probably be a :chapter_page_on_own_page: option to trigger start_new_page after the layout is done. (with a better name, of course :laughing: )

I'm not sure if this is going in the right direction but I'd like to hear your thoughts on the idea.

fapdash commented 7 years ago

The implementation we are currently using is found here: https://github.com/vogellacompany/asciidoctor-pdf/tree/styling_of_part_pages This implementation is less generic and less powerful than what I proposed in my post above, but it works around the (perceived) limitations of the theme loading. Also note that possible page_prefixs are hard coded, this could be solved with a list in the adoc file that contains possible page_prefix values. eg. :chapter_pages: index, appendix

Example config:

chapter_page:
  align: right
  logo:
    top: 10%
    align: right
    image: image:GrayMagier.png[pdfwidth=17%]
  title:
    top: 70%
    font_size: $heading_h1_font_size * 1.4
    font_color: 999999
    line_height: 0.9
appendix_page:
  align: left
  logo:
    top: 30%
    align: right
    image: image:GrayMagier.png[pdfwidth=17%]
  title:
    top: 50%
    font_size: $heading_h1_font_size * 1.4
    font_color: 999999
    line_height: 0.9
vogella commented 7 years ago

@mojavelinux AFAIK this is currently our last local modification of asciidoctor and asciidoctor-pdf for our builds. Please let @fap- know in case he can help to bring this into the standard.

vogella commented 7 years ago

@mojavelinux can we help you to bring this into standard?

gdamore commented 6 years ago

I've used overriding layout_part_title to great effect. But if I had this, I would probably not have bothered to do so.

One thing I wish for Part titles is the ability to have a "subtitle" for the part.

For example, I have part "Section 3: Library Interfaces". The colon separates these, and in my "custom" version layout_part_title I split this up, render them separately, aligned to the right, with a horizontal rule between them. (I also use a different font, which made me create a magical header level -- h0 -- so that I could have a different font in the theme.)

ViToni commented 3 years ago

Not sure if this is the correct issue but I'd love to be able to hide part/chapter pages. I'm trying to move the family recipe collection from LaTeX to AsciiDoc to allow "contributions" from the non-techies. The basic structure is category (chapter) => recipe (section) and the category is only used to structure the ToC. As such there is no need to have a page with a "Cakes" title alone. I'd like to be able to decide on a per cases basis if the chapter title should be shown. Maybe there will be some generic cake text in the future for which it would make sense to show it again (while for "Soups" there is no text and therefore no need to show the chaper title). Maybe something working as the opposite of [discrete] would work?

mojavelinux commented 3 years ago

AsciiDoc provides preprocessor conditionals for this sort of use case. You can learn about them here: https://docs.asciidoctor.org/asciidoc/latest/directives/conditionals/

I invite you to ask questions about use cases in the community chat at https://asciidoctor.zulipchat.com. It's not generally considered a good practice to append tangential use case questions to the bottom of an issue.

ViToni commented 3 years ago

Thanks for the tip with the preprocessor conditionals and the forum. However, I have not yet found a way to add an entry to the ToC using the preprocessor conditionals without also displaying it in the actual document. I will ask questions about this in the forum. Sorry if I gave the impression to hijack this thread. That was not my intention at all. I've only been dealing with AsciiDoc for a week had been looking for various solutions and this issue seemed related, perhaps because my first idea was to display this page differently or as an alternative not display it at all.

mojavelinux commented 3 years ago

No problem at all. I look forward to seeing you in the forum.

mojavelinux commented 2 years ago

I think this is best handled by an extended converter. The reason is, if we start adding keys to the theme, where does it end? We cannot possibly account for all the ways in which a part page can be styled, and anything we do add will likely be insufficient for all but those who were involved in specifying it. Therefore, we've decided not to pursue this change. Instead, we will focus on adding docs for how to make an extended converter to cover this use case. Specifically, the docs will explain how to extend the converter to customize the behavior of the layout_part_title method.

Here's an example that shows how that can be done:

class MyPdfConverter < (Asciidoctor::Converter.for 'pdf')
  register_for 'pdf'

  def layout_part_title sect, title, opts
    canvas do
      fill_bounds 'EEEEEE'
    end
    move_down cursor * 0.5
    stroke_horizontal_rule '0000AA', line_width: 5
    # NOTE: control h1_margin_top, h1_margin_bottom, and h1_text_align using theme
    super
    stroke_horizontal_rule '0000AA', line_width: 5
  end
end

You are free to add images, additional text, or whatever else you want to the page.

If you want to break the title apart, then you might not want to delegate to super. Instead, you may want to call layout_heading, which accepts a string and optional opts. You could also just use typeset_text or layout_prose if you want to add text bit by bit.

I'll leave this open until this example is transfer to the (new) docs.

mojavelinux commented 2 years ago

You can find to use as a starting point at the following location: https://github.com/asciidoctor/asciidoctor-pdf/blob/main/docs/modules/extend/examples/pdf-converter-custom-part-title.rb Keep in mind that the custom converter can still consult the theme keys via the theme accessor (e.g., theme.part_title_font_color).

This example, as well as others, will be included in the documentation published with the Asciidoctor PDF 2.0.0 release.