Skip to content

Instantly share code, notes, and snippets.

@toomasv
Last active March 16, 2019 22:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toomasv/b2719d0635ed965ae22068ad1ecb6536 to your computer and use it in GitHub Desktop.
Save toomasv/b2719d0635ed965ae22068ad1ecb6536 to your computer and use it in GitHub Desktop.
Simplified syntax for rich-text
Red [
Author: "Toomas Vooglaid"
Date: 9-Mar-2019
Purpose: {Simplified syntax for rich-text specification}
]
context [
format-word: no
format-any: copy []
in-string?: no
sp: charset " ^-"
rt-box: none
len: 0
s: i: none
backslash: [
if (in-string?) remove skip skip
| remove skip insert #"{" skip (in-string?: yes)
]
end-tag: [
opt [if (in-string?) insert #"}" s: (in-string?: no)]
[
if (0 < length? format-any) (
loop take format-any [s: insert s #"]"]
s: remove/part s 2
) :s
| (cause-error 'user 'message ["Any-tag-end without tag-start"])
]
]
start-tag: [
remove skip
opt [if (in-string?) insert "} " (in-string?: no)]
[
ahead #"[" s: copy blk thru #"]" :s remove thru #"]" (
blk: load blk
case/all [
1 < length? blk [
parse blk [
some [i:
'bg (
len: len + 1
s: insert s append form take/part i 2 " ["
) :i
| ['f | 'font] [
[integer! string! | string! integer!] (
s: insert s append append append form take i " " mold take/part i 2 " ["
)
| [integer! | string!] (
s: insert s append append append form take i " " mold take i " ["
)
] (len: len + 1) :i
| skip
]
]
]
1 < length? blk [len: len + 1 s: insert s append form to-path blk " ["]
1 = length? blk [len: len + 1 s: insert s append form blk " ["]
]
) :s
| skip (len: 1) insert " ["
][
remove " " (insert format-any len )
| remove #" " (format-word: len )
| insert {"} skip insert {"} s: close-letter-tag :s insert #" "
] (len: 0)
]
close-letter-tag: [
(loop len [s: insert s #"]"])
]
close-tags: [
if (format-word) opt [
if (in-string?) (
if tail? next s [s: tail s]
s: insert s "}"
in-string?: no
) :s
] s: (
loop format-word [s: insert s #"]"]
format-word: no
) :s
]
letter: [if (not in-string?) insert #"{" (in-string?: yes) |]
finalize: [
close-tags
| if (in-string?) insert "}"
]
set 'rtd-simple func [text [string!] /only /with rt-face /width w /raw /local blk][
format-word: no
clear format-any
in-string?: no
len: 0
parse text [
some [s:
ahead "\\" backslash
| ahead "\ " end-tag
| ahead #"\" start-tag
| sp close-tags
| letter skip
]
end finalize
]
out: load/all text
case [
raw [text]
only [load/all text]
'else [
rt-box: rtd-layout load/all text
either with [
rt-face/text: copy rt-box/text
rt-face/data: copy rt-box/data
if width [rt-face/size/x: w]
][
if width [rt-box/size/x: w]
rt-box
]
]
]
]
]
comment {
;Syntax is minimalistic
1. Tag starts with `\` and is followed by
A) single-letter from [i b s u], or
B) by block containing any of the following:
1) `i`, `b`, `s`, `u`
2) color-word or tuple
3) `bg` with color-word or tuple (e.g. [bg blue])
4) `f` (or `font`) with integer! font-size and/or string! font-name (e.g. [f 16], [font "Courier New"], [f "Times" 24])
All of the above may be combined into one tag (e.g. `\[f 24 "Consolas" bg red i b gold]`)
2. Tag may be placed:
A) immediately before a letter (e.g. "\bHello!", "Hello\[red]!"). In this case its scope is the letter.
B) one space before the word (e.g. "\b Hello!"). Scope is word.
C) two spaces before the word or letter for arbitary scope. This must be closed with backslash + space `\ `
(e.g. "Supercali\[b] fragilistic\ expialidocious")
3. Tags can be nested (e.g. "\[f 24 red] The \[b i] Journey \[b bg orange]Begins\b!\ "), but this is buggy, can be conflicts.
4. When called without refinements, `rtd-simple` returns new rich-text face. With refinement `/only` generated layout
block is returned. For debugging purposes `/raw` refinement may be used. It returns generated string before it is
loaded into block. Also, as in `rtd-layout`, `/with` refinement sets text and data facets on provided face.
Finally, `/width` refinement sets width of the new or provided face.
That's it!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment