review-retrovert 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +9 -0
  3. data/.editorconfig +3 -0
  4. data/.github/workflows/retrovert.yml +20 -5
  5. data/.gitignore +1 -0
  6. data/.vscode/launch.json +48 -0
  7. data/Gemfile.lock +13 -4
  8. data/Makefile +24 -0
  9. data/docker/review.Dockerfile +10 -0
  10. data/lib/review/retrovert/converter.rb +374 -111
  11. data/lib/review/retrovert/reviewcompat.rb +57 -0
  12. data/lib/review/retrovert/reviewdef.rb +70 -0
  13. data/lib/review/retrovert/sty/{ird.sty → ird.sty.erb} +9 -1
  14. data/lib/review/retrovert/sty/review-retrovert-custom.sty.erb +6 -0
  15. data/lib/review/retrovert/utils.rb +35 -0
  16. data/lib/review/retrovert/version.rb +1 -1
  17. data/lib/review/retrovert/yamlconfig.rb +0 -1
  18. data/package-lock.json +6 -0
  19. data/package.json +1 -0
  20. data/review-retrovert.gemspec +5 -1
  21. data/testdata/mybook/.gitignore +3 -1
  22. data/testdata/mybook/.textlintrc +11 -0
  23. data/testdata/mybook/Rakefile +8 -0
  24. data/testdata/mybook/catalog.yml +36 -10
  25. data/testdata/mybook/config-starter.yml +134 -9
  26. data/testdata/mybook/config.yml +44 -15
  27. data/testdata/mybook/contents/00-preface.re +48 -2
  28. data/testdata/mybook/contents/01-install.re +38 -5
  29. data/testdata/mybook/contents/02-tutorial.re +333 -113
  30. data/testdata/mybook/contents/03-syntax.re +2370 -373
  31. data/testdata/mybook/contents/04-customize.re +424 -88
  32. data/testdata/mybook/contents/05-faq.re +288 -10
  33. data/testdata/mybook/contents/06-bestpractice.re +431 -59
  34. data/testdata/mybook/contents/91-compare.re +402 -2
  35. data/testdata/mybook/contents/92-filelist.re +14 -8
  36. data/testdata/mybook/contents/93-background.re +10 -10
  37. data/testdata/mybook/contents/99-postface.re +2 -1
  38. data/testdata/mybook/contents/r0-root.re +1 -1
  39. data/testdata/mybook/css/webstyle.css +180 -2
  40. data/testdata/mybook/data/terms.txt +3 -0
  41. data/testdata/mybook/data/words.txt +15 -0
  42. data/testdata/mybook/images/03-syntax/index-page.png +0 -0
  43. data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
  44. data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
  45. data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
  46. data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
  47. data/testdata/mybook/images/avatar-b.png +0 -0
  48. data/testdata/mybook/images/avatar-g.png +0 -0
  49. data/testdata/mybook/images/avatar-r.png +0 -0
  50. data/testdata/mybook/images/caution-icon.png +0 -0
  51. data/testdata/mybook/images/info-icon.png +0 -0
  52. data/testdata/mybook/images/warning-icon.png +0 -0
  53. data/testdata/mybook/layouts/layout.html5.erb +3 -1
  54. data/testdata/mybook/layouts/layout.tex.erb +265 -379
  55. data/testdata/mybook/layouts/layout.tex.erb.orig +386 -0
  56. data/testdata/mybook/lib/ruby/review-book.rb +64 -0
  57. data/testdata/mybook/lib/ruby/review-builder.rb +902 -63
  58. data/testdata/mybook/lib/ruby/review-compiler.rb +675 -22
  59. data/testdata/mybook/lib/ruby/review-epubbuilder.rb +33 -0
  60. data/testdata/mybook/lib/ruby/review-epubmaker.rb +10 -7
  61. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +354 -66
  62. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +429 -146
  63. data/testdata/mybook/lib/ruby/review-maker.rb +117 -6
  64. data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +945 -0
  65. data/testdata/mybook/lib/ruby/review-markdownmaker.rb +91 -0
  66. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +2 -0
  67. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +160 -82
  68. data/testdata/mybook/lib/ruby/review-webmaker.rb +20 -5
  69. data/testdata/mybook/lib/tasks/review.rake +14 -0
  70. data/testdata/mybook/lib/tasks/starter.rake +148 -4
  71. data/testdata/mybook/sty/indexstyle.ist +25 -0
  72. data/testdata/mybook/sty/mytextsize.sty +29 -0
  73. data/testdata/mybook/sty/mytitlepage.sty +34 -11
  74. data/testdata/mybook/sty/review-base.sty +276 -0
  75. data/testdata/mybook/sty/starter-codeblock.sty +237 -106
  76. data/testdata/mybook/sty/starter-color.sty +72 -17
  77. data/testdata/mybook/sty/starter-heading.sty +60 -13
  78. data/testdata/mybook/sty/starter-misc.sty +894 -0
  79. data/testdata/mybook/sty/starter-note.sty +67 -14
  80. data/testdata/mybook/sty/starter-talklist.sty +105 -0
  81. data/testdata/mybook/sty/starter-util.sty +35 -0
  82. data/testdata/mybook/sty/starter.sty +8 -526
  83. metadata +80 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d85946bda0b18fbe3dddfbd6f37ef15a2e2c6892376a1e91245c8d0a98053399
4
- data.tar.gz: a0f7697228f0bf308bb091fb5d7d0ee279d2dbdbdf7fff4580f5ccf6298ad0b3
3
+ metadata.gz: b6300e07afd5a8a952ed11706cb35595a83fa7cb90b381af357fb3387fb22624
4
+ data.tar.gz: 649de1a4923bf1f045684af4d14afcf65724dd021f274bea881adf83b5aa38c1
5
5
  SHA512:
