Twine Tuesday: Timed Replacement of Content

For the few weeks I have been doing these posts, this is the first one in which I highlight code someone else has done. The reason for this change is a simple one: I’ve been using this particular macro for a few different Twine projects lately (notably Tree and R_Caved). It’s far past time for me to credit and, hopefully, spread this solution around for others to use.

Despite first seeing this listed on Glorious Trainwrecks, I didn’t know who “L” was for a few weeks. That is, not until Leon Arnott posted in the (unofficial) Twine community on Google+ and took credit for it. So, thanks for posting this code, Leon!

Source:

:: Start
<<timedreplace 4>> Initial text. <<replacewith>>This replaced the initial text. <<endtimedreplace>>

<<timedreplace 6>>This showed up after 6 seconds.<<endtimedreplace>>

:: script [script]
version.extensions['timedreplaceMacro'] = {major:1, minor:0, revision:0};
  macros['timedreplace'] = {
    handler: function (g, e, f, b) {
		function tagcontents(starttag, endtag, k) {
			var a = b.source.slice(k);
			var l = 0;
			var c = "";
		    for(var i = 0; i < a.length; i++) {
				var w = endtag.length;
				if(a.substr(i, w) == endtag) {
					if(l == 0) {
						b.nextMatch = k + i + w;
						return c;
					}
					else {
						l--;
						c += a.charAt(i);
					}
				}
				else {
					if(a.substr(i, starttag.length) == starttag) {
						l++;
					}
					c += a.charAt(i);
				}
			}
			return "";
		}
		var tr="<<timedreplace";
		var rw="<<replacewith>>";
		var k = b.source.indexOf('>>', b.matchStart) + 2;
		var c = tagcontents(tr, rw, k);
		var d = tagcontents((c ? rw : tr), "<<endtimedreplace>>", c ? b.nextMatch : k);
		var h = null;
        if(c) {
			h = insertElement(g, "span", null, "timedreplacement1");
			new Wikifier(h,c);
		}
		if(d) {
		    var m = insertElement(g, "span", null, "timedreplacement2", d);
			m.style.display = "none";
			setTimeout(function() {
				if (m) { 
				  if (h && h.parentNode) h.parentNode.removeChild(h);
				  var t = m.firstChild ? m.firstChild.nodeValue : "";
				  removeChildren(m);
				  new Wikifier(m,t);
				  m.style.display = "inline";
				  fade(m, { fade: "in" });
				}
			},(parseInt(f[0]) || 0)*500);
        }
        else {
            throwError(g, "can't find matching endtimedreplace");
			return;
        }
    }
  }
  macros['endtimedreplace']={handler: function () {} }
  macros['replacewith']={handler: function () {} }