GithubHelp home page GithubHelp logo

videlais / snowman Goto Github PK

View Code? Open in Web Editor NEW
124.0 4.0 34.0 8.09 MB

An advanced Twine 2 story format designed for people who already know JavaScript and CSS

License: MIT License

JavaScript 35.54% CSS 0.04% EJS 0.02% HTML 64.40%
twine snowman story-formats

snowman's Introduction

Snowman

Node.js CI codecov

Snowman is an advanced Twine 2 story format designed for people who already know JavaScript and CSS. It was originally created by Chris Klimas and is currently maintained by Dan Cox.

What does Snowman offer?

Snowman does not use macros. Instead, it provides template tags, <% ... %>, and a JavaScript API for accessing and manipulating the current story and its passages.

It also includes the JavaScript library jQuery.

Want to learn more?

The official Snowman documentation has more details.

snowman's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar double-a-stories avatar klembot avatar lmorchard avatar toddmazierski avatar videlais avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

snowman's Issues

Functions calling print() do not work

Originally reported by: Jason Taylor (Bitbucket: jaytay579, GitHub: jaytay579)


In start passage:

#!javascript

<%
window.ss.printsomething = function(something) {
	print(something);
}
%>

Tested function there, works fine.

In linked passage:

#!javascript

<%
window.ss.printsomething("another thing");
%>

Returns no output.

However, in another linked passage I included:

#!javascript

<%
for (var i in window.ss) {
	print(window.ss[i]);
}
%>

<%
window.ss.printsomething("yet something else.");
%>

And this version showed that the function did indeed exist across pages (as its body was output by my for..in statement), but the function call did not work.

Calling this "minor" because so far it only seems to apply to "print" which is already wonky, and if the "s" global issue is fixed, then it becomes less of an issue since functions could move there...


Errors within div elements

Originally reported by: Christopher Corella (Bitbucket: cwcorella, GitHub: Unknown)


Hello, a user on the Twine forums has identified a minor problem with Snowman 1.2. It seems that using sub-heading markdown within one of Snowman's generated div elements does not work as it may have been intended. Here's an example of the issue.

#!javascript

Sub-header outside generated div
-----

