review-retrovert 0.9.4 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) 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 +461 -126
  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-starter.yml +134 -9
  29. data/testdata/mybook/config.yml +44 -15
  30. data/testdata/mybook/contents/00-preface.re +48 -2
  31. data/testdata/mybook/contents/01-install.re +38 -5
  32. data/testdata/mybook/contents/02-tutorial.re +333 -113
  33. data/testdata/mybook/contents/03-syntax.re +2370 -373
  34. data/testdata/mybook/contents/04-customize.re +424 -88
  35. data/testdata/mybook/contents/05-faq.re +288 -10
  36. data/testdata/mybook/contents/06-bestpractice.re +431 -59
  37. data/testdata/mybook/contents/91-compare.re +402 -2
  38. data/testdata/mybook/contents/92-filelist.re +14 -8
  39. data/testdata/mybook/contents/93-background.re +10 -10
  40. data/testdata/mybook/contents/99-postface.re +2 -1
  41. data/testdata/mybook/contents/r0-root.re +5 -0
  42. data/testdata/mybook/css/webstyle.css +180 -2
  43. data/testdata/mybook/data/terms.txt +3 -0
  44. data/testdata/mybook/data/words.txt +15 -0
  45. data/testdata/mybook/images/03-syntax/index-page.png +0 -0
  46. data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
  47. data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
  48. data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
  49. data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
  50. data/testdata/mybook/images/avatar-b.png +0 -0
  51. data/testdata/mybook/images/avatar-g.png +0 -0
  52. data/testdata/mybook/images/avatar-r.png +0 -0
  53. data/testdata/mybook/images/caution-icon.png +0 -0
  54. data/testdata/mybook/images/info-icon.png +0 -0
  55. data/testdata/mybook/images/warning-icon.png +0 -0
  56. data/testdata/mybook/layouts/layout.html5.erb +3 -1
  57. data/testdata/mybook/layouts/layout.tex.erb +265 -379
  58. data/testdata/mybook/layouts/layout.tex.erb.orig +386 -0
  59. data/testdata/mybook/lib/ruby/review-book.rb +64 -0
  60. data/testdata/mybook/lib/ruby/review-builder.rb +902 -63
  61. data/testdata/mybook/lib/ruby/review-compiler.rb +675 -22
  62. data/testdata/mybook/lib/ruby/review-epubbuilder.rb +33 -0
  63. data/testdata/mybook/lib/ruby/review-epubmaker.rb +10 -7
  64. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +354 -66
  65. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +429 -146
  66. data/testdata/mybook/lib/ruby/review-maker.rb +117 -6
  67. data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +945 -0
  68. data/testdata/mybook/lib/ruby/review-markdownmaker.rb +91 -0
  69. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +2 -0
  70. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +160 -82
  71. data/testdata/mybook/lib/ruby/review-webmaker.rb +20 -5
  72. data/testdata/mybook/lib/tasks/review.rake +14 -0
  73. data/testdata/mybook/lib/tasks/starter.rake +148 -4
  74. data/testdata/mybook/sty/indexstyle.ist +25 -0
  75. data/testdata/mybook/sty/mytextsize.sty +29 -0
  76. data/testdata/mybook/sty/mytitlepage.sty +34 -11
  77. data/testdata/mybook/sty/review-base.sty +276 -0
  78. data/testdata/mybook/sty/starter-codeblock.sty +237 -106
  79. data/testdata/mybook/sty/starter-color.sty +72 -17
  80. data/testdata/mybook/sty/starter-heading.sty +60 -13
  81. data/testdata/mybook/sty/starter-misc.sty +894 -0
  82. data/testdata/mybook/sty/starter-note.sty +67 -14
  83. data/testdata/mybook/sty/starter-talklist.sty +105 -0
  84. data/testdata/mybook/sty/starter-util.sty +35 -0
  85. data/testdata/mybook/sty/starter.sty +8 -526
  86. metadata +81 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d88019dcbdef1f19522028bd668913c7f2100d2774796ca208a7e72df829b3ef
4
- data.tar.gz: 4b3605223424275e592269e6fbfd1124275087c322522b0d5cb309434ee202ac
3
+ metadata.gz: b6300e07afd5a8a952ed11706cb35595a83fa7cb90b381af357fb3387fb22624
4
+ data.tar.gz: 649de1a4923bf1f045684af4d14afcf65724dd021f274bea881adf83b5aa38c1
5
5
  SHA512:
