let it leave me like a long breath

let it dissipate or fade in the background

(no subject)

Profile

xax: purple-orange {11/3 knotwork star, pointed down (Default)
howling howling howling

Nav

  • Recent Entries
  • Archive
  • Reading
  • Tags
  • Memories
  • Profile

Tags

  • art - 2 uses
  • asteroid garden - 4 uses
  • code - 19 uses
  • demos - 1 use
  • dreams - 5 uses
  • ff7 fangame - 23 uses
  • fic prompts - 13 uses
  • gamedev challenge - 82 uses
  • hell game - 76 uses
  • nanowrimo - 11 uses
  • plants - 9 uses
  • process - 52 uses
  • programming - 51 uses
  • screenshots - 5 uses
  • writing log - 83 uses

May 2025

S M T W T F S
    123
45678 910
1112131415 1617
18192021222324
25262728293031
  • Mar. 6th, 2019
  • xax: yellow-orange {7/2} knotwork star, pointed down (7sided)
    [personal profile] xax
    Tags:
    • code,
    • programming
    posted @ 08:07 pm

    i made a new macro for twine!

    first, you can check out a small demo that uses it.

    this is for twine 1.4, and is a macro that adds some slightly more advanced form controls, with inline displays. this adds three new macros: <<toggle>>, <<block>>, and <<endblock>>.

    a <<toggle>> is in the form <<toggle $varname groupname value display>>, and it generates some clickable text ("display"), which, when clicked, will set $varname to value. if there are multiple toggles with the same groupname, clicking one will deselect any others.

    a <<block>> is in the form <<block groupname>>...<<endblock>>. when a toggle is selected, it will also inline refresh the text inside any blocks with matching groupnames.

    (if you want text to be refreshed based on multiple toggle groups, you can nest <<block>>s with no issue.)

    an example of use:
    <<toggle $foo foo foo_a "foo a">>
    <<toggle $foo foo foo_b "foo b">>
    <<toggle $foo foo foo_c "foo c">>
    
    <<block foo>>\
    $foo is <<print $foo>>
    <<endblock>>
    
    <<toggle $bar bar 1 one>>
    <<toggle $bar bar 2 two>>
    <<toggle $bar bar 3 three>>
    
    <<block bar>>\
    $bar is <<print $bar>>
    <<endblock>>


    would display two sets of three selections, with a "$var is ..." blurb beneath each one that's automatically updated every time you change a value.

    here's the code:

    ::block macro [script]
    function innercontent(tag, parser) {
      var
        i,
        textbegin = parser.source.indexOf(">>",parser.matchStart)+2,
        textend = -1,
        text = parser.source.slice(textbegin),
        depth = 0;
      for (i = 0; i < text.length; i++) {
        if (text.substr(i,tag.length + 5) === ("<<end" + tag)) {
          if(depth===0){
            textend=textbegin+i;
            break;
          }else{
            depth--;
          }
        } else if (text.substr(i,tag.length + 2) === ("<<" + tag)) {
          depth++;
        }
      }
      if (textend === -1) {
        throwError(place,"can't find matching end"+tag,parser.fullMatch());
        return;
      }
      return [textbegin, textend];
    }
    
    function parseArg (str) { return (str[0] == "$"? eval(Wikifier.parse(str)) : str); }
    function varArg (str) { return (str[0] == "$"? str.substr(1) : str); }
    
    macros.block = {
      handler: function (place, macroName, params, parser) {
        var class_ = params[0][0] == "$"
          ? eval(Wikifier.parse(params[0]))
          : params[0];
        var block = insertElement (null, "span", null, "blockSpan " + class_.replace(" ", "_"));
        var inner_index = innercontent ("block", parser);
        block.tweecode = parser.source.slice(inner_index[0], inner_index[1]);
        parser.nextMatch=inner_index[1];
        place.insertBefore(block,null);
        new Wikifier(block, block.tweecode);
      }
    };
    macros.endblock = { handler: function () {}}
    
    macros.toggle = {
      handler: function (place, macroName, params, parser) {
        var varName = params[0] !== undefined ? varArg(params[0]) : null;
        var group = params[1] !== undefined ? parseArg(params[1]) : null;
        var value = params[2] !== undefined ? parseArg(params[2]) : null;
        var display = params[3] !== undefined ? parseArg(params[3]) : null;
    
        var c = insertElement (null, "span", null, "toggleContainer", null);
        var toggleInput = insertElement (c, "input", "toggle_" + value, "toggleInput toggleGroup_" + group, null);
        var toggleLabel = insertElement (c, "label", null, "toggleLabel", display);
        toggleInput.type = "radio";
        toggleInput.name = group;
        toggleInput.value = value;
        toggleLabel.htmlFor = "toggle_" + value;
    
        var changeList = [group];
        toggleInput.addEventListener ('change', function () {
          console.log (params[0] + " set to \"" + toggleInput.value + "\"");
          state.history[0].variables[varName] = toggleInput.value;
          changeList.map (function (f) { console.log (f); reshow (f); });
        });
    
        place.insertBefore(c, null);
      }
    };
    
    window.reshow = function (name) {
      var
        rall=document.querySelectorAll(".passage .blockSpan." + name.replace(" ", "_")),
        ret=false;
      for(var i=0;i<rall.length;i++){
        ret=reshowOne(rall[i]);
      }
      return ret;
    }
    
    function reshowOne (target) {
      target.innerHTML="";
      new Wikifier(target,target.tweecode);
      target.classList.add("blockSpanIn");
      if(target.timeout){
        clearTimeout(target.timeout);
      }
      target.timeout=setTimeout(
        function(){
          target.classList.remove("blockSpanIn");
        },
        1);
    }


    here's some example css:

    ::toggle style [stylesheet]
    input[type="radio"].toggleInput { display: none; }
    input.toggleInput + label { padding: 2px; cursor: pointer; font-weight: bold; transition: 0.5s; }
    
    input.toggleInput + label { background: transparent; color: #f09; }
    input.toggleInput + label:hover { background: #400020; color: #f9c; }
    input.toggleInput:checked + label { background: #f09; color: #000; }


    and you should just be able to drop those into 'script' and 'stylesheet'-tagged passages, respectively, for the macro to work.

    (the one thing missing from that css wrt the demo is the demo also has a table label { display: block; } style rule, to make all the labels the same width inside the table they're laid out in.)

    • Previous Entry
    • Add Memory
    • Share This Entry
    • Next Entry
    • Reply
Page generated Jan. 23rd, 2026 01:54 am
Powered by Dreamwidth Studios

Style Credit

  • Style: (No Theme) for vertical