6
- metadata.gz: 7faaa36fd24484680cd909eeab26a46ab67e7085a59807e0d3d725586422df13be6f0a0d7942bec592bb2e89bef3b1e3faad659e7484c4991b00737864578960
7
- data.tar.gz: 80ff4eea7e4b43cb20486fb87cf9dd6431b0e4766d58fbc24680cdff254bb28e265ce1d3552deef4167d11247b958d2df9caf1a4df9e8b0a294a14d2efc81afa
6
+ metadata.gz: 64661293c30051b5a66ab5cb2c9c4c3a2787508e8659ae26fda67f428594e06870739a9ec7e84a416920e50729f4cf28e5d4da16af496cffd22868e2f0b7b447
7
+ data.tar.gz: b3dc096f12c61c9ed66456e5a24da4822f3279af9ea4ff83057d8b42e70de8b31ef8cdcd5778c289191b0ceea0e6580fa6e2ebaae644de52061e78128ea91d39
data/.dockerignore ADDED
@@ -0,0 +1,9 @@
1
+ .bundle
2
+ .idea
3
+ .vscode
4
+ pkg
5
+ bin
6
+ tmp
7
+ .rake*
8
+ .rspec_status
9
+ Gemfile.lock
data/.editorconfig CHANGED
@@ -11,3 +11,6 @@ indent_size = 2
11
11
 
12
12
  [*.yml]
13
13
  indent_size = 2
14
+
15
+ [Makefile]
16
+ indent_style = tab
@@ -10,7 +10,17 @@ jobs:
10
10
  runs-on: ubuntu-latest
11
11
  strategy:
12
12
  matrix:
13
- review-version: [ "3.2", "4.2", "5.0" ]
13
+ review-version:
14
+ - "3.0"
15
+ - "3.1"
16
+ - "3.2"
17
+ - "4.0"
18
+ - "4.1"
19
+ - "4.2"
20
+ - "5.0"
21
+ - "5.1"
22
+ - "5.2"
23
+ - "latest"
14
24
  fail-fast: false
15
25
  steps:
16
26
  - uses: actions/checkout@v2
@@ -23,13 +33,17 @@ jobs:
23
33
  echo 'gem "review", "${{ matrix.review-version }}"' >> Gemfile-${{ matrix.review-version }}
24
34
  cat Gemfile-${{ matrix.review-version }}
25
35
  echo "BUNDLE_GEMFILE=Gemfile-${{ matrix.review-version }}" >> $GITHUB_ENV
36
+ if: ${{ matrix.review-version != 'latest' }}
26
37
  - run: bundle install --gemfile=Gemfile-${{ matrix.review-version }}
38
+ if: ${{ matrix.review-version != 'latest' }}
39
+ - run: bundle install
40
+ if: ${{ matrix.review-version == 'latest' }}
27
41
  # spec
28
42
  - name: spec
29
43
  run: bundle exec rake spec
30
44
  # convert
31
45
  - name: convert
32
- run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp -f
46
+ run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp-${{ matrix.review-version }} -f
33
47
  # build
34
48
  # - name: review build
35
49
  # uses: ${{ matrix.uses }}
@@ -44,16 +58,17 @@ jobs:
44
58
  password: ${{ secrets.DOCKERHUB_TOKEN }}
45
59
  - name: build html
46
60
  run: |
47
- docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc html
61
+ docker run --rm -v "$(pwd)/tmp-${{ matrix.review-version }}":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc html
48
62
  - name: build pdf
49
63
  run: |
50
- docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc pdf
64
+ docker run --rm -v "$(pwd)/tmp-${{ matrix.review-version }}":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc pdf
65
+ cp tmp-${{ matrix.review-version }}/mybook.pdf mybook-${{ matrix.review-version }}.pdf
51
66
  # artifacts
52
67
  - name: artifacts
53
68
  uses: actions/upload-artifact@v1
54
69
  with:
55
70
  name: mybook
56
- path: tmp/mybook.pdf
71
+ path: mybook-${{ matrix.review-version }}.pdf
57
72
  # - name: artifacts
58
73
  # uses: actions/upload-artifact@v1
59
74
  # with:
data/.gitignore CHANGED
@@ -13,3 +13,4 @@ tmp/
13
13
  .idea
14
14
 
15
15
  *.gem
16
+ mybook.pdf
@@ -0,0 +1,48 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Debug review-retrovert",
9
+ "type": "Ruby",
10
+ "request": "launch",
11
+ "env": {
12
+ "RUBYLIB":"lib"
13
+ },
14
+ "cwd": "${workspaceRoot}",
15
+ "program": "${workspaceRoot}/exe/review-retrovert",
16
+ "args": [
17
+ "convert",
18
+ "--preproc",
19
+ "--tabwidth", "4",
20
+ "--ird",
21
+ "testdata/mybook/config.yml",
22
+ "-f",
23
+ "tmp/debug"
24
+ ]
25
+ },
26
+ {
27
+ "name": "RSpec - active spec file only",
28
+ "type": "Ruby",
29
+ "request": "launch",
30
+ "program": "${workspaceRoot}/bin/rspec",
31
+ "args": [
32
+ "-I",
33
+ "${workspaceRoot}",
34
+ "${file}"
35
+ ]
36
+ },
37
+ {
38
+ "name": "RSpec - all",
39
+ "type": "Ruby",
40
+ "request": "launch",
41
+ "program": "${workspaceRoot}/bin/rspec",
42
+ "args": [
43
+ "-I",
44
+ "${workspaceRoot}"
45
+ ]
46
+ },
47
+ ]
48
+ }
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- review-retrovert (0.9.7)
4
+ review-retrovert (0.9.8)
5
5
  review (>= 3.0.0)
6
6
  thor
7
7
 
@@ -59,20 +59,23 @@ GEM
59
59
  ffi (1.14.2)
60
60
  i18n (1.8.7)
61
61
  concurrent-ruby (~> 1.0)
62
- image_size (2.1.0)
62
+ image_size (2.1.1)
63
63
  middleware (0.1.0)
64
64
  minitest (5.14.3)
65
65
  multi_test (0.1.2)
