twee2 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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