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.14k stars 500 forks source link

Two or more themes for the tables #959

Closed deftmaster closed 2 years ago

deftmaster commented 5 years ago

Dear community,

I am sorry if I re-open the Issue. I tried to find the simmilar topic and failed. I would like to use different themes for tables. According to default yml theme, I create the common style for all tables. What if I want to specify fonts, backgrounds, paddings and margins for several tables, which do not follow the common style?

Thanks in advance!

mojavelinux commented 5 years ago

It's not possible to use a different theme for a table. You can style all tables using the following properties: https://github.com/asciidoctor/asciidoctor-pdf/blob/master/docs/theming-guide.adoc#keys-table

deftmaster commented 5 years ago

Hello Dan,

thank you very much for the reply.

fref commented 5 years ago

I would be very nice to be able to specify to use a role for a table to theme it. That way, we could have a default theme for all tables, but also have some tables themed differently (but consistently)

fref commented 5 years ago

Some sort of syntax like this:

[cols="1,3,1,1", theme="customrole"]
|===
| Key | Value
|===

and then in the yaml theme:

role:
  customrole:
    table:
      header-cell:
        background-color: [255,50,80]
mojavelinux commented 5 years ago

I looked into it and this is not an easy change. It could be done by making all the theme keys in convert_table dynamic. Then roles could be used for this. But I would not recommend modifying the structure of a role. That's unnecessary. The role would be a drop-in replacement (or override) for the table category. In other words, there's no need for the table segment in what you proposed.

Honestly, it's probably better to do this by extending the converter and adding your own logic. You could still use roles from the theme, but you can control how you want to use them. See https://github.com/asciidoctor/asciidoctor-pdf/blob/master/docs/theming-guide.adoc#extending-the-converter

mojavelinux commented 2 years ago

I still hold the same position. Theming tables is incredibly complex and the way roles in the theme are designed are not easily mapped for this purpose. The good news is that this is relatively straightforward to patch in using an extended converter. Here's how you could do it:

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

  def convert_table node
    if (role = node.role)
      key_prefix = %(role_table_#{role}_)
      unless (role_entries = theme.each_pair.select {|name, val| name.start_with? key_prefix }).empty?
        prev_theme = (curr_theme = theme).dup
        role_entries.each do |name, val|
          curr_theme[%(table_#{name.to_s.delete_prefix key_prefix})] = val
          curr_theme.delete_field name
        end
        super
        @theme = prev_theme
        return
      end
    end
    super
  end
end

What this does is promote the keys defined under role_table_rolename_ to the main table category, calls the super method, then restores the theme to its previous state.

While that works as an extended converter, there are a lot of design decisions that we're skipping around that would make this hard to integrate directly into the main converter. However, if a pattern emerges, we can always reconsider.

fref commented 2 years ago

Thank you, I'll have to examine this.

On Tue, 17 May 2022 at 11:58, Dan Allen @.***> wrote:

I still hold the same position. Theming tables is incredibly complex and the way roles in theme are designed are not easily mapped for this purpose. The good news is that this is relatively to patch in using an extended converter. Here's how you could do it:

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

def convert_table node if (role = node.role) key_prefix = %(roletable#{role}_) unless (role_entries = theme.each_pair.select {|name, val| name.start_with? key_prefix }).empty? prev_theme = (curr_theme = theme).dup role_entries.each {|name, val| currtheme[%(table#{name.to_s.delete_prefix key_prefix})] = val } super @theme = prev_theme return end end super endend

What this does is promote the keys defined under role_tablerolename to the main table category, calls the super method, then restores the theme to its previous state.

While that works as a custom converter, there are a lot of design decisions that we're skipping around that would make this hard to integrate directly into the converter. However, if a pattern emerges, we can always reconsider.

— Reply to this email directly, view it on GitHub https://github.com/asciidoctor/asciidoctor-pdf/issues/959#issuecomment-1128668223, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA76CBAI7A537B3XQSVWPDVKNUVLANCNFSM4GDWQUZQ . You are receiving this because you commented.Message ID: @.***>