[
Sub-header inside generated div
-----
]{#the-divs-id}

Another issue with the div elements is that any text added within them is ignored by the story's stylesheet. (e.g. the font style, size, or paragraph layout) I know it's likely you've got a lot on your to-do list already, but I'm sure you'll get around to fixing this eventually.

For greater detail on the issue, visit this post for the full discussion.


Story will not publish

Originally reported by: Victoria Ellis (Bitbucket: ellisvk, GitHub: Unknown)


Every time I try to publish my story (play, test, print proofing copy, or publish to file) I receive an error message: an error occurred while publishing your story. I've been building this story for several weeks and have never received this error before.


Build a Twine-Ready File?

Originally reported by: Anonymous


I'm having trouble putting a link inside a div. It looks like you've recently fixed this issue, but Twine apparently has an old version. I'm not sure when Twine will update, and I'm having trouble building a new version of your Snowman from source since I'm unfamiliar with npm and grunt.

Could you build a Twine-ready format.js file and put it in the downloads section?


How to define handler on 'shown.sm.passage' event?

this section of story.js suggests that a 'shown.sm.passage' event is triggered when the current passage is rendered to the DOM:
https://github.com/klembot/snowman/blob/c1dce3814dc24fd86eb3f0349683b2182f535a29/src/story.js#L377

How can I define a handler function that 'catches' this event and responds to it?

I am able to setup handlers for the showpassage and hidepassage events on window, but can't get this approach to work for shown.sm.passage:

$(window).on('showpassage', function(event){
	console.log(event);
});

$(window).on('hidepassage', function(event){
	console.log(event);
});

window.story.show() broken

As reported on Discord, show() does not work correctly in both Snowman 1.X AND Snowman 2.X

:: Start
Start
<% window.story.show("start2") %>

:: start2
start2

Initializing state varaibles in Story Javascript passage

Originally reported by: greyelf (Bitbucket: greyelf, GitHub: greyelf)


The author has access to variable stored within the story state array when a passage is rendered via the 's' accessor.

How does the author access the story state array within the story's javascript passage to initialize the variables?
Because window.story variable does exist until after the Story constructor function is finished.


How to open passage from script?

I want to make a clickable link those execute a script and then open a passage. How can i do it ? Or if this is not the place, where can i ask then?

savehash() in Snowman 2

According to the documentation, saveHash() is a function of window.story.

In a new Snowman story I create a starting passage:

:: test
<% window.story.saveHash() %>

When playing it: In Passage.render() using _.template(): TypeError: window.story.saveHash is not a function

If I see the contents of window.story in the console, there is no saveHash().

I'm using Snowman 2.0.2 and tryint to use the save and restore system.

Thanks!

`s` Is Not Available in All Contexts

The shorthand s for window.story.state is not always available in Twine2.

Minimal passage to reproduce the bug:

<% s.f = function() { alert('hello'); } %>
<a href='javascript:void(0)' data-passage='Passage' onclick='s.f()'>Go to Passage</a>

This will throw an error, but

<% s.f = function() { alert('hello'); } %>
<a href='javascript:void(0)' data-passage='Passage' onclick='window.story.state.f()'>Go to Passage</a>

works fine.

Linking Passages in 1.0.2 Error

Originally reported by: Melissa Davidson (Bitbucket: Melissapants, GitHub: Unknown)


Hi, klembot. :D

Last night I encountered a bug while testing your software... The double square bracket method of linking two passages spits out the following error:

"Error given is: There is no passage with the ID or name"

I attached a screenshot showing the result.

I was using the online version of Twine on twinery.org.


span markup broken

Originally reported by: Anonymous


#!snowman

[foo]{.bar}

yields

#!html

<p><span class="bar"></span></p><p>foo</p>

Tested in multiple passages of multiple stories. Exported to file from Twine 2.1.1 on Mac OS X 10, and viewed in Safari, Firefox, and Chrome, all with the same results.


Add incoming passage to showpassage event

Originally reported by: Anonymous


Currently showpassage receives a reference to the passage which is about to be replaced. The code comments seem to indicate this is not the intended behaviour (and that it should instead receive the new passage), but I may be reading it wrong. It would be nice if it received both the incoming passage as well as the outgoing one.

Adding both passages to hidepassage and showpassage:after could also be helpful.

Note: This is based on 1.2 as distributed with Twine 2.0.10


jQuery requires a window with a document

Originally reported by: Isak Grozny (Bitbucket: isakgrozny, GitHub: isakgrozny)


Using grunt-entwine to assemble a Twine 2 story, using the snowman.js format as built from this repository, npm spits out this:

jQuery requires a window with a document

and aborts the task.

Using the format.js Snowman file from Twine 2's repository gives me:

Uncaught Error: There is no passage with the ID or name "0"

which is why I tried using the format file built from this repo.

I wasn't sure where to put this bug report, but since it seems to be an issue with Snowman, I'm putting it here.


<script> breaking when inside HTML tags

As I reported at intfiction, in Snowman 1.3 this kind of structure:

<div><script>console.log('Hello world')</script></div>

... produces an error: ⚠️ SyntaxError: expected expression, got '&' (Firefox, similar message in Chrome).

Persistent player statistics

Hi! My apologies if this is not the correct place to ask this question/open an issue. I'm interested in using the player statistics example in a project, and that page notes:

"Note: Elements must exist before the attempt to bind to them in order to be successful. This example uses the ready() function to achieve this with the first, starting passage."

So, the example only works on the first passage. I was just wondering if the devs had any suggestions on how to implement player statistics so that subsequent passages could call for checks like the 'testEmpathy" and "empathyResult" using the empathy statistic set in the first passage. Thanks!

src/index.html missing

Originally reported by: Anonymous


The file src/index.html is not present in the repository or being generated by grunt during the build process. As a result, the build fails on the html:test or html:release steps. Note that .hgignore includes the line "index.html", which may explain why it doesn't appear in the repository.


Color Syntax Highlight

Originally reported by: X-Raym (Bitbucket: X-Raym, GitHub: X-Raym)


Hi !

It would be cool to have color syntax highlight for snowman, for the JS between <% %> and for regular twine components like passage links.

It would be very helpful !

Protagonist planned to have it but its development seems to have stop,
so a native solution would be very welvome :)

