Last active
March 16, 2019 22:24
-
-
Save toomasv/b2719d0635ed965ae22068ad1ecb6536 to your computer and use it in GitHub Desktop.
Simplified syntax for rich-text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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