Skip to content

Commit 619755e

Browse files
committed
Added support for custom tags
Fixes #64
1 parent 063662c commit 619755e

File tree

4 files changed

+139
-55
lines changed

4 files changed

+139
-55
lines changed

README.md

+39-18
Original file line numberDiff line numberDiff line change
@@ -119,30 +119,47 @@ A simple example with some color and linebreaks:
119119
## Advanced example
120120
A more complex example with different fonts, colors, inline images and automatic linebreaks:
121121

122-
local settings = {
123-
fonts = {
124-
Roboto = {
125-
regular = hash("Roboto-Regular"),
126-
italic = hash("Roboto-Italic"),
127-
bold = hash("Roboto-Bold"),
128-
bold_italic = hash("Roboto-BoldItalic"),
129-
},
130-
Nanum = {
131-
regular = hash("Nanum-Regular"),
132-
},
122+
```lua
123+
local settings = {
124+
fonts = {
125+
Roboto = {
126+
regular = hash("Roboto-Regular"),
127+
italic = hash("Roboto-Italic"),
128+
bold = hash("Roboto-Bold"),
129+
bold_italic = hash("Roboto-BoldItalic"),
133130
},
134-
width = 400,
135-
parent = gui.get_node("bg"),
136-
color = vmath.vector4(0.95, 0.95, 1.0, 1.0),
137-
shadow = vmath.vector4(0.0, 0.0, 0.0, 1.0),
138-
}
131+
Nanum = {
132+
regular = hash("Nanum-Regular"),
133+
},
134+
},
135+
width = 400,
136+
parent = gui.get_node("bg"),
137+
color = vmath.vector4(0.95, 0.95, 1.0, 1.0),
138+
shadow = vmath.vector4(0.0, 0.0, 0.0, 1.0),
139+
}
139140

140-
local text = "<size=3><outline=green>RichText</outline></size>Lorem <color=0,0.5,0,1>ipsum </color><img=smileys:zombie/> dolor <color=red>sit </color><color=#ff00ffff>amet, </color><size=1.15><font=Nanum>consectetur </font></size>adipiscing elit. <b>Nunc </b>tincidunt <b><i>mattis</i> libero</b> <i>non viverra</i>.\n\nNullam ornare <img=smileys:hungry/>accumsan rhoncus.\n\nNunc placerat nibh a purus auctor, id scelerisque massa <size=2>rutrum.</size>"
141+
local text = "<size=3><outline=green>RichText</outline></size>Lorem <color=0,0.5,0,1>ipsum </color><img=smileys:zombie/> dolor <color=red>sit </color><color=#ff00ffff>amet, </color><size=1.15><font=Nanum>consectetur </font></size>adipiscing elit. <b>Nunc </b>tincidunt <b><i>mattis</i> libero</b> <i>non viverra</i>.\n\nNullam ornare <img=smileys:hungry/>accumsan rhoncus.\n\nNunc placerat nibh a purus auctor, id scelerisque massa <size=2>rutrum.</size>"
141142

142-
richtext.create(text, "Roboto", settings)
143+
richtext.create(text, "Roboto", settings)
144+
```
143145

144146
![](docs/example.png)
145147

148+
## Custom tags
149+
Custom tags can be accessed and used in two ways:
150+
151+
* Use `richtext.tagged(words, tag)` to get all words with a certain tag, even a custom one
152+
* Use `tags.register(tag, fn)` to register a custom tag handler:
153+
154+
155+
```lua
156+
tags.register("boldred", function(params, settings)
157+
tags.apply("color", "red", settings)
158+
tags.apply("b", nil, settings)
159+
end)
160+
richtext.create("I am <boldred>bold and red</boldred>!", "Roboto", settings)
161+
```
162+
146163

147164
# API
148165
### richtext.create(text, font, settings)
@@ -173,6 +190,7 @@ The `settings` table can contain the following values:
173190

174191
The `fonts` table should have the following format:
175192

193+
```lua
176194
name (string) = {
177195
regular (string) = font (hash),
178196
italic (string) = font (hash),
@@ -182,11 +200,13 @@ The `fonts` table should have the following format:
182200
name (string) = {
183201
...
184202
},
203+
```
185204

186205
Where `name` is the name specified in a `<font>` tag and the `font` for each of `regular`, `italic`, `bold` and `bold_italic` should correspond to the name of a font added to a .gui scene.
187206

188207
The `layers` table should map fonts, textures and spine scenes to layer names. It should have the following format:
189208

209+
```lua
190210
fonts = {
191211
font (hash) = layer (hash),
192212
...
@@ -202,6 +222,7 @@ The `layers` table should map fonts, textures and spine scenes to layer names. I
202222
...
203223
spinescene (hash) = layer (hash),
204224
}
225+
```
205226

206227
Where `layer` is the name of a layer in the .gui scene, `font` is the value returned from a call to `gui.get_font(node)`, `texture` is the value returned from a call to `gui.get_texture(node)` and finally `spinescene` is the value returned from a call to `gui.get_spine_scene(node)`.
207228

example/example.gui_script

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local richtext = require "richtext.richtext"
22
local color = require "richtext.color"
3+
local tags = require "richtext.tags"
34

45
local sherlock = [[At three o'clock precisely I was at Baker Street, but Holmes had not yet returned. The landlady informed me that he had left the house shortly after eight o'clock in the morning. I sat down beside the fire, however, with the intention of awaiting him, however long he might be. I was already deeply interested in his inquiry, for, though it was surrounded by none of the grim and strange features which were associated with the two crimes which I have already recorded, still, the nature of the case and the exalted station of his client gave it a character of its own. Indeed, apart from the nature of the investigation which my friend had on hand, there was something in his masterly grasp of a situation, and his keen, incisive reasoning, which made it a pleasure to me to study his system of work, and to follow the quick, subtle methods by which he disentangled the most inextricable mysteries. So accustomed was I to his invariable success that the very possibility of his failing had ceased to enter into my head. It was close upon four before the door opened, and a drunken-looking groom, ill-kempt and side-whiskered, with an inflamed face and disreputable clothes, walked into the room. Accustomed as I was to my friend's amazing powers in the use of disguises, I had to look three times before I was certain that it was indeed he. With a nod he vanished into the bedroom, whence he emerged in five minutes tweed-suited and respectable, as of old. Putting his hands into his pockets, he stretched out his legs in front of the fire and laughed heartily for some minutes. 'Well, really!' he cried, and then he choked and laughed again until he was obliged to lie back, limp and helpless, in the chair. 'What is it?' 'It's quite too funny. I am sure you could never guess how I employed my morning, or what I ended by doing.' 'I can't imagine. I suppose that you have been watching the habits, and perhaps the house, of Miss Irene Adler.' 'Quite so; but the sequel was rather unusual. I will tell you, however. I left the house a little after eight o'clock this morning in the character of a groom out of work. There is a wonderful sympathy and freemasonry among horsey men. Be one of them, and you will know all that there is to know. I soon found Briony Lodge. It is a bijou villa, with a garden at the back, but built out in front right up to the road, two stories. Chubb lock to the door. Large sitting-room on the right side, well furnished, with long windows almost to the floor, and those preposterous English window fasteners which a child could open. Behind there was nothing remarkable, save that the passage window could be reached from the top of the coach-house. I walked round it and examined it closely from every point of view, but without noting anything else of interest. 'I then lounged down the street and found, as I expected, that there was a mews in a lane which runs down by one wall of the garden. I lent the ostlers a hand in rubbing down their horses, and received in exchange twopence, a glass of half and half, two fills of shag tobacco, and as much information as I could desire about Miss Adler, to say nothing of half a dozen other people in the neighbourhood in whom I was not in the least interested, but whose biographies I was compelled to listen to.']]
56

@@ -305,6 +306,14 @@ end
305306
local function create_repeat_example()
306307
local settings = { position = vmath.vector3(320, 450, 0), align = richtext.ALIGN_CENTER, fonts = { Roboto = ROBOTO } }
307308
return richtext.create("Now repeat<repeat=7>\n<b>after <color=red><i>me</i></color></b></repeat>\nWell done!", "Roboto", settings)
309+
310+
local function create_custom_tag_example()
311+
local settings = { position = vmath.vector3(320, 450, 0), align = richtext.ALIGN_CENTER, fonts = { Roboto = ROBOTO } }
312+
tags.register("boldred", function(params, settings)
313+
tags.apply("color", "red", settings)
314+
tags.apply("b", nil, settings)
315+
end)
316+
return richtext.create("I am <boldred>bold and red</boldred>!", "Roboto", settings)
308317
end
309318

310319

@@ -332,7 +341,8 @@ function init(self)
332341
{ name = "PARAGRAPHS", fn = create_paragraph_example },
333342
{ name = "COLORS", fn = create_colors_example },
334343
{ name = "REPEAT", fn = create_repeat_example },
335-
}
344+
{ name = "CUSTOM TAGS", fn = create_custom_tag_example },
345+
}
336346

337347
self.back = gui.get_node("back/bg")
338348
self.buttons = {}

richtext/parse.lua

+2-36
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,11 @@
1-
local color = require "richtext.color"
21
local utf8 = require("richtext.utf8")
2+
local tags = require("richtext.tags")
33

44
local M = {}
55

66
local function parse_tag(tag, params)
77
local settings = { tags = { [tag] = params }, tag = tag }
8-
if tag == "color" then
9-
settings.color = color.parse(params)
10-
elseif tag == "shadow" then
11-
settings.shadow = color.parse(params)
12-
elseif tag == "outline" then
13-
settings.outline = color.parse(params)
14-
elseif tag == "font" then
15-
settings.font = params
16-
elseif tag == "size" then
17-
settings.size = tonumber(params)
18-
elseif tag == "b" then
19-
settings.bold = true
20-
elseif tag == "i" then
21-
settings.italic = true
22-
elseif tag == "a" then
23-
settings.anchor = true
24-
elseif tag == "br" then
25-
settings.linebreak = true
26-
elseif tag == "img" then
27-
local texture, anim = params:match("(.-):(.*)")
28-
settings.image = {
29-
texture = texture,
30-
anim = anim
31-
}
32-
elseif tag == "spine" then
33-
local scene, anim = params:match("(.-):(.*)")
34-
settings.spine = {
35-
scene = scene,
36-
anim = anim
37-
}
38-
elseif tag == "nobr" then
39-
settings.nobr = true
40-
elseif tag == "p" then
41-
settings.paragraph = tonumber(params) or true
42-
else
8+
if not tags.apply(tag, params, settings) then
439
settings[tag] = params
4410
end
4511

richtext/tags.lua

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
local color = require "richtext.color"
2+
3+
local M = {}
4+
5+
local tags = {}
6+
7+
8+
function M.apply(tag, params, settings)
9+
local fn = tags[tag]
10+
if not fn then
11+
return false
12+
end
13+
14+
fn(params, settings)
15+
return true
16+
end
17+
18+
function M.register(tag, fn)
19+
assert(tag, "You must provide a tag")
20+
assert(fn, "You must provide a tag function")
21+
tags[tag] = fn
22+
end
23+
24+
25+
26+
M.register("color", function(params, settings)
27+
settings.color = color.parse(params)
28+
end)
29+
30+
M.register("shadow", function(params, settings)
31+
settings.shadow = color.parse(params)
32+
end)
33+
34+
M.register("outline", function(params, settings)
35+
settings.outline = color.parse(params)
36+
end)
37+
38+
M.register("font", function(params, settings)
39+
settings.font = params
40+
end)
41+
42+
M.register("size", function(params, settings)
43+
settings.size = tonumber(params)
44+
end)
45+
46+
M.register("b", function(params, settings)
47+
settings.bold = true
48+
end)
49+
50+
M.register("i", function(params, settings)
51+
settings.italic = true
52+
end)
53+
54+
M.register("a", function(params, settings)
55+
settings.anchor = true
56+
end)
57+
58+
M.register("br", function(params, settings)
59+
settings.linebreak = true
60+
end)
61+
62+
M.register("nobr", function(params, settings)
63+
settings.nobr = true
64+
end)
65+
66+
M.register("img", function(params, settings)
67+
local texture, anim = params:match("(.-):(.*)")
68+
settings.image = {
69+
texture = texture,
70+
anim = anim
71+
}
72+
end)
73+
74+
M.register("spine", function(params, settings)
75+
local scene, anim = params:match("(.-):(.*)")
76+
settings.spine = {
77+
scene = scene,
78+
anim = anim
79+
}
80+
end)
81+
82+
M.register("p", function(params, settings)
83+
settings.paragraph = tonumber(params) or true
84+
end)
85+
86+
87+
return M

0 commit comments

Comments
 (0)