twee2 0.3.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Rakefile +37 -0
  4. data/bin/twee2 +5 -0
  5. data/doc/usage.txt +4 -0
  6. data/lib/twee2.rb +29 -3
  7. data/lib/twee2/build_config.rb +10 -0
  8. data/lib/twee2/story_file.rb +10 -1
  9. data/lib/twee2/story_format.rb +7 -2
  10. data/lib/twee2/version.rb +1 -1
  11. data/twee2.gemspec +1 -0
  12. data/web/.gitignore +15 -0
  13. data/web/build/CNAME +1 -0
  14. data/web/build/documentation.html +446 -0
  15. data/web/build/eg1.html +91 -0
  16. data/web/build/escape-from-earth.html +94 -0
  17. data/web/build/escape-from-earth.tw2 +52 -0
  18. data/web/build/favicon.ico +0 -0
  19. data/web/build/fonts/glyphicons-halflings-regular.eot +0 -0
  20. data/web/build/fonts/glyphicons-halflings-regular.svg +288 -0
  21. data/web/build/fonts/glyphicons-halflings-regular.ttf +0 -0
  22. data/web/build/fonts/glyphicons-halflings-regular.woff +0 -0
  23. data/web/build/fonts/glyphicons-halflings-regular.woff2 +0 -0
  24. data/web/build/images/escape-from-earth.png +0 -0
  25. data/web/build/images/notepad.png +0 -0
  26. data/web/build/images/twee2-logo.png +0 -0
  27. data/web/build/index.html +273 -0
  28. data/web/build/install.html +162 -0
  29. data/web/build/javascripts/all.js +15 -0
  30. data/web/build/javascripts/bootstrap.min.js +8 -0
  31. data/web/build/javascripts/jquery-2.1.4.min.js +5 -0
  32. data/web/build/stylesheets/all.css +11 -0
  33. data/web/build/stylesheets/readable.bootstrap.min.css +11 -0
  34. data/web/build/tutorial.html +202 -0
  35. data/web/config.rb +72 -0
  36. data/web/source/CNAME +1 -0
  37. data/web/source/documentation.html.haml +411 -0
  38. data/web/source/eg1.html +91 -0
  39. data/web/source/escape-from-earth.html +94 -0
  40. data/web/source/escape-from-earth.tw2 +52 -0
  41. data/web/source/favicon.ico +0 -0
  42. data/web/source/fonts/glyphicons-halflings-regular.eot +0 -0
  43. data/web/source/fonts/glyphicons-halflings-regular.svg +288 -0
  44. data/web/source/fonts/glyphicons-halflings-regular.ttf +0 -0
  45. data/web/source/fonts/glyphicons-halflings-regular.woff +0 -0
  46. data/web/source/fonts/glyphicons-halflings-regular.woff2 +0 -0
  47. data/web/source/images/escape-from-earth.png +0 -0
  48. data/web/source/images/notepad.png +0 -0
  49. data/web/source/images/twee2-logo.png +0 -0
  50. data/web/source/index.html.haml +184 -0
  51. data/web/source/install.html.haml +81 -0
  52. data/web/source/javascripts/all.js +2 -0
  53. data/web/source/javascripts/bootstrap.min.js +7 -0
  54. data/web/source/javascripts/jquery-2.1.4.min.js +4 -0
  55. data/web/source/layouts/layout.haml +54 -0
  56. data/web/source/stylesheets/all.css +1 -0
  57. data/web/source/stylesheets/readable.bootstrap.min.css +11 -0
  58. data/web/source/tutorial.html.haml +119 -0
  59. metadata +64 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 56b36c1e681bbb26c4908a3418e887ea9dedcdc5
4
- data.tar.gz: 8abeebae4c760910de847591918f14a567759699
3
+ metadata.gz: 80fdeb6e878761f0e195156ed16776fdc086b1cf
4
+ data.tar.gz: 575b4e716c1b2594c9cde614b221403541a759e6
5
5
  SHA512:
6
- metadata.gz: b8d4a3dfdc52ffbec9bbe209e944549999927e199d8bbf83ab40a27f65c726d0d2a354acec0ddd508dbfbeae2d21d4dc03321bfcd6d023393a2afc682fb86600
7
- data.tar.gz: 003ab07e54edff64f7799ce3c33d0a093c146062c7b5e887305f222530d9782c9c1b4ce9aa898fa7046e80117d86e728e631ad34bc1677441d76d7f8a454c529
6
+ metadata.gz: 55b0a31d371fa8cfc7ddb4a96f98d970670aa6080f8eecf929f5f079d5ebac9d5e4b6242b97a23838f632025d208094396c716a6753b810bd6026ce13bcd97ef
7
+ data.tar.gz: 4e54befc3dac3dcaa6a5d92b318230c590b84a9916847a1abb2887bdde3c13697f05b632d576b56c8c10393f720435bcc108914a911e36135a1143b36c51a082
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  pkg/
2
2
  testdata/
