review-retrovert 0.9.5 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) 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/README.md +18 -3
  10. data/docker/review.Dockerfile +10 -0
  11. data/lib/review/retrovert/cli.rb +2 -0
  12. data/lib/review/retrovert/converter.rb +520 -124
  13. data/lib/review/retrovert/ext/review-ext.rb +71 -0
  14. data/lib/review/retrovert/reviewcompat.rb +57 -0
  15. data/lib/review/retrovert/reviewdef.rb +70 -0
  16. data/lib/review/retrovert/sty/ird.sty.erb +326 -0
  17. data/lib/review/retrovert/sty/review-retrovert-custom.sty.erb +6 -0
  18. data/lib/review/retrovert/utils.rb +35 -0
  19. data/lib/review/retrovert/version.rb +1 -1
  20. data/lib/review/retrovert/yamlconfig.rb +0 -1
  21. data/package-lock.json +6 -0
  22. data/package.json +1 -0
  23. data/review-retrovert.gemspec +5 -1
  24. data/testdata/mybook/.gitignore +3 -1
  25. data/testdata/mybook/.textlintrc +11 -0
  26. data/testdata/mybook/Rakefile +8 -0
  27. data/testdata/mybook/catalog.yml +36 -10
  28. data/testdata/mybook/config-retrovert.yml +9 -0
  29. data/testdata/mybook/config-starter.yml +134 -9
  30. data/testdata/mybook/config.yml +44 -15
  31. data/testdata/mybook/contents/00-preface.re +48 -2
  32. data/testdata/mybook/contents/01-install.re +38 -5
  33. data/testdata/mybook/contents/02-tutorial.re +333 -113
  34. data/testdata/mybook/contents/03-syntax.re +2370 -373
  35. data/testdata/mybook/contents/04-customize.re +424 -88
  36. data/testdata/mybook/contents/05-faq.re +288 -10
  37. data/testdata/mybook/contents/06-bestpractice.re +431 -59
  38. data/testdata/mybook/contents/91-compare.re +402 -2
  39. data/testdata/mybook/contents/92-filelist.re +14 -8
  40. data/testdata/mybook/contents/93-background.re +10 -10
  41. data/testdata/mybook/contents/99-postface.re +2 -1
  42. data/testdata/mybook/contents/r0-root.re +24 -2
  43. data/testdata/mybook/contents/table.csv +4 -0
  44. data/testdata/mybook/contents/test.txt +1 -0
  45. data/testdata/mybook/css/webstyle.css +180 -2
  46. data/testdata/mybook/data/terms.txt +3 -0
  47. data/testdata/mybook/data/words.txt +15 -0
  48. data/testdata/mybook/images/03-syntax/index-page.png +0 -0
  49. data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
  50. data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
  51. data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
  52. data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
  53. data/testdata/mybook/images/avatar-b.png +0 -0
  54. data/testdata/mybook/images/avatar-g.png +0 -0
  55. data/testdata/mybook/images/avatar-r.png +0 -0
  56. data/testdata/mybook/images/caution-icon.png +0 -0
  57. data/testdata/mybook/images/info-icon.png +0 -0
  58. data/testdata/mybook/images/warning-icon.png +0 -0
  59. data/testdata/mybook/layouts/layout.html5.erb +3 -1
  60. data/testdata/mybook/layouts/layout.tex.erb +265 -379
  61. data/testdata/mybook/layouts/layout.tex.erb.orig +386 -0
  62. data/testdata/mybook/lib/ruby/review-book.rb +64 -0
  63. data/testdata/mybook/lib/ruby/review-builder.rb +902 -63
  64. data/testdata/mybook/lib/ruby/review-compiler.rb +675 -22
  65. data/testdata/mybook/lib/ruby/review-epubbuilder.rb +33 -0
  66. data/testdata/mybook/lib/ruby/review-epubmaker.rb +10 -7
  67. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +354 -66
  68. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +429 -146
  69. data/testdata/mybook/lib/ruby/review-maker.rb +117 -6
  70. data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +945 -0
  71. data/testdata/mybook/lib/ruby/review-markdownmaker.rb +91 -0
  72. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +2 -0
  73. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +160 -82
  74. data/testdata/mybook/lib/ruby/review-webmaker.rb +20 -5
  75. data/testdata/mybook/lib/tasks/review.rake +14 -0
  76. data/testdata/mybook/lib/tasks/starter.rake +148 -4
  77. data/testdata/mybook/sty/indexstyle.ist +25 -0
  78. data/testdata/mybook/sty/mytextsize.sty +29 -0
  79. data/testdata/mybook/sty/mytitlepage.sty +34 -11
  80. data/testdata/mybook/sty/review-base.sty +276 -0
  81. data/testdata/mybook/sty/starter-codeblock.sty +237 -106
  82. data/testdata/mybook/sty/starter-color.sty +72 -17
  83. data/testdata/mybook/sty/starter-heading.sty +60 -13
  84. data/testdata/mybook/sty/starter-misc.sty +894 -0
  85. data/testdata/mybook/sty/starter-note.sty +67 -14
  86. data/testdata/mybook/sty/starter-talklist.sty +105 -0
  87. data/testdata/mybook/sty/starter-util.sty +35 -0
  88. data/testdata/mybook/sty/starter.sty +8 -526
  89. metadata +83 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1800fdc491a64bc922e8164e966bf6f84c4c2c2439a2330e106398ea97c55cc8
4
- data.tar.gz: 3b1c672c1c85dc6ec2ca28628c64b4ba0f14263eacdc1952d4ca9427644446bf
3
+ metadata.gz: 53d9d91f7b09b23b82d592e511474884b0fa179c39c0ee008a7aad2c69435ddb
4
+ data.tar.gz: 2f72ede1612ddcc17733fbffa6cab7e9acd1479de4d74f04f6e91af3b0de67bd
5
5
  SHA512:
6
- metadata.gz: acf0b640bb8ebb2e3f4549103dd73be14e2258f85a720580d8cb0bdb31d5f150e3ffde958dd77672ba16fd3a9b1f5a99e87d65927dfe9277186e529b89298c57
7
- data.tar.gz: 5c16364152fc108a2214f1126f3583435dba1eafb080e6c07c3fc20a3de8d7702921e8a89143ce6577323182e10df3da50f9b3f08e07115203e1cbcb6d07a319
6
+ metadata.gz: 4e37f04cfa04cdaf146ec9b4db1ac784c2f94f372d43ea43adb2ce451ea01191cb90ad3c2307d6acd405b75178bd5d996e29d292cef6f34235a6e682c7b04fad
7
+ data.tar.gz: 86f95748aaf68ff476af88c72dd2ab7ac095c92a0f96c2c66ae280b56b5438b20840c01e45d89a1d14bdb8e4ccc43ea21d3dad208c14dc876b5474c825deff05
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.5)
4
+ review-retrovert (0.9.9)
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
data/README.md CHANGED
@@ -21,6 +21,12 @@ And then execute:
21
21
  Or install it yourself as:
22
22
 
23
23
  $ gem install review-retrovert
24
+
25
+ ## Use Docker
26
+
27
+ ```
28
+ docker run -v "$(pwd):/work" -w /work srzzumix/review-retrovert convert target/config.yml outdir
29
+ ```
24
30
 
25
31
  ## Commands
26
32
 
@@ -33,16 +39,16 @@ Commands:
33
39
 
34
40
  ### Convert
35
41
 
36
- e.g.
42
+ #### e.g.
37
43
 
38
44
  ```sh
39
45
  review-retrovert convert /path/to/dir/review-starter/config.yml <output directory>
40
46
  ```
41
47
 
42
- Options
48
+ #### Options
43
49
 
44
50
  ```sh
45
- Usage:
51
+ sage:
46
52
  review-retrovert convert {review_starter_configfile} {outdir}
47
53
 
48
54
  Options:
@@ -54,6 +60,8 @@ Options:
54
60
  [--table-br-replace=TABLE-BR-REPLACE] # @<br>{} in table replace string (Default: empty)
55
61
  [--table-empty-replace=TABLE-EMPTY-REPLACE] # empty cell(.) in table replace string (Default full-width space)
56
62
  # Default:  
63
+ [--ird], [--no-ird] # for IRD
64
+ [--no-image] # donot copy image
57
65
 
58
66
  convert Re:VIEW Starter project to Re:VIEW project
59
67
  ```
@@ -85,6 +93,13 @@ inherit: ["config-base.yml", "config-starter.yml", "config-retrovert.yml"]
85
93
  #chapterlink: true
86
94
  ```
87
95
 
96
+ ## Experimental
97
+
98
+ ### IRD sty
99
+
100
+ --ird オプションを付けると IRD 組版に近いレイアウトにするために ird.sty と reveiw-ext.rb をプロジェクトに追加します。
101
+ こちらは実験的機能です。
102
+
88
103
  ## Development
89
104
 
90
105
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -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
@@ -11,6 +11,8 @@ module ReVIEW
11
11
  method_option "tabwidth", desc: 'Preproc tabwidth option value', type: :numeric, default: 0
12
12
  method_option "table-br-replace", desc: '@<br>{} in table replace string (Default: empty)', type: :string, default: ''
13
13
  method_option "table-empty-replace", desc: 'empty cell(.) in table replace string (Default full-width space)', type: :string, default: ' '
14
+ method_option "ird", desc: 'for IRD', type: :boolean
15
+ method_option "no-image", desc: 'donot copy image', type: :boolean
14
16
  def convert(review_starter_configfile, outdir)
15
17
  Converter.execute(review_starter_configfile, outdir, options)
16
18
  end
@@ -1,6 +1,11 @@
1
- require "review"
1
+ require 'review'
2
+ require 'erb'
2
3
  require 'fileutils'
3
- require "review/retrovert/yamlconfig"
4
+ require 'tmpdir'
5
+ require 'review/retrovert/yamlconfig'
6
+ require 'review/retrovert/reviewcompat'
7
+ require 'review/retrovert/reviewdef'
8
+ require 'review/retrovert/utils'
4
9
 
5
10
  module ReVIEW
6
11
  module Retrovert
@@ -15,6 +20,13 @@ module ReVIEW
15
20
  @configs = YamlConfig.new
16
21
  @embeded_contents = []
17
22
  @catalog_contents = []
23
+ @talk_shortcuts = {}
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
18
30
  end
19
31
 
20
32
  def error(msg)
@@ -47,46 +59,132 @@ module ReVIEW
47
59
  FileUtils.cp_r(Dir.glob(File.join(path, '*.re')), outdir)
48
60
  end
49
61
 
50
- def copy_images(outdir)
62
+ def get_out_imagedir(outdir)
51
63
  imagedir = @config['imagedir']
52
- srcpath = File.join(@basedir, imagedir)
53
64
  outimagedir = File.basename(imagedir) # Re:VIEW not support sub-directory
54
65
  outpath = File.join(outdir, outimagedir)
66
+ return outpath
67
+ end
68
+
69
+ def store_out_image(outdir)
70
+ outpath = get_out_imagedir(outdir)
71
+ if File.exist?(outpath)
72
+ dir = Dir.mktmpdir('review-retrovert')
73
+ FileUtils.mv(Dir.glob(File.join(outpath, "**/*")), dir)
74
+ return dir
75
+ end
76
+ return nil
77
+ end
78
+
79
+ def restore_out_image(outpath, tmpdir)
80
+ if File.exist?(tmpdir)
81
+ FileUtils.mkdir_p(outpath)
82
+ FileUtils.mv(Dir.glob(File.join(tmpdir, "**/*")), outpath)
83
+ FileUtils.rm_rf(tmpdir)
84
+ end
85
+ end
86
+
87
+ def copy_images(outdir, store_image_dir)
88
+ imagedir = @config['imagedir']
89
+ outimagedir = File.basename(imagedir) # Re:VIEW not support sub-directory
90
+ outpath = get_out_imagedir(outdir)
55
91
  FileUtils.mkdir_p(outpath)
56
- image_ext = @config['image_ext']
57
- srcroot = Pathname.new(srcpath)
58
- image_ext.each { |ext|
59
- Dir.glob(File.join(srcpath, "**/*.#{ext}")).each { |srcimg|
60
- outimg = File.join(outpath, Pathname.new(srcimg).relative_path_from(srcroot))
61
- FileUtils.makedirs(File.dirname(outimg))
62
- FileUtils.cp(srcimg, outimg)
92
+ if store_image_dir
93
+ restore_out_image(outpath, store_image_dir)
94
+ else
95
+ srcpath = File.join(@basedir, imagedir)
96
+ image_ext = @config['image_ext']
97
+ srcroot = Pathname.new(srcpath)
98
+ image_ext.each { |ext|
99
+ Dir.glob(File.join(srcpath, "**/*.#{ext}")).each { |srcimg|
100
+ outimg = File.join(outpath, Pathname.new(srcimg).relative_path_from(srcroot))
101
+ FileUtils.makedirs(File.dirname(outimg))
102
+ FileUtils.cp(srcimg, outimg)
103
+ }
63
104
  }
64
- }
105
+ end
65
106
  @configs.rewrite_yml('imagedir', outimagedir)
66
107
  end
67
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
+
68
121
  def update_config(outdir)
69
122
  @configs.rewrite_yml('contentdir', '.')
70
123
  @configs.rewrite_yml('hook_beforetexcompile', 'null')
71
124
  @configs.rewrite_yml('texstyle', '["reviewmacro"]')
72
- # @configs.rewrite_yml('chapterlink', 'null')
73
125
  pagesize = @config['starter']['pagesize'].downcase
74
- @configs.rewrite_yml_array('texdocumentclass', "[\"review-jsbook\", \"media=print,paper=#{pagesize}\"]")
126
+ jsbook_config = "media=print,paper=#{pagesize}"
127
+
128
+ # words
129
+ words_files = @config['words_file']
130
+ if words_files
131
+ if words_files.is_a?(Array)
132
+ new_words_files = []
133
+ words_files.each do |words_file|
134
+ new_words_files.push copy_wards(outdir, words_file)
135
+ end
136
+ @configs.rewrite_yml('words_file', "[#{new_words_files.join(',')}]")
137
+ else
138
+ new_words_file = copy_wards(outdir, words_files)
139
+ @configs.rewrite_yml('words_file', new_words_file)
140
+ end
141
+ end
142
+
143
+ # makeindex_dic
144
+ makeindex_dic = @config['pdfmaker']['makeindex_dic']
145
+ if makeindex_dic
146
+ FileUtils.copy(File.join(@basedir, makeindex_dic), File.join(outdir, makeindex_dic))
147
+ end
148
+
149
+ if @ird
150
+ # # リュウミン Pr6N R-KL 12.5Q 22H (9pt = 12.7Q 15.5pt = 21.8Q(H))
151
+ # 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"]
152
+ jsbook_config = "media=ebook,openany,paper=b5,fontsize=9pt,baselineskip=15.5pt,head_space=15mm,gutter=22mm,footskip=16mm,line_length=45zw,number_of_lines=38"
153
+ end
154
+ @configs.rewrite_yml_array('texdocumentclass', "[\"review-jsbook\", \"#{jsbook_config}\"]")
75
155
  @config['retrovert'].each{ |k,v|
76
156
  unless v..is_a?(Hash)
77
157
  @configs.commentout_root_yml(k)
78
158
  end
79
159
  }
160
+ if @ird
161
+ @configs.rewrite_yml('chapterlink', 'null')
162
+ end
80
163
  end
81
164
 
82
- def replace_compatible_block_command_outline(content, command, new_command, option_count)
83
- if option_count > 0
84
- content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
85
- else
86
- content.gsub!(/^\/\/#{command}(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
165
+ def replace_compatible_block_command_outline(content, command, new_command, option_count, begin_option_pos=0)
166
+ 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>//}")
167
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*$/, "//#{new_command}\\k<option>")
168
+ # if begin_option_pos > 0
169
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
170
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}$/, "//#{new_command}")
171
+ # end
172
+ end
173
+
174
+ def exclude_exta_option(content, cmd, max_option_num)
175
+ replace_compatible_block_command_outline(content, cmd, cmd, max_option_num)
176
+ end
177
+
178
+ def exclude_exta_options(content, commands, max_option_num)
179
+ commands.each do |cmd|
180
+ exclude_exta_option(content, cmd, max_option_num)
87
181
  end
88
182
  end
89
183
 
184
+ def starter_caption_to_text(content, command, n)
185
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{n-1}})\[(?<caption>#{@r_option_inner})\](?<post>.*)$/, "\\k<caption>\n//#{command}\\k<option>\\k<post>")
186
+ end
187
+
90
188
  def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
91
189
  body = new_body
92
190
  body += '\n' unless body.empty?
@@ -110,37 +208,30 @@ module ReVIEW
110
208
  content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
111
209
  end
112
210
 
113
- def delete_inline_command(content, command)
114
- # FIXME: 入れ子のフェンス記法({}|$)
115
- content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))((?:.*@<\w*>[\|${].*?[\|$}].*?|.*?)*)(?(1)(\$)|(?(2)(})|(\|)))/){"#{$4}"}
116
- end
117
-
118
- def replace_inline_command(content, command, new_command)
119
- content.gsub!(/@<#{command}>/, "@<#{new_command}>")
120
- end
121
-
122
211
  def replace_block_command_nested_boxed_article_i(content, box, depth)
123
212
  found = false
124
213
  content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
125
214
  matched = m[0..-1].join
126
215
  inner = m[5]
127
216
  # info depth
128
- im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
217
+ im = inner.match(/^\/\/(?<command>\w+)(?<options>(\[#{@r_option_inner}\])*)(?<open>[$|{])/)
129
218
  unless im.nil?
130
- inner_cmd = im[1]
131
- inner_open = im[4]
132
- inner_opts = im[2]
133
- first_opt_m = inner_opts.match(/^\[(.*?)\]/)
134
- first_opt = ""
219
+ inner_cmd = im['command']
220
+ inner_open = im['open']
221
+ inner_opts = im['options']
222
+ id_opt = ""
135
223
 
136
224
  # is_commentout = false
137
225
  is_commentout = true
138
- if first_opt_m
139
- first_opt_v = first_opt_m[1]
140
- unless first_opt_v.empty?
141
- if inner.match(/@<.*?>[$|{]#{first_opt}/)
142
- is_commentout = false
143
- first_opt = "\\[#{first_opt_v}\\]"
226
+ if ReViewDef::is_has_id_block_command(inner_cmd)
227
+ first_opt_m = inner_opts.match(/^\[(.*?)\]/)
228
+ if first_opt_m
229
+ first_opt_v = first_opt_m[1]
230
+ unless first_opt_v.empty?
231
+ if inner.match(/@<#{ReViewDef::id_ref_inline_commands().join('|')}>[$|{]#{first_opt_v}/)
232
+ is_commentout = false
233
+ id_opt = "\\[#{first_opt_v}\\]"
234
+ end
144
235
  end
145
236
  end
146
237
  end
@@ -150,24 +241,44 @@ module ReVIEW
150
241
  if inner_open == m[2..4].join
151
242
  # if same fence then cmd_end == inner_end
152
243
  if is_commentout
153
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
154
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#@##{cmd_end}")
244
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})/) {
245
+ line = $1
246
+ caption = ReViewDef::get_caption(line)
247
+ s = ""
248
+ s += "「#{caption}」\n\n" unless caption.blank?
249
+ s += "#@##{line}"
250
+ s
251
+ }
252
+ rep = "#{cmd_begin}#{inner}#@##{cmd_end}"
253
+ content.gsub!(matched) { |mm| rep }
155
254
  else
156
- imb = inner.match(/(\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/#{inner_cmd}#{first_opt}(\[.*?\])*#{inner_open}.*)\R/m)
255
+ imb = inner.match(/(\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/#{inner_cmd}#{id_opt}(\[#{@r_option_inner}\])*#{inner_open}.*)\R/m)
157
256
  to_out_block = imb[1]
158
257
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
159
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
258
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
259
+ content.gsub!(matched) { |mm| rep }
160
260
  end
161
261
  else
162
- close = inner_open == '{' ? '}' : inner_open
262
+ close = ReViewDef::fence_close(inner_open)
163
263
  if is_commentout
164
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})(.*?)(^\/\/#{close})/m, '#@#\1\2#@#\3')
165
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}")
264
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})(.*?)(^\/\/#{close})/m) {
265
+ first = $1
266
+ body = $2
267
+ last = $3
268
+ caption = ReViewDef::get_caption(first)
269
+ s = ""
270
+ s += "「#{caption}」\n\n" unless caption.blank?
271
+ s += "#@##{first}#{body}@##{last}"
272
+ s
273
+ }
274
+ rep = "#{cmd_begin}#{inner}#{cmd_end}"
275
+ content.gsub!(matched) { |mm| rep }
166
276
  else
167
- imb = inner.match(/\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/(#{inner_cmd})#{first_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
277
+ imb = inner.match(/\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/(#{inner_cmd})#{id_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
168
278
  to_out_block = imb[0]
169
279
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
170
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
280
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
281
+ content.gsub!(matched) { |mm| rep }
171
282
  end
172
283
  end
173
284
  found = true
@@ -183,7 +294,7 @@ module ReVIEW
183
294
  end
184
295
 
185
296
  def replace_block_command_nested_boxed_articles(content)
186
- unless Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('5.0.0')
297
+ unless ReViewCompat::has_nested_minicolumn()
187
298
  replace_block_command_nested_boxed_article(content, 'note')
188
299
  replace_block_command_nested_boxed_article(content, 'memo')
189
300
  replace_block_command_nested_boxed_article(content, 'tip')
@@ -195,24 +306,27 @@ module ReVIEW
195
306
  end
196
307
  end
197
308
 
309
+ # #@+++ ~ #@--- to #@#+++ #@#~ #@#---
198
310
  def replace_block_commentout(content)
199
311
  d = content.dup
200
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
312
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
201
313
  matched = m[0..-1].join
202
314
  inner = m[2]
203
- inner.gsub!(/(^.)/, '#@#\1')
204
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
315
+ inner.gsub!(/^/, '#@#')
316
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
317
+ content.gsub!(matched) { |mm| rep }
205
318
  }
206
319
  end
207
320
 
208
321
  def replace_block_commentout_without_sampleout(content)
209
322
  d = content.dup
210
323
  d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
211
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
324
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
212
325
  matched = m[0..-1].join
213
326
  inner = m[2]
214
- inner.gsub!(/(^.)/, '#@#\1')
215
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
327
+ inner.gsub!(/^/, '#@#\1')
328
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
329
+ content.gsub!(matched) { |mm| rep }
216
330
  }
217
331
  end
218
332
 
@@ -225,7 +339,8 @@ module ReVIEW
225
339
  option = m[1]
226
340
  inner = m[3]
227
341
  # inner.gsub!(/^\/\//, '//@<nop>{}')
228
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
342
+ rep = "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}"
343
+ content.gsub!(matched) { |mm| rep }
229
344
  }
230
345
  end
231
346
 
@@ -239,7 +354,7 @@ module ReVIEW
239
354
  end
240
355
 
241
356
  def fix_deprecated_list(content)
242
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
357
+ if ReViewCompat::is_need_space_term_list()
243
358
  content.gsub!(/^: (.*)/, ' : \1')
244
359
  end
245
360
  end
@@ -251,57 +366,181 @@ module ReVIEW
251
366
  ref = m[4]
252
367
  n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
253
368
  unless n.nil?
254
- content.gsub!(/#{Regexp.escape(matched)}/, n[1])
369
+ rep = n[1]
370
+ content.gsub!(matched) { |mm| rep }
255
371
  content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
256
372
  else
257
- # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
373
+ # content.gsub!(matched, "noteref<#{ref}>")
258
374
  end
259
375
  }
260
376
  end
261
377
 
378
+ def remove_option_param(content, commands, n, param)
379
+ content.gsub!(/(^\/\/(#{commands.join('|')})(\[.*?\]){#{n-1}}\[.*?)((,|)\s*#{param}=[^,\]]*)(.*?\])/) {
380
+ prev = $1
381
+ cmd = $2
382
+ opt = $4
383
+ post = $6
384
+ "#{prev}#{post}"
385
+ }
386
+ end
387
+
262
388
  def remove_starter_options(content)
389
+ # image width
390
+ content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)(,|)(\s*)width=\s*([0-9.]+)%(?<after>.*?\])/) { |m|
391
+ m.gsub!(/width=\s*([0-9.]+)%/) {
392
+ value = $1
393
+ "scale=#{value.to_i * 0.01}"
394
+ }
395
+ }
396
+ remove_option_param(content, ["image"], 3, "width")
263
397
  # image border
264
- content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)((,|)border=[^,\]]*)(.*?\])/, '\1\4')
398
+ remove_option_param(content, ["image"], 3, "border")
399
+ # image pos
400
+ remove_option_param(content, ["image"], 3, "pos")
265
401
  # list lineno
266
- content.gsub!(/(^\/\/list\[.*?\]\[.*?\]\[.*?)((,|)lineno=[^,\]]*)(.*?\])/, '\1\4')
267
- end
268
-
269
- def expand_nested_inline_command(content)
270
- found = false
271
- content.dup.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
272
- matched = m.join
273
- body = m[4]
274
- im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
275
- if im.nil?
276
- im = body.match(/(.*)(@<.*?>)#{m[1..3].join}/)
277
- unless im.nil?
278
- outcmd_begin = m[0] + "$|{".gsub(m[1..3].join, '')
279
- outcmd_end = "$|}".gsub(m[5..7].join, '')
280
- rep = "#{outcmd_begin}#{body}#{outcmd_end}"
281
- content.gsub!(matched, rep)
282
- found = true
402
+ remove_option_param(content, ["list", "listnum"], 3, "lineno")
403
+ end
404
+
405
+ # talklist to //#{cmd}[]{ //emlist[]{}... }
406
+ def talklist_to_nested_contents_list(content, cmd)
407
+ content.gsub!(/^\/\/talklist(.*?){/, "//#{cmd}\\1{")
408
+ content.gsub!(/^\/\/talk(?<options>\[#{@r_option_inner}\]\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
409
+ content.gsub!(/^\/\/t(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
410
+ content.gsub!(/^\/\/(t|talk)((\[#{@r_option_inner}\])*){/) { |s|
411
+ m = s.scan(/(\[(#{@r_option_inner})\])/)
412
+ # 1st option is image id
413
+ avatar = m[0][1]
414
+ first_option = m[0][0]
415
+ traling_options = m[1..-1].map{ |x| x[0] }.join
416
+ if avatar.length > 0
417
+ kv = @talk_shortcuts[avatar]
418
+ if kv&.key?('image')
419
+ "//indepimage[#{kv['image']}][][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
420
+ elsif kv&.key?('name')
421
+ "//emlist[#{kv['name']}]{"
422
+ else
423
+ "//indepimage#{first_option}[][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
283
424
  end
284
425
  else
285
- outcmd_begin = m[0..3].join
286
- outcmd_end = m[5..7].join
287
- rep = "#{outcmd_begin}#{im[1]}#{outcmd_end}#{im[2..9].join}#{outcmd_begin}#{im[-1]}#{outcmd_end}"
288
- content.gsub!(matched, rep)
289
- found = true
426
+ "//emlist#{traling_options}{"
290
427
  end
291
428
  }
292
- if found
293
- expand_nested_inline_command(content)
429
+ end
430
+
431
+ # desclist to //#{cmd}[]{ //emlist[]{}... }
432
+ def desclist_to_nested_contents_list(content, cmd)
433
+ content.gsub!(/^\/\/desclist(.*?){/, "//#{cmd}\\1{")
434
+ content.gsub!(/^\/\/desc(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//desc\\k<options>{\n\\k<body>\n//}")
435
+ content.gsub!(/^\/\/desc((\[#{@r_option_inner}\])*){/, '//emlist\1{')
436
+ end
437
+
438
+ def starter_list_to_nested_contents_list(content)
439
+ # talklist
440
+ talklist_to_nested_contents_list(content, @talklist_replace_cmd)
441
+ # desclist
442
+ desclist_to_nested_contents_list(content, @desclist_replace_cmd)
443
+ replace_block_command_nested_boxed_article(content, 'emlist')
444
+ end
445
+
446
+ def replace_file_option(content, matched, fence_open, option)
447
+ file_param_m = option.match(/\s*file\s*=\s*([^,\]]*)/)
448
+ if file_param_m
449
+ fence_close = ReViewDef::fence_close(fence_open)
450
+ filepath = file_param_m[1]
451
+ if fence_close
452
+ content.gsub!(/#{Regexp.escape(matched)}(.*?)^\/\/#{fence_close}/m) {
453
+ "#{matched}\n\#@mapfile(#{filepath})\n\#@end\n//#{fence_close}"
454
+ }
455
+ end
294
456
  end
295
457
  end
296
458
 
459
+ def convert_starter_option(content)
460
+ # file
461
+ r = /^(?<matched>\/\/(list|listnum|table)\[#{@r_option_inner}\]\[#{@r_option_inner}\]\[(?<options>#{@r_option_inner})\](?<open>.))$/
462
+ content.dup.scan(r) { |m|
463
+ matched = m[0]
464
+ options = m[1]
465
+ fence_open = m[2]
466
+ options.split(',').each { |option|
467
+ replace_file_option(content, matched, fence_open, option)
468
+ }
469
+ }
470
+ remove_option_param(content, ["list", "listnum", "table"], 3, "file")
471
+ # csv
472
+ convert_csv_option(content)
473
+ end
474
+
475
+ def convert_csv_option(content)
476
+ r_table = /^(?<matched>\/\/table\[#{@r_option_inner}\]\[#{@r_option_inner}\]\[(?<options>#{@r_option_inner})\](?<open>.))$/
477
+ content.dup.scan(r_table) { |m|
478
+ matched = m[0]
479
+ options = m[1]
480
+ options.split(',').each { |option|
481
+ if option.match(/\s*csv\s*=\s*on\s*/)
482
+ open = m[2]
483
+ close = ReViewDef::fence_close(open)
484
+ if close
485
+ tm = content.match(/#{Regexp.escape(matched)}(.*?)^\/\/#{close}/m)
486
+ outer = tm[0]
487
+ inner = tm[1]
488
+ im = inner.match(/(.*?)([=\-]{12,}\R)(.*)/m)
489
+ if im
490
+ header = im[1]
491
+ sep = im[2]
492
+ body = im[3]
493
+ new_header = ""
494
+ new_body = ""
495
+ CSV.parse(header) do |h|
496
+ new_header += Utils::GenerateTsv(h)
497
+ end
498
+ CSV.parse(body) do |c|
499
+ new_body += Utils::GenerateTsv(c)
500
+ end
501
+ content.gsub!(outer, "#{matched}#{new_header}#{sep}#{new_body}//#{close}")
502
+ else
503
+ im = inner.match(/^\#@mapfile\((.*?)\)\R^\#@end/m)
504
+ if im
505
+ inner_file = im[1]
506
+ csv_text = "\n"
507
+ csv_text += File.open(File.join(@basedir, inner_file)).read()
508
+ else
509
+ csv_text = inner
510
+ end
511
+ new_body = ""
512
+ CSV.parse(csv_text) do |c|
513
+ new_body += Utils::GenerateTsv(c)
514
+ end
515
+ content.gsub!(outer, "#{matched}#{new_body}//#{close}")
516
+ end
517
+ end
518
+ end
519
+ }
520
+ }
521
+ end
522
+
523
+ # tsize[builder][xxx] to tsize[|builder|xxx]
524
+ def replace_tsize(content)
525
+ content.gsub!(/^\/\/tsize\[(.*?)\]\[(.*?)\]/) {
526
+ builder = $1
527
+ builder = "" if $1 == '*'
528
+ "//tsize[|#{builder}|#{$2}]"
529
+ }
530
+ end
531
+
297
532
  def copy_embedded_contents(outdir, content)
298
- content.scan(/\#@mapfile\((.*?)\)/).each do |filepath|
533
+ content.scan(/\#@mapfile\((.*?)\)/).each do |filepath_|
534
+ filepath = filepath_[0]
535
+ if filepath.blank?
536
+ next
537
+ end
299
538
  srcpath = File.join(@basedir, filepath)
300
539
  if File.exist?(srcpath)
301
540
  outpath = File.join(File.absolute_path(outdir), filepath)
302
541
  FileUtils.mkdir_p(File.dirname(outpath))
303
542
  FileUtils.cp(srcpath, outpath)
304
- @embeded_contents.push(filepath[0])
543
+ @embeded_contents.push(filepath)
305
544
  update_content(outpath, outpath)
306
545
  end
307
546
  end
@@ -337,35 +576,131 @@ module ReVIEW
337
576
  }
338
577
  end
339
578
 
340
- def update_content(outdir, contentfile)
341
- info contentfile
342
- filename = File.basename(contentfile, '.*')
343
- content = File.read(contentfile)
344
- content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
345
- content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
346
- linkurl_footnote = @config['starter']['linkurl_footnote']
347
- # table 内の @ コマンドは不安定らしい
348
- while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
349
- end
350
- # 空セルが2行になることがあるらしい
351
- while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{@table_empty_replace}\\2").nil? do
352
- end
353
- # Re:VIEW Starter commands
354
- replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1)
355
- replace_compatible_block_command_outline(content, 'cmd', 'cmd', 0)
579
+ def replace_starter_command(content)
580
+ replace_compatible_block_command_outline(content, 'program', 'list', 2)
581
+ replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1, 1)
582
+ replace_compatible_block_command_outline(content, 'output', 'list', 3)
356
583
  replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
357
584
  replace_block_command_outline(content, 'abstract', 'lead', true)
585
+ delete_block_command(content, 'vspace')
358
586
  delete_block_command(content, 'needvspace')
359
587
  delete_block_command(content, 'clearpage')
360
588
  delete_block_command(content, 'flushright')
361
- delete_block_command(content, 'centering')
362
- delete_block_command(content, 'noindent')
363
589
  delete_block_command(content, 'paragraphend')
590
+ delete_block_command_outer(content, 'centering')
591
+
592
+ # convert starter option
593
+ convert_starter_option(content)
594
+
595
+ # delete starter option
596
+ # exclude_exta_option(content, 'cmd', 0)
597
+ starter_caption_to_text(content, 'cmd', 1)
598
+ exclude_exta_options(content, [
599
+ 'imgtable',
600
+ 'table',
601
+ # list/listnum の第3引数は言語指定だが、Starter の第3引数と全く異なるため 2 引数にしている
602
+ # Starter 側が言語指定対応したら修正
603
+ 'list',
604
+ 'listnum',
605
+ ], 2)
606
+ # exclude_exta_option(content, 'tsize', 1)
607
+ replace_tsize(content)
608
+
609
+ # delete IRD unsupported commands
610
+ if @ird
611
+ delete_block_command(content, 'noindent')
612
+ end
613
+
614
+ # chapterauthor
615
+ content.gsub!(/^\/\/chapterauthor\[(.*?)\]/, "//lead{\n\\1\n//}")
616
+ # talklist/desclist
617
+ starter_list_to_nested_contents_list(content)
618
+ # empty caption imaget to indepimage
619
+ content.gsub!(/^\/\/image(\[#{@r_option_inner}\]\[\].*)$/, '//indepimage\1')
620
+ end
621
+
622
+ def delete_inline_command(content, command)
623
+ # 既に入れ子は展開されている前提
624
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/, '\4')
625
+ end
626
+
627
+ def do_replace_inline_command(content, command, &blk)
628
+ # 既に入れ子は展開されている前提
629
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/) { blk.call([$1, $2, $3].join, $4, [$5, $6, $7].join) }
630
+ end
631
+
632
+ def replace_inline_command(content, command, new_command)
633
+ do_replace_inline_command(content, command) { |open, inner, close|
634
+ "@<#{new_command}>#{open}#{inner}#{close}"
635
+ }
636
+ end
637
+
638
+ # @<XXX>{AAA@<YYY>{BBB}} to @<XXX>{AAA}@<YYY>{BBB}
639
+ def expand_nested_inline_command(content)
640
+ found = false
641
+ content.dup.each_line do |line|
642
+ if line.match(/^#@#/)
643
+ next
644
+ end
645
+ line.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
646
+ matched = m.join
647
+ body = m[4]
648
+ outcmd_cmd = m[0]
649
+ outcmd_open = m[1..3].join
650
+ outcmd_begin = outcmd_cmd + outcmd_open
651
+ outcmd_close = m[5..7].join
652
+ im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
653
+ if im.nil?
654
+ # for {}
655
+ im2 = body.match(/(.*)(@<.*?>)#{Regexp.escape(outcmd_open)}(.*)/)
656
+ unless im2.nil?
657
+ rep = ""
658
+ if im2[3].length > 0
659
+ incmd_begin = im2[1..2].join + "$|{".gsub(outcmd_open, '')[0]
660
+ incmd_end = "$|}".gsub(outcmd_close, '')[0]
661
+ rep = "#{outcmd_begin}#{incmd_begin}#{im2[3]}#{incmd_end}"
662
+ else
663
+ rep = outcmd_begin + im2[1]
664
+ end
665
+ content.gsub!(matched) { |mm| rep }
666
+ found = true
667
+ else
668
+ # for |$
669
+ if body.match(/.*@<.*?>$/)
670
+ incmd_fence = "$|".gsub(outcmd_open, '')
671
+ rep = "#{outcmd_begin}#{body}#{incmd_fence}"
672
+ content.gsub!(/#{Regexp.escape(matched)}(.*?)#{Regexp.escape(outcmd_open)}/, "#{rep}\\1#{incmd_fence}")
673
+ found = true
674
+ end
675
+ end
676
+ else
677
+ rep = ""
678
+ rep += "#{outcmd_begin}#{im[1]}#{outcmd_close}" if im[1].length > 0
679
+ rep += "#{im[2..9].join}"
680
+ rep += "#{outcmd_begin}#{im[-1]}#{outcmd_close}" if im[-1].length > 0
681
+ content.gsub!(matched) { |mm| rep }
682
+ found = true
683
+ end
684
+ }
685
+ end
686
+ if found
687
+ expand_nested_inline_command(content)
688
+ end
689
+ end
690
+
691
+ def replace_starter_inline_command(content)
692
+ expand_nested_inline_command(content)
364
693
 
365
694
  replace_inline_command(content, 'secref', 'hd')
366
695
  replace_inline_command(content, 'file', 'kw')
367
696
  replace_inline_command(content, 'hlink', 'href')
368
697
  replace_inline_command(content, 'B', 'strong')
698
+ replace_inline_command(content, 'W', 'wb')
699
+ replace_inline_command(content, 'term', 'idx')
700
+ replace_inline_command(content, 'termnoidx', 'hidx')
701
+ unless ReViewCompat::has_bou()
702
+ replace_inline_command(content, 'bou', 'b')
703
+ end
369
704
  delete_inline_command(content, 'userinput')
370
705
  delete_inline_command(content, 'weak')
371
706
  delete_inline_command(content, 'cursor')
@@ -377,12 +712,37 @@ module ReVIEW
377
712
  delete_inline_command(content, 'xlarge')
378
713
  delete_inline_command(content, 'xxlarge')
379
714
 
715
+ do_replace_inline_command(content, 'par') { |open, inner, close| "@<br>#{open}#{close}" }
716
+ do_replace_inline_command(content, 'qq' ) { |open, inner, close| "\"#{inner}\"" }
717
+ end
718
+
719
+ def update_content(outdir, contentfile)
720
+ info contentfile
721
+ filename = File.basename(contentfile, '.*')
722
+ content = File.read(contentfile)
723
+ content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
724
+ content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
725
+ linkurl_footnote = @config['starter']['linkurl_footnote']
726
+ # table 内の @ コマンドは不安定らしい
727
+ while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{Regexp.escape(@table_br_replace)}\\2").nil? do
728
+ end
729
+ # 空セルが2行になることがあるらしい
730
+ while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{Regexp.escape(@table_empty_replace)}\\2").nil? do
731
+ end
732
+ # noop を最後に消すためにダミーに変える
733
+ content.gsub!('@<nop>$$', '@<dummynop>$must_be_replace_nop$')
734
+ content.gsub!('@<nop>||', '@<dummynop>|must_be_replace_nop|')
735
+ content.gsub!('@<nop>{}', '@<dummynop>{must_be_replace_nop}')
736
+
737
+ # Re:VIEW Starter commands
738
+ replace_starter_command(content)
739
+
380
740
  # fixed lack of options
381
741
  content.gsub!(/^\/\/list{/, '//list[][]{')
382
742
  # empty br line to blankline
383
743
  content.gsub!(/^\s*@<br>{}\s*$/, '//blankline')
384
744
 
385
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
745
+ unless ReViewCompat::is_allow_empty_image_caption()
386
746
  # empty caption is not allow
387
747
  content.gsub!(/^\/\/image\[(.*)\]\[\]{/, '//image[\1][ ]{')
388
748
  end
@@ -394,13 +754,11 @@ module ReVIEW
394
754
  add_linkurl_footnote(content, filename)
395
755
  end
396
756
 
397
- # # br to blankline
398
- # content.gsub!(/(.*)@<br>{}(.*)/, '\1\n//blankline\n\2')
399
-
400
757
  # nested command
401
758
  replace_block_command_nested_boxed_articles(content)
402
759
 
403
760
  # empty ids
761
+ replace_auto_ids(content, 'table', 2)
404
762
  replace_auto_ids(content, 'list', 2)
405
763
  replace_auto_ids(content, 'listnum', 2)
406
764
 
@@ -416,17 +774,29 @@ module ReVIEW
416
774
  content.gsub!('@<TeX>{}', 'TeX')
417
775
  content.gsub!('@<hearts>{}', '!HEART!')
418
776
 
419
- # nop replace must be last step
420
- content.gsub!('@<nop>$$', '@<b>$$')
421
- content.gsub!('@<nop>||', '@<b>||')
422
- content.gsub!('@<nop>{}', '@<b>{}')
423
-
424
- # expand nested inline command
425
- expand_nested_inline_command(content)
777
+ replace_starter_inline_command(content)
426
778
 
427
779
  # fix deprecated
428
780
  fix_deprecated_list(content)
429
781
 
782
+ if @ird
783
+ # br to blankline
784
+ content.gsub!(/(^\/\/footnote\[.*?\]\[.*?)((.*?@<br>({}|\$\$|\|\|)){1,})(.*\])$/) { |m|
785
+ m.gsub(/@<br>({}|\$\$|\|\|)/, '@<fnbr>\1')
786
+ }
787
+
788
+ content.gsub!(/(.*)@<br>({}|\$\$|\|\|)$/, "\\1\n\n")
789
+ content.gsub!(/(.*)@<br>({}|\$\$|\|\|)(.*)$/, "\\1\n\n\\2")
790
+ content.gsub!(/@<fnbr>({}|\$\$|\|\|)/, '@<br>\1')
791
+ end
792
+
793
+ # nop replace must be last step
794
+ # content.gsub!('@<dumynop>$must_be_replace_nop$', '@<b>$$')
795
+ # content.gsub!('@<dumynop>|must_be_replace_nop|', '@<b>||')
796
+ content.gsub!('@<dummynop>$must_be_replace_nop$', '@<b>{}')
797
+ content.gsub!('@<dummynop>|must_be_replace_nop|', '@<b>{}')
798
+ content.gsub!('@<dummynop>{must_be_replace_nop}', '@<b>{}')
799
+
430
800
  File.write(contentfile, content)
431
801
  copy_embedded_contents(outdir, content)
432
802
  end
@@ -457,7 +827,7 @@ module ReVIEW
457
827
  contentdir = abspath
458
828
  info 'replace starter block command'
459
829
  info 'replace starter inline command'
460
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
830
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
461
831
  update_content_files(outdir, contentdir, @catalog_contents)
462
832
  unless options['strict']
463
833
  all_contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -472,12 +842,10 @@ module ReVIEW
472
842
  contentpath = File.join(contentdir, content)
473
843
  if File.exist?(contentpath)
474
844
  info "preproc #{contentpath}"
475
- buf = StringIO.new
476
845
  pwd = Dir.pwd
477
846
  Dir.chdir(outdir)
478
- File.open(contentpath) { |f| pp.process(f, buf) }
847
+ content = pp.process(contentpath)
479
848
  Dir.chdir(pwd)
480
- content = buf.string
481
849
  content.gsub!(/^#[@]map.*$/, '')
482
850
  content.gsub!(/^#[@]end$/, '')
483
851
  File.write(contentpath, content)
@@ -491,10 +859,10 @@ module ReVIEW
491
859
  contentdir = abspath
492
860
  param = {}
493
861
  param['tabwidth'] = options['tabwidth'].to_i
494
- pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
862
+ pp = ReViewCompat::Preprocessor(param)
495
863
 
496
864
  if options['strict']
497
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
865
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
498
866
  preproc_content_files(outdir, pp, contentdir, @catalog_contents)
499
867
  else
500
868
  contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -502,6 +870,29 @@ module ReVIEW
502
870
  end
503
871
  end
504
872
 
873
+ def erb_sty(outdir, filename)
874
+ src = File.join(__dir__, "sty/#{filename}.erb")
875
+ dest = File.join(outdir, "sty/#{filename}")
876
+ erb = ERB.new(File.read(src))
877
+ File.write(dest, erb.result)
878
+ end
879
+
880
+ def update_sty(outdir, options)
881
+ review_custom_sty = File.open(File.join(outdir, 'sty/review-custom.sty'), 'a')
882
+ erb_sty(outdir, 'review-retrovert-custom.sty')
883
+ review_custom_sty.puts('\RequirePackage{review-retrovert-custom}')
884
+ if @ird
885
+ erb_sty(outdir, 'ird.sty')
886
+ review_custom_sty.puts('\RequirePackage{ird}')
887
+ end
888
+ end
889
+
890
+ def update_ext(outdir, options)
891
+ if @ird
892
+ FileUtils.cp(File.join(__dir__, 'ext/review-ext.rb'), File.join(outdir, 'review-ext.rb'))
893
+ end
894
+ end
895
+
505
896
  def clean_initial_project(outdir)
506
897
  FileUtils.rm(File.join(outdir, 'config.yml'))
507
898
  FileUtils.rm(File.join(outdir, 'catalog.yml'))
@@ -520,7 +911,7 @@ module ReVIEW
520
911
  @basedir = @configs.basedir
521
912
  @srccontentsdir = @config['contentdir']
522
913
 
523
- catalog = ReVIEW::Catalog.new(File.open(@configs.catalogfile()))
914
+ catalog = ReViewCompat::Catalog(@configs.catalogfile())
524
915
  add_catalog_contents(catalog.predef())
525
916
  add_catalog_contents(catalog.chaps())
526
917
  add_catalog_contents(catalog.appendix())
@@ -536,14 +927,19 @@ module ReVIEW
536
927
  def execute(yamlfile, outdir, options)
537
928
  @table_br_replace = options['table-br-replace']
538
929
  @table_empty_replace = options['table-empty-replace']
930
+ @ird = options['ird']
539
931
  load_config(yamlfile)
932
+ store_image_dir = store_out_image(outdir) if options['no-image']
540
933
  create_initial_project(outdir, options)
934
+ @talk_shortcuts = @config['starter']['talk_shortcuts']
541
935
 
542
936
  copy_config(outdir)
543
937
  copy_catalog(outdir)
544
- copy_images(outdir)
938
+ copy_images(outdir, store_image_dir)
545
939
  update_config(outdir)
546
940
  update_contents(outdir, options)
941
+ update_sty(outdir, options)
942
+ update_ext(outdir, options)
547
943
 
548
944
  pwd = Dir.pwd
549
945
  Dir.chdir(outdir)