Missing the closing tag and making it into different lines, it works again! But
<p><script>console.log("Hello world")</script>
Missing the closing tag but putting all in the same line, it dies screaming again!
The story Iām working on is HTML heavy. Very. Plus lots of inline scripts and rendering one passage inside another. I donāt think I have any fireproof way of preventing the tag combinations that kill the game. And I must use script tags instead of <% %>, since the latter doesnāt work once the passage finishes rendering.
You should report this behaviour on the Issues page of the Snowman projectās repository, as you may of found a bug or unintended behaviour.
One thing to note is that the purpose of the <p> element is to format Textual content (or related elements) as a paragraph, and as the <script> element is definitely not textual content it structurally doesnāt make sense to embed it within a paragraph element.
There are two reasons your 4th example (the one with the missing </p> tag) works:
The line-break after the <p> open tag indicates that is the end of a ālineā of continuous content, and Snowman automatically wraps each ālineā of continuous content within a <p> element.
The web-browser youāre viewing the generated HTML document in notes a unpaired start tag and automatically add the required end tag to the Document Object Model it is generating for the page.
So the HTML generated for your 4th example ends up looking something like the following
As the maintainer of Snowman, Iāll look into this. However, @Greyelf is right about both the tag completion and the reporting. Please submit issues like this on GitHub so I can look into them and fix them going forward.
And I must use script tags instead of <% %>, since the latter doesnāt work once the passage finishes rendering.
Any included template code is the first thing processed in a passage. It wonāt work after the passage is rendered because it already has. If you want to re-process something, you can use <script> tags and call window.passage.render() and pass it additional text to render.
If, as you note, you have lots of HTML, you can also break up the Underscore template code and use conditional statements to optionally display things. Consider the following example.
You see a chest here in the hallway.
<% if (!s.chestOpen) { %>
Do you want to open it?
[[Open the chest.|chest]]
<% } else { %>
It's open, and there's nothing inside.
<% } %>
Something else to consider is using print() to āwriteā to a passage while within templated code blocks.
Thanks to both. I wasnāt aware of the bug tracker, Iāll report that now.
I should note that the p tags were what I happened to have as an example, but the problem also happens with div tags. My exact problem is this: I explicitly define an HTML div with some content. Within that block, I render another passage* with story.render(). That passage includes some script block: that block is now within the div defined in the original passage, and thatās when the thing breaks. Like this:
:: a
<div> <%= story.render("b") %> </div>
:: b
<script>Whatever...</script>
In other situations, I can simply write all scripts outside HTML blocks, but when another passage is embedded I lose control of that. My only solution would be renouncing to use story.render() inside HTML blocks. I would lose layout options (this story is all about layout and heavy design) but at least it would work.
* And this is why I use script tags instead of <%. I have to embed a passage with story.render() long after the passage is rendered, in response to a player clicking a choice.