6
- metadata.gz: 519813a8c9690db53484fb206084a97c36c8bfe1c230fe09bb623c7d93ce178a81b1bb91eed87a9edfb1c753b345e0d12ca36f50bf8789ea0a6906126b62e771
7
- data.tar.gz: '02823e04d7787079bcf94273ab43af37d903c8d8de357fde7c8394094ff88a5e2275e173284496eccf328f74da11c11b8b3d2233814529cb00b4021ff014b19d'
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.4)
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
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,44 +59,122 @@ 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.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
+
147
+ if @ird
148
+ # # リュウミン Pr6N R-KL 12.5Q 22H (9pt = 12.7Q 15.5pt = 21.8Q(H))
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"]
150
+ 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"
151
+ end
152
+ @configs.rewrite_yml_array('texdocumentclass', "[\"review-jsbook\", \"#{jsbook_config}\"]")
75
153
  @config['retrovert'].each{ |k,v|
76
154
  unless v..is_a?(Hash)
77
155
  @configs.commentout_root_yml(k)
78
156
  end
79
157
  }
158
+ if @ird
159
+ @configs.rewrite_yml('chapterlink', 'null')
160
+ end
80
161
  end
81
162
 
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>//}")
87
- 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>")
88
178
  end
89
179
 
90
180
  def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
@@ -110,37 +200,30 @@ module ReVIEW
110
200
  content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
111
201
  end
112
202
 
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
203
  def replace_block_command_nested_boxed_article_i(content, box, depth)
123
204
  found = false
124
205
  content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
125
206
  matched = m[0..-1].join
126
207
  inner = m[5]
127
208
  # info depth
128
- im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
209
+ im = inner.match(/^\/\/(?<command>\w+)(?<options>(\[#{@r_option_inner}\])*)(?<open>[$|{])/)
129
210
  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 = ""
211
+ inner_cmd = im['command']
212
+ inner_open = im['open']
213
+ inner_opts = im['options']
214
+ id_opt = ""
135
215
 
136
216
  # is_commentout = false
137
217
  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}\\]"
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
144
227
  end
145
228
  end
146
229
  end
@@ -150,24 +233,44 @@ module ReVIEW
150
233
  if inner_open == m[2..4].join
151
234
  # if same fence then cmd_end == inner_end
152
235
  if is_commentout
153
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
154
- 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 }
155
246
  else
156
- 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)
157
248
  to_out_block = imb[1]
158
249
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
159
- 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 }
160
252
  end
161
253
  else
162
- close = inner_open == '{' ? '}' : inner_open
254
+ close = ReViewDef::fence_close(inner_open)
163
255
  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}")
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 }
166
268
  else
167
- 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)
168
270
  to_out_block = imb[0]
169
271
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
170
- 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 }
171
274
  end
172
275
  end
173
276
  found = true
@@ -183,7 +286,7 @@ module ReVIEW
183
286
  end
184
287
 
185
288
  def replace_block_command_nested_boxed_articles(content)
186
- unless Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('5.0.0')
289
+ unless ReViewCompat::has_nested_minicolumn()
187
290
  replace_block_command_nested_boxed_article(content, 'note')
188
291
  replace_block_command_nested_boxed_article(content, 'memo')
189
292
  replace_block_command_nested_boxed_article(content, 'tip')
@@ -195,24 +298,27 @@ module ReVIEW
195
298
  end
196
299
  end
197
300
 
301
+ # #@+++ ~ #@--- to #@#+++ #@#~ #@#---
198
302
  def replace_block_commentout(content)
199
303
  d = content.dup
200
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
304
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
201
305
  matched = m[0..-1].join
202
306
  inner = m[2]
203
- inner.gsub!(/(^.)/, '#@#\1')
204
- 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 }
205
310
  }
206
311
  end
207
312
 
208
313
  def replace_block_commentout_without_sampleout(content)
209
314
  d = content.dup
210
315
  d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
211
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
316
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
212
317
  matched = m[0..-1].join
213
318
  inner = m[2]
214
- inner.gsub!(/(^.)/, '#@#\1')
215
- 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 }
216
322
  }
217
323
  end
218
324
 
@@ -225,7 +331,8 @@ module ReVIEW
225
331
  option = m[1]
226
332
  inner = m[3]
227
333
  # inner.gsub!(/^\/\//, '//@<nop>{}')
228
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
334
+ rep = "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}"
335
+ content.gsub!(matched) { |mm| rep }
229
336
  }
230
337
  end
231
338
 
@@ -239,7 +346,7 @@ module ReVIEW
239
346
  end
240
347
 
241
348
  def fix_deprecated_list(content)
242
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
349
+ if ReViewCompat::is_need_space_term_list()
243
350
  content.gsub!(/^: (.*)/, ' : \1')
244
351
  end
245
352
  end
@@ -251,47 +358,124 @@ module ReVIEW
251
358
  ref = m[4]
252
359
  n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
253
360
  unless n.nil?
