User:Jr/assorted

From POV-Wiki
Jump to navigation Jump to search

this page has been created to house stand-alone macros, "how to" snippets and such. also, not necessarily only my own macros/code, I'm willing (and will be happy) to consider your, showcased in the news groups, code for inclusion.

macros

LatinYear()

this macro converts small integer values, typically years, to their Roman Numerals representation, as outlined in the Wikipedia article. it started life as several macros in a include/header file, but with some help and encouragement, it now is "stand-alone" and just 40-odd (formatted) 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)