|
| 1 | +#!/usr/bin/env ruby |
| 2 | +# -*- coding: utf-8 -*- vim:set encoding=utf-8: |
| 3 | +# TODO: |
| 4 | +# - cleanup (and remove dependency with rhg_html_gen) |
| 5 | +# - images |
| 6 | +# - when generating the output data, if Japanese = English, add in the English something like "(To translate)" |
| 7 | +$KCODE = 'u' |
| 8 | + |
| 9 | +ISOLanguage = 'en-US' |
| 10 | + |
| 11 | +$LOAD_PATH.unshift('../lib') |
| 12 | +require 'rhg_html_gen' |
| 13 | + |
| 14 | +COMMENT_RE = /\$comment\((.+?)\)\$/ |
| 15 | +AUTOLINK_RE = %r{(^|[^:])\b((?:ht|f)tp://\S+?)([^\w\/;]*?)(?=\s|<|$)} |
| 16 | +NEW_CODE_RE = /`([^<]*?)`/m |
| 17 | +TAG_RE = /\$tag\((.+?)\)\$/ |
| 18 | + |
| 19 | +AUTO_CONV_ENDING=<<END |
| 20 | +<hr> |
| 21 | +
|
| 22 | +御意見・御感想・誤殖の指摘などは |
| 23 | + |
| 24 | +までお願いします。 |
| 25 | +
|
| 26 | +"『Rubyソースコード完全解説』 |
| 27 | +はインプレスダイレクトで御予約・御購入いただけます (書籍紹介ページへ飛びます)。":http://direct.ips.co.jp/directsys/go_x_TempChoice.cfm?sh_id=EE0040&spm_id=1&GM_ID=1721 |
| 28 | +
|
| 29 | +Copyright (c) 2002-2004 Minero Aoki, All rights reserved. |
| 30 | +END |
| 31 | + |
| 32 | +TranslatedByRE = /^Translated by (.+)$/ |
| 33 | + |
| 34 | +def rhg_redcloth_replace(text) |
| 35 | + text = text.dup |
| 36 | + if md = TranslatedByRE.match(text) |
| 37 | + $tags['translated by'] = md[1] |
| 38 | + text.sub!(TranslatedByRE, '') |
| 39 | + end |
| 40 | + text.sub!(AUTO_CONV_ENDING, '') # remove the ending in the automatically generated Japanese files |
| 41 | + text.gsub!(COMMENT_RE) { |m| '' } # remove comments |
| 42 | + text.gsub(TAG_RE) do |m| # manages tags |
| 43 | + tag_name = $~[1] |
| 44 | + if $tags[tag_name] |
| 45 | + $tags[tag_name] |
| 46 | + else |
| 47 | + puts "Warning: The tag #{tag_name} is not defined" |
| 48 | + '' |
| 49 | + end |
| 50 | + end |
| 51 | + fig_counter = 0 |
| 52 | + text.gsub!(RedCloth::IMAGE_RE) do |m| # must be done before the `` replacement |
| 53 | + fig_counter += 1 |
| 54 | + stln,algn,atts,url,title,href,href_a1,href_a2 = $~[1..8] |
| 55 | + #puts "Warning: the images used the the RHG should be PNGs, not JPEGs" if /\.jpe?g$/i.match(url) |
| 56 | + "\n\n<p style=\"text-align:center;\">\n#{m.gsub(/`/, '')}<br />Figure #{fig_counter}: #{title}\n</p>\n\n" |
| 57 | + end |
| 58 | + text.gsub!(NEW_CODE_RE) { |m| "<code>#{$~[1]}</code>" } |
| 59 | + text.gsub!(AUTOLINK_RE) do |m| |
| 60 | + before, address, after = $~[1..3] |
| 61 | + "#{before}\"#{address}\":#{address}#{after}" |
| 62 | + end |
| 63 | + text |
| 64 | +end |
| 65 | + |
| 66 | +class Blocks |
| 67 | + def initialize(filename) |
| 68 | + @data = rhg_redcloth_replace(IO.read(filename)).split(/\n/).map { |l| l.rstrip } |
| 69 | + @boundaries = [] |
| 70 | + |
| 71 | + find_boundaries |
| 72 | + end |
| 73 | + |
| 74 | + def length |
| 75 | + @boundaries.length |
| 76 | + end |
| 77 | + |
| 78 | + def [](i) |
| 79 | + @data[@boundaries[i]].join("\n") |
| 80 | + end |
| 81 | + |
| 82 | + def regroup_with_following(i) |
| 83 | + @data[@boundaries[i].last] << "\n<==================================>" |
| 84 | + @boundaries[i] = @boundaries[i].first..@boundaries[i+1].last |
| 85 | + @boundaries.delete_at(i+1) |
| 86 | + end |
| 87 | + |
| 88 | + def each |
| 89 | + length.times { |i| yield self[i] } |
| 90 | + end |
| 91 | + |
| 92 | +private |
| 93 | + def find_boundaries |
| 94 | + beginning = 0 |
| 95 | + in_pre = false |
| 96 | + @data.each_with_index do |line, i| |
| 97 | + if line.empty? and not in_pre |
| 98 | + if i != beginning |
| 99 | + @boundaries.push(beginning..(i-1)) |
| 100 | + beginning = i+1 |
| 101 | + else |
| 102 | + beginning += 1 |
| 103 | + end |
| 104 | + elsif i == @data.length - 1 |
| 105 | + @boundaries.push(beginning..i) |
| 106 | + elsif /<pre/.match(line) |
| 107 | + @boundaries.push(beginning..(i-1)) if i > beginning |
| 108 | + beginning = i |
| 109 | + in_pre = true |
| 110 | + elsif /<\/pre/.match(line) |
| 111 | + @boundaries.push(beginning..i) |
| 112 | + beginning = i+1 |
| 113 | + in_pre = false |
| 114 | + end |
| 115 | + end |
| 116 | + end |
| 117 | +end |
| 118 | + |
| 119 | +chapter_num = sprintf("%02d", ARGV[0].to_i) |
| 120 | + |
| 121 | +en_file_name = "../en/chapter#{chapter_num}.txt" |
| 122 | +ja_file_name = "../ja/chapter#{chapter_num}.txt" |
| 123 | +# if the English file does not exist yet, just use the Japanese one as source |
| 124 | +if File.exists?(en_file_name) |
| 125 | + blocks_en = Blocks.new(en_file_name) |
| 126 | +else |
| 127 | + $tags['translated by'] = '(not translated yet)' |
| 128 | + blocks_en = Blocks.new(ja_file_name) |
| 129 | +end |
| 130 | +blocks_ja = Blocks.new(ja_file_name) |
| 131 | + |
| 132 | +BLOCK_REGROUPING_RE = /^(h[1-9]\.|<pre|▼)/ |
| 133 | + |
| 134 | +i = 0 |
| 135 | +regroup_pos = 0 |
| 136 | +while i < blocks_ja.length and i < blocks_en.length |
| 137 | + block_ja = blocks_ja[i] |
| 138 | + block_en = blocks_en[i] |
| 139 | + if BLOCK_REGROUPING_RE.match(block_ja) |
| 140 | + if BLOCK_REGROUPING_RE.match(block_en) |
| 141 | + regroup_pos = i |
| 142 | + i += 1 |
| 143 | + else |
| 144 | + blocks_en.regroup_with_following(regroup_pos) |
| 145 | + end |
| 146 | + elsif BLOCK_REGROUPING_RE.match(block_en) |
| 147 | + blocks_ja.regroup_with_following(regroup_pos) |
| 148 | + else |
| 149 | + i += 1 |
| 150 | + end |
| 151 | +end |
| 152 | + |
| 153 | +# regroup the last blocks to have the same number of blocks in both |
| 154 | +blocks_en.regroup_with_following(blocks_en.length-2) while blocks_ja.length < blocks_en.length |
| 155 | +blocks_ja.regroup_with_following(blocks_ja.length-2) while blocks_en.length < blocks_ja.length |
| 156 | + |
| 157 | +blocks_en.each do |b| |
| 158 | + if md = /h1\.\s*(.+)$/.match(b) |
| 159 | + $tags['title'] = md[1].gsub(/(<[^>]*>|`)/, '') # remove markup and backquotes from the title |
| 160 | + break |
| 161 | + end |
| 162 | +end |
| 163 | +if not $tags['title'] |
| 164 | + STDERR.puts "error: no h1 section in source file" |
| 165 | + return |
| 166 | +end |
| 167 | + |
| 168 | +File.open("chapter#{chapter_num}.txt", "w") do |f| |
| 169 | + f.puts "<table>" |
| 170 | + blocks_ja.length.times do |i| |
| 171 | + f.puts "<tr><td>" |
| 172 | + f.puts |
| 173 | + f.puts blocks_en[i] |
| 174 | + f.puts |
| 175 | + f.puts "</td><td>" |
| 176 | + f.puts |
| 177 | + f.puts blocks_ja[i] |
| 178 | + f.puts |
| 179 | + f.print "</td></tr>" |
| 180 | + end |
| 181 | + f.puts |
| 182 | + f.puts "</table>" |
| 183 | +end |
| 184 | + |
| 185 | +FOOTER = <<EOS |
| 186 | +<hr> |
| 187 | +
|
| 188 | +The original work is Copyright © 2002 - 2004 Minero AOKI.<br /> |
| 189 | +Translated by #{$tags['translated by']}<br /> |
| 190 | +<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/"><img alt="Creative Commons License" border="0" src="images/somerights20.png"/></a><br/>This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/">Creative Commons Attribution-NonCommercial-ShareAlike2.5 License</a>. |
| 191 | +
|
| 192 | +</body> |
| 193 | +</html> |
| 194 | +EOS |
| 195 | + |
| 196 | +RedClothRules = [ :textile ] |
| 197 | + |
| 198 | +generate_html("chapter#{chapter_num}.html", "chapter#{chapter_num}.txt") |
0 commit comments