Last active
June 30, 2017 10:26
-
-
Save toomasv/464bd3bc775b75ce734bebf6d7aca190 to your computer and use it in GitHub Desktop.
Format a block into columns
This file contains 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: "2017-05-05" | |
Needs: {Examples may use `fill.red` by Gregg Irwin (https://gitter.im/red/red/welcome?at=590b4daac93941e153c94b8e) | |
or as adapted by me (https://gitter.im/red/red/welcome?at=590cae8d33e9ee771c793966)} | |
] | |
to-blocks: func [ | |
{Splits a block into more or less equal chuncks} | |
blk [block!] {Initial block to split} | |
num [integer!] {Number of resulting chuncks} | |
/local out l n b | |
][ | |
out: clear [] ; collector | |
l: length? blk ; length of the initial block | |
n: either 0 = (l % num) [l / num][l / num + 1] ; number of elements in resulting blocks | |
b: copy blk ; copy of the initial block to manipulate | |
repeat i num [append/only out take/part b n] ; break the block | |
out ; return result | |
] | |
combine: func [ | |
{Combines elements of provided blocks into one in the order [b1/1 b2/1 ... b1/2 b2/2 ...} | |
blocks [block!] {Block of blocks to combine} | |
/local out num | |
][ | |
out: clear [] ; collector | |
num: length? first blocks ; length of the first block - all blocks should be at most that long | |
repeat i num [foreach b blocks [append out pick b i]] ; combine blocks | |
out ;return result | |
] | |
to-spec: func [ | |
{Prepares a speck block with set-words and values} | |
words [block!] {Block of words to make set-words} | |
values [block!] {Block of values for set-words} | |
][ | |
out: clear [] ; output collector | |
repeat i length? words [ ; get index of each word | |
append out reduce [ ; append to output | |
to-set-word pick words i ; make set-word | |
either v: pick values i [v][""] ; assign values (none is casted as empty string) | |
] ; output is returned automatically on last append | |
] | |
] | |
to-columns: func [ | |
{Formats provided block into columns by template} | |
source [block!] {Block of values to put into columns} | |
cols [block!] {Block of column names to refer to in template} | |
template [block!] {Block of template code referring to provided column names} | |
/down-across {Data runs first down then into next column} | |
/start s {To print before columns if anything} | |
/end e {To print after columns if anything} | |
][ | |
set [s e] reduce [any [s ""] any [e ""]] ; assign start and end strings, if provided | |
unless empty? s [print s] ; print start string | |
if down-across [source: combine to-blocks source length? cols] ; reorder block, if needed | |
foreach (cols) source [ ; for each column | |
;bind template object to-spec cols reduce cols ; bind column names in template to their values | |
;print template ; output | |
print compose template | |
] | |
unless empty? e [print e] ; print end string | |
] | |
;-------- Examples ---------- | |
comment [ | |
; helpers | |
do %myfill.red | |
x: times: make op! func [n c][pad/with copy "" n to char! c] | |
map: func [series [series!] fn [any-function! /local out]][ | |
out: make type? series [] | |
foreach i series [append out fn i] | |
] | |
; Examples | |
src: [123 342 5643 115 49837 324 2 99 3567 878589 9659 959 9589589 95 89589 959 59 95 895 95895 959 94564 242 66] | |
cols: [a b c d] | |
to-columns/start src cols append map cols func [c][ | |
return compose [fill "| " 'right (c)] | |
] #"|" rejoin map [1 2 3 4] func [n][ | |
return compose [fill (t: copy "__________|" either n = 1 [head insert t #"|"][t]) 'center (append copy "Col" n)] | |
] | |
src: ["111" 111 [32 451] "nice!" url! %some/file #(a: map) 'word] | |
to-columns/start src [a] [fill "|____________|" 'center (a)] rejoin [" " 12 x "_"] | |
to-columns src [a] [pad/left (mold a) 10] | |
; Next two go together | |
to-columns/end ["value" "type?"] [a b] [pad/left (a) 10 pad (b) 10] 21 x #"_" | |
to-columns src [a] [pad/left (form a) 10 pad (to-string type?/word a) 10] | |
; Down-across | |
to-columns/down-across ['a 'b 'c 'd 'e 'f 'g 'h 'i 'j 'k 'l] cols: [c1 c2 c3] [pad/left (form c1) 3 pad (form c2) 3 fill "-----" 'center (c3)] | |
;map cols func [c][return compose [pad/left form (c) 5]] | |
; Contents | |
;contents: [0 "Introduction" 3 0 "Chapter 1" 5 1 "Formatting" 5 2 "fill" 6 2 "pad" 6 2 "to-columns" 7 1 "Splitting" 8 0 "Chapter 2" 11] | |
contents: [1 "There is no spoon" 2 2 "Some `copy`-fu drills" 3 2 "`parse`kido exercises" 4 2 "First steps in tai-`do`-`reduce`" 8 1 "There be wizards" 10 2 "`system`-do" 12] | |
to-columns/start contents [level title page] [(level * 4) x " " fill (50 - (4 * level)) x "." 'left (title) pad/left (form page) 3] "RED APPRENTICESHIP" | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment