review 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -0
  4. data/ChangeLog +87 -0
  5. data/bin/review-check +2 -2
  6. data/bin/review-compile +15 -30
  7. data/bin/review-index +1 -1
  8. data/bin/review-init +12 -7
  9. data/bin/review-vol +9 -1
  10. data/doc/catalog.ja.md +53 -0
  11. data/doc/catalog.md +52 -0
  12. data/doc/format.ja.md +734 -0
  13. data/doc/format.md +746 -0
  14. data/doc/format_idg.ja.md +203 -0
  15. data/doc/{quickstart.rdoc → quickstart.ja.md} +138 -104
  16. data/doc/quickstart.md +252 -0
  17. data/doc/sample.yml +216 -48
  18. data/lib/epubmaker.rb +0 -1
  19. data/lib/epubmaker/content.rb +2 -2
  20. data/lib/epubmaker/epubcommon.rb +440 -0
  21. data/lib/epubmaker/epubv2.rb +8 -418
  22. data/lib/epubmaker/epubv3.rb +67 -61
  23. data/lib/epubmaker/producer.rb +60 -19
  24. data/lib/review/book.rb +1 -3
  25. data/lib/review/book/base.rb +18 -11
  26. data/lib/review/book/chapter.rb +5 -24
  27. data/lib/review/book/compilable.rb +5 -1
  28. data/lib/review/book/index.rb +48 -17
  29. data/lib/review/book/page_metric.rb +17 -8
  30. data/lib/review/book/part.rb +12 -2
  31. data/lib/review/book/volume.rb +3 -2
  32. data/lib/review/builder.rb +30 -10
  33. data/lib/review/compiler.rb +6 -4
  34. data/lib/review/configure.rb +3 -3
  35. data/lib/review/epubmaker.rb +56 -26
  36. data/lib/review/htmlbuilder.rb +33 -42
  37. data/lib/review/htmlutils.rb +12 -7
  38. data/lib/review/i18n.rb +77 -17
  39. data/lib/review/i18n.yml +80 -4
  40. data/lib/review/idgxmlbuilder.rb +27 -57
  41. data/lib/review/inaobuilder.rb +3 -3
  42. data/lib/review/latexbuilder.rb +90 -67
  43. data/lib/review/layout.tex.erb +54 -7
  44. data/lib/review/markdownbuilder.rb +21 -3
  45. data/lib/review/pdfmaker.rb +67 -38
  46. data/lib/review/sec_counter.rb +1 -1
  47. data/lib/review/tocparser.rb +9 -5
  48. data/lib/review/topbuilder.rb +6 -6
  49. data/lib/review/version.rb +1 -1
  50. data/review.gemspec +3 -1
  51. data/test/book_test_helper.rb +1 -1
  52. data/test/sample-book/README.md +2 -0
  53. data/test/sample-book/src/Rakefile +31 -0
  54. data/test/sample-book/src/_cover.html +0 -0
  55. data/test/sample-book/src/catalog.yml +10 -0
  56. data/test/sample-book/src/ch01.re +0 -0
  57. data/test/sample-book/src/ch02.re +0 -0
  58. data/test/sample-book/src/config.yml +160 -32
  59. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  60. data/test/sample-book/src/images/cover.jpg +0 -0
  61. data/test/sample-book/src/preface.re +0 -0
  62. data/test/sample-book/src/sty/jumoline.sty +0 -0
  63. data/test/sample-book/src/sty/reviewmacro.sty +18 -0
  64. data/test/sample-book/src/style.css +0 -0
  65. data/test/test_book.rb +25 -27
  66. data/test/test_book_chapter.rb +4 -73
  67. data/test/test_book_part.rb +5 -4
  68. data/test/test_builder.rb +3 -3
  69. data/test/test_epub3maker.rb +527 -0
  70. data/test/test_epubmaker.rb +6 -6
  71. data/test/test_htmlbuilder.rb +143 -6
  72. data/test/test_i18n.rb +95 -10
  73. data/test/test_idgxmlbuilder.rb +28 -2
  74. data/test/test_index.rb +109 -1
  75. data/test/test_latexbuilder.rb +51 -0
  76. data/test/test_markdownbuilder.rb +54 -1
  77. data/test/test_pdfmaker.rb +7 -6
  78. data/test/test_review_ext.rb +31 -0
  79. data/test/test_topbuilder.rb +3 -1
  80. metadata +46 -13
  81. data/doc/catalog.rdoc +0 -49
  82. data/doc/format.rdoc +0 -618
  83. data/doc/format_idg.rdoc +0 -180
  84. data/doc/libepubmaker/config.yml +0 -207
  85. data/lib/epubmaker/resource.rb +0 -82
  86. data/test/sample-book/src/CHAPS +0 -2
  87. data/test/sample-book/src/PREDEF +0 -1
@@ -13,7 +13,6 @@ require 'review/builder'
13
13
  require 'review/htmlutils'
14
14
  require 'review/htmllayout'
15
15
  require 'review/textutils'
16
- require 'review/sec_counter'
17
16
 
18
17
  module ReVIEW
19
18
 
@@ -48,7 +47,6 @@ module ReVIEW
48
47
 
49
48
  def builder_init(no_error = false)
50
49
  @no_error = no_error
51
- @column = 0
52
50
  @noindent = nil
53
51
  @ol_num = nil
54
52
  end
@@ -58,6 +56,7 @@ module ReVIEW
58
56
  @warns = []
59
57
  @errors = []
60
58
  @chapter.book.image_types = %w( .png .jpg .jpeg .gif .svg )
59
+ @column = 0
61
60
  @sec_counter = SecCounter.new(5, @chapter)
62
61
  end
63
62
  private :builder_init_file
@@ -192,14 +191,6 @@ EOT
192
191
  "</ul>\n"
193
192
  end
194
193
 
195
- def headline_prefix(level)
196
- @sec_counter.inc(level)
197
- anchor = @sec_counter.anchor(level)
198
- prefix = @sec_counter.prefix(level, @book.config["secnolevel"])
199
- [prefix, anchor]
200
- end
201
- private :headline_prefix
202
-
203
194
  def headline(level, label, caption)
204
195
  prefix, anchor = headline_prefix(level)
205
196
  puts '' if level > 1
@@ -434,18 +425,18 @@ EOT
434
425
 
435
426
  alias_method :lead, :read
436
427
 
437
- def list(lines, id, caption)
428
+ def list(lines, id, caption, lang = nil)
438
429
  puts %Q[<div class="caption-code">]
439
430
  begin
440
- list_header id, caption
431
+ list_header id, caption, lang
441
432
  rescue KeyError
442
433
  error "no such list: #{id}"
443
434
  end
444
- list_body id, lines
435
+ list_body id, lines, lang
445
436
  puts '</div>'
446
437
  end
447
438
 
448
- def list_header(id, caption)
439
+ def list_header(id, caption, lang)
449
440
  if get_chap.nil?
450
441
  puts %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}</p>]
451
442
  else
@@ -453,11 +444,11 @@ EOT
453
444
  end
454
445
  end
455
446
 
456
- def list_body(id, lines)
447
+ def list_body(id, lines, lang)
457
448
  id ||= ''
458
449
  print %Q[<pre class="list">]
459
450
  body = lines.inject(''){|i, j| i + detab(j) + "\n"}
460
- lexer = File.extname(id).gsub(/\./, '')
451
+ lexer = lang || File.extname(id).gsub(/\./, '')
461
452
  puts highlight(:body => body, :lexer => lexer, :format => 'html')
462
453
  puts '</pre>'
463
454
  end
@@ -484,48 +475,46 @@ EOT
484
475
  puts '</pre>'
485
476
  end
486
477
 
487
- def listnum(lines, id, caption)
478
+ def listnum(lines, id, caption, lang = nil)
488
479
  puts %Q[<div class="code">]
489
480
  begin
490
- list_header id, caption
481
+ list_header id, caption, lang
491
482
  rescue KeyError
492
483
  error "no such list: #{id}"
493
484
  end
494
- listnum_body lines
485
+ listnum_body lines, lang
495
486
  puts '</div>'
496
487
  end
497
488
 
498
- def listnum_body(lines)
499
- print %Q[<pre class="list">]
500
- lines.each_with_index do |line, i|
501
- puts detab((i+1).to_s.rjust(2) + ": " + line)
502
- end
503
- puts '</pre>'
489
+ def listnum_body(lines, lang)
490
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
491
+ lexer = lang
492
+ puts highlight(:body => body, :lexer => lexer, :format => 'html',
493
+ :options => {:linenos => 'inline', :nowrap => false})
504
494
  end
505
495
 
506
- def emlist(lines, caption = nil)
496
+ def emlist(lines, caption = nil, lang = nil)
507
497
  puts %Q[<div class="emlist-code">]
508
498
  if caption.present?
509
499
  puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
510
500
  end
511
501
  print %Q[<pre class="emlist">]
512
- lines.each do |line|
513
- puts detab(line)
514
- end
502
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
503
+ lexer = lang
504
+ puts highlight(:body => body, :lexer => lexer, :format => 'html')
515
505
  puts '</pre>'
516
506
  puts '</div>'
517
507
  end
518
508
 
519
- def emlistnum(lines, caption = nil)
509
+ def emlistnum(lines, caption = nil, lang = nil)
520
510
  puts %Q[<div class="emlistnum-code">]
521
511
  if caption.present?
522
512
  puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
523
513
  end
524
- print %Q[<pre class="emlist">]
525
- lines.each_with_index do |line, i|
526
- puts detab((i+1).to_s.rjust(2) + ": " + line)
527
- end
528
- puts '</pre>'
514
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
515
+ lexer = lang
516
+ puts highlight(:body => body, :lexer => lexer, :format => 'html',
517
+ :options => {:linenos => 'inline', :nowrap => false})
529
518
  puts '</div>'
530
519
  end
531
520
 
@@ -535,9 +524,9 @@ EOT
535
524
  puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
536
525
  end
537
526
  print %Q[<pre class="cmd">]
538
- lines.each do |line|
539
- puts detab(line)
540
- end
527
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
528
+ lexer = 'shell-session'
529
+ puts highlight(:body => body, :lexer => lexer, :format => 'html')
541
530
  puts '</pre>'
542
531
  puts '</div>'
543
532
  end
@@ -594,6 +583,8 @@ QUOTE
594
583
  def texequation(lines)
595
584
  puts %Q[<div class="equation">]
596
585
  if @book.config["mathml"]
586
+ require 'math_ml'
587
+ require 'math_ml/symbol/character_reference'
597
588
  p = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
598
589
  puts p.parse(unescape_html(lines.join("\n")), true)
599
590
  else
@@ -787,7 +778,7 @@ QUOTE
787
778
  end
788
779
 
789
780
  def inline_labelref(idref)
