mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
implemented html export (only for writing the main file, not the write_file functions);
fixed parser bug: (...\n...) was not parsed as a statement separator if the second ... starts with a string or number git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@432 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -91,8 +91,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
// Loop over a container, push next value or jump
|
||||
case I_LOOP: {
|
||||
ScriptValueP& it = stack[stack.size() - 2]; // second element of stack
|
||||
assert(dynamic_pointer_cast<ScriptIterator>(it)); // top of stack must be an iterator
|
||||
ScriptValueP val = static_pointer_cast<ScriptIterator>(it)->next();
|
||||
ScriptValueP val = it->next();
|
||||
if (val) {
|
||||
stack.push_back(val);
|
||||
} else {
|
||||
|
||||
+16
-5
@@ -57,6 +57,12 @@ class Context {
|
||||
/// Get the value of a variable, returns ScriptValue() if it is not set
|
||||
ScriptValueP getVariableOpt(const String& name);
|
||||
|
||||
/// Open a new scope
|
||||
/** returns the number of shadowed binding before that scope */
|
||||
size_t openScope();
|
||||
/// Close a scope, must be passed a value from openScope
|
||||
void closeScope(size_t scope);
|
||||
|
||||
public:// public for FOR_EACH
|
||||
/// Record of a variable
|
||||
struct Variable {
|
||||
@@ -85,11 +91,6 @@ class Context {
|
||||
|
||||
/// Set a variable to a new value (in the current scope)
|
||||
void setVariable(int name, const ScriptValueP& value);
|
||||
/// Open a new scope
|
||||
/** returns the number of shadowed binding before that scope */
|
||||
size_t openScope();
|
||||
/// Close a scope, must be passed a value from openScope
|
||||
void closeScope(size_t scope);
|
||||
/// Return the bindings in the current scope
|
||||
void getBindings(size_t scope, vector<Binding>&);
|
||||
/// Remove all bindings made in the current scope
|
||||
@@ -98,5 +99,15 @@ class Context {
|
||||
void makeObject(size_t n);
|
||||
};
|
||||
|
||||
/// A class that creates a local scope
|
||||
class LocalScope {
|
||||
public:
|
||||
inline LocalScope(Context& ctx) : ctx(ctx), scope(ctx.openScope()) {}
|
||||
inline ~LocalScope() { ctx.closeScope(scope); }
|
||||
private:
|
||||
Context& ctx;
|
||||
size_t scope;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
@@ -220,8 +220,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
||||
// Loop over a container, push next value or jump (almost as normal)
|
||||
case I_LOOP: {
|
||||
ScriptValueP& it = stack[stack.size() - 2]; // second element of stack
|
||||
assert(dynamic_pointer_cast<ScriptIterator>(it)); // top of stack must be an iterator
|
||||
ScriptValueP val = static_pointer_cast<ScriptIterator>(it)->next();
|
||||
ScriptValueP val = it->next();
|
||||
if (val) {
|
||||
it = dependency_dummy; // invalidate iterator, so we loop only once
|
||||
stack.push_back(val);
|
||||
|
||||
@@ -206,7 +206,7 @@ ScriptValueP sort_script(Context& ctx, const ScriptValueP& list, ScriptValue& or
|
||||
sort(s.begin(), s.end());
|
||||
SCRIPT_RETURN(s);
|
||||
} else {
|
||||
// are we sorting a set
|
||||
// are we sorting a set?
|
||||
ScriptObject<Set*>* set = dynamic_cast<ScriptObject<Set*>*>(list.get());
|
||||
// sort a collection
|
||||
vector<pair<String,ScriptValueP> > values;
|
||||
@@ -254,6 +254,22 @@ SCRIPT_FUNCTION(number_of_items) {
|
||||
SCRIPT_RETURN(ctx.getVariable(_("in"))->itemCount());
|
||||
}
|
||||
|
||||
// filtering items from a list
|
||||
SCRIPT_FUNCTION(filter_list) {
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
SCRIPT_PARAM(ScriptValueP, filter);
|
||||
// filter a collection
|
||||
intrusive_ptr<ScriptCustomCollection> ret(new ScriptCustomCollection());
|
||||
ScriptValueP it = input->makeIterator(input);
|
||||
while (ScriptValueP v = it->next()) {
|
||||
ctx.setVariable(_("input"), v);
|
||||
if (*filter->eval(ctx)) {
|
||||
ret->value.push_back(v);
|
||||
}
|
||||
}
|
||||
// TODO : somehow preserve keys
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Keywords
|
||||
|
||||
@@ -560,8 +576,11 @@ class ScriptRule_sort_order: public ScriptValue {
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("sort_rule"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
SCRIPT_PARAM(String, input);
|
||||
SCRIPT_RETURN(spec_sort(order, input));
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
if (input->type() == SCRIPT_COLLECTION) {
|
||||
handle_warning(_("Sorting a collection as a string, this is probably not intended, if it is use 'collection+\"\"' to force conversion"), false);
|
||||
}
|
||||
SCRIPT_RETURN(spec_sort(order, input->toString()));
|
||||
}
|
||||
private:
|
||||
String order;
|
||||
@@ -585,9 +604,13 @@ class ScriptRule_sort: public ScriptValue {
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("sort_rule"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
SCRIPT_PARAM(String, input);
|
||||
sort(input.begin(), input.end());
|
||||
SCRIPT_RETURN(input);
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
if (input->type() == SCRIPT_COLLECTION) {
|
||||
handle_warning(_("Sorting a collection as a string, this is probably not intended, if it is use 'collection+\"\"' to force conversion"), false);
|
||||
}
|
||||
String input_str = input->toString();
|
||||
sort(input_str.begin(), input_str.end());
|
||||
SCRIPT_RETURN(input_str);
|
||||
}
|
||||
private:
|
||||
ScriptValueP order_by;
|
||||
@@ -597,7 +620,7 @@ SCRIPT_FUNCTION(sort_rule) {
|
||||
SCRIPT_OPTIONAL_PARAM(String, order) {
|
||||
return new_intrusive1<ScriptRule_sort_order >(order);
|
||||
}
|
||||
SCRIPT_OPTIONAL_PARAM(ScriptValueP, order_by) {
|
||||
SCRIPT_OPTIONAL_PARAM_N(ScriptValueP, _("order by"), order_by) {
|
||||
return new_intrusive1<ScriptRule_sort_order_by>(order_by);
|
||||
} else {
|
||||
return new_intrusive <ScriptRule_sort >();
|
||||
@@ -607,7 +630,7 @@ SCRIPT_FUNCTION(sort) {
|
||||
SCRIPT_OPTIONAL_PARAM(String, order) {
|
||||
return ScriptRule_sort_order (order ).eval(ctx);
|
||||
}
|
||||
SCRIPT_OPTIONAL_PARAM(ScriptValueP, order_by) {
|
||||
SCRIPT_OPTIONAL_PARAM_N(ScriptValueP, _("order by"), order_by) {
|
||||
return ScriptRule_sort_order_by(order_by).eval(ctx);
|
||||
} else {
|
||||
return ScriptRule_sort ( ).eval(ctx);
|
||||
@@ -637,6 +660,7 @@ void init_script_basic_functions(Context& ctx) {
|
||||
// collection
|
||||
ctx.setVariable(_("position"), script_position_of);
|
||||
ctx.setVariable(_("number of items"), script_number_of_items);
|
||||
ctx.setVariable(_("filter list"), script_filter_list);
|
||||
// keyword
|
||||
ctx.setVariable(_("expand keywords"), script_expand_keywords);
|
||||
ctx.setVariable(_("expand keywords rule"), script_expand_keywords_rule);
|
||||
@@ -645,6 +669,7 @@ void init_script_basic_functions(Context& ctx) {
|
||||
ctx.setVariable(_("filter"), script_filter);
|
||||
ctx.setVariable(_("match"), script_match);
|
||||
ctx.setVariable(_("sort"), script_sort);
|
||||
ctx.setVariable(_("sort list"), script_sort);
|
||||
ctx.setVariable(_("replace rule"), script_replace_rule);
|
||||
ctx.setVariable(_("filter rule"), script_filter_rule);
|
||||
ctx.setVariable(_("match rule"), script_match_rule);
|
||||
|
||||
@@ -56,7 +56,9 @@ class TagStack {
|
||||
}
|
||||
// Close all tags, should be called at end of input
|
||||
void close_all(String& ret) {
|
||||
pending_tags.clear();
|
||||
// cancel out tags with pending tags
|
||||
write_pending_tags(ret);
|
||||
// close all open tags
|
||||
while (!tags.empty()) {
|
||||
tags.back()->write(ret, true);
|
||||
tags.pop_back();
|
||||
@@ -77,7 +79,7 @@ class TagStack {
|
||||
|
||||
void add(String& ret, const NegTag& tag) {
|
||||
// Cancel out with pending tag?
|
||||
for (size_t i = pending_tags.size() - 1 ; i >= 0 ; --i) {
|
||||
for (int i = (int)pending_tags.size() - 1 ; i >= 0 ; --i) {
|
||||
if (pending_tags[i].tag == tag.tag) {
|
||||
if (pending_tags[i].neg != tag.neg) {
|
||||
pending_tags.erase(pending_tags.begin() + i);
|
||||
@@ -89,18 +91,18 @@ class TagStack {
|
||||
}
|
||||
// Cancel out with existing tag?
|
||||
if (tag.neg) {
|
||||
for (size_t i = tags.size() - 1 ; i >= 0 ; --i) {
|
||||
for (int i = (int)tags.size() - 1 ; i >= 0 ; --i) {
|
||||
if (tags[i] == tag.tag) {
|
||||
// cancel out with existing tag i, e.g. <b>:
|
||||
// situation was <a><b><c>text
|
||||
// situation will become <a><b><c>text</c></b><c>
|
||||
vector<NegTag> reopen;
|
||||
for (size_t j = tags.size() - 1 ; j > i ; --j) {
|
||||
for (int j = (int)tags.size() - 1 ; j > i ; --j) {
|
||||
pending_tags.push_back(NegTag(tags[j], true)); // close tag, top down
|
||||
tags.pop_back();
|
||||
}
|
||||
pending_tags.push_back(tag); // now close tag i
|
||||
for (size_t j = i + 1 ; j < tags.size() ; ++j) {
|
||||
for (int j = i + 1 ; j < (int)tags.size() ; ++j) {
|
||||
pending_tags.push_back(NegTag(tags[j], false)); // reopen later, bottom up
|
||||
tags.pop_back();
|
||||
}
|
||||
@@ -119,7 +121,7 @@ String symbols_to_html(const String& str, const SymbolFontP& symbol_font) {
|
||||
}
|
||||
|
||||
String to_html(const String& str_in, const SymbolFontP& symbol_font) {
|
||||
String str = remove_tag_contents(str,_("<sep-soft"));
|
||||
String str = remove_tag_contents(str_in,_("<sep-soft"));
|
||||
String ret;
|
||||
Tag bold (_("<b>"), _("</b>")),
|
||||
italic(_("<i>"), _("</i>")),
|
||||
@@ -163,6 +165,8 @@ String to_html(const String& str_in, const SymbolFontP& symbol_font) {
|
||||
ret += _("&");
|
||||
} else if (c >= 0x80) { // escape non ascii
|
||||
ret += String(_("&#")) << (int)c << _(';');
|
||||
} else if (c == _('\n')) {
|
||||
ret += _("<br>\n");
|
||||
} else {
|
||||
ret += c;
|
||||
}
|
||||
|
||||
@@ -524,7 +524,8 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
|
||||
// without left recursion: expr = expr (oper expr)*
|
||||
while (true) {
|
||||
const Token& token = input.read();
|
||||
if (token != TOK_OPER && token != TOK_NAME && token!=TOK_LPAREN) {
|
||||
if (token != TOK_OPER && token != TOK_NAME && token!=TOK_LPAREN &&
|
||||
!((token == TOK_STRING || token == TOK_INT || token == TOK_DOUBLE) && minPrec <= PREC_NEWLINE && token.newline)) {
|
||||
// not an operator-like token
|
||||
input.putBack();
|
||||
break;
|
||||
|
||||
@@ -172,7 +172,7 @@ class ScriptString : public ScriptValue {
|
||||
public:
|
||||
ScriptString(const String& v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_STRING; }
|
||||
virtual String typeName() const { return _TYPE_("string"); }
|
||||
virtual String typeName() const { return _TYPE_("string") + _(" (\"") + (value.size() < 30 ? value : value.substr(0,30) + _("...")) + _("\")"); }
|
||||
virtual operator String() const { return value; }
|
||||
virtual operator double() const {
|
||||
double d;
|
||||
@@ -209,7 +209,7 @@ class ScriptString : public ScriptValue {
|
||||
if (name.ToLong(&index) && index >= 0 && (size_t)index < value.size()) {
|
||||
return to_script(String(1,value[index]));
|
||||
} else {
|
||||
throw ScriptError(_ERROR_2_("has no member value", value, name));
|
||||
return delayError(_ERROR_2_("has no member value", value, name));
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user