twee2 0.2.0 → 0.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc099c1156382f87238efc566265e62b16c48c51
4
- data.tar.gz: 414eb7bca8f1fc560f59ef2bb894d85f5c380846
3
+ metadata.gz: b63cd0490f4dff22a79e5d67a667c6a433d899ba
4
+ data.tar.gz: db0132a07a752ac8700e44c2062550808ba74c26
5
5
  SHA512:
6
- metadata.gz: b47926ce7ea8e0808672bb8d6bdff78debe866f6149e9f5d7239d3cbed7c8eccc9a315842e77edc0f59459b8b228bec90f997fd86d988ddd6ce44fa7a76c361b
7
- data.tar.gz: 93a12dc5f04f465e955007f7d19e4824a659586c6c0725da2761f2e765b97742e76eabe9430aa6f0ea2061ac67042854fadd9941852803c0109e86fada238b1b
6
+ metadata.gz: 74b26f90671c6f4b7e380ee4fab5f5ee0b8bc716dfaa863d85a5b0611eab6831834ecd3de0ab39ce9db69ba11ea364f7c822cecca08193bcbb946d7bdd283b2c
7
+ data.tar.gz: 9eeba4d00780facc6c2c112b7305596853f6771d53cebb51733d3612e1267f7da5b85c7408a36bb9158f4d154a69522f09ef4be4437b86ed371167f4e0ce1efe
@@ -1,93 +1,23 @@
1
- Encoding.default_external = Encoding::UTF_8
2
- Encoding.default_internal = Encoding::UTF_8
3
-
4
- require "twee2/version"
1
+ Encoding.default_external = Encoding.default_internal = Encoding::UTF_8
5
2
 
6
3
  # Prerequisites (managed by bundler)
7
- require 'rubygems'
8
- require 'bundler/setup'
9
- require 'thor'
10
- require 'json'
11
- require 'builder'
12
- require 'filewatcher'
13
- require 'haml'
14
- require 'coffee_script'
4
+ %w{rubygems bundler/setup thor json builder filewatcher haml coffee_script
5
+ twee2/version twee2/story_format twee2/story_file}.each do |prerequisite|
6
+ require prerequisite
7
+ end
15
8
 
16
9
  module Twee2
17
10
  # Constants
18
11
  DEFAULT_FORMAT = 'Harlowe'
19
- HAML_OPTIONS = {
20
- remove_whitespace: true
21
- }
22
12
 
23
13
  def self.build(input, output, options = {})
24
14
  # Read and parse format file
25
- format_file = File::read(buildpath("storyFormats/#{options[:format]}/format.js"))
26
- format_data = format_file.match(/(["'])source\1 *: *(["']).*?[^\\]\2/)[0]
27
- format_data_for_json = "\{#{format_data}\}"
28
- result = JSON.parse(format_data_for_json)['source']
15
+ story_format = StoryFormat::new(options[:format])
29
16
  # Read and parse input file
30
- passages, current_passage = {}, nil
31
- File::read(input).each_line do |line| # REFACTOR: switch this to using regular expressions, why not?
32
- if line =~ /^:: *([^\[]*?) *(\[(.*?)\])? *[\r\n]+$/
33
- passages[current_passage = $1.strip] = { tags: ($3 || '').split(' '), content: '', exclude_from_output: false, pid: nil}
34
- elsif current_passage
35
- passages[current_passage][:content] << line
36
- end
37
- end
38
- passages.each_key{|k| passages[k][:content].strip!} # Strip excessive trailing whitespace
39
- # Run each passage through a preprocessor, if required
40
- passages.each_key do |k|
41
- # HAML
42
- if passages[k][:tags].include? 'haml'
43
- passages[k][:content] = Haml::Engine.new(passages[k][:content], HAML_OPTIONS).render
44
- passages[k][:tags].delete 'haml'
45
- end
46
- # Coffeescript
47
- if passages[k][:tags].include? 'coffee'
48
- passages[k][:content] = CoffeeScript.compile(passages[k][:content])
49
- passages[k][:tags].delete 'coffee'
50
- end
51
- end
52
- # Extract 'special' passages and mark them as not being included in output
53
- story_name, story_css, story_js, pid, story_start_pid = 'An unnamed story', '', '', 0, 1
54
- passages.each_key do |k|
55
- if k == 'StoryTitle'
56
- story_name = passages[k][:content]
57
- passages[k][:exclude_from_output] = true
58
- elsif %w{StorySubtitle StoryAuthor StoryMenu StorySettings StoryIncludes}.include? k
59
- puts "WARNING: ignoring passage '#{k}'"
60
- passages[k][:exclude_from_output] = true
61
- elsif passages[k][:tags].include? 'stylesheet'
62
- story_css << "#{passages[k][:content]}\n"
63
- passages[k][:exclude_from_output] = true
64
- elsif passages[k][:tags].include? 'script'
65
- story_js << "#{passages[k][:content]}\n"
66
- passages[k][:exclude_from_output] = true
67
- elsif k == 'Start'
68
- passages[k][:pid] = (pid += 1)
69
- story_start_pid = pid
70
- else
71
- passages[k][:pid] = (pid += 1)
72
- end
73
- end
74
- # Generate XML in Twine 2 format
75
- story_data = Builder::XmlMarkup.new
76
- # TODO: what is tw-storydata's "options" attribute for?
77
- story_data.tag!('tw-storydata', { name: story_name, startnode: story_start_pid, creator: 'Twee2', 'creator-version' => Twee2::VERSION, ifid: 'TODO', format: options[:format], options: '' }) do
78
- story_data.style(story_css, role: 'stylesheet', id: 'twine-user-stylesheet', type: 'text/twine-css')
79
- story_data.script(story_js, role: 'script', id: 'twine-user-script', type: 'text/twine-javascript')
80
- passages.each do |k,v|
81
- unless v[:exclude_from_output]
82
- story_data.tag!('tw-passagedata', { pid: v[:pid], name: k, tags: v[:tags].join(' ') }, v[:content])
83
- end
84
- end
85
- end
17
+ story_file = StoryFile::new(input)
86
18
  # Produce output file
87
- result.gsub!('{{STORY_NAME}}', story_name)
88
- result.gsub!('{{STORY_DATA}}', story_data.target!)
89
19
  File::open(output, 'w') do |out|
90
- out.print result
20
+ out.print story_format.compile(story_file)
91
21
  end
92
22
  puts "Done"
93
23
  end
@@ -104,7 +34,7 @@ module Twee2
104
34
 
105
35
  def self.formats
106
36
  puts "I understand the following output formats:"
107
- puts Dir.open(buildpath('storyFormats')).to_a.sort.reject{|d|d=~/^\./}.map{|f|" * #{f}"}.join("\n")
37
+ puts StoryFormat.known_names.join("\n")
108
38
  end
109
39
 
110
40
  def self.help
@@ -0,0 +1,84 @@
1
+ module Twee2
2
+ class StoryFileNotFoundException < Exception; end
3
+
4
+ class StoryFile
5
+ HAML_OPTIONS = {
6
+ remove_whitespace: true
7
+ }
8
+ Tilt::CoffeeScriptTemplate.default_bare = true # bare mode for HAML :coffeescript blocks
9
+ COFFEESCRIPT_OPTIONS = {
10
+ bare: true
11
+ }
12
+
13
+ # Loads the StoryFile with the given name
14
+ def initialize(filename)
15
+ raise(StoryFileNotFoundException) if !File::exists?(filename)
16
+ @passages, current_passage = {}, nil
17
+ File::read(filename).each_line do |line| # REFACTOR: switch this to using regular expressions, why not?
18
+ if line =~ /^:: *([^\[]*?) *(\[(.*?)\])? *[\r\n]+$/
19
+ @passages[current_passage = $1.strip] = { tags: ($3 || '').split(' '), content: '', exclude_from_output: false, pid: nil}
20
+ elsif current_passage
21
+ @passages[current_passage][:content] << line
22
+ end
23
+ end
24
+ @passages.each_key{|k| @passages[k][:content].strip!} # Strip excessive trailing whitespace
25
+ # Run each passage through a preprocessor, if required
26
+ @passages.each_key do |k|
27
+ # HAML
28
+ if @passages[k][:tags].include? 'haml'
29
+ @passages[k][:content] = Haml::Engine.new(@passages[k][:content], HAML_OPTIONS).render
30
+ @passages[k][:tags].delete 'haml'
31
+ end
32
+ # Coffeescript
33
+ if @passages[k][:tags].include? 'coffee'
34
+ @passages[k][:content] = CoffeeScript.compile(@passages[k][:content], COFFEESCRIPT_OPTIONS)
35
+ @passages[k][:tags].delete 'coffee'
36
+ end
37
+ end
38
+ # Extract 'special' passages and mark them as not being included in output
39
+ @story_name, story_css, story_js, pid, story_start_pid = 'An unnamed story', '', '', 0, 1
40
+ @passages.each_key do |k|
41
+ if k == 'StoryTitle'
42
+ @story_name = @passages[k][:content]
43
+ @passages[k][:exclude_from_output] = true
44
+ elsif %w{StorySubtitle StoryAuthor StoryMenu StorySettings StoryIncludes}.include? k
45
+ puts "WARNING: ignoring passage '#{k}'"
46
+ @passages[k][:exclude_from_output] = true
47
+ elsif @passages[k][:tags].include? 'stylesheet'
48
+ story_css << "#{@passages[k][:content]}\n"
49
+ @passages[k][:exclude_from_output] = true
50
+ elsif @passages[k][:tags].include? 'script'
51
+ story_js << "#{@passages[k][:content]}\n"
52
+ @passages[k][:exclude_from_output] = true
53
+ elsif k == 'Start'
54
+ @passages[k][:pid] = (pid += 1)
55
+ story_start_pid = pid
56
+ else
57
+ @passages[k][:pid] = (pid += 1)
58
+ end
59
+ end
60
+ # Generate XML in Twine 2 format
61
+ @story_data = Builder::XmlMarkup.new
62
+ # TODO: what is tw-storydata's "options" attribute for?
63
+ @story_data.tag!('tw-storydata', { name: @story_name, startnode: story_start_pid, creator: 'Twee2', 'creator-version' => Twee2::VERSION, ifid: 'TODO', format: '{{STORY_FORMAT}}', options: '' }) do
64
+ @story_data.style(story_css, role: 'stylesheet', id: 'twine-user-stylesheet', type: 'text/twine-css')
65
+ @story_data.script(story_js, role: 'script', id: 'twine-user-script', type: 'text/twine-javascript')
66
+ @passages.each do |k,v|
67
+ unless v[:exclude_from_output]
68
+ @story_data.tag!('tw-passagedata', { pid: v[:pid], name: k, tags: v[:tags].join(' ') }, v[:content])
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ # Returns the title of this story
75
+ def title
76
+ @story_name
77
+ end
78
+
79
+ # Returns the rendered XML that represents this story
80
+ def xmldata
81
+ @story_data.target!
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,25 @@
1
+ module Twee2
2
+ class StoryFormatNotFoundException < Exception; end
3
+
4
+ class StoryFormat
5
+ # Loads the StoryFormat with the specified name
6
+ def initialize(name)
7
+ raise(StoryFormatNotFoundException) if !File::exists?(format_file_path = Twee2::buildpath("storyFormats/#{name}/format.js"))
8
+ @name = name
9
+ format_file = File::read(format_file_path)
10
+ format_data = format_file.match(/(["'])source\1 *: *(["']).*?[^\\]\2/)[0]
11
+ format_data_for_json = "\{#{format_data}\}"
12
+ @source = JSON.parse(format_data_for_json)['source']
13
+ end
14
+
15
+ # Given a story file, injects it into the StoryFormat and returns the HTML results
16
+ def compile(story_file)
17
+ @source.gsub('{{STORY_NAME}}', story_file.title).gsub('{{STORY_DATA}}', story_file.xmldata).gsub('{{STORY_FORMAT}}', @name)
18
+ end
19
+
20
+ # Returns an array containing the known StoryFormat names
21
+ def self.known_names
22
+ Dir.open(Twee2::buildpath('storyFormats')).to_a.sort.reject{|d|d=~/^\./}.map{|f|" * #{f}"}
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Twee2
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -25,10 +25,16 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.required_ruby_version = '~> 2'
27
27
 
28
- spec.add_development_dependency "bundler", "~> 1.6"
29
- spec.add_development_dependency "rake", '~> 10'
28
+ spec.add_development_dependency 'rake', '~> 10'
30
29
 
31
30
  spec.add_runtime_dependency 'builder', '~> 3.2', '>= 3.2.2'
31
+ spec.add_runtime_dependency 'bundler', '~> 1.6'
32
+ spec.add_runtime_dependency 'coffee-script', '~> 2.4', '>= 2.4.1'
33
+ spec.add_runtime_dependency 'coffee-script-source', '~> 1.9', '>= 1.9.1.1'
34
+ spec.add_runtime_dependency 'execjs', '~> 2.6', '>= 2.6.0'
32
35
  spec.add_runtime_dependency 'filewatcher', '~> 0.5', '>= 0.5.2'
36
+ spec.add_runtime_dependency 'haml', '~> 4.0', '>= 4.0.7'
33
37
  spec.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
38
+ spec.add_runtime_dependency 'tilt', '~> 2.0', '>= 2.0.1'
39
+ spec.add_runtime_dependency 'trollop', '~> 2.1', '>= 2.1.2'
34
40
  end
metadata CHANGED
@@ -1,15 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twee2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Q
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-20 00:00:00.000000000 Z
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 3.2.2
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '3.2'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 3.2.2
13
47
  - !ruby/object:Gem::Dependency
14
48
  name: bundler
15
49
  requirement: !ruby/object:Gem::Requirement
@@ -17,7 +51,7 @@ dependencies:
17
51
  - - "~>"
18
52
  - !ruby/object:Gem::Version
19
53
  version: '1.6'
20
- type: :development
54
+ type: :runtime
21
55
  prerelease: false
22
56
  version_requirements: !ruby/object:Gem::Requirement
23
57
  requirements:
@@ -25,39 +59,65 @@ dependencies:
25
59
  - !ruby/object:Gem::Version
26
60
  version: '1.6'
27
61
  - !ruby/object:Gem::Dependency
28
- name: rake
62
+ name: coffee-script
29
63
  requirement: !ruby/object:Gem::Requirement
30
64
  requirements:
31
65
  - - "~>"
32
66
  - !ruby/object:Gem::Version
33
- version: '10'
34
- type: :development
67
+ version: '2.4'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 2.4.1
71
+ type: :runtime
35
72
  prerelease: false
36
73
  version_requirements: !ruby/object:Gem::Requirement
37
74
  requirements:
38
75
  - - "~>"
39
76
  - !ruby/object:Gem::Version
40
- version: '10'
77
+ version: '2.4'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.4.1
41
81
  - !ruby/object:Gem::Dependency
42
- name: builder
82
+ name: coffee-script-source
43
83
  requirement: !ruby/object:Gem::Requirement
44
84
  requirements:
45
85
  - - "~>"
46
86
  - !ruby/object:Gem::Version
47
- version: '3.2'
87
+ version: '1.9'
48
88
  - - ">="
49
89
  - !ruby/object:Gem::Version
50
- version: 3.2.2
90
+ version: 1.9.1.1
51
91
  type: :runtime
52
92
  prerelease: false
53
93
  version_requirements: !ruby/object:Gem::Requirement
54
94
  requirements:
55
95
  - - "~>"
56
96
  - !ruby/object:Gem::Version
57
- version: '3.2'
97
+ version: '1.9'
58
98
  - - ">="
59
99
  - !ruby/object:Gem::Version
60
- version: 3.2.2
100
+ version: 1.9.1.1
101
+ - !ruby/object:Gem::Dependency
102
+ name: execjs
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '2.6'
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 2.6.0
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.6'
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 2.6.0
61
121
  - !ruby/object:Gem::Dependency
62
122
  name: filewatcher
63
123
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +138,26 @@ dependencies:
78
138
  - - ">="
79
139
  - !ruby/object:Gem::Version
80
140
  version: 0.5.2
141
+ - !ruby/object:Gem::Dependency
142
+ name: haml
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: '4.0'
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: 4.0.7
151
+ type: :runtime
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '4.0'
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 4.0.7
81
161
  - !ruby/object:Gem::Dependency
82
162
  name: thor
83
163
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +178,46 @@ dependencies:
98
178
  - - ">="
99
179
  - !ruby/object:Gem::Version
100
180
  version: 0.19.1
181
+ - !ruby/object:Gem::Dependency
182
+ name: tilt
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '2.0'
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: 2.0.1
191
+ type: :runtime
192
+ prerelease: false
193
+ version_requirements: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: '2.0'
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: 2.0.1
201
+ - !ruby/object:Gem::Dependency
202
+ name: trollop
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '2.1'
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ version: 2.1.2
211
+ type: :runtime
212
+ prerelease: false
213
+ version_requirements: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - "~>"
216
+ - !ruby/object:Gem::Version
217
+ version: '2.1'
218
+ - - ">="
219
+ - !ruby/object:Gem::Version
220
+ version: 2.1.2
101
221
  description: |2
102
222
  Designed for those who preferred the Twee (for Twine 1) approach to source management, because the command-line is awesome,
103
223
  but who want to take advantage of the new features in Twine 2.
@@ -118,6 +238,8 @@ files:
118
238
  - bin/twee2
119
239
  - doc/usage.txt
120
240
  - lib/twee2.rb
241
+ - lib/twee2/story_file.rb
242
+ - lib/twee2/story_format.rb
121
243
  - lib/twee2/version.rb
122
244
  - storyFormats/Harlowe/format.js
123
245
  - storyFormats/Harlowe/icon.svg