3
- Gemfile.lock
3
+ Gemfile.lock
4
+ *~
data/Rakefile CHANGED
@@ -1,2 +1,39 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ namespace :web do
4
+ # Yields to a block after chdir'ing to the specified
5
+ # path (relative to the app root), then chdir's back
6
+ def run_from_directory(path)
7
+ old_dir = Dir::pwd
8
+ Dir::chdir("#{File::dirname(__FILE__)}/#{path}")
9
+ yield
10
+ Dir::chdir(old_dir)
11
+ end
12
+
13
+ desc 'Build the website from source'
14
+ task :build do
15
+ raise 'Middleman not found. Try "gem install middleman".' if `which middleman` == ''
16
+ run_from_directory('web') do
17
+ system("middleman build --clean")
18
+ end
19
+ end
20
+
21
+ desc "Preview the website at http://0.0.0.0:4567"
22
+ task :preview do
23
+ raise 'Middleman not found. Try "gem install middleman".' if `which middleman` == ''
24
+ run_from_directory('web') do
25
+ system("middleman server --bind-address=0.0.0.0")
26
+ end
27
+ end
28
+
29
+ desc "Deploy the website to github pages"
30
+ task :deploy do
31
+ run_from_directory('.') do
32
+ system("git subtree push --prefix web/build origin gh-pages")
33
+ end
34
+ end
35
+
36
+ desc "Build and deploy the website"
37
+ task :build_dep => [:build, :deploy] do
38
+ end
39
+ end
data/bin/twee2 CHANGED
@@ -29,6 +29,11 @@ class Twee2CLI < Thor
29
29
  Twee2::decompile(url, output)
30
30
  end
31
31
 
32
+ desc 'version', "reports which version you're using and checks what the highest available version is"
33
+ def version
34
+ Twee2::version_check
35
+ end
36
+
32
37
  desc 'help', 'shows usage instructions'
33
38
  def help
34
39
  Twee2::help
@@ -18,5 +18,9 @@ Usage:
18
18
  a Twee2 source file.
19
19
  NOT AVAILABLE ON MICROSOFT WINDOWS.
20
20
 
21
+ twee2 version
22
+ Reports what version of Twee2 you're using, and checks what the
23
+ latest-available version is.
24
+
21
25
  twee2 help
22
26
  Displays this message.
@@ -12,10 +12,27 @@ module Twee2
12
12
  DEFAULT_FORMAT = 'Harlowe'
13
13
 
14
14
  def self.build(input, output, options = {})
15
- # Read and parse format file
16
- build_config.story_format = StoryFormat::new(options[:format])
17
15
  # Read and parse input file
18
- build_config.story_file = StoryFile::new(input)
16
+ begin
17
+ build_config.story_file = StoryFile::new(input)
18
+ rescue StoryFileNotFoundException
19
+ puts "ERROR: story file '#{input}' not found."
20
+ exit
21
+ end
22
+ # Read and parse format file, unless already set (by a Twee2::build_config.story_format call in the story file, for example)
23
+ if !build_config.story_format
24
+ begin
25
+ build_config.story_format = StoryFormat::new(options[:format])
26
+ rescue StoryFormatNotFoundException
27
+ puts "ERROR: story format '#{options[:format]}' not found."
28
+ exit
29
+ end
30
+ end
31
+ # Warn if IFID not specified
32
+ if !build_config.story_ifid_specified
33
+ puts "NOTICE: You haven't specified your IFID. Consider adding to your code -"
34
+ puts "::StoryIFID[twee2]\nTwee2::build_config.story_ifid = '#{build_config.story_ifid}'"
35
+ end
19
36
  # Produce output file
20
37
  File::open(output, 'w') do |out|
21
38
  out.print build_config.story_format.compile
@@ -38,6 +55,15 @@ module Twee2
38
55
  puts StoryFormat.known_names.join("\n")
39
56
  end
40
57
 
