review-retrovert 0.3.0 → 0.9.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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/retrovert.yml +39 -0
  3. data/.gitignore +2 -2
  4. data/.ruby-version +1 -0
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +69 -3
  7. data/README.md +6 -3
  8. data/lib/review/retrovert/cli.rb +4 -0
  9. data/lib/review/retrovert/converter.rb +337 -10
  10. data/lib/review/retrovert/version.rb +1 -1
  11. data/review-retrovert.gemspec +1 -1
  12. data/testdata/mybook/.gitignore +7 -0
  13. data/testdata/mybook/README.md +43 -0
  14. data/testdata/mybook/Rakefile +16 -0
  15. data/testdata/mybook/catalog.yml +33 -0
  16. data/testdata/mybook/config-starter.yml +139 -0
  17. data/testdata/mybook/config.yml +375 -0
  18. data/testdata/mybook/contents/00-preface.re +83 -0
  19. data/testdata/mybook/contents/01-install.re +272 -0
  20. data/testdata/mybook/contents/02-tutorial.re +1008 -0
  21. data/testdata/mybook/contents/03-syntax.re +2613 -0
  22. data/testdata/mybook/contents/04-customize.re +728 -0
  23. data/testdata/mybook/contents/05-faq.re +328 -0
  24. data/testdata/mybook/contents/06-bestpractice.re +971 -0
  25. data/testdata/mybook/contents/91-compare.re +18 -0
  26. data/testdata/mybook/contents/92-filelist.re +119 -0
  27. data/testdata/mybook/contents/93-background.re +267 -0
  28. data/testdata/mybook/contents/99-postface.re +38 -0
  29. data/testdata/mybook/css/normalize.css +349 -0
  30. data/testdata/mybook/css/webstyle.css +514 -0
  31. data/testdata/mybook/images/03-syntax/favicon-16x16.png +0 -0
  32. data/testdata/mybook/images/03-syntax/figure_heretop.png +0 -0
  33. data/testdata/mybook/images/03-syntax/tw-icon1.jpg +0 -0
  34. data/testdata/mybook/images/03-syntax/tw-icon2.jpg +0 -0
  35. data/testdata/mybook/images/03-syntax/tw-icon3.jpg +0 -0
  36. data/testdata/mybook/images/03-syntax/tw-icon4.jpg +0 -0
  37. data/testdata/mybook/images/04-customize/caption_pagebreak.png +0 -0
  38. data/testdata/mybook/images/04-customize/chaptitlepage_sample.png +0 -0
  39. data/testdata/mybook/images/05-faq/codeblock_rpadding1.png +0 -0
  40. data/testdata/mybook/images/05-faq/codeblock_rpadding2.png +0 -0
  41. data/testdata/mybook/images/06-bestpractice/figure_heretop.png +0 -0
  42. data/testdata/mybook/images/06-bestpractice/font_beramono.png +0 -0
  43. data/testdata/mybook/images/06-bestpractice/heading_design1.png +0 -0
  44. data/testdata/mybook/images/06-bestpractice/heading_design2.png +0 -0
  45. data/testdata/mybook/images/06-bestpractice/margin_book.png +0 -0
  46. data/testdata/mybook/images/06-bestpractice/multiline-title.png +0 -0
  47. data/testdata/mybook/images/06-bestpractice/preface_numbered.png +0 -0
  48. data/testdata/mybook/images/06-bestpractice/program_border.png +0 -0
  49. data/testdata/mybook/images/06-bestpractice/sechead_design_4.png +0 -0
  50. data/testdata/mybook/images/06-bestpractice/titlepage-samples.png +0 -0
  51. data/testdata/mybook/images/93-background/bug913.png +0 -0
  52. data/testdata/mybook/images/93-background/slide2.png +0 -0
  53. data/testdata/mybook/images/cover_a5.pdf +0 -0
  54. data/testdata/mybook/images/cover_b5.pdf +0 -0
  55. data/testdata/mybook/images/tw-icon.jpg +0 -0
  56. data/testdata/mybook/layouts/layout.epub.erb +29 -0
  57. data/testdata/mybook/layouts/layout.html5.erb +106 -0
  58. data/testdata/mybook/layouts/layout.tex.erb +546 -0
  59. data/testdata/mybook/lib/hooks/beforetexcompile.rb +55 -0
  60. data/testdata/mybook/lib/ruby/review-builder.rb +503 -0
  61. data/testdata/mybook/lib/ruby/review-cli.rb +58 -0
  62. data/testdata/mybook/lib/ruby/review-compiler.rb +523 -0
  63. data/testdata/mybook/lib/ruby/review-epubmaker.rb +606 -0
  64. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +661 -0
  65. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +782 -0
  66. data/testdata/mybook/lib/ruby/review-maker.rb +235 -0
  67. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +91 -0
  68. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +468 -0
  69. data/testdata/mybook/lib/ruby/review-textbuilder.rb +36 -0
  70. data/testdata/mybook/lib/ruby/review-tocparser.rb +285 -0
  71. data/testdata/mybook/lib/ruby/review-webmaker.rb +433 -0
  72. data/testdata/mybook/lib/tasks/mytasks.rake +31 -0
  73. data/testdata/mybook/lib/tasks/review.rake +142 -0
  74. data/testdata/mybook/lib/tasks/review.rake.orig +72 -0
  75. data/testdata/mybook/lib/tasks/starter.rake +326 -0
  76. data/testdata/mybook/locale.yml +6 -0
  77. data/testdata/mybook/review-ext.rb +206 -0
  78. data/testdata/mybook/sty/jumoline.sty +310 -0
  79. data/testdata/mybook/sty/mycolophon.sty +81 -0
  80. data/testdata/mybook/sty/mystyle.sty +8 -0
  81. data/testdata/mybook/sty/mytextsize.sty +61 -0
  82. data/testdata/mybook/sty/mytitlepage.sty +103 -0
  83. data/testdata/mybook/sty/reviewmacro.sty +60 -0
  84. data/testdata/mybook/sty/starter-codeblock.sty +332 -0
  85. data/testdata/mybook/sty/starter-color.sty +79 -0
  86. data/testdata/mybook/sty/starter-font.sty +112 -0
  87. data/testdata/mybook/sty/starter-heading.sty +514 -0
  88. data/testdata/mybook/sty/starter-note.sty +127 -0
  89. data/testdata/mybook/sty/starter-section.sty +262 -0
  90. data/testdata/mybook/sty/starter-toc.sty +72 -0
  91. data/testdata/mybook/sty/starter.sty +554 -0
  92. data/testdata/mybook/style.css +597 -0
  93. metadata +100 -4
  94. data/.travis.yml +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8c6ad831811a8b43789da95255704662ae982c5f8650223a10ec0b56629452d
