Difference between revisions of "User:Jr/assorted"
m (added a category ('macros').) |
(added the 'strSplit()' macro.) |
||
| Line 75: | Line 75: | ||
(fingers crossed :-), tested using version 3.7.0.8) | (fingers crossed :-), tested using version 3.7.0.8) | ||
| + | |||
| + | |||
| + | === strSplit() === | ||
| + | |||
| + | this small macro is designed to "parse" text strings. it splits its input on a given separator character and returns a new array of strings. the macro was posted some time ago in the NG (<web.64b08576d08f3556b49d80446cde94f1@news.povray.org>). | ||
| + | |||
| + | <pre> | ||
| + | #macro strSplit(s_,sep_) | ||
| + | #local n_ = strlen(s_); | ||
| + | #if (!n_) | ||
| + | #error "strSplit: string must not be empty." | ||
| + | #elseif (1 != strlen(sep_)) | ||
| + | #error "strSplit: separator must be a single character." | ||
| + | #end | ||
| + | #local a_ = array; | ||
| + | #local f_ = false; | ||
| + | #local i_ = 1; | ||
| + | #local k_ = 0; | ||
| + | #while (n_ >= i_) | ||
| + | #if (!strcmp(sep_,substr(s_,i_,1))) | ||
| + | #if ((i_ - 1) = k_) #local t_ = ""; | ||
| + | #else #local t_ = substr(s_,(k_ + 1),(i_ - k_ - 1)); | ||
| + | #end | ||
| + | #if (n_ = i_) #local f_ = true; #end | ||
| + | #local a_[dimension_size(a_,1)] = t_; | ||
| + | #local k_ = i_; | ||
| + | #undef t_ | ||
| + | #elseif (n_ = i_) | ||
| + | #local a_[dimension_size(a_,1)] = substr(s_,(k_ + 1),(i_ - k_)); | ||
| + | #end | ||
| + | #local i_ = i_ + 1; | ||
| + | #end | ||
| + | #if (f_) #local a_[dimension_size(a_,1)] = ""; #end | ||
| + | a_ | ||
| + | #end | ||
| + | </pre> | ||
| + | |||
| + | this simple usage demo: | ||
| + | |||
| + | <pre> | ||
| + | #declare demo_ = "apple:3 mango:5 pear:7"; | ||
| + | #declare ddict_ = dictionary; | ||
| + | |||
| + | #declare pass1_ = strSplit(demo_," "); | ||
| + | #for (i_, 0, dimension_size(pass1_,1)-1) | ||
| + | #local pass2_ = strSplit(pass1_[i_],":"); | ||
| + | #local ddict_[pass2_[0]] = val(pass2_[1]); | ||
| + | #end | ||
| + | |||
| + | #debug concat("apple: ",str(ddict_.apple,0,0),"\n") | ||
| + | #debug concat("mango: ",str(ddict_.mango,0,0),"\n") | ||
| + | #debug concat("pear : ",str(ddict_.pear,0,0),"\n") | ||
| + | </pre> | ||
| + | |||
| + | will output: | ||
| + | |||
| + | <pre> | ||
| + | apple: 3 | ||
| + | mango: 5 | ||
| + | pear : 7 | ||
| + | </pre> | ||
| + | |||
| + | (tested using version 3.8.0-alpha.9945627) | ||
[[Category:Macros]] | [[Category:Macros]] | ||
Revision as of 09:38, 26 December 2025
this page has been created to house stand-alone macros, for now, I reserve the right :-) to add "how to" snippets and such. also, not necessarily only my own macros/code, I'm willing (and will be happy) to consider your code for inclusion.
macros
LatinYear()
this macro started life as several in a include/header file, but, with some help and encouragement, it now is "stand-alone", and just 40-odd lines of code.
#macro LatinYear(year_)
#if (int(year_) != year_)
#error "oops, bad 'year'."
#elseif (year_ < 1 | 3999 < year_)
#error "oops, out-of-range 'year'."
#end
#macro __cvt(dgt_, s1_, s5_, s10_)
#local units_ = concat(s1_,s1_,s1_);
#local n_ = val(dgt_);
#switch (n_)
#case(0) #local s_ = ""; #break
#range(1,3) #local s_ = substr(units_,1,n_); #break
#case(4) #local s_ = concat(s1_,s5_); #break
#case(5) #local s_ = s5_; #break
#range(6,8) #local s_ = concat(s5_,substr(units_,1,n_-5)); #break
#case(9) #local s_ = concat(s1_,s10_); #break
#else #error "oops, \"cannot happen\" error in '__cvt()'."
#end
s_
#end
#local ystr_ = str(year_,0,0);
#switch (strlen(ystr_))
#case(4)
#local s_ = concat(substr("MMM",1,val(substr(ystr_,1,1))),
__cvt(substr(ystr_,2,1),"C","D","M"),
__cvt(substr(ystr_,3,1),"X","L","C"),
__cvt(substr(ystr_,4,1),"I","V","X"));
#break
#case(3)
#local s_ = concat(__cvt(substr(ystr_,1,1),"C","D","M"),
__cvt(substr(ystr_,2,1),"X","L","C"),
__cvt(substr(ystr_,3,1),"I","V","X"));
#break
#case(2)
#local s_ = concat(__cvt(substr(ystr_,1,1),"X","L","C"),
__cvt(substr(ystr_,2,1),"I","V","X"));
#break
#case(1)
#local s_ = __cvt(ystr_,"I","V","X");
#break
#else #error "oops, \"cannot happen\" error in 'LatinYear()'."
#end
s_
#end
a copy'n'paste set of calls to try it out:
#debug concat("2000 ",LatinYear(2000),".\n")
#debug concat("1984 ",LatinYear(1984),".\n")
#debug concat("2026 ",LatinYear(2026),".\n")
#debug concat(" 26 ",LatinYear(26),".\n")
#debug concat(" 4 ",LatinYear(4),".\n")
#debug concat("3999 ",LatinYear(3999),".\n")
which shows:
2000 MM. 1984 MCMLXXXIV. 2026 MMXXVI. 26 XXVI. 4 IV. 3999 MMMCMXCIX.
(fingers crossed :-), tested using version 3.7.0.8)
strSplit()
this small macro is designed to "parse" text strings. it splits its input on a given separator character and returns a new array of strings. the macro was posted some time ago in the NG (<web.64b08576d08f3556b49d80446cde94f1@news.povray.org>).
#macro strSplit(s_,sep_)
#local n_ = strlen(s_);
#if (!n_)
#error "strSplit: string must not be empty."
#elseif (1 != strlen(sep_))
#error "strSplit: separator must be a single character."
#end
#local a_ = array;
#local f_ = false;
#local i_ = 1;
#local k_ = 0;
#while (n_ >= i_)
#if (!strcmp(sep_,substr(s_,i_,1)))
#if ((i_ - 1) = k_) #local t_ = "";
#else #local t_ = substr(s_,(k_ + 1),(i_ - k_ - 1));
#end
#if (n_ = i_) #local f_ = true; #end
#local a_[dimension_size(a_,1)] = t_;
#local k_ = i_;
#undef t_
#elseif (n_ = i_)
#local a_[dimension_size(a_,1)] = substr(s_,(k_ + 1),(i_ - k_));
#end
#local i_ = i_ + 1;
#end
#if (f_) #local a_[dimension_size(a_,1)] = ""; #end
a_
#end
this simple usage demo:
#declare demo_ = "apple:3 mango:5 pear:7";
#declare ddict_ = dictionary;
#declare pass1_ = strSplit(demo_," ");
#for (i_, 0, dimension_size(pass1_,1)-1)
#local pass2_ = strSplit(pass1_[i_],":");
#local ddict_[pass2_[0]] = val(pass2_[1]);
#end
#debug concat("apple: ",str(ddict_.apple,0,0),"\n")
#debug concat("mango: ",str(ddict_.mango,0,0),"\n")
#debug concat("pear : ",str(ddict_.pear,0,0),"\n")
will output:
apple: 3 mango: 5 pear : 7
(tested using version 3.8.0-alpha.9945627)