task default: %w(develop) STORY_DIR=File.join(ENV['USERPROFILE'], 'Documents\\Twine\\Stories') STORY_TITLE = 'Volleyball' STORY_FORMAT = 'SugarCube' STORY_FORMAT_PATH = "story_formats/sugarcube-2.28.2-for-twine-2.1-local/sugarcube-2" STORY_FORMAT_VERSION = '2.28.2' FILES = { '01_intro' => '01 Intro', '02_transform' => '02 Transform', '03_custom_girl' => '03 Custom Girl', '04_money_game' => '04 Money Games', '05_beaches' => '05 Beaches', } def files FILES.map do |short_name, long_name| OpenStruct.new({ short_name: short_name, long_name: long_name, source_file: "story/#{short_name}.tw2", dest_file: File.join(STORY_DIR, "#{STORY_TITLE} - #{long_name}.html"), wrapper_file: "#{short_name}_wrapper.tw2", }) end end task develop: %w(bundle_install) do sh "bundle exec twee2 build '--format=#{STORY_FORMAT_PATH}' main.tw2 develop.html" end task watch: %w(bundle_install) do sh 'start watch.html' # FIXME non-windows sh "bundle exec twee2 watch main.tw2 watch.html" end task release: %w(bundle_install) do sh "bundle exec twee2 build main.tw2 release.html" end desc 'export sub files to Twine 2' task export: %w(bundle_install) do files.each do |file| IO.write file.wrapper_file, <<~EOF ::StoryTitle Volleyball - #{file.long_name} ::Twee2Settings [twee2] @story_start_name = 'Start #{file.long_name}' Twee2::build_config.story_format = '#{STORY_FORMAT}' Twee2::build_config.story_format_version = '#{STORY_FORMAT_VERSION}' ::StoryIncludes images.tw2 stylesheet.tw2 storyjs.tw2 #{file.source_file} EOF sh( 'bundle', 'exec', 'twee2', 'export', "--format=#{STORY_FORMAT}", "--format-version=#{STORY_FORMAT_VERSION}", file.wrapper_file, file.dest_file, ) end sh( 'bundle', 'exec', 'twee2', 'export', "--format=#{STORY_FORMAT}", "--format-version=#{STORY_FORMAT_VERSION}", 'main.tw2', STORY_DIR, ) end desc 'import sub files from Twine 2' task import: %w(bundle_install) do files.each do |file| sh( 'bundle', 'exec', 'twee2', 'decompile', file.dest_file, file.source_file, '--exclude=StoryJS,StoryCSS,StoryTitle', '--exclude-from=../stylesheet.tw2,../storyjs.tw2,../stylesheet.tw2,../images.tw2', ) end end task :bundle_install do sh 'bundle check || bundle install' end task :clean do # TODO end task :lint do files.each do |file| twee_source = IO.read(file.source_file) twee_source.lines.each_with_index do |line, lineno| lineno += 1 line .scan(%r{\[\[([^\]]*)\]\]}) .map { |x| x[0] } .each do |link| case link.scan('->').length when 0 #link contains no ->, probably not a problem text = link when 1 # no problem text, dest = link.split('->') else warn("link contains multiple -> definitely a problem") next end if text.start_with?('\'') if !text.end_with?('\'') warn "#{file.source_file}:#{lineno} link text (#{text.inspect}) does not end with single quote despite starting with one" next end text = text[1..-2] text .to_enum(:scan, '\'') .map {Regexp.last_match.offset(0)[0]} .each do |offset| if text[offset - 1] != '\\' warn "#{file.source_file}:#{lineno} link text (#{text.inspect}) contains unquoted single quote in body" end end elsif text.start_with?('"') if !text.end_with?('"') warn "#{file.source_file}:#{lineno} link text (#{text.inspect}) does not end with double quote despite starting with one" next end text = text[1..-2] text .to_enum(:scan, '"') .map {Regexp.last_match.offset(0)[0]} .each do |offset| if text[offset - 1] != '\\' warn "#{file.source_file}:#{lineno} link text (#{text.inspect}) contains unquoted double quote in body" end end elsif text =~ /\A[\[\]'"\\]*\z/ warn "#{file.source_file}:#{lineno} link text (#{text.inspect}) contains special characters but is not quoted with single or double quotes" end end end end end