-
Notifications
You must be signed in to change notification settings - Fork 0
/
doc_sample.py
195 lines (141 loc) · 10.2 KB
/
doc_sample.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Copyright (c) 2020, James P. Imes. All rights reserved.
"""
Sample code in the piltextbox readme.md quickstart guide.
"""
line_sample = 'The quick brown fox jumped over the lazy dog.'
paragraph_sample = "The lazy dog ignored the fox's rude shenanigans. He had more important things on his mind. For him, the art of napping was not a mark of laziness (a label he rejected), but of an appreciation for the finer things in life: namely, doing nothing."
lorem_ipsum_sample = """Quisque justo quam, auctor ac quam et, porta euismod urna. Ut faucibus lorem non scelerisque imperdiet. In hac habitasse platea dictumst. Mauris non elit orci. Nulla venenatis sit amet metus vitae fermentum. Aliquam erat volutpat. Maecenas sed libero blandit, tincidunt tellus quis, euismod diam. In iaculis est semper odio egestas, a porta augue fringilla. Nulla ut augue non arcu blandit mattis id vel nibh.
Proin neque leo, semper a tempor pharetra, posuere sed neque. Cras egestas non nunc ac pellentesque. Sed fermentum ligula ante, ac finibus ante pulvinar vitae. Donec nec libero sit amet leo convallis dapibus. Nulla a sapien ut arcu posuere tristique nec vitae mauris. Etiam varius odio ac lorem blandit, eu ultricies arcu interdum. Maecenas accumsan tempor dui, a posuere ligula convallis efficitur. Curabitur blandit, augue ac varius pretium, erat risus ultrices libero, ac dictum odio diam quis urna.
Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur eleifend dapibus lacus, non feugiat neque luctus ut. Suspendisse vulputate, metus ut varius lacinia, massa arcu mollis turpis, ut blandit dui augue sed justo. Praesent vel ante dolor. Proin lacus metus, lacinia et ultricies eu, interdum nec nibh. Duis ultricies et ipsum in mollis. Nulla augue massa, faucibus ut sem suscipit, congue sagittis dolor. Proin a pellentesque leo. Quisque leo justo, tempus ut nulla nec, tincidunt tincidunt neque. Aliquam sit amet scelerisque odio.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis varius in magna vel scelerisque. Nunc sollicitudin vitae augue et dapibus. Suspendisse dictum et velit quis molestie. Duis sem felis, euismod nec est id, lobortis ultricies sapien. Donec tincidunt est ac lorem dapibus tincidunt. Vestibulum rhoncus ac risus sit amet luctus. Nam euismod malesuada elit. Mauris tempor auctor nunc vel malesuada. Cras sit amet erat eu quam sollicitudin porttitor ut a enim. Quisque maximus placerat lacinia. In vitae sapien eget ipsum elementum vestibulum eget vitae neque. Nam vel libero nisl. Maecenas dapibus dolor a erat interdum vulputate."""
import piltextbox
# Filepath to the .ttf font we want to use. (If no font is set, it will use
# PIL's default font.)
font_fp = r'testing_fonts\LiberationSans-Regular.ttf'
# a new TextBox object, 400x600 px, using the .ttf font at the filepath,
# size 14 font, with 0 spaces indenting for paragraphs, and 8 spaces for
# every subsequent line. 4 px for vertical line spacing, and margins
# (left-top-right-bottom, specified in px).
tb1 = piltextbox.TextBox(
(400, 600), typeface=font_fp, font_size=14, paragraph_indent=0,
new_line_indent=6, spacing=4, margins=(10, 20, 10, 10))
# Write a single line, unjustified. If it can't be fit on a single line,
# gets returned as a list of unwritten text.
unwritten_line_1 = tb1.write_line(line_sample)
# `.write_line()` returns None if the line was written, or a PLine or
# FLine object (which are specialized objects for this module encoding
# unwritten text; PLine is for plain text; FLine is for formatted text).
print(unwritten_line_1) # prints None, since it was successfully written
# Write a single line, justified.
unwritten_line_2 = tb1.write_line(line_sample, justify=True)
print(unwritten_line_2) # Was also successfully written, so prints None
# Move the cursor down to the start of the next line (automatically done
# at the end of `.write_line()` -- just demonstrating here that we can
# manually move the cursor down a line).
tb1.next_line_cursor()
# Write the paragraph of text, unjustified. If all lines were successfully
# written, it will return None; however, any lines that could not be
# written are returned as an UnwrittenLines object, which can be passed
# to `.continue_paragraph()` method on another equally configured TextBox
unwrit_lines_1 = tb1.write_paragraph(paragraph_sample)
# Write the paragraph of text, justified. (Linebreaks are respected by
# the text wrap, and lines ending in linebreaks are not justified.)
unwrit_lines_2 = tb1.write_paragraph(paragraph_sample, justify=True)
# Example writing a block of text (as a paragraph) with existing
# linebreaks in it. Each existing linebreak is treated as a soft return,
# moving the cursor down to the next line, but using `new_line_indent`
# and not `pararaph_indent`. (To treat linebreaks as paragraph_indent,
# you'd have to first break your string by linebreak, and pass each
# resulting string one at a time.)
unwrit_lines_3 = tb1.write_paragraph(lorem_ipsum_sample, justify=True)
# Because the last text could not be fit within what remained of the
# textbox, we create a new TextBox object and continue writing. By using
# the `.new_same_as()` method, the new TextBox will automatically use
# the same settings as our original TextBox (which MUST be the case to
# continue writing an UnwrittenLines object, or errors / incorrect
# results are likely).
tb2 = piltextbox.TextBox.new_same_as(tb1)
# Continue writing, to our new TextBox object, again returning any lines
# that can't fit. We have to re-specify whether we want to justify.
unwrit_lines_4 = tb2.continue_paragraph(unwrit_lines_3, justify=True)
# Use the `.render()` method to output a flattened PIL.Image object with
# the margins. (Accessing `tb1.im` would give you the PIL.Image object
# of the writable area only.)
image1 = tb1.render()
image2 = tb2.render()
# -------------------------------------------------------
# Misc. methods for checking how much space is left:
# How many lines can still be written in the TextBox, using the current font:
tb1.lines_left() # returns 0
tb2.lines_left() # returns 11
# Whether we're on the last line of the TextBox, using the current font:
tb1.on_last_line() # returns False
tb2.on_last_line() # returns False
# Whether the current TextBox is exhausted (i.e. out of room to write,
# using the current font):
tb1.is_exhausted() # returns True
tb2.is_exhausted() # returns False
# -------------------------------------------------------
# Again using a `Liberation` font to initialize our TextBox
font_fp = r'testing_fonts\LiberationSans-Regular.ttf'
tb3 = piltextbox.TextBox(
(400, 80), typeface=font_fp, font_size=14, paragraph_indent=0,
new_line_indent=6, spacing=4, margins=(10, 20, 10, 10))
# Write words, one by one, until there is no room left to write. (Will
# line break as necessary, but afterwards will NOT linebreak.
test_words_1 = 'The quick brown fox'
unwrit_words_1 = tb3.write(test_words_1)
image3 = tb3.render() # current snapshot of this textbox
test_words_2 = 'jumped over the lazy dog,'
unwrit_words_2 = tb3.write(test_words_2)
image4 = tb3.render() # current snapshot of this textbox
test_words_3 = 'and in so doing, she upset a years-long, fragile truce that locals had feared must one day end.'
unwrit_words_3 = tb3.write(test_words_3)
image5 = tb3.render() # final snapshot of this textbox
# -------------------------------------------------------
# Writing Formatted Text
font_fp = r'testing_fonts\LiberationSans-Regular.ttf'
tb4 = piltextbox.TextBox(
(400, 600), typeface=font_fp, font_size=14, paragraph_indent=0,
new_line_indent=6, spacing=4, margins=(10, 20, 10, 10))
# Using a `test_fonts` dict is not required; just seems cleaner here.
# These are not included in the `piltextbox` github repo, but can be acquired at
# <https://github.com/liberationfonts/liberation-fonts/releases/tag/2.1.1>
test_fonts = {
'test_regular': r'testing_fonts\LiberationSans-Regular.ttf',
'test_bold': r'testing_fonts\LiberationSans-Bold.ttf',
'test_ital': r'testing_fonts\LiberationSans-Italic.ttf',
'test_boldital': r'testing_fonts\LiberationSans-BoldItalic.ttf'
}
# First we MUST configure our fonts for 'bold', 'ital', and 'boldital',
# or those stylings will fall back to the 'main' font.
# specifying `style='main'` is redundant here, since it defaults to 'main'.
# (Moreover, in this particular example, 'main' was already set at init
# by specifying `typeface=` and `font_size=`.)
tb4.set_truetype_font(size=14, typeface=test_fonts['test_regular'], style='main')
# Set 'bold', 'ital', and 'boldital' AFTER setting 'main'. (Note that we
# do not need to specify the size after setting it for 'main'.)
tb4.set_truetype_font(typeface=test_fonts['test_bold'], style='bold')
tb4.set_truetype_font(typeface=test_fonts['test_ital'], style='ital')
tb4.set_truetype_font(typeface=test_fonts['test_boldital'], style='boldital')
# Use codes '<b>' and '</b>' for toggling bold.
# Use codes '<i>' and '</i>' for toggling italics.
# Include these format codes within the text string itself; the format
# codes MUST be at word boundaries, and outside of all punctuation.
format_line_sample = 'The <b>quick <i>brown fox</b> jumped</i> over the lazy dog.'
format_paragraph_sample = "The lazy <i><b>dog</b> ignored the</i> <b>fox's rude shenanigans. He had</b> more important things on his mind. For him, the art of napping was not a mark of laziness (a label he rejected), but of an appreciation for the finer things in life: namely, doing nothing."
# We must specify `formatting=True`, or the codes will not be parsed.
tb4.write_line(format_line_sample, formatting=True)
tb4.write_paragraph(format_paragraph_sample, formatting=True)
# Additional linebreak (optional)
tb4.next_line_cursor()
# And we can still `justify=` text with `.write_line()` and `.write_paragraph()`
tb4.write_line(format_line_sample, formatting=True, justify=True)
tb4.write_paragraph(format_paragraph_sample, formatting=True, justify=True)
# Additional linebreak (optional)
tb4.next_line_cursor()
# To parse format codes but to discard the resulting formatting, use
# parameter `discard_formatting=True`, in addition to `formatting=True`.
tb4.write_paragraph(
format_paragraph_sample, formatting=True, discard_formatting=True)
image6 = tb4.render()