Skip to content

Commit 3008826

Browse files
docs/story-class.rst: updated with Robin's suggested text, slightly modified.
1 parent c45efdc commit 3008826

File tree

1 file changed

+59
-18
lines changed

1 file changed

+59
-18
lines changed

docs/story-class.rst

+59-18
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,71 @@ Story
2828

2929
.. method:: __init__(self, html=None, user_css=None, em=12, archive=None)
3030

31-
Create a story, optionally providing HTML and CSS source. In any case, this object points to a HTML structure, a so-called DOM (Document Object Model). This structure may be modified: content (text, images) may be added, copied, modified or removed by using methods of the :ref:`Xml` class.
31+
Create a **story**, optionally providing HTML and CSS source.
32+
The HTML is parsed, and held within the Story as a DOM (Document Object Model).
3233

33-
When finished, the story can be written to pages provided by a :ref:`DocumentWriter`.
34+
This structure may be modified: content (text, images) may be added,
35+
copied, modified or removed by using methods of the :ref:`Xml` class.
36+
37+
When finished, the **story** can be written to any device;
38+
in typical usage the device may be provided by a :ref:`DocumentWriter` to make new pages.
3439

3540
Here are some general remarks:
3641

37-
* The :ref:`Story` constructor parses and validates the provided HTML and CSS sources. PyMuPDF provides a number of ways to manipulate the HTML source by providing access to the *nodes* of the underlying DOM. HTML documents can be completely built from ground up programmatically, or existing HTML can be modified pretty arbitrarily. For details of this interface, please see the :ref:`Xml` class.
38-
39-
* If no (or no more) changes to the DOM are required, the story is ready to produce PDF pages via some :ref:`DocumentWriter`. To achieve this, the following loop should be used:
40-
41-
1. Request a new, empty page from a :ref:`DocumentWriter`.
42+
* The :ref:`Story` constructor parses and validates the provided HTML to create the DOM.
43+
* PyMuPDF provides a number of ways to manipulate the HTML source by
44+
providing access to the *nodes* of the underlying DOM.
45+
Documents can be completely built from ground up programmatically,
46+
or the existing DOM can be modified pretty arbitrarily.
47+
For details of this interface, please see the :ref:`Xml` class.
48+
* If no (or no more) changes to the DOM are required,
49+
the story is ready to be laid out and to be fed to a series of devices
50+
(typically devices provided by a :ref:`DocumentWriter` to produce new pages).
51+
* The next step is to place the story and write it out.
52+
This can either be done directly, by looping around calling `place()` and `draw()`,
53+
or alternatively,
54+
the looping can handled for you using the `write()` or `write_stabilised()` methods.
55+
Which method you choose is largely a matter of taste.
4256

43-
2. Determine one or more rectangles on the page, that should receive story data. Note that not every page needs to have the same set of rectangles.
57+
* To work in the first of these styles, the following loop should be used:
4458

45-
3. Pass each rectangle to the story, each time checking whether the story's data is exhausted. If so, leave the loop, otherwise pass the next rectangle to it, respectively restart the loop requesting the next page.
46-
47-
* Which part of the story will land on which rectangle / which page, is fully under control of the :ref:`Story` object and cannot be predicted.
48-
49-
* Optionally, a story can pass back information to a Python callback function about page positions of HTML headers (tags :htmlTag:`h1` - :htmlTag:`h6`) and nodes with an ``"id"`` attribute. This can conveniently be used for automatic generation of a Table of Contents, an index of images or the like.
50-
51-
* Images may be part of a story. They will be placed together with any surrounding text.
52-
53-
* Multiple stories may -- independently from each other -- write to the same page. For example, one may have separate stories for page header, page footer, regular text, comment boxes, etc.
54-
59+
1. Obtain a suitable device to write to;
60+
typically by requesting a new,
61+
empty page from a :ref:`DocumentWriter`.
62+
2. Determine one or more rectangles on the page,
63+
that should receive **story** data.
64+
Note that not every page needs to have the same set of rectangles.
65+
3. Pass each rectangle to the **story** to place it,
66+
learning what part of that rectangle has been filled,
67+
and whether there is more story data that did not fit.
68+
This step can be repeated several times with adjusted rectangles
69+
until the caller is happy with the results.
70+
4. Optionally, at this point,
71+
we can request details of where interesting items have been placed,
72+
by calling the `element_positions()` method.
73+
Items are deemed to be interesting if their integer ``heading`` attribute is a non-zero
74+
(corresponding to HTML tags :htmlTag:`h1` - :htmlTag:`h6`),
75+
if their ``id`` attribute is not `None` (corresponding to HTML tag :htmlTag:`id`),
76+
or if their ``href`` attribute is not `None` (responding to HTML tag :htmlTag:`href`).
77+
This can conveniently be used for automatic generation of a Table of Contents,
78+
an index of images or the like.
79+
5. Next, draw that rectangle out to the device with the `draw()` method.
80+
6. If the most recent call to `place()` indicated that all the story data had fitted,
81+
stop now.
82+
7. Otherwise, we can loop back.
83+
If there are more rectangles to be placed on the current device (page),
84+
we jump back to step 3 - if not, we jump back to step 1 to get a new device.
85+
* Alternatively, in the case where you are using a :ref:`DocumentWriter`,
86+
the `write()` or `write_stabilized()` methods can be used.
87+
These handle all the looping for you,
88+
in exchange for being provided with callbacks that control the behaviour
89+
(notably a callback that enumerates the rectangles/pages to use).
90+
* Which part of the **story** will land on which rectangle / which page,
91+
is fully under control of the :ref:`Story` object and cannot be predicted.
92+
* Images may be part of a **story**. They will be placed together with any surrounding text.
93+
* Multiple stories may - independently from each other - write to the same page.
94+
For example, one may have separate stories for page header,
95+
page footer, regular text, comment boxes, etc.
5596

5697
:arg str html: HTML source code. If omitted, a basic minimum is generated (see below).
5798
:arg str user_css: CSS source code. If provided, must contain valid CSS specifications.

0 commit comments

Comments
 (0)