brechtm / rinohtype

The Python document processor
http://www.mos6581.org/rinohtype
GNU Affero General Public License v3.0
498 stars 59 forks source link

Making pdf output mirror HTML more closely #375

Closed techauthoruk closed 1 year ago

techauthoruk commented 1 year ago

Again, not sure if this is possible. The same issue happens in LaTeX as well as rinohtype (and rst2pdf...).However, there may be a workaround I'm not aware of.

If I create some output in Sphinx like this:

.. image:: img/caution.png 
   :align: left

**The system should be decommissioned BEFORE attempting to move or reposition equipment.**

it displays beautifully in HTML like this:

html

However, in a pdf, the text doesn't align at the side of the image, it ends up underneath the image:

pdf

Is there a way to flow the text as in HTML?

techauthoruk commented 1 year ago

...and I didn't post this just to get the honour of having raised the 100th issue!

techauthoruk commented 1 year ago

...or is this styling a function of the Sphinx book template? I don't know as I'm not that au-fait yet with all the vagaries of pdf generation from Sphinx. I hope someone can enlighten me!

brechtm commented 1 year ago

At this moment there is no clean, generic way to place content horizontally beside each other. It's popular to use tables for this kind of layout, but you should avoid this since this semantically is not a table.

This is however an admonition and supported by reStructuredText, so I recommend using one of the admonition directives. This is a bit of a hack, but you can achieve the desired effect like this:

reStructuredText:

.. caution::

   The system should be decommissioned BEFORE attempting to move or reposition
   equipment.

   Second paragraph...

Style sheet:

[STYLESHEET]
base = sphinx

[caution admonition]
base = builtin admonition
border_top = none
border_bottom = none

[caution admonition inline title]
hide = true
; set 'width' and 'baseline' to obtain proper positioning of the image
after = IMAGE('img/caution.png', width=44pt, baseline=65%) '\t'

[caution admonition paragraph : Admonition(admonition_type='caution') / Paragraph]
; this should work too, but for some reason doesn't:
; [caution admonition paragraph : 'caution admonition' / Paragraph]
base = body
; this configures a fixed line spacing, so it's not stretched by the tallish caution image
line_spacing = standard
margin_left = 50pt

[caution admonition title paragraph]
base = caution admonition paragraph
indent_first = -50pt
tab_stops = 0

While I was playing around with this, I realized this kind of layout is actually handled pretty well by rinohtype's LabeledFlowable element, but for some reason the admonition rendering code uses another, suboptimal way of handling the inline title/image instead. I'll need to look into making it use LabeledFlowable instead...

techauthoruk commented 1 year ago

@brechtm

Thanks for this, but I have run into two issues:

  1. If I use the reST admonition in the HTML, I lose my Caution image: image

  2. In the pdf, I get this error:
    image

For the first point, I vaguely recollect reading about being able to set specific parts using a .. rinoh only:: and .. html only:: directive - I will have to try this to see if my memory was correct. On the second point, I understand that rinoh is looking for the image in the same directory as the stylesheet, so I assume I have to create a custom stylesheet and put it in the source directory of wy content.

My question there is, how do I reference the new stylesheet? Rinoh will still need to use the base Sphinx.rts stylesheet, just don't understand how to reference it so that it adds the style when I build.

Sorry if I am being very dim here!

techauthoruk commented 1 year ago

Ah so the .. only:: directive does indeed allow for HTML or rinoh specific content to be displayed, so I can work with that.

Do I reference the new stylesheet in conf.py, so something like:

rinoh_documents = [dict(doc='index',        # top-level file (index.rst)
                        target='manual',
                        template='SEaB.rtt',
                        stylesheet='SEaB.rts',
                        title='FLEXIBUSTER',
                        author='Operating and Maintenance Manual',
                        logo='img/logo.png')]

I may end up answering my own question (as I will try this)....

techauthoruk commented 1 year ago

Learning as I go (and I hope this may be helpful to others as inept as me!)

So, creating a custom stylesheet and putting it in the source directory (and adding the entry to the conf.py file) worked. However, now the Caution image doesn't show at all, I just get the word 'caution'

image

No errors displayed, and I can't see where I'm going wrong, as the image exists and is in the img/ directory. Any suggestions?

brechtm commented 1 year ago
  1. If I use the reST admonition in the HTML, I lose my Caution image:

HTML would need separate styling by means of a custom CSS file (see Sphinx's html_css_files).

Personally, I would avoid using the only directive as much as possible, because that will require you to duplicate this boilerplate code everywhere you want an admonition. The idea behind (or my interpretation, at least) a structured text format such as reStructuredText is to describe the semantics of your document and perform styling in a later stage, based on the semantics and the output format.

In the pdf, I get this error:

The path to the image file is resolved relative to the directory where the style sheet resides. Note that the absolute path where rinohtype looks for the image is included in the red error message.

Going by the error message, it looks like you edited the sphinx style sheet included with rinohtype? That is to be avoided, of course. You did get it right by setting the stylesheet entry in _rinohdocuments, though! 👍

As to why the image is not being picked up now is difficult to say. A good place to start is the style log file, which you can find beside the generated PDF. My guess is that the caution admonitions are not being mapped to the newly defined style in your style sheet. If you can share your Sphinx project (publically or privately), I can have a deeper look.

techauthoruk commented 1 year ago

Ah, this is getting far to involved, and beyond my level of competence!

I think I will just live with the fact the text doesn't flow around the image. It's an imperfect world after all, and of course printed copy shouldn't mirror online copy. It's been an interesting learning experience, so I will close this issue.

I'll need to look into making it use LabeledFlowable instead...

If @brechtm you do implement this, do let me know as I would be keen to try it.

brechtm commented 1 year ago
rinoh_documents = [dict(doc='index',        # top-level file (index.rst)
                        target='manual',
                        template='SEaB.rtt',
                        stylesheet='SEaB.rts',
                        title='FLEXIBUSTER',
                        author='Operating and Maintenance Manual',
                        logo='img/logo.png')]

I failed to spot this before, but you're making the same mistake as in #373: rinoh_documents doesn't take a stylesheet. You need to set the style sheet in your template configuration file..

techauthoruk commented 1 year ago

I failed to spot this before, but you're making the same mistake as in #373: rinoh_documents doesn't take a stylesheet. You need to set the style sheet in your template configuration file..

Indeed...I finally figured that out about an hour ago! Thank you for pointing it out!