4
- data.tar.gz: c6db66340797c549a48df210fc17e5685503f6bdf26eeb2636b37ee66f9ebc3c
3
+ metadata.gz: fdd00a05ee2fe184542575f75ff8b5f7541ea11ead119c28b1b00e00d38aeab8
4
+ data.tar.gz: 6a1dcf4eedabf43d6be0b8bf7814dc11d30d8798730a95e33ed6a95cda59173d
5
5
  SHA512:
6
- metadata.gz: f98a2df0d44baf883acd3697195b6145a5ec53d8ba3159036e39f065b60c478a617859f71099d1e36d3a3c659506f45f67538e3f540ce9c5a6ea17654b578b01
7
- data.tar.gz: 81fbcbda5a0bd596a8eee846db5f3fe77e694cfe88d43e956564f2a9412c77e486be2c4ed508943499a76b2f07eef9f20ef8bddbe691146a4cddcade50d63ae3
6
+ metadata.gz: 4f3748ae4c99d94ecb773de86501b720712f25381061055d42e12186f795775ad0a359e7c901b089fa804f82e9fb3d8506a17aeb693d51d14138a80a5b3a8256
7
+ data.tar.gz: 7126a6536e53cceb34e41c9b606d6974b336bd6afb8d6391a279db5ba16ba3b3939aea4b9efcda8a51c0a2221ef0f1226aa4849625e90cd8e25a2e5900d2299f
@@ -0,0 +1,39 @@
1
+ on:
2
+ pull_request:
3
+ push:
4
+ branches:
5
+ - master
6
+
7
+ name: Retrovert
8
+ jobs:
9
+ review:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6
16
+ - run: bundle install
17
+ # spec
18
+ - name: spec
19
+ run: bundle exec rake spec
20
+ # convert
21
+ - name: convert
22
+ run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp -f
23
+ # build
24
+ - name: review build
25
+ uses: docker://srzzumix/review-retrovert
26
+ with:
27
+ entrypoint: bash
28
+ args: -c "cd tmp; rake preproc all"
29
+ # artifacts
30
+ - name: artifacts
31
+ uses: actions/upload-artifact@v1
32
+ with:
33
+ name: mybook
34
+ path: tmp/mybook.pdf
35
+ - name: artifacts
36
+ uses: actions/upload-artifact@v1
37
+ with:
38
+ name: mybook
39
+ path: tmp/mybook.epub
data/.gitignore CHANGED
@@ -5,11 +5,11 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
- /tmp/
8
+ tmp/
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  .rakeTasks
13
13
  .idea
14
14
 
15
- *.gem
15
+ *.gem
@@ -0,0 +1 @@
1
+ 2.5.5
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem 'aruba', '~> 1.0.2'
@@ -1,21 +1,80 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- review-retrovert (0.3.0)
4
+ review-retrovert (0.9.2)
5
5
  review (>= 3.2.0, < 4.0)
6
6
  thor
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
+ activesupport (6.0.3.2)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 0.7, < 2)
14
+ minitest (~> 5.1)
15
+ tzinfo (~> 1.1)
16
+ zeitwerk (~> 2.2, >= 2.2.2)
17
+ aruba (1.0.2)
18
+ childprocess (>= 2.0, < 5.0)
19
+ contracts (~> 0.16.0)
20
+ cucumber (>= 2.4, < 5.0)
21
+ ffi (~> 1.9)
22
+ rspec-expectations (~> 3.4)
23
+ thor (~> 1.0)
24
+ builder (3.2.4)
25
+ childprocess (4.0.0)
26
+ concurrent-ruby (1.1.6)
27
+ contracts (0.16.0)
28
+ cucumber (4.1.0)
29
+ builder (~> 3.2, >= 3.2.3)
30
+ cucumber-core (~> 7.1, >= 7.1.0)
31
+ cucumber-create-meta (~> 1.0.0, >= 1.0.0)
32
+ cucumber-cucumber-expressions (~> 10.1, >= 10.1.0)
33
+ cucumber-gherkin (~> 14.0, >= 14.0.1)
34
+ cucumber-html-formatter (~> 7.0, >= 7.0.0)
35
+ cucumber-messages (~> 12.2, >= 12.2.0)
36
+ cucumber-wire (~> 3.1, >= 3.1.0)
37
+ diff-lcs (~> 1.3, >= 1.3, < 1.4)
38
+ multi_test (~> 0.1, >= 0.1.2)
39
+ sys-uname (~> 1.0, >= 1.0.2)
40
+ cucumber-core (7.1.0)
41
+ cucumber-gherkin (~> 14.0, >= 14.0.1)
42
+ cucumber-messages (~> 12.2, >= 12.2.0)
43
+ cucumber-tag-expressions (~> 2.0, >= 2.0.4)
44
+ cucumber-create-meta (1.0.0)
45
+ cucumber-messages (~> 12.2, >= 12.2.0)
46
+ sys-uname (~> 1.2, >= 1.2.1)
47
+ cucumber-cucumber-expressions (10.2.2)
48
+ cucumber-gherkin (14.2.0)
49
+ cucumber-messages (~> 12.4, >= 12.4.0)
50
+ cucumber-html-formatter (7.2.0)
51
+ cucumber-messages (~> 12.4, >= 12.4.0)
52
+ cucumber-messages (12.4.0)
53
+ protobuf-cucumber (~> 3.10, >= 3.10.8)
54
+ cucumber-tag-expressions (2.0.4)
55
+ cucumber-wire (3.1.0)
56
+ cucumber-core (~> 7.1, >= 7.1.0)
57
+ cucumber-cucumber-expressions (~> 10.1, >= 10.1.0)
58
+ cucumber-messages (~> 12.2, >= 12.2.0)
11
59
  diff-lcs (1.3)