Add Syntax Highlighting · Issue #7 · massivedanger/protagonist

Thanks !


History navigation is broken after one use

My understanding is that snowman uses the browser history to facilitate going forward/backward between passage choices.

However it seems to be broken. Using snowman 2.0.2 in Twine, after pressing the browser back button once, further navigation doesn't work. E.g.

  1. Open story
  2. Click link 1
  3. Press browser back button
  4. Click link 2
  5. Press browser back button again

The result is that the page is destroyed, but it should take you back to the story start. This occurs for me in the latest Firefox and Chrome.

Importing built guide.html throws Unhandled promise rejection

(I'm just getting started with both Twine and Snowman, so I might be doing something wrong)

I downloaded the snowman zip from Github and following instruction ran
npm run build
to build guide.html.

When I try to import this file into Twine (either via https://twinery.org/2/#!/stories or Twine running locally), it throws the following error:

Unhandled promise rejection 
TypeError: passageEl.attributes.position is undefined
Stack trace:
domToObject/<.passages<@http://localhost:8080/twine.js:45149:12
domToObject@http://localhost:8080/twine.js:45147:4
module.exports/<@http://localhost:8080/twine.js:45197:18
module.exports@http://localhost:8080/twine.js:45194:9
import/<@http://localhost:8080/twine.js:45486:21
run@http://localhost:8080/twine.js:64446:22
notify/<@http://localhost:8080/twine.js:64459:28
flush@http://localhost:8080/twine.js:30230:9

screen shot 2018-05-28 at 19 23 10

Importing an exported story works fine in both cases.

Am I doing this right?

Build failure on Windows 10 with npm 4.2.0

Originally reported by: Anonymous


The following errors occur when running npm run build:

#!None

    (node:12932) UnhandledPromiseRejectionWarning: Unhandled promise rejection 
    (rejection id: 1): ChildProcessError: Command failed: cssnano src/*.css
    C:\Users\Fred\Documents\klembot-snowman-2-943b614c649f\node_modules\cssnano-
    cli\cmd.js:37
            throw err;
            ^

    Error: ENOENT: no such file or directory, open 'C:\Users\Fred\Documents\klembot-
    snowman-2-943b614c649f\src\*.css'
     `cssnano src/*.css` (exited with error code 1)
    (node:12932) DeprecationWarning: Unhandled promise rejections are deprecated. In the 
    future, promise rejections that are not handled will terminate the Node.js process with a 
    non-zero exit code.
    fs.js:584
      return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                     ^

    Error: ENOENT: no such file or directory, open 'C:\Users\Fred\Documents\klembot-
    snowman-2-943b614c649f\dist\snowman-2.0.0\format.js'
        at Object.fs.openSync (fs.js:584:18)
        at Object.fs.readFileSync (fs.js:491:33)
        at Object.<anonymous> (C:\Users\Fred\Documents\klembot-snowman-2-
    943b614c649f\scripts\build-guide.js:7:39)
        at Module._compile (module.js:571:32)
        at Object.Module._extensions..js (module.js:580:10)
        at Module.load (module.js:488:32)
        at tryModuleLoad (module.js:447:12)
        at Function.Module._load (module.js:439:3)
        at Module.runMain (module.js:605:10)
        at run (bootstrap_node.js:427:7)

    npm ERR! Windows_NT 10.0.15063
    npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program 
    Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "build"
    npm ERR! node v7.10.0
    npm ERR! npm  v4.2.0
    npm ERR! code ELIFECYCLE
    
    npm ERR! errno 1
    npm ERR! [email protected] build: `node scripts/build-format.js && node scripts/build-
    guide.js`
    npm ERR! Exit status 1

Error if global javascript contains `<% %>` in comments

To reproduce this issue, simply add the this comment in global javascript: /* <% %> */.

It raises Uncaught Error: Error compiling template code: Error: Could not find matching close tag for "<%". in console on Test or Play.

Paragraph tags misplaced for first paragraph in Windows

If you create a new story in Windows using the latest Twine (2.39) and Snowman (2.0.2), the first paragraph in every passage will be missing its paragraph tags, which appear to be shifted onto the next line as an empty paragraph tag. While this has no obvious visual effect out of the box (you have to view the rendered source of the passage to see it), it will mess up any paragraph-based CSS or scripting.

This does not happen on (unix-based) MacOS X. It seems to be a result of some paragraph cleanup code at the end of Passage.js aimed at fixing marked output. The code assumes unix newlines (\n) instead of windows newlines (\r\n). There are other cases as well, like classic mac newlines (\r), but Twine users are unlikely to run into them.

Note that importing a story into a Windows Twine can preserve unix newlines, and then the problem won't occur. (It's not clear exactly what the import and Twine are doing, but for a story I imported the newlines remained unix-style even after some editing in Windows.)

As a temporary workaround I suggested converting the published story to unix newlines, but the original reporter (bphennessy on discord) went with a jQuery fix instead:

var firstpar = $(".passage").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0]

