Skip to content

Instantly share code, notes, and snippets.

@toomasv
Last active June 30, 2017 10:26
Show Gist options
  • Save toomasv/464bd3bc775b75ce734bebf6d7aca190 to your computer and use it in GitHub Desktop.
Save toomasv/464bd3bc775b75ce734bebf6d7aca190 to your computer and use it in GitHub Desktop.
Format a block into columns
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