66
+ pastel (0.8.0)
67
+ tty-color (~> 0.5)
66
68
  protobuf-cucumber (3.10.8)
67
69
  activesupport (>= 3.2)
68
70
  middleware
69
71
  thor
70
72
  thread_safe
71
73
  rake (12.3.3)
72
- review (5.0.0)
74
+ review (5.2.0)
73
75
  image_size
74
76
  rouge
75
77
  rubyzip
78
+ tty-logger
76
79
  rouge (3.26.0)
77
80
  rspec (3.10.0)
78
81
  rspec-core (~> 3.10.0)
@@ -87,11 +90,16 @@ GEM
87
90
  diff-lcs (>= 1.2.0, < 2.0)
88
91
  rspec-support (~> 3.10.0)
89
92
  rspec-support (3.10.1)
90
- rubyzip (2.3.0)
93
+ ruby-debug-ide (0.7.2)
94
+ rake (>= 0.8.1)
95
+ rubyzip (2.3.2)
91
96
  sys-uname (1.2.2)
92
97
  ffi (~> 1.1)
93
98
  thor (1.0.1)
94
99
  thread_safe (0.3.6)
100
+ tty-color (0.6.0)
101
+ tty-logger (0.6.0)
102
+ pastel (~> 0.8)
95
103
  tzinfo (2.0.4)
96
104
  concurrent-ruby (~> 1.0)
97
105
  zeitwerk (2.4.2)
@@ -104,6 +112,7 @@ DEPENDENCIES
104
112
  rake (~> 12.0)
105
113
  review-retrovert!
106
114
  rspec (~> 3.0)
115
+ ruby-debug-ide
107
116
 
108
117
  BUNDLED WITH
109
118
  2.1.4
data/Makefile ADDED
@@ -0,0 +1,24 @@
1
+ help: ## show help
2
+ @grep -E '^[a-zA-Z][a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed -e 's/^GNUmakefile://' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
3
+
4
+ init:
5
+ bundle install --binstubs
6
+
7
+ review3:
8
+ docker build . -t review-3-retrovert -f docker/review.Dockerfile --build-arg REVIEW_VERSION=3.2
9
+ docker run -it --rm -w /work review-3-retrovert bash
10
+
11
+ test:
12
+ RUBYLIB=lib ./exe/review-retrovert convert --preproc --tabwidth 4 testdata/mybook/config.yml -f tmp/debug
13
+
14
+ test-ird:
15
+ RUBYLIB=lib ./exe/review-retrovert convert --preproc --tabwidth 4 --ird testdata/mybook/config.yml -f tmp/debug
16
+
17
+ REVIEW_VERSION:=latest
18
+
19
+ debug-build:
20
+ docker run --rm -v "${PWD}/tmp/debug":/work -w /work vvakame/review:${REVIEW_VERSION} rake preproc pdf
21
+ # docker run --rm -v "${PWD}":/work -w /work vvakame/review rake preproc pdf
22
+
23
+ testdata-pdf:
24
+ docker run --rm -v ${PWD}/testdata/mybook:/work -w /work kauplan/review2.5 rake pdf
@@ -0,0 +1,10 @@
1
+ ARG REVIEW_VERSION=lastest
2
+ FROM vvakame/review:$REVIEW_VERSION
3
+ ARG REVIEW_VERSION
4
+
5
+ WORKDIR /work
6
+ COPY . .
7
+ ENV BUNDLE_GEMFILE=Gemfile-$REVIEW_VERSION
8
+ RUN cp Gemfile Gemfile-$REVIEW_VERSION && \
9
+ echo "gem \"review\", \"$REVIEW_VERSION\"" >> Gemfile-$REVIEW_VERSION && \
10
+ bundle install
@@ -1,7 +1,11 @@
1
- require "review"
1
+ require 'review'
2
+ require 'erb'
2
3
  require 'fileutils'
3
4
  require 'tmpdir'
4
- require "review/retrovert/yamlconfig"
5
+ require 'review/retrovert/yamlconfig'
6
+ require 'review/retrovert/reviewcompat'
7
+ require 'review/retrovert/reviewdef'
8
+ require 'review/retrovert/utils'
5
9
 
6
10
  module ReVIEW
7
11
  module Retrovert
@@ -16,7 +20,13 @@ module ReVIEW
16
20
  @configs = YamlConfig.new
17
21
  @embeded_contents = []
18
22
  @catalog_contents = []
23
+ @talk_shortcuts = {}
19
24
  @ird = false
25
+ @talklist_replace_cmd = "note"
26
+ @desclist_replace_cmd = "info"
27
+ @talk_icon_scale = 0.1
28
+
29
+ @r_option_inner = ReViewDef::r_option_inner
20
30
  end
21
31
 
22
32
  def error(msg)
@@ -96,12 +106,44 @@ module ReVIEW
96
106
  @configs.rewrite_yml('imagedir', outimagedir)
97
107
  end
98
108
 
109
+ def copy_wards(outdir, words_file)
110
+ new_file = words_file
111
+ FileUtils.mkdir_p(File.join(outdir, File.dirname(words_file)))
112
+ if File.extname(words_file) == ".csv"
113
+ FileUtils.copy(File.join(@basedir, words_file), File.join(outdir, new_file))
114
+ else
115
+ new_file += ".csv"
116
+ Utils.Tsv2Csv(File.join(@basedir, words_file), File.join(outdir, new_file))
117
+ end
118
+ new_file
119
+ end
120
+
99
121
  def update_config(outdir)
100
122
  @configs.rewrite_yml('contentdir', '.')
101
123
  @configs.rewrite_yml('hook_beforetexcompile', 'null')
102
124
  @configs.rewrite_yml('texstyle', '["reviewmacro"]')
103
125
  pagesize = @config['starter']['pagesize'].downcase
104
126
  jsbook_config = "media=print,paper=#{pagesize}"