254
- content.gsub!(/#{Regexp.escape(matched)}/, n[1])
361
+ rep = n[1]
362
+ content.gsub!(matched) { |mm| rep }
255
363
  content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
256
364
  else
257
- # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
365
+ # content.gsub!(matched, "noteref<#{ref}>")
258
366
  end
259
367
  }
260
368
  end
261
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
+
262
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")
263
383
  # image border
264
- 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")
265
387
  # 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
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}{"
283
410
  end
284
411
  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
412
+ "//emlist#{traling_options}{"
290
413
  end
291
414
  }
292
- if found
293
- expand_nested_inline_command(content)
294
- 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
+ }
295
479
  end
296
480
 
297
481
  def copy_embedded_contents(outdir, content)
@@ -307,7 +491,11 @@ module ReVIEW
307
491
  end
308
492
  end
309
493
 
310
- def add_linkurl_footnote(content)
494
+ def make_id_label(name)
495
+ name.gsub(/[^A-Za-z0-9]/, '_')
496
+ end
497
+
498
+ def add_linkurl_footnote(content, filename)
311
499
  urls = {}
312
500
  content.dup.scan(/(^.*)(@<href>{)(.*?)(,)(.*?)(})(.*)$/) { |m|
313
501
  unless m[0].match(/^#@#/)
@@ -316,7 +504,7 @@ module ReVIEW
316
504
  url = m[2]
317
505
  text = m[4]
318
506
  post = m[6]
319
- id = "link_auto_footnote#{urls.length}"
507
+ id = "#{make_id_label(filename)}_link_auto_footnote#{urls.length}"
320
508
  urls[id] = url
321
509
  content.sub!(/#{Regexp.escape(matched)}$/, "#{prev}@<href>{#{url},#{text}} @<fn>{#{id}} #{post}")
322
510
  end
@@ -333,34 +521,123 @@ module ReVIEW
333
521
  }
334
522
  end
335
523
 
336
- def update_content(outdir, contentfile)
337
- info contentfile
338
- content = File.read(contentfile)
339
- content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
340
- content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
341
- linkurl_footnote = @config['starter']['linkurl_footnote']
342
- # table 内の @ コマンドは不安定らしい
343
- while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
344
- end
345
- # 空セルが2行になることがあるらしい
346
- while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{@table_empty_replace}\\2").nil? do
347
- end
348
- # Re:VIEW Starter commands
349
- replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1)
350
- 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)
351
528
  replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
352
529
  replace_block_command_outline(content, 'abstract', 'lead', true)
530
+ delete_block_command(content, 'vspace')
353
531
  delete_block_command(content, 'needvspace')
354
532
  delete_block_command(content, 'clearpage')
355
533
  delete_block_command(content, 'flushright')
356
- delete_block_command(content, 'centering')
357
- delete_block_command(content, 'noindent')
358
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)
547
+
548
+ # delete IRD unsupported commands
549
+ if @ird
550
+ delete_block_command(content, 'noindent')
551
+ end
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)
359
630
 
360
631
  replace_inline_command(content, 'secref', 'hd')
361
632
  replace_inline_command(content, 'file', 'kw')
362
633
  replace_inline_command(content, 'hlink', 'href')
363
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
364
641
  delete_inline_command(content, 'userinput')
365
642
  delete_inline_command(content, 'weak')
366
643
  delete_inline_command(content, 'cursor')
@@ -372,10 +649,37 @@ module ReVIEW
372
649
  delete_inline_command(content, 'xlarge')
373
650
  delete_inline_command(content, 'xxlarge')
374
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
+
375
677
  # fixed lack of options
376
678
  content.gsub!(/^\/\/list{/, '//list[][]{')
679
+ # empty br line to blankline
680
+ content.gsub!(/^\s*@<br>{}\s*$/, '//blankline')
377
681
 
378
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
682
+ unless ReViewCompat::is_allow_empty_image_caption()
379
683
  # empty caption is not allow
380
684
  content.gsub!(/^\/\/image\[(.*)\]\[\]{/, '//image[\1][ ]{')
381
685
  end
@@ -384,16 +688,14 @@ module ReVIEW
384
688
  replace_sampleoutput(content)
385
689
 
386
690
  if linkurl_footnote
387
- add_linkurl_footnote(content)
691
+ add_linkurl_footnote(content, filename)
388
692
  end
389
693
 
390
- # # br to blankline
391
- # content.gsub!(/(.*)@<br>{}(.*)/, '\1\n//blankline\n\2')
392
-
393
694
  # nested command
394
695
  replace_block_command_nested_boxed_articles(content)
395
696
 
396
697
  # empty ids
698
+ replace_auto_ids(content, 'table', 2)
397
699
  replace_auto_ids(content, 'list', 2)
398
700
  replace_auto_ids(content, 'listnum', 2)
399
701
 
@@ -409,17 +711,24 @@ module ReVIEW
409
711
  content.gsub!('@<TeX>{}', 'TeX')
410
712
  content.gsub!('@<hearts>{}', '!HEART!')
411
713
 
412
- # nop replace must be last step
413
- content.gsub!('@<nop>$$', '@<b>$$')
414
- content.gsub!('@<nop>||', '@<b>||')
415
- content.gsub!('@<nop>{}', '@<b>{}')
416
-
417
- # expand nested inline command
418
- expand_nested_inline_command(content)
714
+ replace_starter_inline_command(content)
419
715
 
420
716
  # fix deprecated
421
717
  fix_deprecated_list(content)
422
718
 
719
+ if @ird
720
+ # br to blankline
721
+ content.gsub!(/(.*)@<br>{}$/, "\\1\n\n")
722
+ content.gsub!(/(.*)@<br>{}(.*)$/, "\\1\n\n\\2")
723
+ end
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
+
423
732
  File.write(contentfile, content)
424
733
  copy_embedded_contents(outdir, content)
425
734
  end
@@ -450,7 +759,7 @@ module ReVIEW
450
759
  contentdir = abspath
451
760
  info 'replace starter block command'
452
761
  info 'replace starter inline command'
453
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
762
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
454
763
  update_content_files(outdir, contentdir, @catalog_contents)
455
764
  unless options['strict']
456
765
  all_contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -465,12 +774,10 @@ module ReVIEW
465
774
  contentpath = File.join(contentdir, content)
466
775
  if File.exist?(contentpath)
467
776
  info "preproc #{contentpath}"
468
- buf = StringIO.new
469
777
  pwd = Dir.pwd
470
778
  Dir.chdir(outdir)
471
- File.open(contentpath) { |f| pp.process(f, buf) }
779
+ content = pp.process(contentpath)
472
780
  Dir.chdir(pwd)
473
- content = buf.string
474
781
  content.gsub!(/^#[@]map.*$/, '')
475
782
  content.gsub!(/^#[@]end$/, '')
476
783
  File.write(contentpath, content)
@@ -484,10 +791,10 @@ module ReVIEW
484
791
  contentdir = abspath
485
792
  param = {}
486
793
  param['tabwidth'] = options['tabwidth'].to_i
487
- pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
794
+ pp = ReViewCompat::Preprocessor(param)
488
795
 
489
796
  if options['strict']
490
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
797
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
491
798
  preproc_content_files(outdir, pp, contentdir, @catalog_contents)
492
799
  else
493
800
  contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -495,6 +802,29 @@ module ReVIEW
495
802
  end
496
803
  end
497
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
+
812
+ def update_sty(outdir, options)
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}')
816
+ if @ird
817
+ erb_sty(outdir, 'ird.sty')
818
+ review_custom_sty.puts('\RequirePackage{ird}')
819
+ end
820
+ end
821
+
822
+ def update_ext(outdir, options)
823
+ if @ird
824
+ FileUtils.cp(File.join(__dir__, 'ext/review-ext.rb'), File.join(outdir, 'review-ext.rb'))
825
+ end
826
+ end
827
+
498
828
  def clean_initial_project(outdir)
499
829
  FileUtils.rm(File.join(outdir, 'config.yml'))
500
830
  FileUtils.rm(File.join(outdir, 'catalog.yml'))
@@ -513,7 +843,7 @@ module ReVIEW
513
843
  @basedir = @configs.basedir
514
844
  @srccontentsdir = @config['contentdir']
515
845
 
516
- catalog = ReVIEW::Catalog.new(File.open(@configs.catalogfile()))
846
+ catalog = ReViewCompat::Catalog(@configs.catalogfile())
517
847
  add_catalog_contents(catalog.predef())
518
848
  add_catalog_contents(catalog.chaps())
519
849
  add_catalog_contents(catalog.appendix())
@@ -529,14 +859,19 @@ module ReVIEW
529
859
  def execute(yamlfile, outdir, options)
530
860
  @table_br_replace = options['table-br-replace']
531
861
  @table_empty_replace = options['table-empty-replace']
862
+ @ird = options['ird']
532
863
  load_config(yamlfile)
864
+ store_image_dir = store_out_image(outdir) if options['no-image']
533
865
  create_initial_project(outdir, options)
866
+ @talk_shortcuts = @config['starter']['talk_shortcuts']
534
867
 
535
868
  copy_config(outdir)
536
869
  copy_catalog(outdir)
537
- copy_images(outdir)
870
+ copy_images(outdir, store_image_dir)
538
871
  update_config(outdir)
539
872
  update_contents(outdir, options)
873
+ update_sty(outdir, options)
874
+ update_ext(outdir, options)
540
875
 
541
876
  pwd = Dir.pwd
542
877
  Dir.chdir(outdir)