Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammars in Twine #140

Open
dhowe opened this issue Mar 19, 2021 · 8 comments
Open

Grammars in Twine #140

dhowe opened this issue Mar 19, 2021 · 8 comments
Assignees

Comments

@dhowe
Copy link
Owner

dhowe commented Mar 19, 2021

I'd like to support the following two types of grammar cases (with and without closing tag). Can you see if this is possible?

<<rg $rules >>

<<rg>>
{
  rules
}
<</rg>>
@Real-John-Cheung
Copy link
Collaborator

I think this
<<rg $rules>> <<rg>>{}<</rg>>
is not possible at least in sugarCube... coz a Macro is either self-closing or have closing tag, and there can't be two Marcos of the same name

it is possible to have something like this
<<rg $rules>>
<<rg {"start":"a"}>>
//must be a valid json object without line break
//or
<<rg '{ start: "a" }'>>
//can be json or js object and have line-breaker, but must pass in as a string

@dhowe
Copy link
Owner Author

dhowe commented Mar 23, 2021

ok, can you include (either here or in a notebook) the simplest possible code for a <<rg>> macro as below:

<<rg>>{start: $rule1, ... }<</rg>>

<<rg>>$rules<</rg>>

and also with an optional start rule:

<<rg 'optionalStartRuleName'>>$rules<</rg>>

where rules is either a literal JS object, or a previously declared twine variable
no need for JSON unless it is an external .json file (not sure how this works in twine)

note: the only added benefit of doing this, over what what he have now, is that we can pass State.variables to grammar.expand automatically

@Real-John-Cheung
Copy link
Collaborator

Real-John-Cheung commented Mar 23, 2021

https://observablehq.com/@real-john-cheung/riscript-and-rigrammar-in-twine
rules can be a literal JS object, a json object or a twine variable

setup.JSLoaded = false;
setup.lockID = LoadScreen.lock();
function parseObject (obj) {
  return Function('"use strict";return (' + obj + ')')();
}
importScripts("https://unpkg.com/rita").then(function () {
  Macro.add('rg',{
   skipArgs: false,
   tags: null,
   handler: function () {
     let s = this.payload[0].contents.trim();
     let o;
     try {
        o = JSON.parse(s);
     } catch(e) {
     }
     if (!o) {
        try {
           o = parseObject(s);
        } catch {
        }
     }
     if (!o && /^\$[A-Za-z0-9$_]+$/.test(s)){
	 s = s.replace('$','');
	 o = State.variables[s] ? State.variables[s] : undefined;
     }
     if (!o) throw Error("fail to parse grammar, " + s + " is not a vaild object.");
     $(this.output).wiki(RiTa.grammar(o).expand(this.args[0],State.variables));
   }
  });
  setup.JSLoaded = true;
  Engine.play(passage(), true);
  LoadScreen.unlock(setup.lockID);
}).catch(function (err) {
  alert(err);
});

@dhowe
Copy link
Owner Author

dhowe commented Mar 23, 2021

the grammar() function already accepts json and js objects, no? why parse them separately ?

@Real-John-Cheung
Copy link
Collaborator

because what inside Macro.playload.contents is string, so it need to be parsed into object

grammar() actually can take in JSON string but literal jsobject string need to parsed first

@dhowe
Copy link
Owner Author

dhowe commented Mar 30, 2021

so we don't need JSON.parse in there, correct?

@Real-John-Cheung
Copy link
Collaborator

We don't need it (i.e. we can code another (I think will be more complex) version that do the same without it) but maybe we should keep the JSON.parse() because we don't want to pass a random(unchecked) string into grammar(), and with it we can make sure that the type of the parameter pass in grammar() is always object.

@dhowe
Copy link
Owner Author

dhowe commented Apr 7, 2021

sounds good, reassigning to myself

@dhowe dhowe reopened this Apr 7, 2021
@dhowe dhowe assigned dhowe and unassigned Real-John-Cheung Apr 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants