review-retrovert 0.9.7 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +9 -0
  3. data/.editorconfig +3 -0
  4. data/.github/workflows/docker-build.yml +26 -0
  5. data/.github/workflows/release.yml +1 -1
  6. data/.github/workflows/retrovert.yml +35 -5
  7. data/.vscode/launch.json +48 -0
  8. data/Gemfile.lock +13 -4
  9. data/Makefile +31 -0
  10. data/README.md +3 -2
  11. data/docker/review.Dockerfile +10 -0
  12. data/lib/review/retrovert/cli.rb +4 -2
  13. data/lib/review/retrovert/converter.rb +511 -130
  14. data/lib/review/retrovert/reviewcompat.rb +57 -0
  15. data/lib/review/retrovert/reviewdef.rb +99 -0
  16. data/lib/review/retrovert/sty/{ird.sty → ird.sty.erb} +9 -1
  17. data/lib/review/retrovert/sty/review-retrovert-custom.sty.erb +6 -0
  18. data/lib/review/retrovert/sty/review-utbook.cls +7 -0
  19. data/lib/review/retrovert/utils.rb +35 -0
  20. data/lib/review/retrovert/version.rb +1 -1
  21. data/lib/review/retrovert/yamlconfig.rb +0 -1
  22. data/package-lock.json +6 -0
  23. data/package.json +1 -0
  24. data/review-retrovert.gemspec +5 -1
  25. data/testdata/mybook/.gitignore +7 -1
  26. data/testdata/mybook/.textlintrc +11 -0
  27. data/testdata/mybook/Rakefile +8 -0
  28. data/testdata/mybook/catalog.yml +36 -10
  29. data/testdata/mybook/config-noretrovert.yml +404 -0
  30. data/testdata/mybook/config-retrovert.yml +9 -0
  31. data/testdata/mybook/config-starter.yml +134 -9
  32. data/testdata/mybook/config.yml +44 -15
  33. data/testdata/mybook/contents/00-preface.re +48 -2
  34. data/testdata/mybook/contents/01-install.re +38 -5
  35. data/testdata/mybook/contents/02-tutorial.re +333 -113
  36. data/testdata/mybook/contents/03-syntax.re +2370 -373
  37. data/testdata/mybook/contents/04-customize.re +424 -88
  38. data/testdata/mybook/contents/05-faq.re +288 -10
  39. data/testdata/mybook/contents/06-bestpractice.re +431 -59
  40. data/testdata/mybook/contents/91-compare.re +402 -2
  41. data/testdata/mybook/contents/92-filelist.re +14 -8
  42. data/testdata/mybook/contents/93-background.re +10 -10
  43. data/testdata/mybook/contents/99-postface.re +2 -1
  44. data/testdata/mybook/contents/r0-root.re +42 -2
  45. data/testdata/mybook/contents/table.csv +4 -0
  46. data/testdata/mybook/contents/test.txt +1 -0
  47. data/testdata/mybook/contents/ut.re +5 -0
  48. data/testdata/mybook/css/webstyle.css +180 -2
  49. data/testdata/mybook/data/terms.txt +3 -0
  50. data/testdata/mybook/data/words.txt +15 -0
  51. data/testdata/mybook/images/03-syntax/index-page.png +0 -0
  52. data/testdata/mybook/images/03-syntax/order-detail.png +0 -0
  53. data/testdata/mybook/images/04-customize/section_decoration_samples.png +0 -0
  54. data/testdata/mybook/images/05-faq/dummy-image.png +0 -0
  55. data/testdata/mybook/images/06-bestpractice/section_title_wlines.png +0 -0
  56. data/testdata/mybook/images/avatar-b.png +0 -0
  57. data/testdata/mybook/images/avatar-g.png +0 -0
  58. data/testdata/mybook/images/avatar-r.png +0 -0
  59. data/testdata/mybook/images/caution-icon.png +0 -0
  60. data/testdata/mybook/images/info-icon.png +0 -0
  61. data/testdata/mybook/images/warning-icon.png +0 -0
  62. data/testdata/mybook/layouts/layout.html5.erb +3 -1
  63. data/testdata/mybook/layouts/layout.tex.erb +265 -379
  64. data/testdata/mybook/layouts/layout.tex.erb.orig +386 -0
  65. data/testdata/mybook/lib/ruby/review-book.rb +64 -0
  66. data/testdata/mybook/lib/ruby/review-builder.rb +902 -63
  67. data/testdata/mybook/lib/ruby/review-compiler.rb +675 -22
  68. data/testdata/mybook/lib/ruby/review-epubbuilder.rb +33 -0
  69. data/testdata/mybook/lib/ruby/review-epubmaker.rb +10 -7
  70. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +354 -66
  71. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +429 -146
  72. data/testdata/mybook/lib/ruby/review-maker.rb +117 -6
  73. data/testdata/mybook/lib/ruby/review-markdownbuilder.rb +945 -0
  74. data/testdata/mybook/lib/ruby/review-markdownmaker.rb +91 -0
  75. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +2 -0
  76. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +160 -82
  77. data/testdata/mybook/lib/ruby/review-webmaker.rb +20 -5
  78. data/testdata/mybook/lib/tasks/review.rake +14 -0
  79. data/testdata/mybook/lib/tasks/starter.rake +148 -4
  80. data/testdata/mybook/sty/indexstyle.ist +25 -0
  81. data/testdata/mybook/sty/mytextsize.sty +34 -1
  82. data/testdata/mybook/sty/mytitlepage.sty +34 -11
  83. data/testdata/mybook/sty/review-base.sty +276 -0
  84. data/testdata/mybook/sty/starter-codeblock.sty +237 -106
  85. data/testdata/mybook/sty/starter-color.sty +72 -17
  86. data/testdata/mybook/sty/starter-heading.sty +60 -13
  87. data/testdata/mybook/sty/starter-misc.sty +894 -0
  88. data/testdata/mybook/sty/starter-note.sty +67 -14
  89. data/testdata/mybook/sty/starter-talklist.sty +105 -0
  90. data/testdata/mybook/sty/starter-util.sty +39 -0
  91. data/testdata/mybook/sty/starter.sty +8 -526
  92. data/testdata/mybook/sty/ut.sty +26 -0
  93. data/testdata/mybook/ut-catalog.yml +61 -0
  94. data/testdata/mybook/ut-config-starter.yml +3 -0
  95. data/testdata/mybook/ut-config.yml +404 -0
  96. metadata +90 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d85946bda0b18fbe3dddfbd6f37ef15a2e2c6892376a1e91245c8d0a98053399
4
- data.tar.gz: a0f7697228f0bf308bb091fb5d7d0ee279d2dbdbdf7fff4580f5ccf6298ad0b3
3
+ metadata.gz: 393624484f41bea59ee793d9720b43084058a7d3e3c6c3ad77adbe79b05d400f
4
+ data.tar.gz: 29975b33f89f570df49d12956b42606f24d6e86224d4a495935ad228fb3dceac
5
5
  SHA512:
