Skip to content

Commit 4a67f9e

Browse files
committed
Example code explaining how to use library (lispkit styled-text).
1 parent 4e022ca commit 4a67f9e

File tree

3 files changed

+305
-1
lines changed

3 files changed

+305
-1
lines changed

LispKit.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,8 @@
955955
CCCACB5C248D753800F012AC /* SystemOSLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCCACB5B248D753800F012AC /* SystemOSLibrary.swift */; };
956956
CCCB5C9D28403E870005248D /* 118.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CCCB5C9C28403E550005248D /* 118.sld */; };
957957
CCCB5C9E28403E960005248D /* 118.sld in Copy pre-installed SRFI libraries */ = {isa = PBXBuildFile; fileRef = CCCB5C9C28403E550005248D /* 118.sld */; };
958+
CCCB5CA0284225470005248D /* StyledTextDoc.scm in Copy examples */ = {isa = PBXBuildFile; fileRef = CCCB5C9F284224260005248D /* StyledTextDoc.scm */; };
959+
CCCB5CA12842255E0005248D /* StyledTextDoc.scm in Copy examples */ = {isa = PBXBuildFile; fileRef = CCCB5C9F284224260005248D /* StyledTextDoc.scm */; };
958960
CCCB66E1282DBBC80004827D /* DrawBarCharts.scm in Copy examples */ = {isa = PBXBuildFile; fileRef = CCCB66E0282DB9790004827D /* DrawBarCharts.scm */; };
959961
CCCB66E2282DBBDB0004827D /* DrawBarCharts.scm in Copy examples */ = {isa = PBXBuildFile; fileRef = CCCB66E0282DB9790004827D /* DrawBarCharts.scm */; };
960962
CCCB66E4283056E30004827D /* StyledTextLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCCB66E3283056E30004827D /* StyledTextLibrary.swift */; };
@@ -1338,6 +1340,7 @@
13381340
dstPath = Root/LispKit/Examples;
13391341
dstSubfolderSpec = 7;
13401342
files = (
1343+
CCCB5CA0284225470005248D /* StyledTextDoc.scm in Copy examples */,
13411344
CCCB66E1282DBBC80004827D /* DrawBarCharts.scm in Copy examples */,
13421345
CCD6414027FABE420065E2BF /* ObjectOrientation.scm in Copy examples */,
13431346
CC2427DF279E1A5000913C05 /* Channels.scm in Copy examples */,
@@ -2157,6 +2160,7 @@
21572160
dstPath = Root/LispKit/Examples;
21582161
dstSubfolderSpec = 7;
21592162
files = (
2163+
CCCB5CA12842255E0005248D /* StyledTextDoc.scm in Copy examples */,
21602164
CCCB66E2282DBBDB0004827D /* DrawBarCharts.scm in Copy examples */,
21612165
CCD6414127FABE5C0065E2BF /* ObjectOrientation.scm in Copy examples */,
21622166
CC2427E0279E1A5F00913C05 /* Channels.scm in Copy examples */,
@@ -2895,6 +2899,7 @@
28952899
CCCAF5AE23B7A71400FE2C60 /* HtmlColors.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = HtmlColors.plist; sourceTree = "<group>"; };
28962900
CCCAF92D1F941A43006692E9 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; path = Package.swift; sourceTree = "<group>"; tabWidth = 2; };
28972901
CCCB5C9C28403E550005248D /* 118.sld */ = {isa = PBXFileReference; lastKnownFileType = text; path = 118.sld; sourceTree = "<group>"; };
2902+
CCCB5C9F284224260005248D /* StyledTextDoc.scm */ = {isa = PBXFileReference; lastKnownFileType = text; path = StyledTextDoc.scm; sourceTree = "<group>"; };
28982903
CCCB66E0282DB9790004827D /* DrawBarCharts.scm */ = {isa = PBXFileReference; lastKnownFileType = text; path = DrawBarCharts.scm; sourceTree = "<group>"; };
28992904
CCCB66E3283056E30004827D /* StyledTextLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyledTextLibrary.swift; sourceTree = "<group>"; };
29002905
CCCEB3FE1DF2DAA9009BF66B /* FileHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileHandler.swift; sourceTree = "<group>"; };
@@ -4016,6 +4021,7 @@
40164021
CC8D20F42533C35F00741D07 /* DrawTrees.scm */,
40174022
CCCB66E0282DB9790004827D /* DrawBarCharts.scm */,
40184023
CC202DE325AA9D70003901BE /* VisualizePointSets.scm */,
4024+
CCCB5C9F284224260005248D /* StyledTextDoc.scm */,
40194025
CC7E7C2524564D33002E8A73 /* Covid.scm */,
40204026
CCC7A9DB26D0473600F05361 /* EUStats.scm */,
40214027
CC1EA5C8214E6BF3006BBE7E /* Turtle.scm */,

Sources/LispKit/Primitives/StyledTextLibrary.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ public final class StyledTextLibrary: NativeLibrary {
455455
table.numberOfColumns = ncols
456456
table.collapsesBorders = collapse.isTrue
457457
table.hidesEmptyCells = hideEmptyCells.isTrue
458-
let res = NSMutableAttributedString(string: "\n")
458+
let res = NSMutableAttributedString(string: "")
459459
var rows = expr
460460
var i = 0
461461
while case .pair(let row, let next) = rows {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
;;; Generate a RTFD document with different text styles
2+
;;;
3+
;;; This is a demo of library (lispkit styled-text). It explains how to
4+
;;; programmatically generate a complex text document, composing it out of
5+
;;; several different paragraph styles, text styles, and text block styles.
6+
;;; The example also shows how to create styled lists and styled text tables
7+
;;; and explains how to nest them.
8+
;;;
9+
;;; Author: Matthias Zenger
10+
;;; Copyright © 2022 Matthias Zenger. All rights reserved.
11+
;;;
12+
;;; Licensed under the Apache License, Version 2.0 (the "License"); you may not
13+
;;; use this file except in compliance with the License. You may obtain a copy
14+
;;; of the License at
15+
;;;
16+
;;; http://www.apache.org/licenses/LICENSE-2.0
17+
;;;
18+
;;; Unless required by applicable law or agreed to in writing, software
19+
;;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
20+
;;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
21+
;;; License for the specific language governing permissions and limitations
22+
;;; under the License.
23+
24+
; Import required libraries
25+
26+
(import (lispkit base)
27+
(lispkit draw)
28+
(lispkit styled-text))
29+
30+
; Load all the fonts we need upfront
31+
32+
(define title-font (font "Times" 20 bold))
33+
(define header-font (font "Times" 17 bold))
34+
(define body-font (font "Times" 15 normal))
35+
(define bold-font (font "Times" 15 bold))
36+
(define italic-font (font "Times" 15 normal italic))
37+
(define small-font (font "Times" 13 bold))
38+
39+
; Define common paragraph styles
40+
41+
(define title-style
42+
(make-paragraph-style
43+
'alignment: 'center
44+
'paragraph-spacing-after: 8
45+
'paragraph-spacing-before: 14))
46+
47+
(define header-style
48+
(make-paragraph-style
49+
'alignment: 'left
50+
'paragraph-spacing-after: 9
51+
'paragraph-spacing-before: 14))
52+
53+
(define body-style
54+
(make-paragraph-style
55+
'alignment: 'justified
56+
'paragraph-spacing-after: 6))
57+
58+
(define body-style-left (copy-paragraph-style body-style))
59+
(paragraph-style-set! body-style-left 'alignment 'left)
60+
61+
(define indented-style
62+
(make-paragraph-style
63+
'alignment: 'left
64+
'paragraph-spacing-after: 8
65+
'paragraph-spacing-before: 8
66+
'first-head-indent: 20
67+
'head-indent: 20
68+
'tail-indent: 500))
69+
70+
; Start document with a title that is centered and shown in blue. Subsequent elements of
71+
; the document are appended to styled text `document`
72+
73+
(define document
74+
(styled-text "Generated Sample Document\n" title-font blue title-style))
75+
76+
; First section
77+
78+
; Add the section title
79+
(styled-text-append! document
80+
(styled-text "Overview of the approach\n" header-font black header-style))
81+
; Start with regular text
82+
(styled-text-append! document
83+
(styled-text "Lorem ipsum dolor sit amet, " body-font black body-style))
84+
; Inject some text in italics
85+
(styled-text-append! document
86+
(styled-text "consectetur adipiscing elit" italic-font black body-style))
87+
(styled-text-append! document
88+
(styled-text ". Maecenas lectus orci, accumsan sed arcu ornare, " body-font black body-style))
89+
; Inject some text in bold
90+
(styled-text-append! document
91+
(styled-text "egestas mattis diam" bold-font black body-style))
92+
; And now two paragraphs are added to showcase the paragraph spacing
93+
(styled-text-append! document
94+
(styled-text
95+
(string-append
96+
". Vestibulum ut mauris quis nulla laoreet varius. Etiam luctus ac diam tincidunt "
97+
"pharetra. Nulla a mi sed nunc sagittis venenatis. Curabitur quis lorem et ipsum "
98+
"aliquam maximus. Duis eget magna mauris. Sed malesuada est rhoncus eros hendrerit "
99+
"porttitor.\n"
100+
"Aenean sagittis ac mi vitae vehicula. Nam consequat eros aliquam sem feugiat "
101+
"aliquet. Cras ultrices pretium eros ut euismod. Aliquam nec turpis sed urna "
102+
"condimentum ullamcorper a tristique augue.\n")
103+
body-font black body-style))
104+
105+
; Second section
106+
107+
; We start with a section title and some normal text first
108+
(styled-text-append! document
109+
(styled-text "Detailed exploration\n" header-font black header-style))
110+
(styled-text-append! document
111+
(styled-text
112+
(string-append
113+
"Donec rhoncus, neque a consequat ultrices, massa erat tempor nulla, et sodales "
114+
"nulla lectus facilisis enim. Pellentesque habitant morbi tristique senectus et "
115+
"netus et malesuada fames ac turpis egestas. Nam quis vestibulum augue.\n")
116+
body-font black body-style-left))
117+
; The following paragraph gets indented and its width gets capped; text is shown
118+
; in italics.
119+
(styled-text-append! document
120+
(make-styled-text
121+
(string-append
122+
"Mauris scelerisque massa erat, maximus luctus purus laoreet nec. In et massa eu "
123+
"eros porttitor sollicitudin ut nec tortor. Suspendisse gravida magna placerat, "
124+
"volutpat enim ut, accumsan elit.\n")
125+
'font: italic-font
126+
'foreground-color: (color 0.3 0.3 0.3)
127+
'paragraph-style: indented-style))
128+
129+
; Third section
130+
131+
; The next section shows a table; we define a few text block styles ahead which will be
132+
; used to set up the table. Tables are not available on iOS, so the following section
133+
; is added only on macOS.
134+
135+
(cond-expand (macos
136+
137+
; Headers get centered
138+
(define table-header-style (make-paragraph-style 'alignment: 'center))
139+
140+
; The header row's first column takes 20% of the overall width, has a bold border at the
141+
; bottom and its background is light gray
142+
(define fst-head-style
143+
(make-text-block-style
144+
'width: (percent 20)
145+
'height: 20
146+
'border: '(1 1 1 2)
147+
'padding: '(2 2 4 4)
148+
'margin: 2
149+
'border-color: gray
150+
'background-color: (color 0.9 0.9 0.9)
151+
'vertical-alignment: 'middle))
152+
153+
; The header row's second column takes 80% of the overall width, it spans two regular
154+
; columns (we define this later).
155+
(define snd-head-style (copy-text-block-style fst-head-style))
156+
(text-block-style-set! snd-head-style 'width (percent 80))
157+
158+
; The tables first column has again gray borders, takes up 20%, and has border, padding,
159+
; and margin spaces.
160+
(define fst-col-style
161+
(make-text-block-style
162+
'width: (percent 20)
163+
'border: 1
164+
'padding: 8
165+
'margin: 2
166+
'border-color: gray))
167+
168+
; The other two columns each take up 40% and are otherwise identical to the first column
169+
(define col-style (copy-text-block-style fst-col-style))
170+
(text-block-style-set! col-style 'width (percent 40))
171+
172+
; We also predefine a simple nested table below (embedded in some text):
173+
(define nested-tbl
174+
(styled-text "Nullam efficitur tellus non molestie:\n" body-font black body-style-left))
175+
(define table-start (string-length (styled-text-string nested-tbl)))
176+
(styled-text-append! nested-tbl
177+
(make-styled-text-table 2
178+
(list
179+
(list "Lorem" "Dolor")
180+
(list "Ipsum" "Sit"))
181+
(make-text-block-style
182+
'width: (percent 100)
183+
'border: 1
184+
'padding: 2
185+
'margin: 2
186+
'border-color: (color 0.4 0.4 0.9)
187+
'background-color: (color 0.93 0.93 1.0))
188+
(make-paragraph-style
189+
'paragraph-spacing-after: 8
190+
'paragraph-spacing-before: 2)
191+
#t))
192+
(define table-end (string-length (styled-text-string nested-tbl)))
193+
(styled-text-append! nested-tbl
194+
(styled-text "Mauris egestas dolor mauris, id mollis urna ultrices feugiat."
195+
body-font black
196+
body-style-left))
197+
; The following lines set all fonts in the nested table to `small-font` and the
198+
; foreground color of the text is set to dark blue. Patching attributes is another
199+
; possibility to change the style of a large section of text quickly.
200+
(styled-text-add! nested-tbl table-start table-end 'font small-font)
201+
(styled-text-add! nested-tbl table-start table-end 'foreground-color (color 0 0 0.6))
202+
203+
; Now we start adding the section title
204+
(styled-text-append! document
205+
(styled-text "Tabular data\n" header-font black header-style))
206+
; ...followed by the table:
207+
(styled-text-append! document
208+
(make-styled-text-table 3
209+
(list
210+
(list (list (make-styled-text "First column"
211+
'font: (font "Helvetica-Bold" 12)
212+
'paragraph-style: table-header-style) 1 fst-head-style)
213+
(list (make-styled-text "Second column\n(experimental)"
214+
'font: (font "Helvetica-Bold" 12)
215+
'paragraph-style: table-header-style) 2 snd-head-style))
216+
(list (list (styled-text "Maecenas eget nibh felis. Etiam sagittis sit."
217+
body-font black body-style-left) 1 fst-col-style)
218+
(list (styled-text (string-append
219+
"Nunc pretium, ante porta varius eleifend, nulla quam tristique nisl, "
220+
"id vulputate felis est sed quam.") body-font black body-style-left) 1 col-style)
221+
(list (styled-text (string-append
222+
"Nam ac accumsan elit. Pellentesque habitant morbi tristique senectus "
223+
"et netus et malesuada fames ac turpis egestas.") body-font black) 1 col-style))
224+
(list (list
225+
(styled-text (string-append
226+
"Maecenas non dui scelerisque, tincidunt lacus in, suscipit felis. "
227+
"Suspendisse pharetra.") body-font black body-style-left) 1 fst-col-style)
228+
(list nested-tbl 1 col-style)
229+
(styled-text (string-append
230+
"Aliquam velit est, congue sed sollicitudin in, luctus non enim. Nulla "
231+
"facilisi. Aliquam diam urna, ultrices facilisis diam quis, tempor "
232+
"pharetra felis. Nullam nec condimentum sapien. Nullam at dolor nec "
233+
"tortor.") body-font black body-style-left)
234+
))
235+
col-style
236+
body-style-left
237+
#t))
238+
))
239+
240+
; Fourth section
241+
242+
; The last section showcases lists. We define the list style upfront here:
243+
(define list-style
244+
(make-paragraph-style
245+
'alignment: 'left
246+
'first-head-indent: 0.0
247+
'head-indent: 40.0
248+
'line-spacing: -1.0
249+
'paragraph-spacing-before: 4.0
250+
'paragraph-spacing-after: 4.0))
251+
; Tab stops are used to format the table. All predefined tab stops are removed first and
252+
; then two tab stops are added. The first is for the number (it's right aligned), the
253+
; second is for the list content (it's left aligned).
254+
(paragraph-style-tabstops-clear! list-style)
255+
(paragraph-style-tabstop-add! list-style 30 'right)
256+
(paragraph-style-tabstop-add! list-style 40 'left)
257+
258+
; Again, first the section header is added
259+
(styled-text-append! document
260+
(styled-text "Summary\n" header-font black header-style))
261+
; ...followed by some text
262+
(styled-text-append! document
263+
(styled-text
264+
(string-append
265+
"Donec vestibulum tortor at est venenatis malesuada. Aliquam erat volutpat. "
266+
"Sed consectetur quam quis odio varius, eget facilisis justo pharetra. "
267+
"Nulla maximus vestibulum laoreet. Interdum et malesuada fames ac ante "
268+
"ipsum primis in faucibus.\n")
269+
body-font black body-style))
270+
; ...followed by the enumerated list.
271+
(styled-text-append! document
272+
(styled-text
273+
(string-append
274+
"\t1.\tLorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nec "
275+
"rhoncus erat, in ullamcorper diam. Pellentesque tristique pulvinar sagittis.\n"
276+
"\t2.\tAliquam id tortor ac nulla tempus auctor a ut sem. Nulla eget aliquam "
277+
"sem, a consequat nibh. Sed ullamcorper semper semper. Quisque mattis.\n"
278+
"\t3.\tVulputate accumsan. Morbi euismod dolor turpis, at dignissim augue "
279+
"maximus sed. Etiam neque tortor, venenatis non eros quis, dignissim rhoncus "
280+
"lectus. Duis accumsan diam eget neque rutrum bibendum. Suspendisse laoreet, "
281+
"turpis in tempus congue, sapien dui vulputate elit, vitae porttitor metus "
282+
"lorem vitae ante. Proin efficitur lorem vel dui finibus pretium. Donec "
283+
"pretium erat nec turpis laoreet sagittis.\n")
284+
body-font
285+
black
286+
list-style))
287+
288+
; Saving and opening the document
289+
290+
; Path to the generated RTFD file
291+
(define rtfd-file-path
292+
(path (car (system-directory 'documents)) "sample-doc.rtfd"))
293+
294+
; Save the document
295+
(save-styled-text rtfd-file-path document 'rtfd)
296+
297+
; Open the document in a system-specific fashion
298+
(open-file rtfd-file-path)

0 commit comments

Comments
 (0)