Skip to content

Commit

Permalink
Added support for custom tags
Browse files Browse the repository at this point in the history
Fixes #64
  • Loading branch information
britzl committed May 4, 2022
1 parent 063662c commit 619755e
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 55 deletions.
57 changes: 39 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,30 +119,47 @@ A simple example with some color and linebreaks:
## Advanced example
A more complex example with different fonts, colors, inline images and automatic linebreaks:

local settings = {
fonts = {
Roboto = {
regular = hash("Roboto-Regular"),
italic = hash("Roboto-Italic"),
bold = hash("Roboto-Bold"),
bold_italic = hash("Roboto-BoldItalic"),
},
Nanum = {
regular = hash("Nanum-Regular"),
},
```lua
local settings = {
fonts = {
Roboto = {
regular = hash("Roboto-Regular"),
italic = hash("Roboto-Italic"),
bold = hash("Roboto-Bold"),
bold_italic = hash("Roboto-BoldItalic"),
},
width = 400,
parent = gui.get_node("bg"),
color = vmath.vector4(0.95, 0.95, 1.0, 1.0),
shadow = vmath.vector4(0.0, 0.0, 0.0, 1.0),
}
Nanum = {
regular = hash("Nanum-Regular"),
},
},
width = 400,
parent = gui.get_node("bg"),
color = vmath.vector4(0.95, 0.95, 1.0, 1.0),
shadow = vmath.vector4(0.0, 0.0, 0.0, 1.0),
}

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>"
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>"

richtext.create(text, "Roboto", settings)
richtext.create(text, "Roboto", settings)
```

![](docs/example.png)

## Custom tags
Custom tags can be accessed and used in two ways:

* Use `richtext.tagged(words, tag)` to get all words with a certain tag, even a custom one
* Use `tags.register(tag, fn)` to register a custom tag handler:


```lua
tags.register("boldred", function(params, settings)
tags.apply("color", "red", settings)
tags.apply("b", nil, settings)
end)
richtext.create("I am <boldred>bold and red</boldred>!", "Roboto", settings)
```


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

The `fonts` table should have the following format:

```lua
name (string) = {
regular (string) = font (hash),
italic (string) = font (hash),
Expand All @@ -182,11 +200,13 @@ The `fonts` table should have the following format:
name (string) = {
...
},
```

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.

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

```lua
fonts = {
font (hash) = layer (hash),
...
Expand All @@ -202,6 +222,7 @@ The `layers` table should map fonts, textures and spine scenes to layer names. I
...
spinescene (hash) = layer (hash),
}
```

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)`.

Expand Down
12 changes: 11 additions & 1 deletion example/example.gui_script
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local richtext = require "richtext.richtext"
local color = require "richtext.color"
local tags = require "richtext.tags"

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.']]

Expand Down Expand Up @@ -305,6 +306,14 @@ end
local function create_repeat_example()
local settings = { position = vmath.vector3(320, 450, 0), align = richtext.ALIGN_CENTER, fonts = { Roboto = ROBOTO } }
return richtext.create("Now repeat<repeat=7>\n<b>after <color=red><i>me</i></color></b></repeat>\nWell done!", "Roboto", settings)

local function create_custom_tag_example()
local settings = { position = vmath.vector3(320, 450, 0), align = richtext.ALIGN_CENTER, fonts = { Roboto = ROBOTO } }
tags.register("boldred", function(params, settings)
tags.apply("color", "red", settings)
tags.apply("b", nil, settings)
end)
return richtext.create("I am <boldred>bold and red</boldred>!", "Roboto", settings)
end


Expand Down Expand Up @@ -332,7 +341,8 @@ function init(self)
{ name = "PARAGRAPHS", fn = create_paragraph_example },
{ name = "COLORS", fn = create_colors_example },
{ name = "REPEAT", fn = create_repeat_example },
}
{ name = "CUSTOM TAGS", fn = create_custom_tag_example },
}

self.back = gui.get_node("back/bg")
self.buttons = {}
Expand Down
38 changes: 2 additions & 36 deletions richtext/parse.lua
Original file line number Diff line number Diff line change
@@ -1,45 +1,11 @@
local color = require "richtext.color"
local utf8 = require("richtext.utf8")
local tags = require("richtext.tags")

local M = {}

local function parse_tag(tag, params)
local settings = { tags = { [tag] = params }, tag = tag }
if tag == "color" then
settings.color = color.parse(params)
elseif tag == "shadow" then
settings.shadow = color.parse(params)
elseif tag == "outline" then
settings.outline = color.parse(params)
elseif tag == "font" then
settings.font = params
elseif tag == "size" then
settings.size = tonumber(params)
elseif tag == "b" then
settings.bold = true
elseif tag == "i" then
settings.italic = true
elseif tag == "a" then
settings.anchor = true
elseif tag == "br" then
settings.linebreak = true
elseif tag == "img" then
local texture, anim = params:match("(.-):(.*)")
settings.image = {
texture = texture,
anim = anim
}
elseif tag == "spine" then
local scene, anim = params:match("(.-):(.*)")
settings.spine = {
scene = scene,
anim = anim
}
elseif tag == "nobr" then
settings.nobr = true
elseif tag == "p" then
settings.paragraph = tonumber(params) or true
else
if not tags.apply(tag, params, settings) then
settings[tag] = params
end

Expand Down
87 changes: 87 additions & 0 deletions richtext/tags.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
local color = require "richtext.color"

local M = {}

local tags = {}


function M.apply(tag, params, settings)
local fn = tags[tag]
if not fn then
return false
end

fn(params, settings)
return true
end

function M.register(tag, fn)
assert(tag, "You must provide a tag")
assert(fn, "You must provide a tag function")
tags[tag] = fn
end



M.register("color", function(params, settings)
settings.color = color.parse(params)
end)

M.register("shadow", function(params, settings)
settings.shadow = color.parse(params)
end)

M.register("outline", function(params, settings)
settings.outline = color.parse(params)
end)

M.register("font", function(params, settings)
settings.font = params
end)

M.register("size", function(params, settings)
settings.size = tonumber(params)
end)

M.register("b", function(params, settings)
settings.bold = true
end)

M.register("i", function(params, settings)
settings.italic = true
end)

M.register("a", function(params, settings)
settings.anchor = true
end)

M.register("br", function(params, settings)
settings.linebreak = true
end)

M.register("nobr", function(params, settings)
settings.nobr = true
end)

M.register("img", function(params, settings)
local texture, anim = params:match("(.-):(.*)")
settings.image = {
texture = texture,
anim = anim
}
end)

M.register("spine", function(params, settings)
local scene, anim = params:match("(.-):(.*)")
settings.spine = {
scene = scene,
anim = anim
}
end)

M.register("p", function(params, settings)
settings.paragraph = tonumber(params) or true
end)


return M

0 comments on commit 619755e

Please sign in to comment.