6
- metadata.gz: 7faaa36fd24484680cd909eeab26a46ab67e7085a59807e0d3d725586422df13be6f0a0d7942bec592bb2e89bef3b1e3faad659e7484c4991b00737864578960
7
- data.tar.gz: 80ff4eea7e4b43cb20486fb87cf9dd6431b0e4766d58fbc24680cdff254bb28e265ce1d3552deef4167d11247b958d2df9caf1a4df9e8b0a294a14d2efc81afa
6
+ metadata.gz: db1bd1b2451f1af8a5ea77829a0781d2ddb755ebaca266f2db5c45adb6a835e1c41fa2baca89d45f625b1c4bcc84faf7c0f093b7344524db24e19a3e21155071
7
+ data.tar.gz: 9d44921e109fb1b9e436c10721c4ef8fb0c0840c8757f201fc71b1fa90dc7611013f79b7c2a1eb8ea686b84b92210fe49fa870ad55ffed0c092a69713a2fc415
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
@@ -0,0 +1,26 @@
1
+ name: Docker Build
2
+ on: workflow_dispatch
3
+
4
+ jobs:
5
+ push_to_registries:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - name: Check out the repo
9
+ uses: actions/checkout@v2
10
+ - name: Log in to Docker Hub
11
+ uses: docker/login-action@v1
12
+ with:
13
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
14
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
15
+ - name: Push to Docker Hub
16
+ uses: docker/build-push-action@v2
17
+ with:
18
+ push: true
19
+ tags: srzzumix/review-retrovert:latest
20
+ - name: Push to version tag
21
+ env:
22
+ DOCKER_TAG: latest
23
+ IMAGE_NAME: srzzumix/review-retrovert:latest
24
+ DOCKER_REPO: srzzumix/review-retrovert
25
+ run: |
26
+ ./hooks/post_push
@@ -23,4 +23,4 @@ jobs:
23
23
  gem build *.gemspec
24
24
  gem push *.gem
25
25
  env:
26
- GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
26
+ GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
@@ -6,11 +6,36 @@ on:
6
6
 
7
7
  name: Retrovert
8
8
  jobs:
9
+ review-starter:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: build pdf
14
+ run: |
15
+ docker run --rm -v "$(pwd)/testdata/mybook":/work -w /work kauplan/review2.5 rake preproc pdf
16
+ cp testdata/mybook/mybook.pdf mybook-starter.pdf
17
+ # artifacts
18
+ - name: artifacts
19
+ uses: actions/upload-artifact@v1
20
+ with:
21
+ name: mybook
22
+ path: mybook-starter.pdf
23
+
9
24
  review:
10
25
  runs-on: ubuntu-latest
11
26
  strategy:
12
27
  matrix:
13
- review-version: [ "3.2", "4.2", "5.0" ]
28
+ review-version:
29
+ - "3.0"
30
+ - "3.1"
31
+ - "3.2"
32
+ - "4.0"
33
+ - "4.1"
34
+ - "4.2"
35
+ - "5.0"
36
+ - "5.1"
37
+ - "5.2"
38
+ - "latest"
14
39
  fail-fast: false
15
40
  steps:
16
41
  - uses: actions/checkout@v2
@@ -23,13 +48,17 @@ jobs:
23
48
  echo 'gem "review", "${{ matrix.review-version }}"' >> Gemfile-${{ matrix.review-version }}
24
49
  cat Gemfile-${{ matrix.review-version }}
25
50
  echo "BUNDLE_GEMFILE=Gemfile-${{ matrix.review-version }}" >> $GITHUB_ENV
51
+ if: ${{ matrix.review-version != 'latest' }}
26
52
  - run: bundle install --gemfile=Gemfile-${{ matrix.review-version }}
53
+ if: ${{ matrix.review-version != 'latest' }}
54
+ - run: bundle install
55
+ if: ${{ matrix.review-version == 'latest' }}
27
56
  # spec
28
57
  - name: spec
29
58
  run: bundle exec rake spec
30
59
  # convert
31
60
  - name: convert
32
- run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp -f
61
+ run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp-${{ matrix.review-version }} -f
33
62
  # build
34
63
  # - name: review build
35
64
  # uses: ${{ matrix.uses }}
@@ -44,16 +73,17 @@ jobs:
44
73
  password: ${{ secrets.DOCKERHUB_TOKEN }}
45
74
  - name: build html
46
75
  run: |
47
- docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc html
76
+ docker run --rm -v "$(pwd)/tmp-${{ matrix.review-version }}":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc html
48
77
  - name: build pdf
49
78
  run: |
50
- docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc pdf
79
+ docker run --rm -v "$(pwd)/tmp-${{ matrix.review-version }}":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc pdf
80
+ cp tmp-${{ matrix.review-version }}/mybook.pdf mybook-${{ matrix.review-version }}.pdf
51
81
  # artifacts
52
82
  - name: artifacts
53
83
  uses: actions/upload-artifact@v1
54
84
  with:
55
85
  name: mybook
56
- path: tmp/mybook.pdf
86
+ path: mybook-${{ matrix.review-version }}.pdf
57
87
  # - name: artifacts
58
88
  # uses: actions/upload-artifact@v1
59
89
  # with:
