Rebol [ Title: "AnaMezzanines" File: %anamezzanines.r Author: "Romano Paolo Tenca" Copyright: {GNU General Public License - Copyright (C) Romano Paolo Tenca 2005} Web: http://www.rebol.it/~romano Rights: { This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. } Version: 1.0.0 Date: 01/10/2005 History: [ 1.0.0 01/10/2005 "First public release" ] ] probe: func [ "Print any-type! value and return it (for debug)." value [any-type!] ][ print either value? 'value [mold :value]["unset"] get/any 'value ] join: func [ "Form a value or copy a series and append the reduced rest to it." value "The primary value" rest "Value to be appended and reduced." ][ head insert tail either series? :value [copy value] [form :value] reduce rest ] replace: func [ {Replace one or all occurences of a value with another one.} series [series!] "Series to change." search "Value to search." replace "Replace value." /all "Replace all occurrences." /case "Search case sensitive." /local start len ][ start: series len: either any-string? series [ if any [ not any-string? :search tag? :search ] [search: form :search] length? :search ][ either any-block? :search [length? :search] [1] ] while pick [ [series: find/case series :search] [series: find series :search] ] none <> case [ series: change/part series :replace len any [all break] ] start ] array: func [ [catch] "Make an array and init it with none or an user value." size [integer! block!] "Size(s) of array." /initial "Init the array with this value." value /local block ][ throw-on-error [ initial: insert copy [] size until [ any [ integer? size: first initial: back initial make error! "Array size must be an integer" ] block: make block! size value: head either series? :value [ loop size [insert/only tail block copy/deep :value] ][ insert/dup block :value size ] head? initial ] block ] ] source: func [ "Show the source of functions" 'word [word!] ][ print join word [ ": " either not value? word ["undefined"][ either any [function? get word not any-function? get word][ mold get word ][ reduce [type? get word mold third get word] ] ] ] ] found?: func [ "Shortcut for: value <> none (also a false value return true). " value ][ none <> :value ] forskip: func [ [throw catch] "Do the body and skip the series until the end." 'word [word!] {Word set to the series} skip-pos [integer!] "Positions to skip at every loop" body [block!] "The body to do at every loop" /local start result ][ any [ skip-pos > 0 throw make error! reduce ['script 'invalid-arg skip-pos] ] any [ series? get word port? get word throw make error! reduce ['script 'invalid-arg word] ] start: get word while [1][ all [ tail? get word set word start break/return get/any 'result ] set/any 'result do body set word skip get word skip-pos ] ] forall: func [ "Do the body for every series index." [throw catch] 'word [word!] {Word set to the series} body [block!] "The body to do" /local start result ][ any [ series? get word port? get word throw make error! reduce ['script 'invalid-arg word] ] start: get word while [1][ all [ tail? get word set word start break/return get/any 'result ] set/any 'result do body set word next get word ] ] split-path: func [ {Transform a name in path and target. Return a block.} target [file! url!] /local dir pos ][ parse/all target [ [#"/" | 1 2 #"." opt #"/"] end (dir: dirize target) | pos: any [thru #"/" [end | pos:]] ( all [empty? dir: copy/part target at head target index? pos dir: %./] all [find [%. %..] pos: to file! pos insert tail pos #"/"] ) ] reduce [dir pos] ] dirize: func [ {Transform a name into a directory name.} path [file! string! url!] ][ either parse/all path [some[thru #"/" ]] [copy path][head insert tail copy path #"/"] ] alter: func [ "Append a value to a series or port if missing, else remove it." series [series! port!] value ][ ;either temp: find series value [remove temp] [append series value] any [remove find series :value insert tail series :value] ] switch: func [ "Call select and do the result." [throw] value "Value to select." cases [block!] "Block to search." /default case "Case to do if select return none or false." ][ case: any [select cases value all [default case]] do case ] extract: func [ [catch] {Build a new block and fill it with values picked from the source series.} source [series!] skip-num [integer!] "Size to skip each time." /index "Pick value at index." pos [number! logic!] ][ throw-on-error [ any [index pos: 1] index: make block! (length? source) + skip-num / skip-num while [not tail? source] [ insert/only tail index pick source pos source: skip source skip-num ] index ] ] ;alternative version with /part refinement extract2: func [ [catch] {Build a new series and fill it with values copied from the source.} source [series!] skip-num [integer!] "Size to skip each time." /index "Copy value(s) at the index." pos [number! logic!] /part "Copy the given length." length [number!] "The length to copy (default: 1)." ][ throw-on-error [ all [index source: at source pos] any [part length: 1] index: make source (length? source) / skip-num * length while [not tail? source] [ insert/part tail index source length source: skip source skip-num ] index ] ] to-itime: func [ {Form a time in the 00:00:00 format} time [time!] ][ copy/part change next "000:00:00" time -8 ]