12
- image_size (2.0.2)
60
+ ffi (1.13.1)
61
+ i18n (1.8.5)
62
+ concurrent-ruby (~> 1.0)
63
+ image_size (2.1.0)
64
+ middleware (0.1.0)
65
+ minitest (5.14.1)
66
+ multi_test (0.1.2)
67
+ protobuf-cucumber (3.10.8)
68
+ activesupport (>= 3.2)
69
+ middleware
70
+ thor
71
+ thread_safe
13
72
  rake (12.3.3)
14
73
  review (3.2.0)
15
74
  image_size
16
75
  rouge
17
76
  rubyzip
18
- rouge (3.20.0)
77
+ rouge (3.26.0)
19
78
  rspec (3.9.0)
20
79
  rspec-core (~> 3.9.0)
21
80
  rspec-expectations (~> 3.9.0)
@@ -30,12 +89,19 @@ GEM
30
89
  rspec-support (~> 3.9.0)
31
90
  rspec-support (3.9.2)
32
91
  rubyzip (2.3.0)
92
+ sys-uname (1.2.1)
93
+ ffi (>= 1.0.0)
33
94
  thor (1.0.1)
95
+ thread_safe (0.3.6)
96
+ tzinfo (1.2.7)
97
+ thread_safe (~> 0.1)
98
+ zeitwerk (2.4.0)
34
99
 
35
100
  PLATFORMS
36
101
  ruby
37
102
 
38
103
  DEPENDENCIES
104
+ aruba (~> 1.0.2)
39
105
  rake (~> 12.0)
40
106
  review-retrovert!
41
107
  rspec (~> 3.0)
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  # ReVIEW::Retrovert
6
6
 
7
+ [Re:VIEW Starter](https://kauplan.org/reviewstarter/) Project convert to [Re:VIEW](https://reviewml.org/ja/) 3.X
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -22,7 +24,9 @@ Or install it yourself as:
22
24
 
23
25
  ## Usage
24
26
 
25
- TODO: Write usage instructions here
27
+ ```sh
28
+ review-retrovert convert /path/to/dir/review-starter/config.yml <output directory>
29
+ ```
26
30
 
27
31
  ## Development
28
32
 
@@ -34,10 +38,9 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
34
38
 
35
39
  Bug reports and pull requests are welcome on GitHub at https://github.com/srz-zumix/review-retrovert.
36
40
 
37
-
38
41
  ## Develop
39
42
 
40
- docker run -it --rm -v $(pwd)/../:/github vvakame/review:3.2 bash
43
+ docker run -it --rm -v $(pwd)/:/work -w /work vvakame/review:3.2 bash
41
44
 
42
45
  ## License
43
46
 
@@ -7,6 +7,10 @@ module ReVIEW
7
7
  desc "convert {review_starter_configfile} {outdir}", "convert Re:VIEW Starter project to Re:VIEW project"
8
8
  method_option "force", aliases: "f", desc: 'Force output', type: :boolean
9
9
  method_option "strict", desc: 'Only process files registered in the catalog', type: :boolean
10
+ method_option "preproc", desc: 'Execute preproc after conversion', type: :boolean
11
+ method_option "tabwidth", desc: 'Preproc tabwidth option value', type: :numeric, default: 0
12
+ method_option "table-br-replace", desc: '@<br>{} in table replace string', type: :string, default: ''
13
+ method_option "table-empty-replace", desc: 'empty cell(.) in table replace string', type: :string, default: ' '
10
14
  def convert(review_starter_configfile, outdir)
11
15
  Converter.execute(review_starter_configfile, outdir, options)
12
16
  end
@@ -52,8 +52,13 @@ module ReVIEW
52
52
  outpath = File.join(outdir, outimagedir)
53
53
  FileUtils.mkdir_p(outpath)
54
54
  image_ext = @config['image_ext']
55
+ srcroot = Pathname.new(srcpath)
55
56
  image_ext.each { |ext|
56
- FileUtils.cp_r(Dir.glob(File.join(srcpath, "**/*.#{ext}")), outpath)
57
+ Dir.glob(File.join(srcpath, "**/*.#{ext}")).each { |srcimg|
58
+ outimg = File.join(outpath, Pathname.new(srcimg).relative_path_from(srcroot))
59
+ FileUtils.makedirs(File.dirname(outimg))
60
+ FileUtils.cp(srcimg, outimg)
61
+ }
57
62
  }
58
63
  @configs.rewrite_yml('imagedir', outimagedir)
59
64
  end
@@ -64,8 +69,35 @@ module ReVIEW
64
69
  @configs.rewrite_yml('texstyle', '["reviewmacro"]')
65
70
  end
66
71
 
67
- def replace_inline_command(content, command, sub)
72
+ def replace_compatible_block_command_outline(content, command, new_command, option_count)
73
+ if option_count > 0
74
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
75
+ else
76
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
77
+ end
78
+ end
79
+
80
+ def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
81
+ body = new_body
82
+ body += '\n' unless body.empty?
83
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>#{add_options}{\n#{new_body}//}\\k<inner>")
84
+ end
85
+
86
+ def replace_block_command_outline(content, command, new_command, use_option)
87
+ if use_option
88
+ content.gsub!(/^\/\/#{command}(?<option>\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
89
+ else
90
+ content.gsub!(/^\/\/#{command}(?<option>\[[^\r\n]*?\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
91
+ end
92
+ end
93
+
94
+ def delete_block_command_outer(content, command)
95
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\])*{(?<inner>.*?)\/\/}\R/m, '\k<inner>')
96
+ end
68
97
 