@@ -0,0 +1,48 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Debug review-retrovert",
9
+ "type": "Ruby",
10
+ "request": "launch",
11
+ "env": {
12
+ "RUBYLIB":"lib"
13
+ },
14
+ "cwd": "${workspaceRoot}",
15
+ "program": "${workspaceRoot}/exe/review-retrovert",
16
+ "args": [
17
+ "convert",
18
+ "--preproc",
19
+ "--tabwidth", "4",
20
+ "--ird",
21
+ "testdata/mybook/config.yml",
22
+ "-f",
23
+ "tmp/debug"
24
+ ]
25
+ },
26
+ {
27
+ "name": "RSpec - active spec file only",
28
+ "type": "Ruby",
29
+ "request": "launch",
30
+ "program": "${workspaceRoot}/bin/rspec",
31
+ "args": [
32
+ "-I",
33
+ "${workspaceRoot}",
34
+ "${file}"
35
+ ]
36
+ },
37
+ {
38
+ "name": "RSpec - all",
39
+ "type": "Ruby",
40
+ "request": "launch",
41
+ "program": "${workspaceRoot}/bin/rspec",
42
+ "args": [
43
+ "-I",
44
+ "${workspaceRoot}"
45
+ ]
46
+ },
47
+ ]
48
+ }
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- review-retrovert (0.9.7)
4
+ review-retrovert (0.9.11)
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.2)
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,31 @@
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
+ test-ut:
18
+ RUBYLIB=lib ./exe/review-retrovert convert --preproc --tabwidth 4 testdata/mybook/ut-config.yml -f tmp/debug
19
+
20
+ REVIEW_VERSION:=latest
21
+
22
+ debug-build:
23
+ docker run --rm -v "${PWD}/tmp/debug":/work -w /work vvakame/review:${REVIEW_VERSION} rake preproc pdf
24
+ # docker run --rm -v "${PWD}":/work -w /work vvakame/review rake preproc pdf
25
+
26
+ testdata-pdf:
27
+ docker run --rm -v ${PWD}/testdata/mybook:/work -w /work kauplan/review2.5 rake pdf
28
+
29
+ testdata-ut-pdf:
30
+ # rm -rf ./testdata/mybook/mybook-ut-pdf
31
+ docker run --rm -v ${PWD}/testdata/mybook:/work -w /work -e config=ut-config.yml kauplan/review2.5 rake pdf
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/review-retrovert.svg)](https://badge.fury.io/rb/review-retrovert)
2
- [![Build Status](https://travis-ci.com/srz-zumix/review-retrovert.svg?token=ArNHjRjvfZfyqQUCbXSt&branch=master)](https://travis-ci.com/srz-zumix/review-retrovert)
3
- [![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/srzzumix/review-retrovert.svg)](https://hub.docker.com/r/srzzumix/review-retrovert/)
2
+ [![Retrovert](https://github.com/srz-zumix/review-retrovert/actions/workflows/retrovert.yml/badge.svg?branch=master)](https://github.com/srz-zumix/review-retrovert/actions/workflows/retrovert.yml)
3
+ [![Docker Build](https://github.com/srz-zumix/review-retrovert/actions/workflows/docker-build.yml/badge.svg)](https://github.com/srz-zumix/review-retrovert/actions/workflows/docker-build.yml)
4
+ [![Docker Pulls](https://img.shields.io/docker/pulls/srzzumix/review-retrovert)](https://hub.docker.com/r/srzzumix/review-retrovert)
4
5
 
5
6
  # ReVIEW::Retrovert
6
7
 
@@ -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,8 +11,10 @@ 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
+ method_option "ird", desc: 'For IRD', type: :boolean
15
+ method_option "no-update", desc: 'Do not Re:VIEW update', type: :boolean
16
+ method_option "no-image", desc: 'Do not copy image', type: :boolean
17
+ method_option "no-delegate-yaml", desc: 'review-retrovert creates an inherited file if the config.yml/catalog.yml file does not exist. Not done if no-delegate-yaml option is specified', type: :boolean
16
18
  def convert(review_starter_configfile, outdir)
17
19
  Converter.execute(review_starter_configfile, outdir, options)
18
20
  end
@@ -1,7 +1,11 @@
1
- require "review"
1
+ require 'review'
2
+ require 'erb'
2
3
  require 'fileutils'
3
4
  require 'tmpdir'
4
- require "review/retrovert/yamlconfig"
5
+ require 'review/retrovert/yamlconfig'
6
+ require 'review/retrovert/reviewcompat'
7
+ require 'review/retrovert/reviewdef'
8
+ require 'review/retrovert/utils'
5
9
 
6
10
  module ReVIEW
7
11
  module Retrovert
@@ -16,7 +20,13 @@ module ReVIEW
16
20
  @configs = YamlConfig.new
17
21
  @embeded_contents = []
18
22
  @catalog_contents = []
23
+ @talk_shortcuts = {}
19
24
  @ird = false
25
+ @talklist_replace_cmd = "note"
26
+ @desclist_replace_cmd = "info"
27
+ @talk_icon_scale = 0.1
28
+
29
+ @r_option_inner = ReViewDef::r_option_inner
20
30
  end
21
31
 
22
32
  def error(msg)
@@ -96,36 +106,114 @@ module ReVIEW
96
106
  @configs.rewrite_yml('imagedir', outimagedir)
97
107
  end
98
108
 
109
+ def copy_wards(outdir, words_file)
110
+ new_file = words_file
111
+ FileUtils.mkdir_p(File.join(outdir, File.dirname(words_file)))
112
+ if File.extname(words_file) == ".csv"
113
+ FileUtils.copy(File.join(@basedir, words_file), File.join(outdir, new_file))
114
+ else
115
+ new_file += ".csv"
116
+ Utils.Tsv2Csv(File.join(@basedir, words_file), File.join(outdir, new_file))
117
+ end
118
+ new_file
119
+ end
120
+
99
121
  def update_config(outdir)
100
122
  @configs.rewrite_yml('contentdir', '.')
101
123
  @configs.rewrite_yml('hook_beforetexcompile', 'null')
102
124
  @configs.rewrite_yml('texstyle', '["reviewmacro"]')
125
+
126
+ # words
127
+ words_files = @config['words_file']
128
+ if words_files
129
+ if words_files.is_a?(Array)
130
+ new_words_files = []
131
+ words_files.each do |words_file|
132
+ new_words_files.push copy_wards(outdir, words_file)
133
+ end
134
+ @configs.rewrite_yml('words_file', "[#{new_words_files.join(',')}]")
135
+ else
136
+ new_words_file = copy_wards(outdir, words_files)
137
+ @configs.rewrite_yml('words_file', new_words_file)
138
+ end
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
+ # texdocumentclass
103
148
  pagesize = @config['starter']['pagesize'].downcase
104
- jsbook_config = "media=print,paper=#{pagesize}"
149
+ book_configs = [
150
+ "media=print",
151
+ "paper=#{pagesize}"
152
+ ]
153
+
154
+ texdocumentclass = @config['texdocumentclass']
155
+ book_style = texdocumentclass[0]
156
+ if book_style == "jsbook"
157
+ book_style = "review-jsbook"
158
+ elsif book_style == "utbook"
159
+ book_style = "review-utbook"
160
+ FileUtils.cp(File.join(__dir__, 'sty/review-utbook.cls'), File.join(outdir, 'sty/review-utbook.cls'))
161
+ end
162
+ origin_book_configs = texdocumentclass[1].split(',')
163
+ book_configs.concat origin_book_configs.select { |c| !ReViewDef::review_jsbook_invalid_configs().include?(c) }
164
+
105
165
  if @ird
106
166
  # # リュウミン Pr6N R-KL 12.5Q 22H (9pt = 12.7Q 15.5pt = 21.8Q(H))
107
167
  # 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"]
108
- 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"
168
+ book_config = [
169
+ "media=ebook",
170
+ "openany",
171
+ "paper=b5",
172
+ "fontsize=9pt",
173
+ "baselineskip=15.5pt",
174
+ "head_space=15mm",
175
+ "gutter=22mm",
176
+ "footskip=16mm",
177
+ "line_length=45zw",
178
+ "number_of_lines=38"
179
+ ]
180
+ end
181
+ @configs.rewrite_yml_array('texdocumentclass', "[\"#{book_style}\", \"#{book_configs.join(',')}\"]")
182
+ if @config.key?('retrovert')
183
+ @config['retrovert'].each{ |k,v|
184
+ unless v..is_a?(Hash)
185
+ @configs.commentout_root_yml(k)
186
+ end
187
+ }
109
188
  end
110
- @configs.rewrite_yml_array('texdocumentclass', "[\"review-jsbook\", \"#{jsbook_config}\"]")
111
- @config['retrovert'].each{ |k,v|
112
- unless v..is_a?(Hash)
113
- @configs.commentout_root_yml(k)
114
- end
115
- }
116
189
  if @ird
117
190
  @configs.rewrite_yml('chapterlink', 'null')
118
191
  end
119
192
  end
120
193
 
121
- def replace_compatible_block_command_outline(content, command, new_command, option_count)
122
- if option_count > 0
123
- content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
124
- else
125
- content.gsub!(/^\/\/#{command}(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
194
+ def replace_compatible_block_command_outline(content, command, new_command, option_count, begin_option_pos=0)
195
+ 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>//}")
196
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*$/, "//#{new_command}\\k<option>")
197
+ # if begin_option_pos > 0
198
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
199
+ # content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\]){0,#{begin_option_pos}}$/, "//#{new_command}")
200
+ # end
201
+ end
202
+
203
+ def exclude_exta_option(content, cmd, max_option_num)
204
+ replace_compatible_block_command_outline(content, cmd, cmd, max_option_num)
205
+ end
206
+
207
+ def exclude_exta_options(content, commands, max_option_num)
208
+ commands.each do |cmd|
209
+ exclude_exta_option(content, cmd, max_option_num)
126
210
  end
127
211
  end
128
212
 
213
+ def starter_caption_to_text(content, command, n)
214
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{n-1}})\[(?<caption>#{@r_option_inner})\](?<post>.*)$/, "\\k<caption>\n//#{command}\\k<option>\\k<post>")
215
+ end
216
+
129
217
  def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
130
218
  body = new_body
131
219
  body += '\n' unless body.empty?
@@ -149,37 +237,30 @@ module ReVIEW
149
237
  content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
150
238
  end
151
239
 
152
- def delete_inline_command(content, command)
153
- # FIXME: 入れ子のフェンス記法({}|$)
154
- content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))((?:.*@<\w*>[\|${].*?[\|$}].*?|.*?)*)(?(1)(\$)|(?(2)(})|(\|)))/){"#{$4}"}
155
- end
156
-
157
- def replace_inline_command(content, command, new_command)
158
- content.gsub!(/@<#{command}>/, "@<#{new_command}>")
159
- end
160
-
161
240
  def replace_block_command_nested_boxed_article_i(content, box, depth)
162
241
  found = false
163
242
  content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
164
243
  matched = m[0..-1].join
165
244
  inner = m[5]
166
245
  # info depth
167
- im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
246
+ im = inner.match(/^\/\/(?<command>\w+)(?<options>(\[#{@r_option_inner}\])*)(?<open>[$|{])/)
168
247
  unless im.nil?
169
- inner_cmd = im[1]
170
- inner_open = im[4]
171
- inner_opts = im[2]
172
- first_opt_m = inner_opts.match(/^\[(.*?)\]/)
173
- first_opt = ""
248
+ inner_cmd = im['command']
249
+ inner_open = im['open']
250
+ inner_opts = im['options']
251
+ id_opt = ""
174
252
 
175
253
  # is_commentout = false
176
254
  is_commentout = true
177
- if first_opt_m
178
- first_opt_v = first_opt_m[1]
179
- unless first_opt_v.empty?
180
- if inner.match(/@<.*?>[$|{]#{first_opt}/)
181
- is_commentout = false
182
- first_opt = "\\[#{first_opt_v}\\]"
255
+ if ReViewDef::is_has_id_block_command(inner_cmd)
256
+ first_opt_m = inner_opts.match(/^\[(.*?)\]/)
257
+ if first_opt_m
258
+ first_opt_v = first_opt_m[1]
259
+ unless first_opt_v.empty?
260
+ if inner.match(/@<#{ReViewDef::id_ref_inline_commands().join('|')}>[$|{]#{first_opt_v}/)
261
+ is_commentout = false
262
+ id_opt = "\\[#{first_opt_v}\\]"
263
+ end
183
264
  end
184
265
  end
185
266
  end
@@ -189,24 +270,44 @@ module ReVIEW
189
270
  if inner_open == m[2..4].join
190
271
  # if same fence then cmd_end == inner_end
191
272
  if is_commentout
192
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
193
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#@##{cmd_end}")
273
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})/) {
274
+ line = $1
275
+ caption = ReViewDef::get_caption(line)
276
+ s = ""
277
+ s += "「#{caption}」\n\n" unless caption.blank?
278
+ s += "#@##{line}"
279
+ s
280
+ }
281
+ rep = "#{cmd_begin}#{inner}#@##{cmd_end}"
282
+ content.gsub!(matched) { |mm| rep }
194
283
  else
195
- imb = inner.match(/(\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/#{inner_cmd}#{first_opt}(\[.*?\])*#{inner_open}.*)\R/m)
284
+ imb = inner.match(/(\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/#{inner_cmd}#{id_opt}(\[#{@r_option_inner}\])*#{inner_open}.*)\R/m)
196
285
  to_out_block = imb[1]
197
286
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
198
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
287
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
288
+ content.gsub!(matched) { |mm| rep }
199
289
  end
200
290
  else
201
- close = inner_open == '{' ? '}' : inner_open
291
+ close = ReViewDef::fence_close(inner_open)
202
292
  if is_commentout
203
- inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})(.*?)(^\/\/#{close})/m, '#@#\1\2#@#\3')
204
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}")
293
+ inner.gsub!(/(^\/\/(\w+(\[#{@r_option_inner}\]|))*#{inner_open})(.*?)(^\/\/#{close})/m) {
294
+ first = $1
295
+ body = $2
296
+ last = $3
297
+ caption = ReViewDef::get_caption(first)
298
+ s = ""
299
+ s += "「#{caption}」\n\n" unless caption.blank?
300
+ s += "#@##{first}#{body}@##{last}"
301
+ s
302
+ }
303
+ rep = "#{cmd_begin}#{inner}#{cmd_end}"
304
+ content.gsub!(matched) { |mm| rep }
205
305
  else
206
- imb = inner.match(/\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/(#{inner_cmd})#{first_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
306
+ imb = inner.match(/\R((^\/\/\w+(\[#{@r_option_inner}\])*)\s*)*^\/\/(#{inner_cmd})#{id_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
207
307
  to_out_block = imb[0]
208
308
  inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
209
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
309
+ rep = "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}"
310
+ content.gsub!(matched) { |mm| rep }
210
311
  end
211
312
  end
212
313
  found = true
@@ -222,7 +323,7 @@ module ReVIEW
222
323
  end
223
324
 
224
325
  def replace_block_command_nested_boxed_articles(content)
225
- unless Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('5.0.0')
326
+ unless ReViewCompat::has_nested_minicolumn()
226
327
  replace_block_command_nested_boxed_article(content, 'note')
227
328
  replace_block_command_nested_boxed_article(content, 'memo')
228
329
  replace_block_command_nested_boxed_article(content, 'tip')
@@ -234,24 +335,27 @@ module ReVIEW
234
335
  end
235
336
  end
236
337
 
338
+ # #@+++ ~ #@--- to #@#+++ #@#~ #@#---
237
339
  def replace_block_commentout(content)
238
340
  d = content.dup
239
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
341
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
240
342
  matched = m[0..-1].join
241
343
  inner = m[2]
242
- inner.gsub!(/(^.)/, '#@#\1')
243
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
344
+ inner.gsub!(/^/, '#@#')
345
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
346
+ content.gsub!(matched) { |mm| rep }
244
347
  }
245
348
  end
246
349
 
247
350
  def replace_block_commentout_without_sampleout(content)
248
351
  d = content.dup
249
352
  d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
250
- d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
353
+ d.scan(/(^#@)(\++\R)(.*?)(^#@)(-+)/m) { |m|
251
354
  matched = m[0..-1].join
252
355
  inner = m[2]
253
- inner.gsub!(/(^.)/, '#@#\1')
254
- content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
356
+ inner.gsub!(/^/, '#@#\1')
357
+ rep = "#@##{m[1]}#{inner}#@##{m[4]}"
358
+ content.gsub!(matched) { |mm| rep }
255
359
  }
256
360
  end
257
361
 
@@ -264,7 +368,8 @@ module ReVIEW
264
368
  option = m[1]
265
369
  inner = m[3]
266
370
  # inner.gsub!(/^\/\//, '//@<nop>{}')
267
- content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
371
+ rep = "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}"
372
+ content.gsub!(matched) { |mm| rep }
268
373
  }
269
374
  end
270
375
 
@@ -278,7 +383,7 @@ module ReVIEW
278
383
  end
279
384
 
280
385
  def fix_deprecated_list(content)
281
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
386
+ if ReViewCompat::is_need_space_term_list()
282
387
  content.gsub!(/^: (.*)/, ' : \1')
283
388
  end
284
389
  end
@@ -290,57 +395,181 @@ module ReVIEW
290
395
  ref = m[4]
291
396
  n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
292
397
  unless n.nil?
293
- content.gsub!(/#{Regexp.escape(matched)}/, n[1])
398
+ rep = n[1]
399
+ content.gsub!(matched) { |mm| rep }
294
400
  content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
295
401
  else
296
- # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
402
+ # content.gsub!(matched, "noteref<#{ref}>")
297
403
  end
298
404
  }
299
405
  end
300
406
 
407
+ def remove_option_param(content, commands, n, param)
408
+ content.gsub!(/(^\/\/(#{commands.join('|')})(\[.*?\]){#{n-1}}\[.*?)((,|)\s*#{param}=[^,\]]*)(.*?\])/) {
409
+ prev = $1
410
+ cmd = $2
411
+ opt = $4
412
+ post = $6
413
+ "#{prev}#{post}"
414
+ }
415
+ end
416
+
301
417
  def remove_starter_options(content)
418
+ # image width
419
+ content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)(,|)(\s*)width=\s*([0-9.]+)%(?<after>.*?\])/) { |m|
420
+ m.gsub!(/width=\s*([0-9.]+)%/) {
421
+ value = $1
422
+ "scale=#{value.to_i * 0.01}"
423
+ }
424
+ }
425
+ remove_option_param(content, ["image"], 3, "width")
302
426
  # image border
303
- content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)((,|)border=[^,\]]*)(.*?\])/, '\1\4')
427
+ remove_option_param(content, ["image"], 3, "border")
428
+ # image pos
429
+ remove_option_param(content, ["image"], 3, "pos")
304
430
  # list lineno
305
- content.gsub!(/(^\/\/list\[.*?\]\[.*?\]\[.*?)((,|)lineno=[^,\]]*)(.*?\])/, '\1\4')
306
- end
307
-
308
- def expand_nested_inline_command(content)
309
- found = false
310
- content.dup.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
311
- matched = m.join
312
- body = m[4]
313
- im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
314
- if im.nil?
315
- im = body.match(/(.*)(@<.*?>)#{m[1..3].join}/)
316
- unless im.nil?
317
- outcmd_begin = m[0] + "$|{".gsub(m[1..3].join, '')
318
- outcmd_end = "$|}".gsub(m[5..7].join, '')
319
- rep = "#{outcmd_begin}#{body}#{outcmd_end}"
320
- content.gsub!(matched, rep)
321
- found = true
431
+ remove_option_param(content, ["list", "listnum"], 3, "lineno")
432
+ end
433
+
434
+ # talklist to //#{cmd}[]{ //emlist[]{}... }
435
+ def talklist_to_nested_contents_list(content, cmd)
436
+ content.gsub!(/^\/\/talklist(.*?){/, "//#{cmd}\\1{")
437
+ content.gsub!(/^\/\/talk(?<options>\[#{@r_option_inner}\]\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
438
+ content.gsub!(/^\/\/t(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//talk\\k<options>{\n\\k<body>\n//}")
439
+ content.gsub!(/^\/\/(t|talk)((\[#{@r_option_inner}\])*){/) { |s|
440
+ m = s.scan(/(\[(#{@r_option_inner})\])/)
441
+ # 1st option is image id
442
+ avatar = m[0][1]
443
+ first_option = m[0][0]
444
+ traling_options = m[1..-1].map{ |x| x[0] }.join
445
+ if avatar.length > 0
446
+ kv = @talk_shortcuts[avatar]
447
+ if kv&.key?('image')
448
+ "//indepimage[#{kv['image']}][][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
449
+ elsif kv&.key?('name')
450
+ "//emlist[#{kv['name']}]{"
451
+ else
452
+ "//indepimage#{first_option}[][scale=#{@talk_icon_scale}]{\n//}\n//emlist[]#{traling_options}{"
322
453
  end
323
454
  else
324
- outcmd_begin = m[0..3].join
325
- outcmd_end = m[5..7].join
326
- rep = "#{outcmd_begin}#{im[1]}#{outcmd_end}#{im[2..9].join}#{outcmd_begin}#{im[-1]}#{outcmd_end}"
327
- content.gsub!(matched, rep)
328
- found = true
455
+ "//emlist#{traling_options}{"
329
456
  end
330
457
  }
331
- if found
332
- expand_nested_inline_command(content)
458
+ end
459
+
460
+ # desclist to //#{cmd}[]{ //emlist[]{}... }
461
+ def desclist_to_nested_contents_list(content, cmd)
462
+ content.gsub!(/^\/\/desclist(.*?){/, "//#{cmd}\\1{")
463
+ content.gsub!(/^\/\/desc(?<options>\[#{@r_option_inner}\])\[(?<body>#{@r_option_inner})\]$/, "//desc\\k<options>{\n\\k<body>\n//}")
464
+ content.gsub!(/^\/\/desc((\[#{@r_option_inner}\])*){/, '//emlist\1{')
465
+ end
466
+
467
+ def starter_list_to_nested_contents_list(content)
468
+ # talklist
469
+ talklist_to_nested_contents_list(content, @talklist_replace_cmd)
470
+ # desclist
471
+ desclist_to_nested_contents_list(content, @desclist_replace_cmd)
472
+ replace_block_command_nested_boxed_article(content, 'emlist')
473
+ end
474
+
475
+ def replace_file_option(content, matched, fence_open, option)
476
+ file_param_m = option.match(/\s*file\s*=\s*([^,\]]*)/)
477
+ if file_param_m
478
+ fence_close = ReViewDef::fence_close(fence_open)
479
+ filepath = file_param_m[1]
480
+ if fence_close
481
+ content.gsub!(/#{Regexp.escape(matched)}(.*?)^\/\/#{fence_close}/m) {
482
+ "#{matched}\n\#@mapfile(#{filepath})\n\#@end\n//#{fence_close}"
483
+ }
484
+ end
333
485
  end
334
486
  end
335
487
 
488
+ def convert_starter_option(content)
489
+ # file
490
+ r = /^(?<matched>\/\/(list|listnum|table)\[#{@r_option_inner}\]\[#{@r_option_inner}\]\[(?<options>#{@r_option_inner})\](?<open>.))$/
491
+ content.dup.scan(r) { |m|
492
+ matched = m[0]
493
+ options = m[1]
494
+ fence_open = m[2]
495
+ options.split(',').each { |option|
496
+ replace_file_option(content, matched, fence_open, option)
497
+ }
498
+ }
499
+ remove_option_param(content, ["list", "listnum", "table"], 3, "file")
500
+ # csv
501
+ convert_csv_option(content)
502
+ end
503
+
504
+ def convert_csv_option(content)
505
+ r_table = /^(?<matched>\/\/table\[#{@r_option_inner}\]\[#{@r_option_inner}\]\[(?<options>#{@r_option_inner})\](?<open>.))$/
506
+ content.dup.scan(r_table) { |m|
507
+ matched = m[0]
508
+ options = m[1]
509
+ options.split(',').each { |option|
510
+ if option.match(/\s*csv\s*=\s*on\s*/)
511
+ open = m[2]
512
+ close = ReViewDef::fence_close(open)
513
+ if close
514
+ tm = content.match(/#{Regexp.escape(matched)}(.*?)^\/\/#{close}/m)
515
+ outer = tm[0]
516
+ inner = tm[1]
517
+ im = inner.match(/(.*?)([=\-]{12,}\R)(.*)/m)
518
+ if im
519
+ header = im[1]
520
+ sep = im[2]
521
+ body = im[3]
522
+ new_header = ""
523
+ new_body = ""
524
+ CSV.parse(header) do |h|
525
+ new_header += Utils::GenerateTsv(h)
526
+ end
527
+ CSV.parse(body) do |c|
528
+ new_body += Utils::GenerateTsv(c)
529
+ end
530
+ content.gsub!(outer, "#{matched}#{new_header}#{sep}#{new_body}//#{close}")
531
+ else
532
+ im = inner.match(/^\#@mapfile\((.*?)\)\R^\#@end/m)
533
+ if im
534
+ inner_file = im[1]
535
+ csv_text = "\n"
536
+ csv_text += File.open(File.join(@basedir, inner_file)).read()
537
+ else
538
+ csv_text = inner
539
+ end
540
+ new_body = ""
541
+ CSV.parse(csv_text) do |c|
542
+ new_body += Utils::GenerateTsv(c)
543
+ end
544
+ content.gsub!(outer, "#{matched}#{new_body}//#{close}")
545
+ end
546
+ end
547
+ end
548
+ }
549
+ }
550
+ end
551
+
552
+ # tsize[builder][xxx] to tsize[|builder|xxx]
553
+ def replace_tsize(content)
554
+ content.gsub!(/^\/\/tsize\[(.*?)\]\[(.*?)\]/) {
555
+ builder = $1
556
+ builder = "" if $1 == '*'
557
+ "//tsize[|#{builder}|#{$2}]"
558
+ }
559
+ end
560
+
336
561
  def copy_embedded_contents(outdir, content)
337
- content.scan(/\#@mapfile\((.*?)\)/).each do |filepath|
562
+ content.scan(/\#@mapfile\((.*?)\)/).each do |filepath_|
563
+ filepath = filepath_[0]
564
+ if filepath.blank?
565
+ next
566
+ end
338
567
  srcpath = File.join(@basedir, filepath)
339
568
  if File.exist?(srcpath)
340
569
  outpath = File.join(File.absolute_path(outdir), filepath)
341
570
  FileUtils.mkdir_p(File.dirname(outpath))
342
571
  FileUtils.cp(srcpath, outpath)
343
- @embeded_contents.push(filepath[0])
572
+ @embeded_contents.push(filepath)
344
573
  update_content(outpath, outpath)
345
574
  end
346
575
  end
@@ -376,42 +605,136 @@ module ReVIEW
376
605
  }
377
606
  end
378
607
 
379
- def update_content(outdir, contentfile)
380
- info contentfile
381
- filename = File.basename(contentfile, '.*')
382
- content = File.read(contentfile)
383
- content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
384
- content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
385
- linkurl_footnote = @config['starter']['linkurl_footnote']
386
- # table 内の @ コマンドは不安定らしい
387
- while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
388
- end
389
- # 空セルが2行になることがあるらしい
390
- while !content.gsub!(/(\/\/table.*\s)\.(\s.*?\/\/})/m, "\\1#{@table_empty_replace}\\2").nil? do
391
- end
392
- # Re:VIEW Starter commands
393
- replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1)
394
- replace_compatible_block_command_outline(content, 'cmd', 'cmd', 0)
608
+ def replace_starter_command(content)
609
+ replace_compatible_block_command_outline(content, 'program', 'list', 2)
610
+ replace_compatible_block_command_outline(content, 'terminal', 'cmd', 1, 1)
611
+ replace_compatible_block_command_outline(content, 'output', 'list', 3)
395
612
  replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
396
613
  replace_block_command_outline(content, 'abstract', 'lead', true)
614
+ delete_block_command(content, 'makechaptitlepage')
615
+ delete_block_command(content, 'vspace')
397
616
  delete_block_command(content, 'needvspace')
398
617
  delete_block_command(content, 'clearpage')
399
618
  delete_block_command(content, 'flushright')
400
- delete_block_command(content, 'centering')
401
619
  delete_block_command(content, 'paragraphend')
620
+ delete_block_command_outer(content, 'centering')
621
+
622
+ # convert starter option
623
+ convert_starter_option(content)
624
+
625
+ # delete starter option
626
+ # exclude_exta_option(content, 'cmd', 0)
627
+ starter_caption_to_text(content, 'cmd', 1)
628
+ exclude_exta_options(content, [
629
+ 'imgtable',
630
+ 'table',
631
+ # list/listnum の第3引数は言語指定だが、Starter の第3引数と全く異なるため 2 引数にしている
632
+ # Starter 側が言語指定対応したら修正
633
+ 'list',
634
+ 'listnum',
635
+ ], 2)
636
+ # exclude_exta_option(content, 'tsize', 1)
637
+ replace_tsize(content)
402
638
 
403
639
  # delete IRD unsupported commands
404
640
  if @ird
405
641
  delete_block_command(content, 'noindent')
406
642
  end
407
643
 
644
+ # chapterauthor
645
+ content.gsub!(/^\/\/chapterauthor\[(.*?)\]/, "//lead{\n\\1\n//}")
646
+ # talklist/desclist
647
+ starter_list_to_nested_contents_list(content)
648
+ # empty caption imaget to indepimage
649
+ content.gsub!(/^\/\/image(\[#{@r_option_inner}\]\[\].*)$/, '//indepimage\1')
650
+ end
651
+
652
+ def delete_inline_command(content, command)
653
+ # 既に入れ子は展開されている前提
654
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/, '\4')
655
+ end
656
+
657
+ def do_replace_inline_command(content, command, &blk)
658
+ # 既に入れ子は展開されている前提
659
+ content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))(.*?)(?(1)(\$)|(?(2)(})|(\|)))/) { blk.call([$1, $2, $3].join, $4, [$5, $6, $7].join) }
660
+ end
661
+
662
+ def replace_inline_command(content, command, new_command)
663
+ do_replace_inline_command(content, command) { |open, inner, close|
664
+ "@<#{new_command}>#{open}#{inner}#{close}"
665
+ }
666
+ end
667
+
668
+ # @<XXX>{AAA@<YYY>{BBB}} to @<XXX>{AAA}@<YYY>{BBB}
669
+ def expand_nested_inline_command(content)
670
+ found = false
671
+ content.dup.each_line do |line|
672
+ if line.match(/^#@#/)
673
+ next
674
+ end
675
+ line.scan(/(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
676
+ matched = m.join
677
+ body = m[4]
678
+ outcmd_cmd = m[0]
679
+ outcmd_open = m[1..3].join
680
+ outcmd_begin = outcmd_cmd + outcmd_open
681
+ outcmd_close = m[5..7].join
682
+ im = body.match(/(.*)(@<.*?>)(?:(\$)|(?:({)|(\|)))(.*?)(?(3)(\$)|(?(4)(})|(\|)))(.*)/)
683
+ if im.nil?
684
+ # for {}
685
+ im2 = body.match(/(.*)(@<.*?>)#{Regexp.escape(outcmd_open)}(.*)/)
686
+ unless im2.nil?
687
+ rep = ""
688
+ if im2[3].length > 0
689
+ incmd_begin = im2[1..2].join + "$|{".gsub(outcmd_open, '')[0]
690
+ incmd_end = "$|}".gsub(outcmd_close, '')[0]
691
+ rep = "#{outcmd_begin}#{incmd_begin}#{im2[3]}#{incmd_end}"
692
+ else
693
+ rep = outcmd_begin + im2[1]
694
+ end
695
+ content.gsub!(matched) { |mm| rep }
696
+ found = true
697
+ else
698
+ # for |$
699
+ if body.match(/.*@<.*?>$/)
700
+ incmd_fence = "$|".gsub(outcmd_open, '')
701
+ rep = "#{outcmd_begin}#{body}#{incmd_fence}"
702
+ content.gsub!(/#{Regexp.escape(matched)}(.*?)#{Regexp.escape(outcmd_open)}/, "#{rep}\\1#{incmd_fence}")
703
+ found = true
704
+ end
705
+ end
706
+ else
707
+ rep = ""
708
+ rep += "#{outcmd_begin}#{im[1]}#{outcmd_close}" if im[1].length > 0
709
+ rep += "#{im[2..9].join}"
710
+ rep += "#{outcmd_begin}#{im[-1]}#{outcmd_close}" if im[-1].length > 0
711
+ content.gsub!(matched) { |mm| rep }
712
+ found = true
713
+ end
714
+ }
715
+ end
716
+ if found
717
+ expand_nested_inline_command(content)
718
+ end
719
+ end
720
+
721
+ def replace_starter_inline_command(content)
722
+ expand_nested_inline_command(content)
723
+
408
724
  replace_inline_command(content, 'secref', 'hd')
409
725
  replace_inline_command(content, 'file', 'kw')
410
726
  replace_inline_command(content, 'hlink', 'href')
411
727
  replace_inline_command(content, 'B', 'strong')
728
+ replace_inline_command(content, 'W', 'wb')
729
+ replace_inline_command(content, 'term', 'idx')
730
+ replace_inline_command(content, 'termnoidx', 'hidx')
731
+ unless ReViewCompat::has_bou()
732
+ replace_inline_command(content, 'bou', 'b')
733
+ end
412
734
  delete_inline_command(content, 'userinput')
413
735
  delete_inline_command(content, 'weak')
414
736
  delete_inline_command(content, 'cursor')
737
+ delete_inline_command(content, 'foldhere')
415
738
  # font size
416
739
  delete_inline_command(content, 'small')
417
740
  delete_inline_command(content, 'xsmall')
@@ -420,12 +743,31 @@ module ReVIEW
420
743
  delete_inline_command(content, 'xlarge')
421
744
  delete_inline_command(content, 'xxlarge')
422
745
 
746
+ do_replace_inline_command(content, 'par') { |open, inner, close| "@<br>#{open}#{close}" }
747
+ do_replace_inline_command(content, 'qq' ) { |open, inner, close| "\"#{inner}\"" }
748
+ end
749
+
750
+ def update_content(outdir, contentfile)
751
+ info contentfile
752
+ filename = File.basename(contentfile, '.*')
753
+ content = File.read(contentfile)
754
+ content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
755
+ content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
756
+ linkurl_footnote = @config['starter']['linkurl_footnote']
757
+ # noop を最後に消すためにダミーに変える
758
+ content.gsub!('@<nop>$$', '@<dummynop>$must_be_replace_nop$')
759
+ content.gsub!('@<nop>||', '@<dummynop>|must_be_replace_nop|')
760
+ content.gsub!('@<nop>{}', '@<dummynop>{must_be_replace_nop}')
761
+
762
+ # Re:VIEW Starter commands
763
+ replace_starter_command(content)
764
+
423
765
  # fixed lack of options
424
766
  content.gsub!(/^\/\/list{/, '//list[][]{')
425
767
  # empty br line to blankline
426
768
  content.gsub!(/^\s*@<br>{}\s*$/, '//blankline')
427
769
 
428
- if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
770
+ unless ReViewCompat::is_allow_empty_image_caption()
429
771
  # empty caption is not allow
430
772
  content.gsub!(/^\/\/image\[(.*)\]\[\]{/, '//image[\1][ ]{')
431
773
  end
@@ -441,6 +783,7 @@ module ReVIEW
441
783
  replace_block_command_nested_boxed_articles(content)
442
784
 
443
785
  # empty ids
786
+ replace_auto_ids(content, 'table', 2)
444
787
  replace_auto_ids(content, 'list', 2)
445
788
  replace_auto_ids(content, 'listnum', 2)
446
789
 
@@ -456,23 +799,40 @@ module ReVIEW
456
799
  content.gsub!('@<TeX>{}', 'TeX')
457
800
  content.gsub!('@<hearts>{}', '!HEART!')
458
801
 
459
- # nop replace must be last step
460
- content.gsub!('@<nop>$$', '@<b>$$')
461
- content.gsub!('@<nop>||', '@<b>||')
462
- content.gsub!('@<nop>{}', '@<b>{}')
463
-
464
- # expand nested inline command
465
- expand_nested_inline_command(content)
802
+ replace_starter_inline_command(content)
466
803
 
467
804
  # fix deprecated
468
805
  fix_deprecated_list(content)
469
806
 
470
807
  if @ird
471
808
  # br to blankline
472
- content.gsub!(/(.*)@<br>{}$/, "\\1\n\n")
473
- content.gsub!(/(.*)@<br>{}(.*)$/, "\\1\n\n\\2")
809
+ content.gsub!(/(^\/\/footnote\[.*?\]\[.*?)((.*?@<br>({}|\$\$|\|\|)){1,})(.*\])$/) { |m|
810
+ m.gsub(/@<br>({}|\$\$|\|\|)/, '@<fnbr>\1')
811
+ }
812
+
813
+ content.gsub!(/(\/\/table.*?{.*?\/\/})/m) { |m|
814
+ # table 内の @ コマンドは不安定らしい
815
+ m.gsub!('@<br>{}', "#{Regexp.escape(@table_br_replace)}")
816
+ # 空セルが2行になることがあるらしい
817
+ m.gsub!(/(\s)\.(\s)/, "\\1#{Regexp.escape(@table_empty_replace)}\\2")
818
+ m
819
+ }
820
+
821
+ content.gsub!(/(.*)@<br>({}|\$\$|\|\|)$/, "\\1\n\n")
822
+ content.gsub!(/(.*)@<br>({}|\$\$|\|\|)(.*)$/, "\\1\n\n\\2")
823
+
824
+ content.gsub!('@<fnbr>{}', '@<br>{}')
825
+ content.gsub!('@<fnbr>$$', '@<br>$$')
826
+ content.gsub!('@<fnbr>||', '@<br>||')
474
827
  end
475
828
 
829
+ # nop replace must be last step
830
+ # content.gsub!('@<dumynop>$must_be_replace_nop$', '@<b>$$')
831
+ # content.gsub!('@<dumynop>|must_be_replace_nop|', '@<b>||')
832
+ content.gsub!('@<dummynop>$must_be_replace_nop$', '@<b>{}')
833
+ content.gsub!('@<dummynop>|must_be_replace_nop|', '@<b>{}')
834
+ content.gsub!('@<dummynop>{must_be_replace_nop}', '@<b>{}')
835
+
476
836
  File.write(contentfile, content)
477
837
  copy_embedded_contents(outdir, content)
478
838
  end
@@ -503,7 +863,7 @@ module ReVIEW
503
863
  contentdir = abspath
504
864
  info 'replace starter block command'
505
865
  info 'replace starter inline command'
506
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
866
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
507
867
  update_content_files(outdir, contentdir, @catalog_contents)
508
868
  unless options['strict']
509
869
  all_contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -518,12 +878,10 @@ module ReVIEW
518
878
  contentpath = File.join(contentdir, content)
519
879
  if File.exist?(contentpath)
520
880
  info "preproc #{contentpath}"
521
- buf = StringIO.new
522
881
  pwd = Dir.pwd
523
882
  Dir.chdir(outdir)
524
- File.open(contentpath) { |f| pp.process(f, buf) }
883
+ content = pp.process(contentpath)
525
884
  Dir.chdir(pwd)
526
- content = buf.string
527
885
  content.gsub!(/^#[@]map.*$/, '')
528
886
  content.gsub!(/^#[@]end$/, '')
529
887
  File.write(contentpath, content)
@@ -537,10 +895,10 @@ module ReVIEW
537
895
  contentdir = abspath
538
896
  param = {}
539
897
  param['tabwidth'] = options['tabwidth'].to_i
540
- pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
898
+ pp = ReViewCompat::Preprocessor(param)
541
899
 
542
900
  if options['strict']
543
- catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
901
+ catalog = ReViewCompat::Catalog(File.join(abspath, yamlfile))
544
902
  preproc_content_files(outdir, pp, contentdir, @catalog_contents)
545
903
  else
546
904
  contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
@@ -548,12 +906,20 @@ module ReVIEW
548
906
  end
549
907
  end
550
908
 
909
+ def erb_sty(outdir, filename)
910
+ src = File.join(__dir__, "sty/#{filename}.erb")
911
+ dest = File.join(outdir, "sty/#{filename}")
912
+ erb = ERB.new(File.read(src))
913
+ File.write(dest, erb.result)
914
+ end
915
+
551
916
  def update_sty(outdir, options)
552
- # FileUtils.cp(File.join(@basedir, 'sty/review-custom.sty'), File.join(outdir, 'sty/review-custom.sty'))
917
+ review_custom_sty = File.open(File.join(outdir, 'sty/review-custom.sty'), 'a')
918
+ erb_sty(outdir, 'review-retrovert-custom.sty')
919
+ review_custom_sty.puts('\RequirePackage{review-retrovert-custom}')
553
920
  if @ird
554
- FileUtils.cp(File.join(__dir__, 'sty/ird.sty'), File.join(outdir, 'sty/ird.sty'))
555
- file = File.open(File.join(outdir, 'sty/review-custom.sty'), 'a')
556
- file.puts('\RequirePackage{ird}')
921
+ erb_sty(outdir, 'ird.sty')
922
+ review_custom_sty.puts('\RequirePackage{ird}')
557
923
  end
558
924
  end
559
925
 
@@ -581,7 +947,7 @@ module ReVIEW
581
947
  @basedir = @configs.basedir
582
948
  @srccontentsdir = @config['contentdir']
583
949
 
584
- catalog = ReVIEW::Catalog.new(File.open(@configs.catalogfile()))
950
+ catalog = ReViewCompat::Catalog(@configs.catalogfile())
585
951
  add_catalog_contents(catalog.predef())
586
952
  add_catalog_contents(catalog.chaps())
587
953
  add_catalog_contents(catalog.appendix())
@@ -601,6 +967,7 @@ module ReVIEW
601
967
  load_config(yamlfile)
602
968
  store_image_dir = store_out_image(outdir) if options['no-image']
603
969
  create_initial_project(outdir, options)
970
+ @talk_shortcuts = @config['starter']['talk_shortcuts']
604
971
 
605
972
  copy_config(outdir)
606
973
  copy_catalog(outdir)
@@ -610,16 +977,30 @@ module ReVIEW
610
977
  update_sty(outdir, options)
611
978
  update_ext(outdir, options)
612
979
 
613
- pwd = Dir.pwd
614
- Dir.chdir(outdir)
615
- updater = ReVIEW::Update.new
616
- updater.force = true
617
- # updater.backup = false
618
- begin
619
- updater.execute()
620
- rescue
980
+ unless options['no-delegate-config']
981
+ unless File.exist?(File.join(outdir, 'config.yml'))
982
+ root_config = File.open(File.join(outdir, 'config.yml'), 'w')
983
+ root_config.puts("review_version: #{ReVIEW::VERSION}")
984
+ root_config.puts("inherit: [\"#{File.basename(yamlfile)}\"]")
985
+ end
986
+ unless File.exist?(File.join(outdir, 'catalog.yml'))
987
+ catalogfile = @config['catalogfile']
988
+ FileUtils.copy(File.join(@basedir, catalogfile), File.join(outdir, 'catalog.yml'))
989
+ end
990
+ end
991
+
992
+ unless options['no-update']
993
+ pwd = Dir.pwd
994
+ Dir.chdir(outdir)
995
+ updater = ReVIEW::Update.new
996
+ updater.force = true
997
+ # updater.backup = false
998
+ begin
999
+ updater.execute()
1000
+ rescue
1001
+ end
1002
+ Dir.chdir(pwd)
621
1003
  end
622
- Dir.chdir(pwd)
623
1004
 
624
1005
  if options['preproc']
625
1006
  info 'preproc'