Search code examples
pdfcodenameoneapache-fopasciidocasciidoctor

How to generate a cover image picture with asciidoctor-fopub


I'm trying to customize our developer guide pdf to have a decent looking first page. I'm totally fine with doing everything in photoshop as an image since asciidoc seems to be pretty limited in abilities here.

Unfortunately despite looking everywhere I can't seem to find a single way to customize the cover sheet or replace it with an image that works for asciidoctor-fopub.

The annoying thing is that this use case is specifically mentioned in the readme of the project https://github.com/asciidoctor/asciidoctor-fopub (under Custom XSL templates) but there is no mention on how to actually do it other than "its in the XSL". As someone who isn't familiar with docbook I have no idea where to begin.

asciidoctor-pdf has a tag for including an image but it barfs on our document and generates garbage (the ToC is painted over everything).


Solution

  • This can be done using division.xsl file under build/fopub/docbook/fo/

    search for "Placeholder templates"

    and paste below code there, you will be able to see cover image in your generated fopub

    <!-- Placeholder templates -->
    <xsl:template name="front.cover">
      <xsl:call-template name="page.sequence">
        <xsl:with-param name="master-reference">titlepage-cover-image</xsl:with-param>
        <xsl:with-param name="content">
          <fo:block text-align="center">
         <fo:external-graphic src="url(path/to/cover.png)" content-height="250mm" content-width="176mm"/>
          </fo:block>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:template>
    

    Change height and width as per your book requirement.

    Once that is done you need to provide margin for image on the cover page to be clear. Add below in pagesetup.xsl

    <fo:simple-page-master master-name="titlepage-cover-image"
                               page-width="{$page.width}"
                               page-height="{$page.height}"
                               margin-top="{$title.page.margin.top}"
                               margin-bottom="{$page.margin.bottom}">
          <xsl:attribute name="margin-{$direction.align.start}">
            <xsl:value-of select="$page.margin.inner"/>
      <xsl:if test="$fop.extensions != 0">
        <xsl:value-of select="concat(' - (',$title.margin.left,')')"/>
            </xsl:if>
          </xsl:attribute>
          <xsl:attribute name="margin-{$direction.align.end}">
            <xsl:value-of select="$page.margin.outer"/>
          </xsl:attribute>
          <xsl:if test="$axf.extensions != 0">
            <xsl:call-template name="axf-page-master-properties">
              <xsl:with-param name="page.master">titlepage-cover-image</xsl:with-param>
            </xsl:call-template>
          </xsl:if>
          <fo:region-body margin-bottom="{$body.margin.bottom}"
                          margin-top="{$title.body.margin.top}"
                          column-gap="{$column.gap.titlepage}"
                          column-count="{$column.count.titlepage}">
            <xsl:attribute name="margin-{$direction.align.start}">
              <xsl:value-of select="$body.margin.inner"/>
            </xsl:attribute>
            <xsl:attribute name="margin-{$direction.align.end}">
              <xsl:value-of select="$body.margin.outer"/>
            </xsl:attribute>
          </fo:region-body>
          <fo:region-before region-name="xsl-region-before-first"
                            extent="{$region.before.extent}"
                            precedence="{$region.before.precedence}"
                            display-align="before"/>
          <fo:region-after region-name="xsl-region-after-first"
                           extent="{$region.after.extent}"
                            precedence="{$region.after.precedence}"
                            display-align="after"/>
          <xsl:call-template name="region.inner">
            <xsl:with-param name="sequence">first</xsl:with-param>
            <xsl:with-param name="pageclass">titlepage</xsl:with-param>
          </xsl:call-template>
          <xsl:call-template name="region.outer">
            <xsl:with-param name="sequence">first</xsl:with-param>
            <xsl:with-param name="pageclass">titlepage</xsl:with-param>
          </xsl:call-template>
        </fo:simple-page-master>
    

    Then add variables in fo-pdf.xsl to zeroed out your body top margin.

    HTH.