The FormattedDocument class maintains style information for individual characters in the text, rather than a single style for the whole document. Styles can be accessed and modified by name, for example:
# Get the font name used at character index 0 font_name = document.get_style('font_name', 0) # Set the font name and size for the first 5 characters document.set_style(0, 5, dict(font_name='Arial', font_size=12))
Internally, character styles are run-length encoded over the document text; so longer documents with few style changes do not use excessive memory.
From the document's point of view, there are no predefined style names: it simply maps names and character ranges to arbitrary Python values. It is the TextLayout classes that interpret this style information; for example, by selecting a different font based on the font_name style. Unrecognised style names are ignored by the layout -- you can use this knowledge to store additional data alongside the document text (for example, a URL behind a hyperlink).
The following character styles are recognised by all TextLayout classes.
Where an attribute is marked "as a distance" the value is assumed to be in pixels if given as an int or float, otherwise a string of the form "0u" is required, where 0 is the distance and u is the unit; one of "px" (pixels), "pt" (points), "pc" (picas), "cm" (centimeters), "mm" (millimeters) or "in" (inches). For example, "14pt" is the distance covering 14 points, which at the default DPI of 96 is 18 pixels.
Although FormattedDocument does not distinguish between character- and paragraph-level styles, TextLayout interprets the following styles only at the paragraph level. You should take care to set these styles for complete paragraphs only, for example, by using FormattedDocument.set_paragraph_style.
These styles are ignored for layouts without the multiline flag set.
For the purposes of these attributes, paragraphs are split by the newline character (U+0010) or the paragraph break character (U+2029). Line breaks within a paragraph can be forced with character U+2028.
pyglet provides two formats for decoding formatted documents from plain text. These are useful for loading preprepared documents such as help screens. At this time there is no facility for saving (encoding) formatted documents.
The attributed text format is an encoding specific to pyglet that can exactly describe any FormattedDocument. You must use this encoding to access all of the features of pyglet text layout. For a more accessible, yet less featureful encoding, see the HTML encoding, described below.
The following example shows a simple attributed text encoded document:
Chapter 1 My father's family name being Pirrip, and my Christian name Philip, my infant tongue could make of both names nothing longer or more explicit than Pip. So, I called myself Pip, and came to be called Pip. I give Pirrip as my father's family name, on the authority of his tombstone and my sister - Mrs. Joe Gargery, who married the blacksmith. As I never saw my father or my mother, and never saw any likeness of either of them (for their days were long before the days of photographs), my first fancies regarding what they were like, were unreasonably derived from their tombstones.
Newlines are ignored, unless two are made in succession, indicating a paragraph break. Line breaks can be forced with the \\ sequence:
This is the way the world ends \\ This is the way the world ends \\ This is the way the world ends \\ Not with a bang but a whimper.
Line breaks are also forced when the text is indented with one or more spaces or tabs, which is useful for typesetting code:
The following paragraph has hard line breaks for every line of code: import pyglet window = pyglet.window.Window() pyglet.app.run()
Text can be styled using a attribute tag:
This sentence makes a {bold True}bold{bold False} statement.
The attribute tag consists of the attribute name (in this example, bold) followed by a Python bool, int, float, string, tuple or list.
Unlike most structured documents such as HTML, attributed text has no concept of the "end" of a style; styles merely change within the document. This corresponds exactly to the representation used by FormattedDocument internally.
Some more examples follow:
{font_name 'Times New Roman'}{font_size 28}Hello{font_size 12}, {color (255, 0, 0, 255)}world{color (0, 0, 0, 255)}!
(This example uses 28pt Times New Roman for the word "Hello", and 12pt red text for the word "world").
Paragraph styles can be set by prefixing the style name with a period (.). This ensures the style range exactly encompasses the paragraph:
{.margin_left "12px"}This is a block quote, as the margin is inset. {.margin_left "24px"}This paragraph is inset yet again.
Attributed text can be loaded as a Unicode string. In addition, any character can be inserted given its Unicode code point in numeric form, either in decimal:
This text is Copyright {#169}.
or hexadecimal:
This text is Copyright {#xa9}.
The characters { and } can be escaped by duplicating them:
Attributed text uses many "{{" and "}}" characters.
Use the decode_attributed function to decode attributed text into a FormattedDocument:
document = pyglet.text.decode_attributed('Hello, {bold True}world')
While attributed text gives access to all of the features of FormattedDocument and TextLayout, it is quite verbose and difficult produce text in. For convenience, pyglet provides an HTML 4.01 decoder that can translate a small, commonly used subset of HTML into a FormattedDocument.
Note that the decoder does not preserve the structure of the HTML document -- all notion of element hierarchy is lost in the translation, and only the visible style changes are preserved.
The following example uses decode_html to create a FormattedDocument from a string of HTML:
document = pyglet.text.decode_html('Hello, <b>world</b>')
The following elements are supported:
B BLOCKQUOTE BR CENTER CODE DD DIR DL EM FONT H1 H2 H3 H4 H5 H6 I IMG KBD LI MENU OL P PRE Q SAMP STRONG SUB SUP TT U UL VAR
The style attribute is not supported, so font sizes must be given as HTML logical sizes in the range 1 to 7, rather than as point sizes. The corresponding font sizes, and some other stylesheet parameters, can be modified by subclassing HTMLDecoder.