58
+ def self.version_check
59
+ `gem list -r -q twee2` =~ /\((.*)\)/
60
+ puts " Your version: #{Twee2::VERSION}"
61
+ puts " Latest version: #{$1}"
62
+ if Twee2::VERSION.to_s != $1
63
+ puts "To upgrade, run: gem install twee2"
64
+ end
65
+ end
66
+
41
67
  unless Gem.win_platform?
42
68
  # Reverse-engineers a Twee2/Twine 2 output HTML file into a Twee2 source file
43
69
  def self.decompile(url, output)
@@ -1,14 +1,24 @@
1
1
  require 'singleton'
2
+ require 'securerandom'
2
3
 
3
4
  module Twee2
4
5
  class BuildConfig
5
6
  include Singleton
6
7
 
7
8
  attr_accessor :story_format, :story_file, :story_name
9
+ attr_reader :story_ifid, :story_ifid_specified
8
10
 
9
11
  # Set defaults
10
12
  def initialize
11
13
  @story_name = 'An unnamed story'
14
+ @story_ifid, @story_ifid_specified = SecureRandom.uuid, false
15
+ end
16
+
17
+ # Set the IFID - we track when this occurs so that the user can be
18
+ # nagged for not manually setting it
19
+ def story_ifid=(value)
20
+ @story_ifid = value
21
+ @story_ifid_specified = true
12
22
  end
13
23
  end
14
24
 
@@ -1,3 +1,4 @@
1
+ require 'rubygems'
1
2
  require 'haml'
2
3
  require 'coffee_script'
3
4
  require 'sass'
@@ -89,7 +90,15 @@ module Twee2
89
90
  # Generate XML in Twine 2 format
90
91
  @story_data = Builder::XmlMarkup.new
91
92
  # TODO: what is tw-storydata's "options" attribute for?
92
- @story_data.tag!('tw-storydata', { name: Twee2::build_config.story_name, startnode: @story_start_pid, creator: 'Twee2', 'creator-version' => Twee2::VERSION, ifid: 'TODO', format: '{{STORY_FORMAT}}', options: '' }) do
93
+ @story_data.tag!('tw-storydata', {
94
+ name: Twee2::build_config.story_name,
95
+ startnode: @story_start_pid,
96
+ creator: 'Twee2',
97
+ 'creator-version' => Twee2::VERSION,
98
+ ifid: Twee2::build_config.story_ifid,
99
+ format: '{{STORY_FORMAT}}',
100
+ options: ''
101
+ }) do
93
102
  @story_data.style(story_css, role: 'stylesheet', id: 'twine-user-stylesheet', type: 'text/twine-css')
94
103
  @story_data.script(story_js, role: 'script', id: 'twine-user-script', type: 'text/twine-javascript')
95
104
  @passages.each do |k,v|
@@ -6,7 +6,7 @@ module Twee2
6
6
  class StoryFormat
7
7
  # Loads the StoryFormat with the specified name
8
8
  def initialize(name)
9
- raise(StoryFormatNotFoundException) if !File::exists?(format_file_path = Twee2::buildpath("storyFormats/#{name}/format.js"))
9
+ raise(StoryFormatNotFoundException) if !File::exists?(format_file_path = Twee2::buildpath("storyFormats/#{name}/format.js")) && !File::exists?(format_file_path = Twee2::buildpath("#{name}/format.js"))
10
10
  @name = name
11
11
  format_file = File::read(format_file_path)