127
+
128
+ # words
129
+ words_files = @config['words_file']
130
+ if words_files.is_a?(Array)
131
+ new_words_files = []
132
+ words_files.each do |words_file|
133
+ new_words_files.push copy_wards(outdir, words_file)
134
+ end
135
+ @configs.rewrite_yml('words_file', "[#{new_words_files.join(',')}]")
136
+ else
137
+ new_words_file = copy_wards(outdir, words_files)
138
+ @configs.rewrite_yml('words_file', new_words_file)
139
+ end
140
+
141
+ # makeindex_dic
142
+ makeindex_dic = @config['pdfmaker']['makeindex_dic']
143
+ if makeindex_dic
144
+ FileUtils.copy(File.join(@basedir, makeindex_dic), File.join(outdir, makeindex_dic))
145
+ end
146
+
105
147
  if @ird
106
148
  # # リュウミン Pr6N R-KL 12.5Q 22H (9pt = 12.7Q 15.5pt = 21.8Q(H))
107
149
  # texdocumentclass: ["review-jsbook", "media=ebook,openany,paper=b5,fontsize=9pt,baselineskip=15.5pt,head_space=15mm,gutter=22mm,footskip=16mm,line_length=45zw,number_of_lines=38"]
@@ -118,12 +160,21 @@ module ReVIEW
118
160
  end
119
161
  end
120
162
 