98
+ def delete_block_command(content, command)
99
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\])*{.*?\/\/}\R/m, '')
100
+ content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
69
101
  end
70
102
 
71
103
  def delete_inline_command(content, command)
@@ -73,6 +105,167 @@ module ReVIEW
73
105
  content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))((?:.*@<\w*>[\|${].*?[\|$}].*?|.*?)*)(?(1)(\$)|(?(2)(})|(\|)))/){"#{$4}"}
74
106
  end
75
107
 
108
+ def replace_inline_command(content, command, new_command)
109
+ content.gsub!(/@<#{command}>/, "@<#{new_command}>")
110
+ end
111
+
112
+ def replace_block_command_nested_boxed_article_i(content, box, depth)
113
+ found = false
114
+ content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
115
+ matched = m[0..-1].join
116
+ inner = m[5]
117
+ # info depth
118
+ im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
119
+ unless im.nil?
120
+ inner_cmd = im[1]
121
+ inner_open = im[4]
122
+ inner_opts = im[2]
123
+ first_opt_m = inner_opts.match(/^\[(.*?)\]/)
124
+ first_opt = ""
125
+
126
+ # is_commentout = false
127
+ is_commentout = true
128
+ if first_opt_m
129
+ first_opt_v = first_opt_m[1]
130
+ unless first_opt_v.empty?
131
+ if inner.match(/@<.*?>[$|{]#{first_opt}/)
132
+ is_commentout = false
133
+ first_opt = "\\[#{first_opt_v}\\]"
134
+ end
135
+ end
136
+ end
137
+ cmd_begin = m[0..4].join
138
+ cmd_end = m[6..-1].join
139
+ # check other fence inner block (block command has fence??)
140
+ if inner_open == m[2..4].join
141
+ # if same fence then cmd_end == inner_end
142
+ if is_commentout
143
+ inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
144
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#@##{cmd_end}")
145
+ else
146
+ imb = inner.match(/(\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/#{inner_cmd}#{first_opt}(\[.*?\])*#{inner_open}.*)\R/m)
147
+ to_out_block = imb[1]
148
+ inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
149
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
150
+ end
151
+ else
152
+ close = inner_open == '{' ? '}' : inner_open
153
+ if is_commentout
154
+ inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})(.*?)(^\/\/#{close})/m, '#@#\1\2#@#\3')
155
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}")
156
+ else
157
+ imb = inner.match(/\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/(#{inner_cmd})#{first_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
158
+ to_out_block = imb[0]
159
+ inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
160
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
161
+ end
162
+ end
163
+ found = true
164
+ end
165
+ }
166
+ if found
167
+ replace_block_command_nested_boxed_article_i(content, box, depth+1)
168
+ end
169
+ end
170
+
171
+ def replace_block_command_nested_boxed_article(content, box)
172
+ replace_block_command_nested_boxed_article_i(content, box, 0)
173
+ end
174
+
175
+ def replace_block_command_nested_boxed_articles(content)
176
+ replace_block_command_nested_boxed_article(content, 'note')
177
+ replace_block_command_nested_boxed_article(content, 'memo')
178
+ replace_block_command_nested_boxed_article(content, 'tip')
179
+ replace_block_command_nested_boxed_article(content, 'info')
180
+ replace_block_command_nested_boxed_article(content, 'warning')
181
+ replace_block_command_nested_boxed_article(content, 'important')
182
+ replace_block_command_nested_boxed_article(content, 'caution')
183
+ replace_block_command_nested_boxed_article(content, 'notice')
184
+ end
185
+
186
+ def replace_block_commentout(content)
187
+ d = content.dup
188
+ d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
189
+ d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
190
+ matched = m[0..-1].join
191
+ inner = m[2]
192
+ inner.gsub!(/(^.)/, '#@#\1')
193
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
194
+ }
195
+ end
196
+
197
+ def replace_sampleoutput(content)
198
+ replace_block_commentout(content)
199
+ content.dup.scan(/(^\/\/sampleoutputbegin\[)(.*?)(\].*?\R)(.*?)(^\/\/sampleoutputend)/m) { |m|
200
+ matched = m[0..-1].join
201
+ sampleoutputbegin = m[0..2].join
202
+ sampleoutputend = m[4]
203
+ option = m[1]
204
+ inner = m[3]
205
+ # inner.gsub!(/^\/\//, '//@<nop>{}')
206
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
207
+ }
208
+ end
209
+
210
+ def replace_auto_ids(content, command, require_option_count)
211
+ index = -1
212
+ content.gsub!(/^\/\/#{command}\[(|\?)\]/) { |s| index += 1; "//#{command}[starter_auto_id_#{command}_#{index}]" }
213
+ if require_option_count > 0
214
+ while !content.gsub!(/(^\/\/#{command}(\[[^\[\]]*?\]){0,#{require_option_count-1}})($|{)/, '\1[]\3').nil?
215
+ end
216
+ end
217
+ end
218
+
219
+ def remove_starter_refid(content)
220
+ # note - noteref
221
+ content.dup.scan(/(@<noteref>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
222
+ matched = m[0..-1].join
223
+ ref = m[4]
224
+ n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
225
+ unless n.nil?
226
+ content.gsub!(/#{Regexp.escape(matched)}/, n[1])
227
+ content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
228
+ else
229
+ # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
230
+ end
231
+ }
232
+ end
233
+
234
+ def remove_starter_options(content)
235
+ # image border
236
+ content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)((,|)border=[^,\]]*)(.*?\])/, '\1\4')
237
+ # list lineno
238
+ content.gsub!(/(^\/\/list\[.*?\]\[.*?\]\[.*?)((,|)lineno=[^,\]]*)(.*?\])/, '\1\4')
239
+ end
240
+
241
+ def expand_nested_inline_command(content)
242
+ found = false
243
+ content.dup.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
244
+ matched = m.join
245
+ body = m[4]
246
+ im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
247
+ if im.nil?
248
+ im = body.match(/(.*)(@<.*?>)#{m[1..3].join}/)
249
+ unless im.nil?
250
+ outcmd_begin = m[0] + "$|{".gsub(m[1..3].join, '')
251
+ outcmd_end = "$|}".gsub(m[5..7].join, '')
252
+ rep = "#{outcmd_begin}#{body}#{outcmd_end}"
253
+ content.gsub!(matched, rep)
254
+ found = true
255
+ end
256
+ else
257
+ outcmd_begin = m[0..3].join
258
+ outcmd_end = m[5..7].join
259
+ rep = "#{outcmd_begin}#{im[1]}#{outcmd_end}#{im[2..9].join}#{outcmd_begin}#{im[-1]}#{outcmd_end}"
260
+ content.gsub!(matched, rep)
261
+ found = true
262
+ end
263
+ }
264
+ if found
265
+ expand_nested_inline_command(content)
266
+ end
267
+ end
268
+
76
269
  def copy_embedded_contents(outdir, content)
77
270
  content.scan(/\#@mapfile\((.*?)\)/).each do |filepath|
78
271
  srcpath = File.join(@basedir, filepath)
@@ -85,16 +278,105 @@ module ReVIEW
85
278
  end
86
279
  end
87
280
 
281
+ def add_linkurl_footnote(content)
282
+ urls = {}
283
+ content.dup.scan(/(^.*)(@<href>{)(.*?)(,)(.*?)(})(.*)$/) { |m|
284
+ unless m[0].match(/^#@#/)
285
+ matched = m.join
286
+ prev = m[0]
287
+ url = m[2]
288
+ text = m[4]
289
+ post = m[6]
290
+ id = "link_auto_footnote#{urls.length}"
291
+ urls[id] = url
292
+ content.sub!(/#{matched}$/, "#{prev}@<href>{#{url},#{text}} @<fn>{#{id}} #{post}")
293
+ end
294
+ }
295
+
296
+ urls.each { |k,v|
297
+ content.sub!(/(@<href>{#{v},.*?} @<fn>{#{k}}.*?\R\R)/m, "\\1//footnote[#{k}][#{v}]\n")
298
+ }
299
+
300
+ urls.each { |k,v|
301
+ unless content.match(/\/\/footnote\[#{k}\]\[#{v}\]/)
302
+ content << "//footnote[#{k}][#{v}]\n"
303
+ end
304
+ }
305
+ end
306
+
88
307
  def update_content(outdir, contentfile)
89
308
  info contentfile
90
309
  content = File.read(contentfile)
91
- content.gsub!(/(\/\/sideimage\[.*?\]\[.*?\])\[.*?\]/, '\1')
92
- content.gsub!(/\/\/sideimage/, '//image')
310
+ content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
93
311
  content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
94
- while !content.gsub!(/(\/\/table.*)@<br>(.*?\/\/})/m, '\1\2').nil? do
312
+ linkurl_footnote = @config['starter']['linkurl_footnote']
313
+ # table 内の @ コマンドは不安定らしい
314
+ while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
315
+ end
316
+ # 空セルが2行になることがあるらしい
317
+ while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{@table_empty_replace}\\2").nil? do
95
318
  end
96
- delete_inline_command(content , 'xsmall')
97
- delete_inline_command(content , 'weak')
319
+ # Re:VIEW Starter commands
320
+ replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1)
321
+ replace_compatible_block_command_outline(content, 'cmd', 'cmd', 0)
322
+ replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
323
+ replace_block_command_outline(content, 'abstract', 'lead', true)
324
+ delete_block_command(content, 'needvspace')
325
+ delete_block_command(content, 'clearpage')
326
+ delete_block_command(content, 'flushright')
327
+ delete_block_command(content, 'centering')
328
+ delete_block_command(content, 'noindent')
329
+ delete_block_command(content, 'paragraphend')
330
+
331
+ replace_inline_command(content, 'secref', 'hd')
332
+ replace_inline_command(content, 'file', 'kw')
333
+ replace_inline_command(content, 'hlink', 'href')
334
+ replace_inline_command(content, 'B', 'strong')
335
+ delete_inline_command(content, 'userinput')
336
+ delete_inline_command(content, 'weak')
337
+ delete_inline_command(content, 'cursor')
338
+ # font size
339
+ delete_inline_command(content, 'small')
340
+ delete_inline_command(content, 'xsmall')
341
+ delete_inline_command(content, 'xxsmall')
342
+ delete_inline_command(content, 'large')
343
+ delete_inline_command(content, 'xlarge')
344
+ delete_inline_command(content, 'xxlarge')
345
+
346
+ # fixed lack of options
347
+ content.gsub!(/^\/\/list{/, '//list[][]{')
348
+
349
+ # special command
350
+ replace_sampleoutput(content)
351
+
352
+ if linkurl_footnote
353
+ add_linkurl_footnote(content)
354
+ end
355
+
356
+ # nested command
357
+ replace_block_command_nested_boxed_articles(content)
358
+
359
+ # empty ids
360
+ replace_auto_ids(content, 'list', 2)
361
+ replace_auto_ids(content, 'listnum', 2)
362
+
363
+ # remove starter extension
364
+ remove_starter_refid(content)
365
+ remove_starter_options(content)
366
+
367
+ # special charactor
368
+ content.gsub!('@<LaTeX>{}', 'LaTeX')
369
+ content.gsub!('@<TeX>{}', 'TeX')
370
+ content.gsub!('@<hearts>{}', '!HEART!')
371
+
372
+ # nop replace must be last step
373
+ content.gsub!('@<nop>$$', '@<b>$$')
374
+ content.gsub!('@<nop>||', '@<b>||')
375
+ content.gsub!('@<nop>{}', '@<b>{}')
376
+
377
+ # expand nested inline command
378
+ expand_nested_inline_command(content)
379
+
98
380
  File.write(contentfile, content)
99
381
  copy_embedded_contents(outdir, content)
100
382
  end
@@ -118,7 +400,7 @@ module ReVIEW
118
400
  yamlfile = @config['catalogfile']
119
401
  abspath = File.absolute_path(outdir)
120
402
  contentdir = abspath
121
- info 'replace //sideimage to //image'
403
+ info 'replace starter block command'
122
404
  info 'replace starter inline command'
123
405
  if options['strict']
124
406
  catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
@@ -128,12 +410,50 @@ module ReVIEW
128
410
  update_content_files(outdir, contentdir, catalog.postdef())
129
411
  else
130
412
  # copy_contents(outdir)
131
- Dir.chdir(File.join(@basedir, @srccontentsdir)) do
132
- update_content_files(outdir, contentdir, Dir.glob('*.re'))
413
+ contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
414
+ update_content_files(outdir, contentdir, contentsfiles)
415
+ end
416
+ end
417
+
418
+ def preproc_content_files(outdir, pp, contentdir, contentfiles)
419
+ files = contentfiles.is_a?(String) ? contentfiles.split(/\R/) : contentfiles
420
+ files.each do |content|
421
+ contentpath = File.join(contentdir, content)
422
+ if File.exist?(contentpath)
423
+ info "preproc #{contentpath}"
424
+ buf = StringIO.new
425
+ pwd = Dir.pwd
426
+ Dir.chdir(outdir)
427
+ File.open(contentpath) { |f| pp.process(f, buf) }
428
+ Dir.chdir(pwd)
429
+ content = buf.string
430
+ content.gsub!(/^#[@]map.*$/, '')
431
+ File.write(contentpath, content)
133
432
  end
134
433
  end
135
434
  end
136
435
 
436
+ def preproc_contents(outdir, options)
437
+ yamlfile = @config['catalogfile']
438
+ abspath = File.absolute_path(outdir)
439
+ contentdir = abspath
440
+ param = {}
441
+ param['tabwidth'] = options['tabwidth'].to_i
442
+ pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
443
+
444
+ if options['strict']
445
+ catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
446
+ preproc_content_files(outdir, pp, contentdir, catalog.predef())
447
+ preproc_content_files(outdir, pp, contentdir, catalog.chaps())
448
+ preproc_content_files(outdir, pp, contentdir, catalog.appendix())
449
+ preproc_content_files(outdir, pp, contentdir, catalog.postdef())
450
+ else
451
+ # copy_contents(outdir)
452
+ contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
453
+ preproc_content_files(outdir, pp, contentdir, contentsfiles)
454
+ end
455
+ end
456
+
137
457
  def clean_initial_project(outdir)
138
458
  FileUtils.rm(File.join(outdir, 'config.yml'))
139
459
  FileUtils.rm(File.join(outdir, 'catalog.yml'))
@@ -155,6 +475,8 @@ module ReVIEW
155
475
  end
156
476
 
157
477
  def execute(yamlfile, outdir, options)
478
+ @table_br_replace = options['table-br-replace']
479
+ @table_empty_replace = options['table-empty-replace']
158
480
  load_config(yamlfile)
159
481
  create_initial_project(outdir, options)
160
482
 
@@ -171,6 +493,11 @@ module ReVIEW
171
493
  # updater.backup = false
172
494
  updater.execute()
173
495
  Dir.chdir(pwd)
496
+
497
+ if options['preproc']
498
+ info 'preproc'
499
+ preproc_contents(outdir, options)
500
+ end
174
501
  end
175
502
 
176
503
  def self.execute(yamlfile, outdir, options)