$(firstpar).wrap("<p></p>")

To fix Snowman itself I assume a better regex would be sufficient, depending on what problem the code was fixing:

    if ((!result.endsWith('</p>\n') && newResult.endsWith('</p>\n')) || (!result.endsWith('</p>\r\n') && newResult.endsWith('</p>\r\n')) {
      newResult = newResult.replace(/^<p>|<\/p>$|<\/p>(\r)?\n$/g, '');
    }

Since I can't reproduce the original issue (my stories behave the same with and without the paragraph correction code) I can't be sure that actually works as intended.

Cannot build from source

Originally reported by: Anonymous


Using latest commits, running npm install gives an error about the version number (1.1 -> 1.1.0 fixed it), and everything else worked fine, however running gulp doesn't create a format.html file, and gulp release gives an error that there is no build/format.html file.


Save issues in Snowman 3

Forgive me for combining 3 issues into one, but since they are all related to the saving I'm too lazy to create three separate issues.
This example story can be used to demonstrate all 3 issues.

:: Start
<h1>Page 1</h1>
<button id="save">Save</button>
<button id="load">Load</button>
[[Page 2]]

<script>
    $('#save').click(() => window.Story.storage.createSave());
    $('#load').click(() => window.Story.storage.restoreSave());

    if (typeof window.Story.store.someVar === 'undefined')
        window.Story.store.someVar = 0;
</script>

:: Page 2
<h1>Page 2</h1>
<button id="save">Save</button>
<button id="load">Load</button>
[[Page 1|Start]]

<script>
    $('#save').click(() => window.Story.storage.createSave());
    $('#load').click(() => window.Story.storage.restoreSave());
    
    window.Story.store.someVar += 1;
</script>
  1. Error during restoreSave().
    If you make a save, then go back and forth between Start and 'Page 2', then press load, you will get an Uncaught TypeError . This presumably happens because History.position isn't saved and restored, so it is out of bounds when History.history is restored.
  2. createSave() ignores updated state.
    If you go to 'Page 2' someVar will be updated. This results in a discrepancy between the state in store and latest entry in History.history. If the story is saved and then restored you will lose the latest updates to the store.
    I don't know if this is by design, but it can lead to some frustrating bugs down the line, if people aren't aware of it. An optional argument to instruct createSave() to save the actual current state instead of the state when the passage is entered would be useful.
  3. restoreSave() doesn't take you to the saved passage.
    Another gotcha that might confuse people. When you restoreSave() it doesn't actually take you to the passage where you saved.
    Again this might be by design, but it can confuse people that the state is restored, but nothing is visibly changed since and you are still looking at the same passage. I would say an option to goto the last passage in the restored history is the right move, so we can decide it for ourselves.
  4. getAllSaveNames().
    One last suggestion. I implemented it myself, but I could imagine other would find it useful if there was a method for getting all the save names in case you want the player to have multiple saves and not having to remember the save names themself.

Event Ordering for Passage link handler

Currently, attaching an event to the 'click' event for links works in a non intuitive way-
(Specifically, what I'm doing is rendering the next passage differently based on if the link is clicked while shift is down or not)

Unfortunately, when I attach my click event, it only fires after the new passage is already rendered, preventing the new passage from using said information.

This is because events fire in the order that they were attached, and snowman attaches it's events first(before loading the story javascript). If this click event could be moved till after the story javascrit is evaled, then things would work as intuitively expected.

Currently I've gotten it to work for my code by the following(less than optimal) hack:
//Disable Snowman's default click event // This is needed so that if you add a click event they happen first // (instead of firing after the new passage has already been loaded) $("tw-story").off( 'click', 'a[data-passage]');

my click handling code

//Restore Snowman's default click event // So that your event fires, then the default one // This code is copied directly from snowman's source $("tw-story").on('click', 'a[data-passage]', function (e) { window.story.show(_.unescape( $(e.target).closest('[data-passage]').data('passage') )); });

Add support for story and temporary variables

Add support for story, $, and temporary, _ variables. (Internally, these will be added and checked against the s global as symbols so they don't pollute anyone's existing use of the s namespace.)

Snowman Story Format not working in Safari…

Originally reported by: Tim Samoff (Bitbucket: timsamoff, GitHub: timsamoff)


This has been verified in the Twine discussion forum here:

http://twinery.org/forum/discussion/comment/9271

Using Safari (8.0.7) in OS X (10.10.4), Twine (2.0.4) Snowman (1.0) stories don’t Play/Test properly: they display as a blank screen. Publishing a story works fine — the HTML shows content when viewed in Safari, but Playing/Testing yields no results.

I tested this in various browsers and Safari seems to be the only one where this happens.

There are no Console errors.


Make loading external libraries easier.

Needed to load some external scripts.
Like it to be in one location, for the entire story. Avoid duplication.
$.getScript(url) in Story Javascript

Unfortunately, you run into race conditions all over the place.
Both in the Story Javascript, and in passages. It'd be nice to either make this easier(story html so you could use <script> tags?), or have a tutorial on how to do this(these issues are related to snowman's structure, not js in general).

Here's what I had to do to fix:
`

//This just loads them in parallel
f.ExtLibs = function (libs) {
    return new Promise(function(resolve, reject) {
		var toReturn = [];
  	var previousError = false; 
		libs.map(function(url) {
			$.getScript(url)
     		.done(function( script, textStatus ) {
        		if (previousError) { return; }
          		toReturn.push(url +":" + textStatus);
        		if (toReturn.length === libs.length) {
          			resolve(null, toReturn);
        		}
			})
  			.fail(function( jqxhr, settings, exception ) {        
	        	previousError = true;
          		reject('Error' + exception);
      		});
    });                       
 });
};

//this fixes story js race conditions, and does the actual loading
f.load = async function(){    
	f.loaded = f.ExtLibs(ext_libs); 
	await f.loaded;
       <code using external libs within story javascript.>
}
f.load();

//this fixes the passage race conditions
window.story.oldshow = window.story.show;

window.story.show = async function (idOrName, noHistory = false) {
		await f.loaded;
		window.story.oldshow(idOrName, noHistory);
};

[Proposal] Add support to onclick custom code in links

Twine standard links in bar or arrow form (ie. [[text|passageName]]) could accept a simple additional expression executed on user click before next passage rendering (ie. [[text|passageName][onClickCallback]]).

It can be very useful to set a variable value (ie. [[text|passageName][s.myVar=1]]) or run a custom function (ie. [[text|passageName][s.myFunc(event, this)]]) that depends on user choice.

Syntax is inspired by SugarCube v2 link feature.

Here is the working code, I can open a PR if ok for you.

Jshint?

I know it's probably a lot to ask, but it'd be SUPER cool if we could integrate jshint- running it on the javascript code before eval, then if the code errors, spitting out what jshint found.

Dist js file in title case

If I simply clone this repo and run npm install && npm run package I obtain a Snowman-2.2.0-format.js in dist/ folder with the first lettere in uppercase.

Maybe this can be a hit for a fix?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.