diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 662e5eff..bc906c69 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -818,6 +818,7 @@ type: boolean: boolean color: color image: image + date: date nil: nothing # Object types diff --git a/doc/function/index.txt b/doc/function/index.txt index aa6460f5..16aaf465 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -9,6 +9,7 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:to_number]] Convert any value to a number | [[fun:to_boolean]] Convert any value to a [[type:boolean]] | [[fun:to_color]] Convert any value to a [[type:color]] +| [[fun:to_date]] Convert any value to a [[type:date]] ! Numbers <<< | [[fun:abs]] Absolute value diff --git a/doc/function/to_date.txt b/doc/function/to_date.txt new file mode 100644 index 00000000..8b29d7b9 --- /dev/null +++ b/doc/function/to_date.txt @@ -0,0 +1,19 @@ +Function: to_date + +DOC_MSE_VERSION: since 0.3.8 + +--Usage-- +> to_date(any value) + +Convert a string value to a [[type:date]]. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:string]] Value to convert to a date. + +--Examples-- +> to_date("2008-12-31 23:59:59") +> to_date("today midnight") + +--See also-- +| [[fun:to_string]] Convert dates to strings diff --git a/doc/function/to_string.txt b/doc/function/to_string.txt index 489c5a66..caff65de 100644 --- a/doc/function/to_string.txt +++ b/doc/function/to_string.txt @@ -15,12 +15,13 @@ The former converts things like number to string, while the latter removes tags ! Parameter Type Description | @input@ ''any type'' Value to convert to a string | @format@ ''optional'' Formatting to apply.
- This takes the same form as [[http://www.cplusplus.com/reference/clibrary/cstdio/printf.html|printf format specifiers]]. + This takes the same form as [[http://www.cplusplus.com/reference/clibrary/cstdio/printf.html|printf format specifiers]].
+ When formating a date, the format string takes the same form as [[http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html|strftime format specifiers]]. --Examples-- > to_string(to_color("blue")) == "rgb(0,0,255)" > to_string(10 + 20) == "30" > to_string(10 + 20, format: ".3f") == "30.000" > to_string(10 + 20, format: "x") == "1e" # hexadecimal notation -> to_string("xy", format: "3s") == " xy" - +> to_string("xy", format: "3s") == " xy" +> to_string(to_date("2008-12-31 23:59:59"), format:"%d/%m/%y") == "31/12/08" diff --git a/doc/type/date.txt b/doc/type/date.txt new file mode 100644 index 00000000..09056472 --- /dev/null +++ b/doc/type/date.txt @@ -0,0 +1,13 @@ +Primitive type: date and time + +DOC_MSE_VERSION: since 0.3.8 + +A point in time, consisting of a date and a time. +The file syntax uses [[http://en.wikipedia.org/wiki/ISO_8601|ISO 8601]] notation. + +--File syntax-- +> something: 2008-12-31 23:59:59 + +--See also-- +| [[fun:to_date]] Convert a value to a date +| [[fun:to_string]] Convert dates to strings diff --git a/doc/type/index.txt b/doc/type/index.txt index e5e6aec3..0e94f6ac 100644 --- a/doc/type/index.txt +++ b/doc/type/index.txt @@ -66,3 +66,4 @@ These contain several properties, similair to the file types. But they are part | [[type:double]] Real numbers, @1, 0.5, 21.3@ | [[type:version]] Version numbers | [[type:color]] Colors +| [[type:date]] Dates/times diff --git a/src/data/card.cpp b/src/data/card.cpp index 9a518bc7..52646d0b 100644 --- a/src/data/card.cpp +++ b/src/data/card.cpp @@ -78,8 +78,8 @@ IMPLEMENT_REFLECTION(Card) { } } REFLECT(notes); - REFLECT_NO_SCRIPT(time_created); - REFLECT_NO_SCRIPT(time_modified); + REFLECT(time_created); + REFLECT(time_modified); REFLECT(extra_data); // don't allow scripts to depend on style specific data REFLECT_NAMELESS(data); } diff --git a/src/gfx/color.cpp b/src/gfx/color.cpp index 58e06e68..c67be874 100644 --- a/src/gfx/color.cpp +++ b/src/gfx/color.cpp @@ -16,9 +16,6 @@ template <> void Reader::handle(Color& col) { if (!col.Ok()) col = *wxBLACK; } -template <> void GetDefaultMember::handle(const AColor& col) { - handle((const Color&)col); -} template <> void Reader::handle(AColor& col) { col = parse_acolor(getValue()); if (!col.Ok()) col = AColor(0,0,0,0); diff --git a/src/resource/common/expected_locale_keys b/src/resource/common/expected_locale_keys index db11e054..70b98b25 100644 --- a/src/resource/common/expected_locale_keys +++ b/src/resource/common/expected_locale_keys @@ -1,6 +1,6 @@ # This file contains the keys expected to be in MSE locales # It was automatically generated by tools/locale/locale.pl -# Generated on Sat Jan 10 02:51:15 2009 +# Generated on Sun Jan 11 17:40:25 2009 action: add control point: 0 @@ -580,6 +580,7 @@ type: collection: 0 collection of: 1 color: 0 + date: 0 double: 0 ellipse: 0 export template: 0 diff --git a/src/script/functions/basic.cpp b/src/script/functions/basic.cpp index 0b0be30f..237f80dd 100644 --- a/src/script/functions/basic.cpp +++ b/src/script/functions/basic.cpp @@ -59,33 +59,36 @@ SCRIPT_FUNCTION(warning_if_neq) { // ----------------------------------------------------------------------------- : Conversion /// Format the input variable based on a printf like style specification -String format_input(const String& format, Context& ctx) { - String fmt = _("%") + replace_all(format, _("%"), _("")); - // determine type expected by format string - if (format.find_first_of(_("DdIiOoXx")) != String::npos) { - SCRIPT_PARAM_C(int, input); - return String::Format(fmt, input); - } else if (format.find_first_of(_("EeFfGg")) != String::npos) { - SCRIPT_PARAM_C(double, input); - return String::Format(fmt, input); - } else if (format.find_first_of(_("Ss")) != String::npos) { - SCRIPT_PARAM_C(String, input); - return format_string(fmt, input); +String format_input(const String& format, const ScriptValue& input) { + // determine type of input + ScriptType type = input.type(); + if (type == SCRIPT_DATETIME) { + return static_cast(input).Format(format.c_str()); } else { - throw ScriptError(_ERROR_1_("unsupported format", format)); + // determine type expected by format string + String fmt = _("%") + replace_all(format, _("%"), _("")); + if (format.find_first_of(_("DdIiOoXx")) != String::npos) { + return String::Format(fmt, (int)input); + } else if (format.find_first_of(_("EeFfGg")) != String::npos) { + return String::Format(fmt, (double)input); + } else if (format.find_first_of(_("Ss")) != String::npos) { + return format_string(fmt, input.toString()); + } else { + throw ScriptError(_ERROR_1_("unsupported format", format)); + } } } SCRIPT_FUNCTION(to_string) { + SCRIPT_PARAM_C(ScriptValueP, input); ScriptValueP format = ctx.getVariable(SCRIPT_VAR_format); try { if (format && format->type() == SCRIPT_STRING) { // format specifier. Be careful, the built in function 'format' has the same name - SCRIPT_RETURN(format_input(*format, ctx)); + SCRIPT_RETURN(format_input(*format, *input)); } else { // simple conversion - SCRIPT_PARAM_C(String, input); - SCRIPT_RETURN(input); + SCRIPT_RETURN(input->toString()); } } catch (const ScriptError& e) { return new_intrusive1(e); @@ -203,6 +206,15 @@ SCRIPT_FUNCTION(to_color) { } } +SCRIPT_FUNCTION(to_date) { + try { + SCRIPT_PARAM_C(wxDateTime, input); + SCRIPT_RETURN(input); + } catch (const ScriptError& e) { + return delay_error(e); + } +} + SCRIPT_FUNCTION(to_code) { SCRIPT_PARAM_C(ScriptValueP, input); SCRIPT_RETURN(input->toCode()); @@ -295,7 +307,8 @@ SCRIPT_FUNCTION(contains) { SCRIPT_FUNCTION(format) { SCRIPT_PARAM_C(String, format); - SCRIPT_RETURN(format_input(format,ctx)); + SCRIPT_PARAM_C(ScriptValueP, input); + SCRIPT_RETURN(format_input(format,*input)); } SCRIPT_FUNCTION(curly_quotes) { @@ -651,6 +664,7 @@ void init_script_basic_functions(Context& ctx) { ctx.setVariable(_("to number"), script_to_number); ctx.setVariable(_("to boolean"), script_to_boolean); ctx.setVariable(_("to color"), script_to_color); + ctx.setVariable(_("to date"), script_to_date); ctx.setVariable(_("to code"), script_to_code); // math ctx.setVariable(_("abs"), script_abs); diff --git a/src/script/to_value.hpp b/src/script/to_value.hpp index e8110222..d16ab4f2 100644 --- a/src/script/to_value.hpp +++ b/src/script/to_value.hpp @@ -390,6 +390,7 @@ inline ScriptValueP to_script(long v) { return to_script((int) v); } ScriptValueP to_script(const String& v); ScriptValueP to_script(Color v); ScriptValueP to_script(AColor v); + ScriptValueP to_script(wxDateTime v); inline ScriptValueP to_script(bool v) { return v ? script_true : script_false; } template inline ScriptValueP to_script(const vector* v) { return new_intrusive1 > >(v); } @@ -419,6 +420,7 @@ template <> inline double from_script (const ScriptValueP& va template <> inline bool from_script (const ScriptValueP& value) { return *value; } template <> inline Color from_script (const ScriptValueP& value) { return (AColor)*value; } template <> inline AColor from_script (const ScriptValueP& value) { return *value; } +template <> inline wxDateTime from_script (const ScriptValueP& value) { return *value; } // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/script/value.cpp b/src/script/value.cpp index b14b7d28..5e9080cf 100644 --- a/src/script/value.cpp +++ b/src/script/value.cpp @@ -24,6 +24,7 @@ ScriptValue::operator int() const { throw Script ScriptValue::operator bool() const { throw ScriptErrorConversion(typeName(), _TYPE_("boolean" )); } ScriptValue::operator double() const { throw ScriptErrorConversion(typeName(), _TYPE_("double" )); } ScriptValue::operator AColor() const { throw ScriptErrorConversion(typeName(), _TYPE_("color" )); } +ScriptValue::operator wxDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date" )); } ScriptValueP ScriptValue::eval(Context&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); } ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); } ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection"))); } @@ -276,6 +277,13 @@ class ScriptString : public ScriptValue { } return c; } + virtual operator wxDateTime() const { + wxDateTime date; + if (!date.ParseDateTime(value.c_str())) { + throw ScriptErrorConversion(value, typeName(), _TYPE_("date")); + } + return date; + } virtual GeneratedImageP toImage(const ScriptValueP&) const { if (value.empty()) { return new_intrusive(); @@ -327,6 +335,27 @@ ScriptValueP to_script(AColor v) { } +// ----------------------------------------------------------------------------- : DateTime + +// wxDateTime values +class ScriptDateTime : public ScriptValue { + public: + ScriptDateTime(const wxDateTime& v) : value(v) {} + virtual ScriptType type() const { return SCRIPT_DATETIME; } + virtual String typeName() const { return _TYPE_("date"); } + virtual operator wxDateTime() const { return value; } + virtual operator String() const { + return value.Format(_("%Y-%m-%d %H:%M:%S")); + } + private: + wxDateTime value; +}; + +ScriptValueP to_script(wxDateTime v) { + return new_intrusive1(v); +} + + // ----------------------------------------------------------------------------- : Nil type // the nil object diff --git a/src/script/value.hpp b/src/script/value.hpp index 238e1f58..1e2e143b 100644 --- a/src/script/value.hpp +++ b/src/script/value.hpp @@ -32,6 +32,7 @@ enum ScriptType , SCRIPT_OBJECT // Only ScriptObject , SCRIPT_COLLECTION , SCRIPT_REGEX +, SCRIPT_DATETIME , SCRIPT_ITERATOR , SCRIPT_DUMMY , SCRIPT_ERROR @@ -67,6 +68,8 @@ class ScriptValue : public IntrusivePtrBaseWithDelete { virtual operator bool() const; /// Convert this value to a color virtual operator AColor() const; + /// Convert this value to a wxDateTime + virtual operator wxDateTime() const; /// Script code to generate this value virtual String toCode() const; diff --git a/src/util/io/get_member.cpp b/src/util/io/get_member.cpp index 8e22e4c6..839af60d 100644 --- a/src/util/io/get_member.cpp +++ b/src/util/io/get_member.cpp @@ -25,6 +25,8 @@ template <> void GetDefaultMember::handle(const bool& v) { value = to_sc template <> void GetDefaultMember::handle(const tribool& v) { value = to_script((bool)v); } template <> void GetDefaultMember::handle(const Vector2D& v) { value = to_script(String::Format(_("(%.10lf,%.10lf)"), v.x, v.y)); } template <> void GetDefaultMember::handle(const Color& v) { value = to_script(v); } +template <> void GetDefaultMember::handle(const AColor& v) { value = to_script(v); } +template <> void GetDefaultMember::handle(const wxDateTime& v) { value = to_script(v); } void GetDefaultMember::handle(const ScriptValueP& v) { value = v; } void GetDefaultMember::handle(const ScriptP& v) { value = v; } diff --git a/tools/website/drupal/mse-drupal-modules/highlight.inc b/tools/website/drupal/mse-drupal-modules/highlight.inc index 4c60362a..d4b73d33 100644 --- a/tools/website/drupal/mse-drupal-modules/highlight.inc +++ b/tools/website/drupal/mse-drupal-modules/highlight.inc @@ -11,6 +11,7 @@ $built_in_functions = array( 'to_number' =>'', 'to_boolean' =>'', 'to_color' =>'', + 'to_date' =>'', // numbers 'abs' =>'', 'random_int' =>'', @@ -33,6 +34,7 @@ $built_in_functions = array( 'match' =>'', 'match_rule' => 'match', 'trim' =>'', 'regex_escape' =>'', + 'check_spelling' =>'', // tags 'tag_contents' =>'', 'tag_contents_rule'=>'tag_contents', 'remove_tag' =>'', 'tag_remove_rule' =>'remove_tag',