121
- def replace_compatible_block_command_outline(content, command, new_command, option_count)
122
- if option_count > 0
123
- content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
124
- else
125
- content.gsub!(/^\/\/#{command}(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
126
- end
163
+ def replace_compatible_block_command_outline(content, command, new_command, option_count, begin_option_pos=0)
164
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
165
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*$/, "//#{new_command}\\k<option>")
166
+ # if begin_option_pos > 0
167
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
168
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}$/, "//#{new_command}")
169
+ # end
170
+ end
171
+
172
+ def exclude_exta_option(content, cmd, max_option_num)
173
+ replace_compatible_block_command_outline(content, cmd, cmd, max_option_num)
174
+ end
175
+
176
+ def starter_caption_to_text(content, command, n)
177
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{n-1}})\[(?<caption>#{@r_option_inner})\](?<post>.*)$/, "\\k<caption>\n//#{command}\\k<option>\\k<post>")
127
178
  end
128
179
 
129
180
  def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
@@ -149,37 +200,30 @@ module ReVIEW
149
200
  content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
150
201
  end
151
202
 
152
- def delete_inline_command(content, command)
153
- # FIXME: 入れ子のフェンス記法({}|$)
154
- content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))((?:.*@<\w*>[\|${].*?[\|$}].*?|.*?)*)(?(1)(\$)|(?(2)(})|(\|)))/){"#{$4}"}
155
- end
156
-
157
- def replace_inline_command(content, command, new_command)
158
- content.gsub!(/@<#{command}>/, "@<#{new_command}>")
159
- end
160
-
161
203
  def replace_block_command_nested_boxed_article_i(content, box, depth)
162
204
  found = false
163
205
  content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
164
206
  matched = m[0..-1].join
165
207
  inner = m[5]
166
208
  # info depth
167
- im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
209
+ im = inner.match(/^\/\/(?<command>\w+)(?<options>(\[#{@r_option_inner}\])*)(?<open>[$|{])/)
168
210
  unless im.nil?
169
- inner_cmd = im[1]
170
- inner_open = im[4]
171
- inner_opts = im[2]
172
- first_opt_m = inner_opts.match(/^\[(.*?)\]/)
173
- first_opt = ""
211
+ inner_cmd = im['command']
212
+ inner_open = im['open']
213
+ inner_opts = im['options']
214
+ id_opt = ""
174
215
 
175
216
  # is_commentout = false
176
217
  is_commentout = true
177
- if first_opt_m
178
- first_opt_v = first_opt_m[1]
179
- unless first_opt_v.empty?
180
- if inner.match(/@<.*?>[$|{]#{first_opt}/)
181
- is_commentout = false
182
- first_opt = "\\[#{first_opt_v}\\]"
218
+ if ReViewDef::is_has_id_block_command(inner_cmd)
219
+ first_opt_m = inner_opts.match(/^\[(.*?)\]/)
220
+ if first_opt_m
221
+ first_opt_v = first_opt_m[1]
222
+ unless first_opt_v.empty?
223
+ if inner.match(/@<#{ReViewDef::id_ref_inline_commands().join('|')}>[$|{]#{first_opt_v}/)
224
+ is_commentout = false
225
+ id_opt = "\\[#{first_opt_v}\\]"
226
+ end
183
227
  end
184
228
  end
185
229
  end
@@ -189,24 +233,44 @@ module ReVIEW
189
233
  if inner_open == m[2..4].join
190
234
  # if same fence then cmd_end == inner_end
191
235
  if is_commentout
192
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
193
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#@##{cmd_end}")
236
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})/) {
237
+ line = $1
238
+ caption = ReViewDef::get_caption(line)
239
+ s = ""
240
+ s += "「#{caption}」\n\n" unless caption.blank?
241
+ s += "#@##{line}"
242
+ s
243
+ }
244
+ rep = "#{cmd_begin}#{inner}#@##{cmd_end}"
245
+ content.gsub!(matched) { |mm| rep }
194
246
  else
195
- imb = inner.match(/(\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/#{inner_cmd}#{first_opt}(\[.*?\])*#{inner_open}.*)\R/m)
247
+ imb = inner.match(/(\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/#{inner_cmd}#{id_opt}(\[#{@r_option_inner}\])*#{inner_open}.*)\R/m)
196
248
  to_out_block = imb[1]
197
249
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
198
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
250
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
251
+ content.gsub!(matched) { |mm| rep }
199
252
  end
200
253
  else
201
- close = inner_open == '{' ? '}' : inner_open
254
+ close = ReViewDef::fence_close(inner_open)
202
255
  if is_commentout
203
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})(.*?)(^\/\/#{close})/m, '#@#\1\2#@#\3')
204
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}")
256
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})(.*?)(^\/\/#{close})/m) {
257
+ first = $1
258
+ body = $2
259
+ last = $3
260
+ caption = ReViewDef::get_caption(first)
261
+ s = ""
262
+ s += "「#{caption}」\n\n" unless caption.blank?
263
+ s += "#@##{first}#{body}@##{last}"
264
+ s
265
+ }
266
+ rep = "#{cmd_begin}#{inner}#{cmd_end}"
267
+ content.gsub!(matched) { |mm| rep }
205
268
  else
206
- imb = inner.match(/\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/(#{inner_cmd})#{first_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
269
+ imb = inner.match(/\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/(#{inner_cmd})#{id_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
207
270
  to_out_block = imb[0]
208
271
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
209
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
272
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
273
+ content.gsub!(matched) { |mm| rep }
210
274
  end
211
275
  end
212
276
  found = true
@@ -222,7 +286,7 @@ module ReVIEW
222
286
  end
223
287
 
224
288
  def replace_block_command_nested_boxed_articles(content)
225
- unless Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('5.0.0')
289
+ unless ReViewCompat::has_nested_minicolumn()
226
290
  replace_block_command_nested_boxed_article(content, 'note')
227
291
  replace_block_command_nested_boxed_article(content, 'memo')
228
292
  replace_block_command_nested_boxed_article(content, 'tip')
@@ -234,24 +298,27 @@ module ReVIEW
234
298
  end
235
299
  end
236
300
 
301
+ # #@+++ ~ #@--- to #@#+++ #@#~ #@#---
237
302
  def replace_block_commentout(content)
238
303
  d = content.dup
239
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
304
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
240
305
  matched = m[0..-1].join
241
306
  inner = m[2]
242
- inner.gsub!(/(^.)/, '#@#\1')
243
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
307
+ inner.gsub!(/^/, '#@#')
308
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
309
+ content.gsub!(matched) { |mm| rep }
244
310
  }
245
311
  end
246
312
 
247
313
  def replace_block_commentout_without_sampleout(content)
248
314
  d = content.dup
249
315
  d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
250
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
316
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
251
317
  matched = m[0..-1].join
252
318
  inner = m[2]
253
- inner.gsub!(/(^.)/, '#@#\1')
254
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
319
+ inner.gsub!(/^/, '#@#\1')
320
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
321
+ content.gsub!(matched) { |mm| rep }
255
322
  }
256
323
  end
257
324
 
@@ -264,7 +331,8 @@ module ReVIEW
264
331
  option = m[1]
265
332
  inner = m[3]
266
333
  # inner.gsub!(/^\/\//, '//@<nop>{}')
267
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
334
+ rep = "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}"
335
+ content.gsub!(matched) { |mm| rep }
268
336
  }
269
337
  end
270
338
 
@@ -278,7 +346,7 @@ module ReVIEW
278
346
  end
279
347
 
280
348
  def fix_deprecated_list(content)
281
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
349
+ if ReViewCompat::is_need_space_term_list()
282
350
  content.gsub!(/^: (.*)/, ' : \1')
283
351
  end
284
352
  end
@@ -290,47 +358,124 @@ module ReVIEW
290
358
  ref = m[4]
291
359
  n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
292
360
  unless n.nil?
293
- content.gsub!(/#{Regexp.escape(matched)}/, n[1])
361
+ rep = n[1]
362
+ content.gsub!(matched) { |mm| rep }
294
363
  content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
295
364
  else
296
- # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
365
+ # content.gsub!(matched, "noteref<#{ref}>")
297
366
  end
298
367
  }
299
368
  end
300
369
 
370
+ def remove_option_param(content, commands, n, param)
371
+ content.gsub!(/(?<prev>^\/\/(#{commands.join('|')})(\[.*?\]){#{n-1}}\[.*?)((,|)\s*#{param}=[^,\]]*)(?<post>.*?\])/, '\k<prev>\k<post>')
372
+ end
373
+
301
374
  def remove_starter_options(content)
375
+ # image width
376
+ content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)(,|)(\s*)width=\s*([0-9.]+)%(?<after>.*?\])/) { |m|
377
+ m.gsub!(/width=\s*([0-9.]+)%/) {
378
+ value = $1
379
+ "scale=#{value.to_i * 0.01}"
380
+ }
381
+ }
382
+ remove_option_param(content, ["image"], 3, "width")
302
383
  # image border
303
- content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)((,|)border=[^,\]]*)(.*?\])/, '\1\4')
384
+ remove_option_param(content, ["image"], 3, "border")
385
+ # image pos
386
+ remove_option_param(content, ["image"], 3, "pos")
304
387
  # list lineno
305
- content.gsub!(/(^\/\/list\[.*?\]\[.*?\]\[.*?)((,|)lineno=[^,\]]*)(.*?\])/, '\1\4')
306
- end
307
-
308
- def expand_nested_inline_command(content)
309
- found = false
310
- content.dup.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
311
- matched = m.join
312
- body = m[4]
313
- im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
314
- if im.nil?
315
- im = body.match(/(.*)(@<.*?>)#{m[1..3].join}/)
316
- unless im.nil?
317
- outcmd_begin = m[0] + "$|{".gsub(m[1..3].join, '')
318
- outcmd_end = "$|}".gsub(m[5..7].join, '')
319
- rep = "#{outcmd_begin}#{body}#{outcmd_end}"
320
- content.gsub!(matched, rep)
321
- found = true
388
+ remove_option_param(content, ["list"], 3, "lineno")
389
+ end
390
+
391
+ # talklist to //#{cmd}[]{ //emlist[]{}... }
392
+ def talklist_to_nested_contents_list(content, cmd)
393
+ content.gsub!(/^\/\/talklist(.*?){/, "//#{cmd}\\1{")
394
+ content.gsub!(/^\/\/talk(?<options>\[#{@r_option_inner}\]\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
395
+ content.gsub!(/^\/\/t(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
396
+ content.gsub!(/^\/\/(t|talk)((\[#{@r_option_inner}\])*){/) { |s|
397
+ m = s.scan(/(\[(#{@r_option_inner})\])/)
398
+ # 1st option is image id
399
+ avatar = m[0][1]
400
+ first_option = m[0][0]
401
+ traling_options = m[1..-1].map{ |x| x[0] }.join
402
+ if avatar.length > 0
403
+ kv = @talk_shortcuts[avatar]
404
+ if kv&.key?('image')
405
+ "//indepimage[#{kv['image']}][][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
406
+ elsif kv&.key?('name')
407
+ "//emlist[#{kv['name']}]{"
408
+ else
409
+ "//indepimage#{first_option}[][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
322
410
  end
323
411
  else
324
- outcmd_begin = m[0..3].join
325
- outcmd_end = m[5..7].join
326
- rep = "#{outcmd_begin}#{im[1]}#{outcmd_end}#{im[2..9].join}#{outcmd_begin}#{im[-1]}#{outcmd_end}"
327
- content.gsub!(matched, rep)
328
- found = true
412
+ "//emlist#{traling_options}{"
329
413
  end
330
414
  }
331
- if found
332
- expand_nested_inline_command(content)
333
- end
415
+ end
416
+
417
+ # desclist to //#{cmd}[]{ //emlist[]{}... }
418
+ def desclist_to_nested_contents_list(content, cmd)
419
+ content.gsub!(/^\/\/desclist(.*?){/, "//#{cmd}\\1{")
420
+ content.gsub!(/^\/\/desc(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//desc\\k<options>{\n\\k<body>\n//}")
421
+ content.gsub!(/^\/\/desc((\[#{@r_option_inner}\])*){/, '//emlist\1{')
422
+ end
423
+
424
+ def starter_list_to_nested_contents_list(content)
425
+ # talklist
426
+ talklist_to_nested_contents_list(content, @talklist_replace_cmd)
427
+ # desclist
428
+ desclist_to_nested_contents_list(content, @desclist_replace_cmd)
429
+ replace_block_command_nested_boxed_article(content, 'emlist')
430
+ end
431
+
432
+ def convert_table_option(content)
433
+ r_table = /^(?<matched>\/\/table\[#{@r_option_inner}\]\[#{@r_option_inner}\]\[(?<options>#{@r_option_inner})\](?<open>.))$/
434
+ content.dup.scan(r_table) { |m|
435
+ matched = m[0]
436
+ options = m[1]
437
+ options.split(',').each { |option|
438
+ if option.match(/\s*csv\s*=\s*on\s*/)
439
+ open = m[2]
440
+ close = ReViewDef::fence_close(open)
441
+ if close
442
+ tm = content.match(/#{Regexp.escape(matched)}(.*?)^\/\/#{close}/m)
443
+ outer = tm[0]
444
+ inner = tm[1]
445
+ im = inner.match(/(.*?)([=\-]{12,}\R)(.*)/m)
446
+ if im
447
+ header = im[1]
448
+ sep = im[2]
449
+ body = im[3]
450
+ new_header = ""
451
+ new_body = ""
452
+ CSV.parse(header) do |h|
453
+ new_header += Utils::GenerateTsv(h)
454
+ end
455
+ CSV.parse(body) do |c|
456
+ new_body += Utils::GenerateTsv(c)
457
+ end
458
+ content.gsub!(outer, "#{matched}#{new_header}#{sep}#{new_body}//#{close}")
459
+ else
460
+ new_body = ""
461
+ CSV.parse(inner) do |c|
462
+ new_body += Utils::GenerateTsv(c)
463
+ end
464
+ content.gsub!(outer, "#{matched}#{new_body}//#{close}")
465
+ end
466
+ end
467
+ end
468
+ }
469
+ }
470
+ end
471
+
472
+ # tsize[builder][xxx] to tsize[|builder|xxx]
473
+ def replace_tsize(content)
474
+ content.gsub!(/^\/\/tsize\[(.*?)\]\[(.*?)\]/) {
475
+ builder = $1
476
+ builder = "" if $1 == '*'
477
+ "//tsize[|#{builder}|#{$2}]"
478
+ }
334
479
  end
335
480
 
336
481
  def copy_embedded_contents(outdir, content)
@@ -376,39 +521,123 @@ module ReVIEW
376
521
  }
377
522
  end
378
523
 
379
- def update_content(outdir, contentfile)
380
- info contentfile
381
- filename = File.basename(contentfile, '.*')
382
- content = File.read(contentfile)
383
- content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
384
- content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
385
- linkurl_footnote = @config['starter']['linkurl_footnote']
386
- # table 内の @ コマンドは不安定らしい
387
- while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
388
- end
389
- # 空セルが2行になることがあるらしい
390
- while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{@table_empty_replace}\\2").nil? do
391
- end
392
- # Re:VIEW Starter commands
393
- replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1)
394
- replace_compatible_block_command_outline(content, 'cmd', 'cmd', 0)
524
+ def replace_starter_command(content)
525
+ replace_compatible_block_command_outline(content, 'program', 'list', 2)
526
+ replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1, 1)
527
+ replace_compatible_block_command_outline(content, 'output', 'list', 3)
395
528
  replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
396
529
  replace_block_command_outline(content, 'abstract', 'lead', true)
530
+ delete_block_command(content, 'vspace')
397
531
  delete_block_command(content, 'needvspace')
398
532
  delete_block_command(content, 'clearpage')
399
533
  delete_block_command(content, 'flushright')
400
- delete_block_command(content, 'centering')
401
534
  delete_block_command(content, 'paragraphend')
535
+ delete_block_command_outer(content, 'centering')
536
+
537
+ # convert starter option
538
+ convert_table_option(content)
539
+
540
+ # delete starter option
541
+ # exclude_exta_option(content, 'cmd', 0)
542
+ starter_caption_to_text(content, 'cmd', 1)
543
+ exclude_exta_option(content, 'imgtable', 2)
544
+ exclude_exta_option(content, 'table', 2)
545
+ # exclude_exta_option(content, 'tsize', 1)
546
+ replace_tsize(content)
402
547
 
403
548
  # delete IRD unsupported commands
404
549
  if @ird
405
550
  delete_block_command(content, 'noindent')
406
551
  end
407
552
 
553
+ # chapterauthor
554
+ content.gsub!(/^\/\/chapterauthor\[(.*?)\]/, "//lead{\n\\1\n//}")
555
+ # talklist/desclist
556
+ starter_list_to_nested_contents_list(content)
557
+ end
558
+
559
+ def delete_inline_command(content, command)
560
+ # 既に入れ子は展開されている前提
561
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/, '\4')
562
+ end
563
+
564
+ def do_replace_inline_command(content, command, &blk)
565
+ # 既に入れ子は展開されている前提
566
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/) { blk.call([$1, $2, $3].join, $4, [$5, $6, $7].join) }
567
+ end
568
+
569
+ def replace_inline_command(content, command, new_command)
570
+ do_replace_inline_command(content, command) { |open, inner, close|
571
+ "@<#{new_command}>#{open}#{inner}#{close}"
572
+ }
573
+ end
574
+
575
+ # @<XXX>{AAA@<YYY>{BBB}} to @<XXX>{AAA}@<YYY>{BBB}
576
+ def expand_nested_inline_command(content)
577
+ found = false
578
+ content.dup.each_line do |line|
579
+ if line.match(/^#@#/)
580
+ next
581
+ end
582
+ line.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
583
+ matched = m.join
584
+ body = m[4]
585
+ outcmd_cmd = m[0]
586
+ outcmd_open = m[1..3].join
587
+ outcmd_begin = outcmd_cmd + outcmd_open
588
+ outcmd_close = m[5..7].join
589
+ im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
590
+ if im.nil?
591
+ # for {}
592
+ im2 = body.match(/(.*)(@<.*?>)#{Regexp.escape(outcmd_open)}(.*)/)
593
+ unless im2.nil?
594
+ rep = ""
595
+ if im2[3].length > 0
596
+ incmd_begin = im2[1..2].join + "$|{".gsub(outcmd_open, '')[0]
597
+ incmd_end = "$|}".gsub(outcmd_close, '')[0]
598
+ rep = "#{outcmd_begin}#{incmd_begin}#{im2[3]}#{incmd_end}"
599
+ else
600
+ rep = outcmd_begin + im2[1]
601
+ end
602
+ content.gsub!(matched) { |mm| rep }
603
+ found = true
604
+ else
605
+ # for |$
606
+ if body.match(/.*@<.*?>$/)
607
+ incmd_fence = "$|".gsub(outcmd_open, '')
608
+ rep = "#{outcmd_begin}#{body}#{incmd_fence}"
609
+ content.gsub!(/#{Regexp.escape(matched)}(.*?)#{Regexp.escape(outcmd_open)}/, "#{rep}\\1#{incmd_fence}")
610
+ found = true
611
+ end
612
+ end
613
+ else
614
+ rep = ""
615
+ rep += "#{outcmd_begin}#{im[1]}#{outcmd_close}" if im[1].length > 0
616
+ rep += "#{im[2..9].join}"
617
+ rep += "#{outcmd_begin}#{im[-1]}#{outcmd_close}" if im[-1].length > 0
618
+ content.gsub!(matched) { |mm| rep }
619
+ found = true
620
+ end
621
+ }
622
+ end
623
+ if found
624
+ expand_nested_inline_command(content)
625
+ end
626
+ end
627
+
628
+ def replace_starter_inline_command(content)
629
+ expand_nested_inline_command(content)
630
+
408
631
  replace_inline_command(content, 'secref', 'hd')
409
632
  replace_inline_command(content, 'file', 'kw')
410
633
  replace_inline_command(content, 'hlink', 'href')
411
634
  replace_inline_command(content, 'B', 'strong')
635
+ replace_inline_command(content, 'W', 'wb')
636
+ replace_inline_command(content, 'term', 'idx')
637
+ replace_inline_command(content, 'termnoidx', 'hidx')
638
+ unless ReViewCompat::has_bou()
639
+ replace_inline_command(content, 'bou', 'b')
640
+ end
412
641
  delete_inline_command(content, 'userinput')
413
642
  delete_inline_command(content, 'weak')
414
643
  delete_inline_command(content, 'cursor')
@@ -420,12 +649,37 @@ module ReVIEW
420
649
  delete_inline_command(content, 'xlarge')
421
650
  delete_inline_command(content, 'xxlarge')
422
651
 
652
+ do_replace_inline_command(content, 'par') { |open, inner, close| "@<br>#{open}#{close}" }
653
+ do_replace_inline_command(content, 'qq' ) { |open, inner, close| "\"#{inner}\"" }
654
+ end
655
+
656
+ def update_content(outdir, contentfile)
657
+ info contentfile
658
+ filename = File.basename(contentfile, '.*')
659
+ content = File.read(contentfile)
660
+ content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
661
+ content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
662
+ linkurl_footnote = @config['starter']['linkurl_footnote']
663
+ # table 内の @ コマンドは不安定らしい
664
+ while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{Regexp.escape(@table_br_replace)}\\2").nil? do
665
+ end
666
+ # 空セルが2行になることがあるらしい
667
+ while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{Regexp.escape(@table_empty_replace)}\\2").nil? do
668
+ end
669
+ # noop を最後に消すためにダミーに変える
670
+ content.gsub!('@<nop>$$', '@<dummynop>$must_be_replace_nop$')
671
+ content.gsub!('@<nop>||', '@<dummynop>|must_be_replace_nop|')
672
+ content.gsub!('@<nop>{}', '@<dummynop>{must_be_replace_nop}')
673
+
674
+ # Re:VIEW Starter commands
675
+ replace_starter_command(content)
676
+
423
677
  # fixed lack of options
424
678
  content.gsub!(/^\/\/list{/, '//list[][]{')
425
679
  # empty br line to blankline
426
680
  content.gsub!(/^\s*@<br>{}\s*$/, '//blankline')
427
681
 
428
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
682
+ unless ReViewCompat::is_allow_empty_image_caption()
429
683
  # empty caption is not allow
430
684
  content.gsub!(/^\/\/image\[(.*)\]\[\]{/, '//image[\1][ ]{')
431
685
  end
@@ -441,6 +695,7 @@ module ReVIEW
441
695
  replace_block_command_nested_boxed_articles(content)
442
696
 
443
697
  # empty ids
698
+ replace_auto_ids(content, 'table', 2)
444
699
  replace_auto_ids(content, 'list', 2)
445
700
  replace_auto_ids(content, 'listnum', 2)
446
701
 
@@ -456,13 +711,7 @@ module ReVIEW
456
711
  content.gsub!('@<TeX>{}', 'TeX')
457
712
  content.gsub!('@<hearts>{}', '!HEART!')
458
713
 
459
- # nop replace must be last step
460
- content.gsub!('@<nop>$$', '@<b>$$')
461
- content.gsub!('@<nop>||', '@<b>||')
462
- content.gsub!('@<nop>{}', '@<b>{}')
463
-
464
- # expand nested inline command
465
- expand_nested_inline_command(content)
714
+ replace_starter_inline_command(content)
466
715
 
467
716
  # fix deprecated
468
717
  fix_deprecated_list(content)
@@ -473,6 +722,13 @@ module ReVIEW
473
722
  content.gsub!(/(.*)@<br>{}(.*)$/, "\\1\n\n\\2")
474
723
  end
475
724
 
725
+ # nop replace must be last step
726
+ # content.gsub!('@<dumynop>$must_be_replace_nop$', '@<b>$$')
727
+ # content.gsub!('@<dumynop>|must_be_replace_nop|', '@<b>||')
728
+ content.gsub!('@<dummynop>$must_be_replace_nop$', '@<b>{}')
729
+ content.gsub!('@<dummynop>|must_be_replace_nop|', '@<b>{}')
730
+ content.gsub!('@<dummynop>{must_be_replace_nop}', '@<b>{}')
731
+
476
732
  File.write(contentfile, content)
477
733
  copy_embedded_contents(outdir, content)
478
734
  end
@@ -503,7 +759,7 @@ module ReVIEW
503
759
  contentdir = abspath
504
760
  info 'replace starter block command'
505
761
  info 'replace starter inline command'
506
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
762
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
507
763
  update_content_files(outdir, contentdir, @catalog_contents)
508
764
  unless options['strict']
509
765
  all_contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -518,12 +774,10 @@ module ReVIEW
518
774
  contentpath = File.join(contentdir, content)
519
775
  if File.exist?(contentpath)
520
776
  info "preproc #{contentpath}"
521
- buf = StringIO.new
522
777
  pwd = Dir.pwd
523
778
  Dir.chdir(outdir)
524
- File.open(contentpath) { |f| pp.process(f, buf) }
779
+ content = pp.process(contentpath)
525
780
  Dir.chdir(pwd)
526
- content = buf.string
527
781
  content.gsub!(/^#[@]map.*$/, '')
528
782
  content.gsub!(/^#[@]end$/, '')
529
783
  File.write(contentpath, content)
@@ -537,10 +791,10 @@ module ReVIEW
537
791
  contentdir = abspath
538
792
  param = {}
539
793
  param['tabwidth'] = options['tabwidth'].to_i
540
- pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
794
+ pp = ReViewCompat::Preprocessor(param)
541
795
 
542
796
  if options['strict']
543
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
797
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
544
798
  preproc_content_files(outdir, pp, contentdir, @catalog_contents)
545
799
  else
546
800
  contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -548,12 +802,20 @@ module ReVIEW
548
802
  end
549
803
  end
550
804
 
805
+ def erb_sty(outdir, filename)
806
+ src = File.join(__dir__, "sty/#{filename}.erb")
807
+ dest = File.join(outdir, "sty/#{filename}")
808
+ erb = ERB.new(File.read(src))
809
+ File.write(dest, erb.result)
810
+ end
811
+
551
812
  def update_sty(outdir, options)
552
- # FileUtils.cp(File.join(@basedir, 'sty/review-custom.sty'), File.join(outdir, 'sty/review-custom.sty'))
813
+ review_custom_sty = File.open(File.join(outdir, 'sty/review-custom.sty'), 'a')
814
+ erb_sty(outdir, 'review-retrovert-custom.sty')
815
+ review_custom_sty.puts('\RequirePackage{review-retrovert-custom}')
553
816
  if @ird
554
- FileUtils.cp(File.join(__dir__, 'sty/ird.sty'), File.join(outdir, 'sty/ird.sty'))
555
- file = File.open(File.join(outdir, 'sty/review-custom.sty'), 'a')
556
- file.puts('\RequirePackage{ird}')
817
+ erb_sty(outdir, 'ird.sty')
818
+ review_custom_sty.puts('\RequirePackage{ird}')
557
819
  end
558
820
  end
559
821
 
@@ -581,7 +843,7 @@ module ReVIEW
581
843
  @basedir = @configs.basedir
582
844
  @srccontentsdir = @config['contentdir']
583
845
 
584
- catalog = ReVIEW::Catalog.new(File.open(@configs.catalogfile()))
846
+ catalog = ReViewCompat::Catalog(@configs.catalogfile())
585
847
  add_catalog_contents(catalog.predef())
586
848
  add_catalog_contents(catalog.chaps())
587
849
  add_catalog_contents(catalog.appendix())
@@ -601,6 +863,7 @@ module ReVIEW
601
863
  load_config(yamlfile)
602
864
  store_image_dir = store_out_image(outdir) if options['no-image']
603
865
  create_initial_project(outdir, options)
866
+ @talk_shortcuts = @config['starter']['talk_shortcuts']
604
867
 
605
868
  copy_config(outdir)
606
869
  copy_catalog(outdir)