790
- %Q[<a target='#{escape_html(idref)}'>「●● #{escape_html(idref)}」</a>]
781
+ %Q[<a target='#{escape_html(idref)}'>「#{I18n.t("label_marker")}#{escape_html(idref)}」</a>]
791
782
  end
792
783
 
793
784
  alias_method :inline_ref, :inline_labelref
@@ -806,9 +797,9 @@ QUOTE
806
797
 
807
798
  def inline_chap(id)
808
799
  if @book.config["chapterlink"]
809
- %Q(<a href="./#{id}#{extname}">#{@chapter.env.chapter_index.number(id)}</a>)
800
+ %Q(<a href="./#{id}#{extname}">#{@book.chapter_index.number(id)}</a>)
810
801
  else
811
- @chapter.env.chapter_index.number(id)
802
+ @book.chapter_index.number(id)
812
803
  end
813
804
  rescue KeyError
814
805
  error "unknown chapter: #{id}"
@@ -973,7 +964,7 @@ QUOTE
973
964
  if @book.config["chapterlink"]
974
965
  %Q(<a href="\##{column_label(id)}" class="columnref">#{I18n.t("column", escape_html(@chapter.column(id).caption))}</a>)
975
966
  else
976
- escape_html(@chapter.column(id).caption)
967
+ I18n.t("column", escape_html(@chapter.column(id).caption))
977
968
  end
978
969
  rescue KeyError
979
970
  error "unknown column: #{id}"
@@ -40,22 +40,27 @@ module ReVIEW
40
40
  str.gsub('-', '&#45;')
41
41
  end
42
42
 
43
+ def highlight_pygments?
44
+ @book.config["pygments"].present? ||
45
+ @book.config["highlight"] && @book.config["highlight"]["html"] == "pygments"
46
+ end
47
+
43
48
  def highlight(ops)
44
49
  body = ops[:body] || ''
45
- lexer = ops[:lexer] || ''
50
+ lexer = ops[:lexer].blank? ? 'text' : ops[:lexer]
46
51
  format = ops[:format] || ''
47
-
48
- return body if @book.config["pygments"].nil?
52
+ options = {:nowrap => true, :noclasses => true}
53
+ if ops[:options] && ops[:options].kind_of?(Hash)
54
+ options.merge!(ops[:options])
55
+ end
56
+ return body if !highlight_pygments?
49
57
 
50
58
  begin
51
59
  require 'pygments'
52
60
  begin
53
61
  Pygments.highlight(
54
62
  unescape_html(body),
55
- :options => {
56
- :nowrap => true,
57
- :noclasses => true
58
- },
63
+ :options => options,
59
64
  :formatter => format,
60
65
  :lexer => lexer)
61
66
  rescue MentosError
data/lib/review/i18n.rb CHANGED
@@ -3,31 +3,91 @@ require 'yaml'
3
3
 
4
4
  module ReVIEW
5
5
  class I18n
6
- def self.setup
7
- lfile = File.expand_path "locale.yml", Dir.pwd
8
- # backward compatibility
9
- lfile = File.expand_path "locale.yaml", Dir.pwd unless File.exist?(lfile)
10
- user_i18n = YAML.load_file(lfile)
11
- I18n.i18n user_i18n["locale"], user_i18n
12
- rescue
13
- I18n.i18n "ja"
6
+ def self.setup(locale="ja", ymlfile = "locale.yml")
7
+ @i18n = ReVIEW::I18n.new(locale)
8
+
9
+ lfile = nil
10
+ if ymlfile
11
+ lfile = File.expand_path(ymlfile, Dir.pwd)
12
+
13
+ # backward compatibility
14
+ if !File.exist?(lfile) && (ymlfile == "locale.yml")
15
+ lfile = File.expand_path("locale.yaml", Dir.pwd)
16
+ end
17
+ end
18
+
19
+ if lfile && File.file?(lfile)
20
+ @i18n.update_localefile(lfile)
21
+ end
22
+ end
23
+
24
+ def self.i18n(*args)
25
+ raise NotImplementedError, "I18n.i18n is obsoleted. Please use I18n.setup(locale, [ymlfile])"
14
26
  end
15
27
 
16
- def self.i18n(locale, user_i18n = {})
17
- locale ||= "ja"
18
- i18n_yaml_path = File.expand_path "i18n.yml", File.dirname(__FILE__)
19
- @i18n = YAML.load_file(i18n_yaml_path)[locale]
28
+ def self.t(str, args = nil)
29
+ @i18n.t(str, args)
30
+ end
31
+
32
+ def self.locale=(locale)
20
33
  if @i18n
21
- @i18n.merge!(user_i18n)
34
+ @i18n.locale = locale
35
+ else
36
+ I18n.setup(locale)
22
37
  end
23
38
  end
24
39
 
25
- def self.t(str, args = nil)
26
- @i18n[str] % args
40
+ class << self
41
+ alias v t ## for EPUBMaker backward compatibility
42
+ end
43
+
44
+ def self.update(user_i18n, locale = nil)
45
+ @i18n.update(user_i18n, locale)
46
+ end
47
+
48
+ attr_accessor :locale
49
+
50
+ def initialize(locale = nil)
51
+ @locale = locale
52
+ load_default
53
+ end
54
+
55
+ def load_default
56
+ load_file(File.expand_path "i18n.yml", File.dirname(__FILE__))
57
+ end
58
+
59
+ def load_file(path)
60
+ @store = YAML.load_file(path)
61
+ end
62
+
63
+ def update_localefile(path)
64
+ user_i18n = YAML.load_file(path)
65
+ locale = user_i18n["locale"]
66
+ if locale
67
+ user_i18n.delete("locale")
68
+ @store[locale].merge!(user_i18n)
69
+ else
70
+ key = user_i18n.keys.first
71
+ if !user_i18n[key].kind_of? Hash
72
+ raise KeyError, "Invalid locale file: #{path}"
73
+ end
74
+ @store.merge!(user_i18n)
75
+ end
76
+ end
77
+
78
+ def update(user_i18n, locale = nil)
79
+ locale ||= @locale
80
+ if @store[locale]
81
+ @store[locale].merge!(user_i18n)
82
+ else
83
+ @store[locale] = user_i18n
84
+ end
85
+ end
86
+
87
+ def t(str, args = nil)
88
+ @store[@locale][str] % args
27
89
  rescue
28
90
  str
29
91
  end
30
92
  end
31
-
32
- I18n.setup
33
93
  end
data/lib/review/i18n.yml CHANGED
@@ -3,19 +3,25 @@ ja:
3
3
  table: 表
4
4
  list: リスト
5
5
  column: "コラム「%s」"
6
+ columnname: "コラム"
7
+ column_head: "■コラム"
6
8
  part: 第%d部
7
9
  chapter: 第%d章
8
10
  chapter_postfix: " "
11
+ chapter_quote: "「%s」"
9
12
  appendix: 付録%s
10
13
  numberless_image: "図:"
14
+ memo_head: ■メモ
11
15
  format_number: "%s.%d"
12
16
  format_number_header: "%s.%d:"
13
17
  format_number_without_chapter: "%d"
14
18
  format_number_header_without_chapter: "%d:"
19
+ image_quote: "「%s」"
15
20
  caption_prefix: " "
16
21
  caption_prefix_idgxml: " "
17
22
  ruby_prefix: "("
18
23
  ruby_postfix: ")"
24
+ label_marker: "●● "
19
25
  aut: "著 者"
20
26
  csl: "監 修"
21
27
  dsr: "デザイン"
@@ -28,39 +34,87 @@ ja:
28
34
  prt: "発行所"
29
35
  pbl: "発行所"
30
36
  contact: "連絡先"
31
- author_postfix: " 著"
32
- supervisor_postfix: " 監修"
33
- translator_postfix: " 訳"
37
+ author_with_label: "%s 著"
38
+ supervisor_with_label: "%s 監修"
39
+ translator_with_label: "%s 訳"
34
40
  names_splitter: "、"
41
+ edition: "版"
42
+ nth_edition: "第%s版"
43
+ first_edition: "初版"
44
+ nth_impression: "第%s刷"
45
+ published_by: "%s 発行"
46
+ published_by1: "%s %s 発行"
47
+ published_by2: "%s 発行"
48
+ published_by3: "%s %s"
49
+ date_format: '%%Y年%%-m月%%-d日'
50
+ toctitle: "目次"
51
+ covertitle: "表紙"
52
+ titlepagetitle: "大扉"
53
+ originaltitle: "原書大扉"
54
+ credittitle: "クレジット"
55
+ colophontitle: "奥付"
56
+ advtitle: "広告"
57
+ profiletitle: "著者紹介"
58
+ backcovertitle: "裏表紙"
35
59
 
36
60
  en:
37
61
  image: "Figure "
38
62
  table: "Table "
39
63
  list: "List "
40
64
  column: "Column %s"
65
+ columnname: "Column"
66
+ column_head: "Column"
67
+ part: "Part %s"
41
68
  chapter: Chapter %d
42
69
  chapter_postfix: ". "
70
+ chapter_quote: '"%s"'
43
71
  appendix: Appendix %s
44
72
  numberless_image: "Figure:"
73
+ memo_head: Note
45
74
  format_number: "%s.%d"
46
75
  format_number_header: "%s.%d:"
47
76
  format_number_without_chapter: "%d"
48
77
  format_number_header_without_chapter: "%d:"
78
+ image_quote: '"%s"'
49
79
  caption_prefix: " "
50
80
  caption_prefix_idgxml: " "
51
81
  ruby_prefix: "("
52
82
  ruby_postfix: ")"
83
+ label_marker: "●● "
53
84
  aut: "Author"
54
85
  csl: "Consultant"
55
86
  dsr: "Design"
56
87
  ill: "Illustrator"
88
+ cov: "Cover"
57
89
  edt: "Editor"
58
- pht: "Photographer"
90
+ pht: "Director of Photography"
59
91
  trl: "Translator"
60
92
  prt: "Printer"
61
93
  pbl: "Publisher"
62
94
  contact: "Contact"
95
+ author_with_label: "Author: %s"
96
+ supervisor_with_label: "Supervisor: %s"
97
+ translator_with_label: "Translator: %s"
63
98
  names_splitter: ", "
99
+ edition: "edition"
100
+ impression: "impression"
101
+ nth_edition: "%s edition"
102
+ first_edition: "first edition"
103
+ nth_impression: "%s impression"
104
+ published_by: "%s"
105
+ published_by1: "published by %s %s"
106
+ published_by2: "published by %s"
107
+ published_by3: "%s %s"
108
+ date_format: '%%b. %%e, %%Y'
109
+ toctitle: "Table of Contents"
110
+ covertitle: "Cover"
111
+ titlepagetitle: "Title Page"
112
+ originaltitle: "Title Page of Original"
113
+ credittitle: "Credit"
114
+ colophontitle: "Colophon"
115
+ advtitle: "Advertisement"
116
+ profiletitle: "Profile"
117
+ backcovertitle: "Back Cover"
64
118
 
65
119
  zh_TW:
66
120
  image: 圖
@@ -69,14 +123,36 @@ zh_TW:
69
123
  part: 第%d部份
70
124
  chapter: 第%d章
71
125
  chapter_postfix: " "
126
+ chapter_quote: "「%s」"
72
127
  appendix: 附錄%s
73
128
  numberless_image: "圖:"
74
129
  format_number: "%s.%d"
75
130
  format_number_header: "%s.%d:"
76
131
  format_number_without_chapter: "%d"
77
132
  format_number_header_without_chapter: "%d:"
133
+ image_quote: '"%s"'
78
134
  caption_prefix: " "
79
135
  caption_prefix_idgxml: " "
80
136
  ruby_prefix: "("
81
137
  ruby_postfix: ")"
138
+ label_marker: "●● "
139
+ aut: "著作人"
140
+ csl: "監 修"
141
+ dsr: "美術編輯"
142
+ cov: "封面設計"
143
+ edt: "編 輯"
144
+ pht: "攝 影"
145
+ trl: "翻 譯"
146
+ prt: "印刷所"
147
+ pbl: "發行所"
148
+ contact: "联系方式"
149
+ author_with_label: "%s 著"
150
+ supervisor_with_label: "%s 監修"
151
+ translator_with_label: "%s 譯"
82
152
  names_splitter: ", "
153
+ edition: "版"
154
+ published_by: "%s 出版"
155
+ published_by1: "%s %s 出版"
156
+ published_by2: "%s 出版"
157
+ published_by3: "%s %s"
158
+ impression: "刷"