12
12
  format_data = format_file.match(/(["'])source\1 *: *(["']).*?[^\\]\2/)[0]
@@ -21,7 +21,12 @@ module Twee2
21
21
 
22
22
  # Returns an array containing the known StoryFormat names
23
23
  def self.known_names
24
- Dir.open(Twee2::buildpath('storyFormats')).to_a.sort.reject{|d|d=~/^\./}.map{|f|" * #{f}"}
24
+ Dir.open(Twee2::buildpath('storyFormats')).to_a.sort.reject{|d|d=~/^\./}.map do |name|
25
+ format_file_path = Twee2::buildpath("storyFormats/#{name}/format.js")
26
+ format_file = File::read(format_file_path)
27
+ version = format_file.match(/(["'])version\1 *: *(["'])(.*?[^\\])\2/)[3]
28
+ " * #{name} (#{version})"
29
+ end
25
30
  end
26
31
  end
27
32
  end
@@ -1,3 +1,3 @@
1
1
  module Twee2
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.required_ruby_version = '~> 2'
27
27
 
28
28
  spec.add_development_dependency 'rake', '~> 10'
29
+ spec.add_development_dependency 'middleman', '>= 3.4.0'
29
30
 
30
31
  spec.add_runtime_dependency 'builder', '~> 3.2', '>= 3.2.2'
31
32
  spec.add_runtime_dependency 'bundler', '~> 1.6'
@@ -0,0 +1,15 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile ~/.gitignore_global
6
+
7
+ # Ignore bundler config
8
+ /.bundle
9
+
10
+ # Ignore cache
11
+ /.sass-cache
12
+ /.cache
13
+
14
+ # Ignore .DS_store file
15
+ .DS_Store
@@ -0,0 +1 @@
1
+ twee2.danq.me
@@ -0,0 +1,446 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset='utf-8'>
5
+ <title>
6
+ Twee2
7
+ | Full documentation
8
+ </title>
9
+ <meta content='IE=edge' http-equiv='X-UA-Compatible'>
10
+ <meta content='width=device-width, initial-scale=1' name='viewport'>
11
+ <link href="/stylesheets/all.css" rel="stylesheet" />
12
+ <script src="/javascripts/all.js"></script>
13
+ </head>
14
+ <body>
15
+ <div class='navbar navbar-default navbar-static-top'>
16
+ <div class='container'>
17
+ <div class='navbar-header'>
18
+ <a class='navbar-brand' href='./'>Twee2</a>
19
+ <button class='navbar-toggle' data-target='#navbar-main' data-toggle='collapse' type='button'>
20
+ <span class='icon-bar'></span>
21
+ <span class='icon-bar'></span>
22
+ <span class='icon-bar'></span>
23
+ </button>
24
+ </div>
25
+ <div class='navbar-collapse collapse' id='navbar-main'>
26
+ <ul class='nav navbar-nav'>
27
+ <li>
28
+ <a href='index.html'>Home</a>
29
+ </li>
30
+ <li>
31
+ <a href='install.html'>Install</a>
32
+ </li>
33
+ <li>
34
+ <a href='tutorial.html'>2-minute tutorial</a>
35
+ </li>
36
+ <li>
37
+ <a href='documentation.html'>Documentation</a>
38
+ </li>
39
+ <li>
40
+ <a href='https://github.com/avapoet/twee2'>Source</a>
41
+ </li>
42
+ </ul>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <div class='container'>
47
+ <div class='row'>
48
+ <div class='col-sm-3 col-sm-push-9'>
49
+ <h2>Index</h2>
50
+ <ul>
51
+ <li>
52
+ <a href='#relationship-to-twine'>Relationship to Twine</a>
53
+ </li>
54
+ <li>
55
+ <a href='#writing-code'>Writing and compiling code</a>
56
+ </li>
57
+ <li>
58
+ <a href='#story-formats'>Understanding story formats</a>
59
+ </li>
60
+ <li>
61
+ <a href='#twee2-syntax'>Twee2 syntax</a>
62
+ <ul>
63
+ <li>
64
+ <a href='#twee2-syntax-passages'>Passages</a>
65
+ </li>
66
+ <li>
67
+ <a href='#twee2-syntax-content'>Content</a>
68
+ </li>
69
+ <li>
70
+ <a href='#twee2-syntax-special-passages'>Special passages</a>
71
+ </li>
72
+ </ul>
73
+ </li>
74
+ <li>
75
+ <a href='#includes'>Splitting your code into multiple files</a>
76
+ </li>
77
+ <li>
78
+ <a href='#build-config'>Setting build configuration options</a>
79
+ </li>
80
+ <li>
81
+ <a href='#decompiler'>Decompiling Twine 2 stories</a>
82
+ </li>
83
+ </ul>
84
+ </div>
85
+ <div class='col-sm-9 col-sm-pull-3'>
86
+ <h1>Full documentation</h1>
87
+ <h2 id='relationship-to-twine'>Relationship to Twine</h2>
88
+ <p>
89
+ Twee2 is built on top of
90
+ <a href='http://twinery.org/'>Twine 2</a>,
91
+ minus the graphical user interface. As a result, virtually all of the
92
+ <a href='http://twinery.org/wiki/twine2:guide'>documentation about Twine 2</a>
93
+ (and specifically the documentation about the
94
+ <a href='http://twinery.org/wiki/twine2:how_to_choose_a_story_format'>different story formats</a>)
95
+ is relevant to Twee2, too.
96
+ Because Twee2 is inspired by Twee, its documentation is also a valuable resource: however note that
97
+ you can't use Twee 'macros' in Twee2.
98
+ </p>
99
+ <h2 id='writing-code'>Writing and compiling code</h2>
100
+ <p>
101
+ Write Twee2 code using your favourite text editor. Syntax highlighting is available via
102
+ <a href='https://github.com/monospaced/sublime-twee'>this Sublime Text plugin</a>
103
+ for Twee. By convention, Twee2 source files have the
104
+ <code>.tw2</code>
105
+ extension.
106
+ </p>
107
+ <p>
108
+ Compile Twee2 files using the
109
+ <code>twee2</code>
110
+ command-line tool. There are two important modes of operation:
111
+ </p>
112
+ <ul>
113
+ <li>
114
+ <code>twee2 build input.tw2 output.html</code>
115
+ produces output.html based on the code in input.tw2
116
+ </li>
117
+ <li>
118
+ <code>twee2 watch input.tw2 output.html</code>
119
+ does the same thing, but
120
+ <em>watches</em>
121
+ input.tw2 for changes, automatically recompiling whenever it is updated (note that it's not
122
+ smart enough to understand when
123
+ <a href='#includes'>'included'</a>
124
+ files have been changed, though).
125
+ </li>
126
+ </ul>
127
+ <p>
128
+ Because Twee2 source files are just plain text files, they're well-suited to use with
129
+ source control systems: you could, for example, use
130
+ <a href='https://github.com/'>Github</a>
131
+ to share your code or to collaborate with other authors, even working on the same file.
132
+ </p>
133
+ <h2 id='story-formats'>Understanding story formats</h2>
134
+ <p>
135
+ Twee2 comes with built-in support for all of the same story formats that Twine 2 does:
136
+ </p>
137
+ <ul>
138
+ <li>
139
+ <a href='http://twine2.neocities.org/'>Harlowe</a>
140
+ - the default format, which includes a simplified scripting format
141
+ </li>
142
+ <li>
143
+ <a href='https://bitbucket.org/klembot/snowman-2'>Snowman</a>
144
+ - a minimal format that uses Underscore.js templates and jQuery to provide programmers with a powerful toolset
145
+ </li>
146
+ <li>
147
+ <a href='http://www.motoslave.net/sugarcube/'>SugarCube</a>
148
+ - a TiddlyWiki-powered format that comes with support for multiple save 'slots' and a Twine 1/Twee 'macro'-like scripting syntax
149
+ </li>
150
+ <li>
151
+ Paperthin - used when you select "View Proofing Copy" in Twine 2, this minimal skeleton isn't really an output format as it is a proofing tool
152
+ </li>
153
+ </ul>
154
+ <p>
155
+ If you've having difficulty choosing between them, there's
156
+ <a href='http://twinery.org/wiki/twine2:how_to_choose_a_story_format'>a summary of the differences</a>
157
+ in the Twine 2 documentation.
158
+ </p>
159
+ <p>
160
+ To specify which format to use during compilation, use the optional
161
+ <code>--format</code>
162
+ parameter. E.g. you might type
163
+ <code>twee2 build input.tw2 output.html --format=Snowman</code>.
164
+ You can get a list of the formats that Twee2 natively understands by running
165
+ <code>twee2 formats</code>.
166
+ </p>
167
+ <p>
168
+ It's possible to use any story format, e.g. if you've downloaded or written your own, by specifying the path
169
+ to the story format's directory (the one containing the format.js file) in your
170
+ <code>--format</code>
171
+ parameter. For example, you might run
172
+ <code>twee2 build input.tw2 output.html --format=./MyFormat</code>.
173
+ </p>
174
+ <p>
175
+ Rather than setting the format on the command-line, it's possible to specify it within your source code
176
+ itself, using
177
+ <a href='#build-config'>build configuration</a>
178
+ options.
179
+ </p>
180
+ <h2 id='twee2-syntax'>Twee2 syntax</h2>
181
+ <p>
182
+ Twee2 uses a syntax that's heavily inspired-by but not 100% compatible with Twee:
183
+ </p>
184
+ <h3 id='twee2-syntax-passages'>Passages</h3>
185
+ <p>
186
+ Each block of text in Twee2 exists in a
187
+ <em>passage</em>.
188
+ Each passage begins with a title, which is prefixed by two colons:
189
+ </p>
190
+ <p>
191
+ <code>::My Passage Name</code>
192
+ </p>
193
+ <p>
194
+ Passage titles may only contain letters, numbers, basic punctuation, and spaces. Some authors prefer to avoid
195
+ spaces in their passage titles. Passage titles are not case-sensitive: you don't have to use the same case when
196
+ referring to a passage every time. Passages titles
197
+ <em>should</em>
198
+ be unique within a story: if they're not, only the last passage with a given title will be included in the story.
199
+ </p>
200
+ <p>
201
+ Passage titles may optionally be suffixed by one or both of:
202
+ </p>
203
+ <ul>
204
+ <li>
205
+ Any number of
206
+ <em>tags</em>,
207
+ separated by spaced, inside a pair of square brackets. E.g:
208
+ <br>
209
+ <code>::My Passage Name [tagone tagtwo]</code>
210
+ <br>
211
+ Tags can be used by code in your story (e.g. to send the player to a randomly-selected passage from a subset).
212
+ <a href='#twee2-syntax-special-passages'>Some tags have special meanings</a>,
213
+ as described below.
214
+ </li>
215
+ <li>
216
+ A pair of coordinates, separated by a comma and enclosed within angle brackets. E.g.:
217
+ <br>
218
+ <code>::My Passage Name <123,456></code>
219
+ <br>
220
+ Coordinates have no meaning to Twee2, but they can be used to enhance compatability with Twine 2: Twine 2 uses
221
+ these coordinates to decide where to show the passages in its WYSIWYG editor.
222
+ </li>
223
+ </ul>
224
+ <p>
225
+ If you include both tags and coordinates after a passage, the tags must come before the coordinates, e.g.:
226
+ </p>
227
+ <p>
228
+ <code>::My Passage Name [tagone tagtwo] <123,456></code>
229
+ </p>
230
+ <p>
231
+ Some passages and tags
232
+ <a href='#twee2-syntax-special-passages'>have special meanings</a>,
233
+ as described below
234
+ </p>
235
+ <h3 id='twee2-syntax-content'>Content</h3>
236
+ <p>
237
+ Each passage may contain any amount of content, most of which will be stuff that the player sees. Many
238
+ story formats understand
239
+ <em>Markdown</em>
240
+ formatting in passages, which makes it possible to easily add formatting to your passages. Links to different
241
+ passages are supported in any of the following syntaxes (where 'Dungeon' is the name of the passage they'll be
242
+ transported if they click the link, and 'click here', where present, is the text that they'll see to click on):
243
+ </p>
244
+ <ul>
245
+ <li>
246
+ <code>[Dungeon]</code>
247
+ </li>
248
+ <li>
249
+ <code>[click here->Dungeon]</code>
250
+ </li>
251
+ <li>
252
+ <code>[Dungeon<-click here]</code>
253
+ </li>
254
+ <li>
255
+ <code>[click here|Dungeon]</code>
256
+ </li>
257
+ </ul>
258
+ <h2 id='twee2-syntax-special-passages'>Special passages</h2>
259
+ <p>
260
+ Some passage names and tags have special meanings. These are:
261
+ </p>
262
+ <h3>::Start</h3>
263
+ <p>
264
+ The
265
+ <code>::Start</code>
266
+ passage will, by default, be used as the initial passage that your player sees when they start reading.
267
+ You can override this using
268
+ <a href='#build-config'>build configuration options</a>,
269
+ but it's probably easier just to follow this convention.
270
+ </p>
271
+ <h3>::StorySubtitle, ::StoryAuthor, ::StoryMenu, and ::StorySettings</h3>
272
+ <p>
273
+ These names were used for special passages in Twee 1. They're not used by Twee2, but to maintain compatability
274
+ with Twee 1 they're ignored and you should avoid using them unless you're writing a story that needs to be
275
+ capable of being compiled by both Twee 1 and Twee2.
276
+ </p>
277
+ <h3>::StoryIncludes</h3>
278
+ <p>
279
+ Any
280
+ <code>::StoryIncludes</code>
281
+ passages (you can have as many as you like, but you probably should avoid having more than one in any file in
282
+ order to avoid confusion) are treated as lists of secondary Twee2 files to 'include' into your story. This is
283
+ described in more detail below, under
284
+ <a href='#includes'>splitting your code into multiple files</a>.
285
+ </p>
286
+ <h3>[stylesheet]</h3>
287
+ <p>
288
+ Any passages with the 'stylesheet' tag will not be included in your story, but their contents will be injected
289
+ into the story's stylesheet. For example, you could write:
290
+ </p>
291
+ <p>
292
+ <pre>::MyCoolStylesheet [stylesheet]&#x000A;&#x000A;body {&#x000A; background: #eee;&#x000A;}&#x000A;&#x000A;tw-passage tw-link {&#x000A; color: red;&#x000A;}</pre>
293
+ </p>
294
+ <p>
295
+ It's also possible to use
296
+ <a href='http://sass-lang.com/'>SASS</a>
297
+ to enhance your stylesheet. Simply add the tag 'sass' or 'scss' to specify the dialect of SASS that you want
298
+ to use, e.g.:
299
+ <pre>::MyCoolStylesheet [scss stylesheet]&#x000A;&#x000A;body {&#x000A; background: #eee;&#x000A;}&#x000A;&#x000A;tw-passage {&#x000A; tw-link {&#x000A; color: red;&#x000A; }&#x000A;}&#x000A;</pre>
300
+ </p>
301
+ <h3>[script]</h3>
302
+ <p>
303
+ Any passages with the 'script' tag will not be included in your story, but their contents will be injected
304
+ into the resulting web page as Javascript. For example, you could write:
305
+ </p>
306
+ <p>
307
+ <pre>::SomeAwesomeCode [script]&#x000A;&#x000A;alert('This message will appear when the adventure starts!');</pre>
308
+ </p>
309
+ <p>
310
+ It's also possible to use
311
+ <a href='http://coffeescript.org/'>Coffeescript</a>
312
+ to make your Javascript development more-beautiful. Simply add the tag 'coffee' to your script block:
313
+ <pre>::SomeAwesomeCode [coffee script]&#x000A;&#x000A;alert 'This message will appear when the adventure starts!'&#x000A;</pre>
314
+ </p>
315
+ <h3>[haml]</h3>
316
+ <p>
317
+ Put the 'haml' tag into your regular passages in order to allow you to write
318
+ <a href='http://haml.info/'>HAML</a>
319
+ code into your passages. HAML is a sophisticated templating language for producing HTML output, and
320
+ for some it might be preferable to writing plain old Markdown. This includes the ability to inject
321
+ Javascript/CoffeeScript into particular passages. For example, you could write:
322
+ </p>
323
+ <p>
324
+ <pre>::NicksBar [haml]&#x000A;%p&#x000A; Nick's Bar is exactly the kind of nightspot that helps you remember why you quit drinking.&#x000A; A depressed-looking barman pours another beer for an equally depressed-looking drunk, while&#x000A; over in the corner a street thug plays with a knife as he eyes you up. The floor is sticky&#x000A; and the air reeks of stale alcohol.&#x000A;%p&#x000A; %strong What would you like to do?&#x000A;%ul&#x000A; %li [Nick<-Talk to the bartender]&#x000A; %li [BarToilet<-Go to the bathroom]&#x000A; %li [BarSit<-Sit in a booth]&#x000A;&#x000A;:coffeescript&#x000A; $ ->&#x000A; alert "This message will appear when you reach Nick's Bar!"&#x000A;</pre>
325
+ </p>
326
+ <h3>[twee2]</h3>
327
+ <p>
328
+ Passages marked with the 'twee2' tag are not included in your story. However, any Ruby code in them
329
+ will be executed when the passage is processed by the builder. This can be used to
330
+ <a href='#build-config'>set build configuration options</a>
331
+ as described below.
332
+ </p>
333
+ <h2 id='includes'>Splitting your code into multiple files</h2>
334
+ <p>
335
+ A major benefit of Twee2 over Twine 2 is that it's possible to break apart your story into multiple
336
+ files, which can be used to structure your work, to facilitate teamworking with or without source
337
+ control, and to make 'reusable' components such as stylesheets and scripts which can then be injected
338
+ into later stories. There are two ways to do this:
339
+ </p>
340
+ <h3>Using ::StoryIncludes</h3>
341
+ <p>
342
+ Insert a
343
+ <code>::StoryIncludes</code>
344
+ passage into your file and list within it the names of the files to include. Each will be appended
345
+ to the end of your story before compilation. For example, the following game skeleton includes the
346
+ contents of four other files - the main file contains only the
347
+ <code>::Start</code>
348
+ passage:
349
+ </p>
350
+ <p>
351
+ <pre>::Start&#x000A;**Journey To The Centre Of The Earth**&#x000A;&#x000A;by Dan Q&#x000A;&#x000A;[Play]&#x000A;&#x000A;::StoryIncludes&#x000A;first_section.tw2&#x000A;second_section.tw2&#x000A;stylesheet.tw2&#x000A;javascripts.tw2&#x000A;</pre>
352
+ </p>
353
+ <h3>Using ::@include directives</h3>
354
+ <p>
355
+ You can put an
356
+ <code>::@include</code>
357
+ directive anywhere in your code to insert the contents of another file at that point.
358
+ <code>::@include</code>
359
+ respects your current indentation level (e.g. when using HAML), so it's safe to use at any indentation
360
+ 'depth'. For example, the following passages each include a separate file that contains a description
361
+ of the house in the distance: that description is shared between the two passages, and updating the
362
+ file updates the description in both.
363
+ </p>
364
+ <p>
365
+ <pre>::Greenhouse [haml]&#x000A;%p&#x000A; Light shines brightly through the tall glass walls of the ornate wrought-iron greenhouse, and&#x000A; the plants are verdant and lively. The [Garden<-door] stands open and a cool breeze blows in.&#x000A;%p&#x000A; ::@include description-of-house.tw2&#x000A;&#x000A;::Garden [haml]&#x000A;%p&#x000A; The garden winds around decorative trees betwen the [greenhouse] and the [Porch<-mansion].&#x000A;%p&#x000A; ::@include description-of-house.tw2&#x000A;</pre>
366
+ </p>
367
+ <p>
368
+ Note that neither method of including code works recursively (i.e. you can't include a file that in
369
+ turn includes another file), but this may be fixed in a future version.
370
+ </p>
371
+ <h2 id='build-config'>Setting build configuration options</h2>
372
+ <p>
373
+ Creating a passage with the 'twee2' tag can be used to run arbritrary Ruby code or to pass additional
374
+ options to the Twee2 compiler. This expands the potential capability of Twee2 almost-limitlessly, but for now
375
+ the only supported options are:
376
+ </p>
377
+ <ul>
378
+ <li>
379
+ <strong>
380
+ <code>Twee2::build_config.story_ifid = '<em>[your IFID]</em>'</code>
381
+ </strong>
382
+ - used to set the
383
+ <a href='http://www.ifwiki.org/index.php/IFID'>IFID of your story, to facilitate catologuing. If you</a>
384
+ don't include this directive, the compiler will suggest a random one to you every time you run it and
385
+ explain how to add it: if you're going to publish your story publicly, you should add the line it
386
+ suggests before you do so.
387
+ </li>
388
+ <li>
389
+ <strong>
390
+ <code>Twee2::build_config.story_format = '<em>[a story format]</em>'</code>
391
+ </strong>
392
+ - an alternative way of specifying the story format used by your story, rather than using the --format
393
+ switch to the compiler. The syntax of format names and means of specifying externally-stored formats is
394
+ identical to
395
+ <a href='#story-formats'>using the --format switch</a>.
396
+ </li>
397
+ </ul>
398
+ <p>
399
+ For example:
400
+ </p>
401
+ <p>
402
+ <pre>::Configuration [twee2]&#x000A;Twee2::build_config.story_ifid = '41AB7776-D198-40F5-BD54-0493D49DA58C'&#x000A;Twee2::build_config.story_format = 'Snowman'&#x000A;</pre>
403
+ </p>
404
+ <h2 id='decompiler'>Decompiling Twine 2 stories</h2>
405
+ <p>
406
+ It's possible to convert existing (compiled) Twee2/Twine 2 story files, in HTML format, back into
407
+ Twee2 source files for further editing. This can be used to convert your Twine 2 projects into Twee2
408
+ files or to easily examine the contents of somebody else's story. This feature does not work on Microsoft
409
+ Windows. To use it, run:
410
+ </p>
411
+ <p>
412
+ <code>twee2 decompile input.html output.tw2</code>
413
+ </p>
414
+ <p>
415
+ The input HTML file can optionally be a full web URL.
416
+ </p>
417
+ </div>
418
+ </div>
419
+ <footer>
420
+ <hr>
421
+ <div class='row'>
422
+ <div class='col-lg-12'>
423
+ <ul class='list-unstyled'>
424
+ <li class='pull-right'>
425
+ <a href='#top'>Back to top</a>
426
+ </li>
427
+ </ul>
428
+ <p class='small'>
429
+ &copy;
430
+ <a href='https://danq.me/'>Dan Q</a>
431
+ 2015—
432
+ |
433
+ Twee2 is distributed
434
+ <a href='https://github.com/avapoet/twee2'>via Github</a>
435
+ under the
436
+ <a href='https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html'>GNU General Public License version 2</a>
437
+ |
438
+ This website is licensed under the
439
+ <a href='http://opencontent.org/openpub/'>Open Publication License version 1</a>
440
+ </p>
441
+ </div>
442
+ </div>
443
+ </footer>
444
+ </div>
445
+ </body>
446
+ </html>