Commit eabd8825 authored by Leon Arnott's avatar Leon Arnott
Browse files

Reinstated the debug notification for the (set:) macro

This was formerly removed in 6f68c369ce69, because the change in 4022efc59d4c that made (set:) return a special object instead of a string can be leveraged to supply the debug notification without passing it directly to userland code. This is fortunate indeed.

 * Updated the README to list version 1.2 details, and changed the version numbers.

 * Removed the still-in-development (enchant:) macro for now.
parent c7476476fc7e
......@@ -2,21 +2,30 @@
Rough documentation is at http://twine2.neocities.org/
###2.0.0 changes (unreleased):
###1.2.0 changes (unreleased):
####Bugfixes
* Fixed a bug where links created by `(click:)` not having a tabindex, and thus not being selectable with the tab key (a big issue for players who can't use the mouse).
* Fixed a bug where `(align: "<==")` couldn't be used at all, even inside another aligned hook.
* Fixed a bug where errors for using changer macros (such as `(link:)`) detached from a hook were not appearing.
* Fixed a bug where `(align:)` commands didn't have structural equality with each other - `(align:"==>")` didn't equal another `(align:"==>")`.
* Fixed `(move:)`'s inability to delete items from arrays.
* `(move: ?a into $a)` will now, after copying their text into `$a`, clear the contents of all `?a` hooks.
####Alterations
* Fixed a bug where the "Story stylesheet" `<style>` element was attached between `<head>` and `<body>`. This should have had no obvious effects in any browser, but was untidy anyway.
* Altered the CSS of `<tw-story>` to use vertical padding instead of vertical margins.
* It is now an error to use `(set:)` or `(put:)` macros, as well as `to` constructs, in expression position: `(set: $a to (set: $b to 1))` is now an error, as is `(set: $a to ($b to 1))`.
* `(if:)`/`(unless:)`/`(elseif:)`/`(else:)` now evaluate to changer commands, rather than booleans. This means, among other things, that you can now compose them with other changers: `(set: $a to (text-style:"bold") + (if:$audible is true))`, for instance, will create a style that is bold, and also only appears if the $audible variable had been true. (Note: Changing the $audible variable afterward will not change the effect of the $a style.)
* Now, setting a markup string to a `?hookSet` will cause that markup to be rendered in the hookset, instead of being used as raw text. For instance, `(set: ?hookSet to "//Golly//")` will put "*Golly*" into the hookset, instead of "//Golly//".
* Also, it is now an error to set a `?hookSet` to a non-string.
* `(if:)`/`(unless:)`/`(elseif:)`/`(else:)` now evaluate to changer commands, rather than booleans. This means, among other things, that you can now compose them with other changers: `(set: $a to (text-style: "bold") + (if: $audible is true))`, for instance, will create a style that is bold, and also only appears if the $audible variable had, at that time, been true. (Note: Changing the $audible variable afterward will not change the effect of the `$a` style.)
####Additions
* Now, authors can supply an array of property names to the "'s" and "of" property syntax to obtain a "slice" of the container. For instance, `(a: 'A','B','C')'s (a: 1,2)` will evaluate to a subarray of the first array, containing just 'A' and 'B'.
* As well as creating subarrays, you can also get a slice of the values in a datamap - in effect, a subarray of the datamap's datavalues. You can do `(datamap:'Hat','Beret','Shoe','Clog','Sock','Long')'s (a: 'Hat','Sock')` to obtain an array `(a: 'Beret','Long')`.
* Additionally, you can obtain characters from a string - "abcde"'s (a: 2,4) becomes the string "bd". Note that for convenience, slices of strings are also strings, not arrays of characters.
* Combined this with the `(range:)` macro, this essentially obsoletes the `(subarray:)` and `(substring:)` macros. However, those will remain for compatibility reasons for now.
* Combined with the `(range:)` macro, this essentially obsoletes the `(subarray:)` and `(substring:)` macros. However, those will remain for compatibility reasons for now.
* `(link-reveal:)` is similar to `(link:)` except that the link text remains in the passage after it's been clicked - a desirable use-case which is now available. The code `(link-reveal:"Sin")[cerity]` features a link that, when clicked, makes the text become `Sincerity`. Note that this currently necessitates that the attached hook always appear after the link element in the text, due to how the attaching syntax works.
* `(link-repeat:)` is similar to the above as well, but allows the link to be clicked multiple times, rerunning the markup and code within.
* Also added `(link-replace:)` as an identical alias of the current `(link:)` macro, indicating how it differs from the others.
......
window.storyFormat({"name":"Harlowe","version":"1.1.1","author":"Leon Arnott","description":"The default story format for Twine 2.","image":"icon.svg","url":"http://twinery.org/","proofing":false,"source":"","setup":""});
window.storyFormat({"name":"Harlowe","version":"1.2","author":"Leon Arnott","description":"The default story format for Twine 2.","image":"icon.svg","url":"http://twinery.org/","proofing":false,"source":"","setup":""});
......@@ -3,8 +3,6 @@ define(['jquery', 'utils'], ($, {impossible}) => {
/*
TwineNotifiers are special debug notifications created by the TwineScript runtime in debug mode.
They are used to signify when a special event has occurred.
NOTE: Currently (July 2015), nothing uses this.
*/
const TwineNotifier = {
......@@ -17,7 +15,7 @@ define(['jquery', 'utils'], ($, {impossible}) => {
message: message
});
},
render() {
/*
This is attached as an attr instead of body text, so that
......
......@@ -9,7 +9,7 @@ define([
'internaltypes/assignmentrequest',
'internaltypes/twineerror',
'internaltypes/twinenotifier'],
($, NaturalSort, Macros, {objectName, subset, collectionType, isValidDatamapName}, State, Engine, Passages, AssignmentRequest, TwineError) => {
($, NaturalSort, Macros, {objectName, subset, collectionType, isValidDatamapName}, State, Engine, Passages, AssignmentRequest, TwineError, TwineNotifier) => {
"use strict";
const {optional, rest, zeroOrMore, Any} = Macros.TypeSignature;
......@@ -63,6 +63,7 @@ define([
(push:)
*/
("set", (_, ...assignmentRequests) => {
let debugMessage = "";
/*
This has to be a plain for-loop so that an early return
is possible.
......@@ -80,6 +81,13 @@ define([
if (TwineError.isPrototypeOf(result)) {
return result;
}
if (Engine.options.debug) {
// Add a semicolon only if a previous iteration appended a message.
debugMessage += (debugMessage ? "; " : "")
+ objectName(ar.dest)
+ " is now "
+ objectName(ar.src);
}
}
/*
......@@ -91,7 +99,7 @@ define([
TwineScript_TypeName: "a (set:) operation",
TwineScript_ObjectName: "a (set:) operation",
TwineScript_Unobservable: true,
TwineScript_Print: "",
TwineScript_Print: () => debugMessage && TwineNotifier.create(debugMessage).render(),
};
},
[rest(AssignmentRequest)])
......@@ -123,6 +131,7 @@ define([
Once again, this evaluates to an empty string.
*/
("put", (_, ...assignmentRequests) => {
let debugMessage = "";
/*
This has to be a plain for-loop so that an early return
is possible.
......@@ -140,12 +149,19 @@ define([
if (TwineError.isPrototypeOf(result)) {
return result;
}
if (Engine.options.debug) {
// Add a semicolon only if a previous iteration appended a message.
debugMessage += (debugMessage ? "; " : "")
+ objectName(ar.dest)
+ " is now "
+ objectName(ar.src);
}
}
return {
TwineScript_TypeName: "a (put:) operation",
TwineScript_ObjectName: "a (put:) operation",
TwineScript_Unobservable: true,
TwineScript_Print: "",
TwineScript_Print: () => debugMessage && TwineNotifier.create(debugMessage).render(),
};
},
[rest(AssignmentRequest)])
......
......@@ -8,26 +8,6 @@ define(['jquery', 'utils', 'macros', 'datatypes/hookset', 'datatypes/changercomm
This module modifies the Macros module only, and exports nothing.
*/
/*
This experimental (enchant:) macro is currently just for testing purposes.
*/
Macros.add("enchant",
(section, changer, scope) => ({
TwineScript_ObjectName: "an (enchant:) command",
TwineScript_TypeName: "an (enchant:) command",
TwineScript_Print() {
const enchantment = Enchantment.create({
scope: section.selectHook(scope),
changer,
});
section.enchantments.push(enchantment);
enchantment.enchantScope();
return "";
},
}),
[ChangerCommand, either(HookSet,String)]
);
/*
Revision macros produce ChangerCommands that redirect where the attached hook's
text is rendered - usually rendering inside an entirely different hook.
......
......@@ -18,7 +18,8 @@
"text-rotate,background,text-style,css,replace,append,prepend,click,mouseover,mouseout,click-replace," +
"mouseover-replace,mouseout-replace,click-append,mouseover-append,mouseout-append,click-prepend," +
"mouseover-prepend,mouseout-prepend,set,put,move,a,array,range,subarray,shuffled,sorted,rotated," +
"datanames,datavalues,history,datamap,dataset,count,display,print,goto,live,stop,savegame,savedgames,loadgame,link,link-goto"
"datanames,datavalues,history,datamap,dataset,count,display,print,goto,live,stop,savegame,savedgames,loadgame,link,link-goto," +
"link-replace,link-repeat,link-reveal"
).split(',').map(insensitiveName);
/*
......
{
"name": "twine-harlowe",
"version": "1.1.0",
"version": "1.2",
"author": "Leon Arnott",
"description": "The default runtime for Twine 2 stories",
"license": "GPL v3",
......
......@@ -120,7 +120,6 @@ afterAll(function() {
<script src="spec/changer_macros/style.js"></script>
<script src="spec/changer_macros/links.js"></script>
<script src="spec/changer_macros/hooks.js"></script>
<script src="spec/changer_macros/enchantment.js"></script>
<script src="spec/changer_macros/interaction.js"></script>
<script src="spec/changer_macros/revision.js"></script>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment