review-retrovert 0.3.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/retrovert.yml +61 -0
  3. data/.gitignore +2 -2
  4. data/.ruby-version +1 -0
  5. data/Dockerfile +1 -1
  6. data/Gemfile +1 -0
  7. data/Gemfile.lock +82 -17
  8. data/README.md +64 -4
  9. data/lib/review/retrovert/cli.rb +4 -0
  10. data/lib/review/retrovert/converter.rb +393 -15
  11. data/lib/review/retrovert/version.rb +1 -1
  12. data/lib/review/retrovert/yamlconfig.rb +33 -2
  13. data/review-retrovert.gemspec +2 -2
  14. data/testdata/mybook/.gitignore +7 -0
  15. data/testdata/mybook/README.md +43 -0
  16. data/testdata/mybook/Rakefile +16 -0
  17. data/testdata/mybook/catalog.yml +34 -0
  18. data/testdata/mybook/config-retrovert.yml +7 -0
  19. data/testdata/mybook/config-starter.yml +139 -0
  20. data/testdata/mybook/config.yml +375 -0
  21. data/testdata/mybook/contents/00-preface.re +83 -0
  22. data/testdata/mybook/contents/01-install.re +272 -0
  23. data/testdata/mybook/contents/02-tutorial.re +1008 -0
  24. data/testdata/mybook/contents/03-syntax.re +2613 -0
  25. data/testdata/mybook/contents/04-customize.re +728 -0
  26. data/testdata/mybook/contents/05-faq.re +328 -0
  27. data/testdata/mybook/contents/06-bestpractice.re +971 -0
  28. data/testdata/mybook/contents/91-compare.re +18 -0
  29. data/testdata/mybook/contents/92-filelist.re +119 -0
  30. data/testdata/mybook/contents/93-background.re +267 -0
  31. data/testdata/mybook/contents/99-postface.re +38 -0
  32. data/testdata/mybook/contents/r0-inner.re +2 -0
  33. data/testdata/mybook/contents/r0-root.re +4 -0
  34. data/testdata/mybook/css/normalize.css +349 -0
  35. data/testdata/mybook/css/webstyle.css +514 -0
  36. data/testdata/mybook/images/03-syntax/favicon-16x16.png +0 -0
  37. data/testdata/mybook/images/03-syntax/figure_heretop.png +0 -0
  38. data/testdata/mybook/images/03-syntax/tw-icon1.jpg +0 -0
  39. data/testdata/mybook/images/03-syntax/tw-icon2.jpg +0 -0
  40. data/testdata/mybook/images/03-syntax/tw-icon3.jpg +0 -0
  41. data/testdata/mybook/images/03-syntax/tw-icon4.jpg +0 -0
  42. data/testdata/mybook/images/04-customize/caption_pagebreak.png +0 -0
  43. data/testdata/mybook/images/04-customize/chaptitlepage_sample.png +0 -0
  44. data/testdata/mybook/images/05-faq/codeblock_rpadding1.png +0 -0
  45. data/testdata/mybook/images/05-faq/codeblock_rpadding2.png +0 -0
  46. data/testdata/mybook/images/06-bestpractice/figure_heretop.png +0 -0
  47. data/testdata/mybook/images/06-bestpractice/font_beramono.png +0 -0
  48. data/testdata/mybook/images/06-bestpractice/heading_design1.png +0 -0
  49. data/testdata/mybook/images/06-bestpractice/heading_design2.png +0 -0
  50. data/testdata/mybook/images/06-bestpractice/margin_book.png +0 -0
  51. data/testdata/mybook/images/06-bestpractice/multiline-title.png +0 -0
  52. data/testdata/mybook/images/06-bestpractice/preface_numbered.png +0 -0
  53. data/testdata/mybook/images/06-bestpractice/program_border.png +0 -0
  54. data/testdata/mybook/images/06-bestpractice/sechead_design_4.png +0 -0
  55. data/testdata/mybook/images/06-bestpractice/titlepage-samples.png +0 -0
  56. data/testdata/mybook/images/93-background/bug913.png +0 -0
  57. data/testdata/mybook/images/93-background/slide2.png +0 -0
  58. data/testdata/mybook/images/cover_a5.pdf +0 -0
  59. data/testdata/mybook/images/cover_b5.pdf +0 -0
  60. data/testdata/mybook/images/tw-icon.jpg +0 -0
  61. data/testdata/mybook/layouts/layout.epub.erb +29 -0
  62. data/testdata/mybook/layouts/layout.html5.erb +106 -0
  63. data/testdata/mybook/layouts/layout.tex.erb +546 -0
  64. data/testdata/mybook/lib/hooks/beforetexcompile.rb +55 -0
  65. data/testdata/mybook/lib/ruby/review-builder.rb +503 -0
  66. data/testdata/mybook/lib/ruby/review-cli.rb +58 -0
  67. data/testdata/mybook/lib/ruby/review-compiler.rb +523 -0
  68. data/testdata/mybook/lib/ruby/review-epubmaker.rb +606 -0
  69. data/testdata/mybook/lib/ruby/review-htmlbuilder.rb +661 -0
  70. data/testdata/mybook/lib/ruby/review-latexbuilder.rb +782 -0
  71. data/testdata/mybook/lib/ruby/review-maker.rb +235 -0
  72. data/testdata/mybook/lib/ruby/review-monkeypatch.rb +91 -0
  73. data/testdata/mybook/lib/ruby/review-pdfmaker.rb +468 -0
  74. data/testdata/mybook/lib/ruby/review-textbuilder.rb +36 -0
  75. data/testdata/mybook/lib/ruby/review-tocparser.rb +285 -0
  76. data/testdata/mybook/lib/ruby/review-webmaker.rb +433 -0
  77. data/testdata/mybook/lib/tasks/mytasks.rake +31 -0
  78. data/testdata/mybook/lib/tasks/review.rake +142 -0
  79. data/testdata/mybook/lib/tasks/review.rake.orig +72 -0
  80. data/testdata/mybook/lib/tasks/starter.rake +326 -0
  81. data/testdata/mybook/locale.yml +6 -0
  82. data/testdata/mybook/review-ext.rb +206 -0
  83. data/testdata/mybook/sty/jumoline.sty +310 -0
  84. data/testdata/mybook/sty/mycolophon.sty +81 -0
  85. data/testdata/mybook/sty/mystyle.sty +8 -0
  86. data/testdata/mybook/sty/mytextsize.sty +61 -0
  87. data/testdata/mybook/sty/mytitlepage.sty +103 -0
  88. data/testdata/mybook/sty/reviewmacro.sty +60 -0
  89. data/testdata/mybook/sty/starter-codeblock.sty +332 -0
  90. data/testdata/mybook/sty/starter-color.sty +79 -0
  91. data/testdata/mybook/sty/starter-font.sty +112 -0
  92. data/testdata/mybook/sty/starter-heading.sty +514 -0
  93. data/testdata/mybook/sty/starter-note.sty +127 -0
  94. data/testdata/mybook/sty/starter-section.sty +262 -0
  95. data/testdata/mybook/sty/starter-toc.sty +72 -0
  96. data/testdata/mybook/sty/starter.sty +554 -0
  97. data/testdata/mybook/style.css +597 -0
  98. metadata +105 -12
  99. data/.travis.yml +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e40dda814381806e0927906afc41f12020c6208c5dae0dcddd8ac764bd641fd0
4
- data.tar.gz: 43a77d50400f9241a8a3186bd1f243a9efc3a564151d2ed14779d80a30cc052a
3
+ metadata.gz: d88019dcbdef1f19522028bd668913c7f2100d2774796ca208a7e72df829b3ef
4
+ data.tar.gz: 4b3605223424275e592269e6fbfd1124275087c322522b0d5cb309434ee202ac
5
5
  SHA512:
6
- metadata.gz: 94d70f7740602edc84f8e87fa0d9317481e61f179fa054a55267b8635f5b89f9fa2d506e6b99ed453c3babed9e1c1a20001cb6998fdb88c0eb749035520a03df
7
- data.tar.gz: 6afa54492f1a57f1b5cf5d9066e173cd7113ce5e5d7a3544656c7464cf8393b8709468ebe50e558d488b18da198c71e924384b9cbd752631f174d4f1d5c28885
6
+ metadata.gz: 519813a8c9690db53484fb206084a97c36c8bfe1c230fe09bb623c7d93ce178a81b1bb91eed87a9edfb1c753b345e0d12ca36f50bf8789ea0a6906126b62e771
7
+ data.tar.gz: '02823e04d7787079bcf94273ab43af37d903c8d8de357fde7c8394094ff88a5e2275e173284496eccf328f74da11c11b8b3d2233814529cb00b4021ff014b19d'
@@ -0,0 +1,61 @@
1
+ on:
2
+ pull_request:
3
+ push:
4
+ branches:
5
+ - master
6
+
7
+ name: Retrovert
8
+ jobs:
9
+ review:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ review-version: [ "3.2", "4.2", "5.0" ]
14
+ fail-fast: false
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.6
20
+ - run: |
21
+ rm -f Gemfile.lock
22
+ cp Gemfile Gemfile-${{ matrix.review-version }}
23
+ echo 'gem "review", "${{ matrix.review-version }}"' >> Gemfile-${{ matrix.review-version }}
24
+ cat Gemfile-${{ matrix.review-version }}
25
+ echo "BUNDLE_GEMFILE=Gemfile-${{ matrix.review-version }}" >> $GITHUB_ENV
26
+ - run: bundle install --gemfile=Gemfile-${{ matrix.review-version }}
27
+ # spec
28
+ - name: spec
29
+ run: bundle exec rake spec
30
+ # convert
31
+ - name: convert
32
+ run: bundle exec review-retrovert convert testdata/mybook/config.yml tmp -f
33
+ # build
34
+ # - name: review build
35
+ # uses: ${{ matrix.uses }}
36
+ # with:
37
+ # entrypoint: bash
38
+ # args: -c "cd tmp; rake preproc all"
39
+ # docker login
40
+ - name: Login to DockerHub
41
+ uses: docker/login-action@v1
42
+ with:
43
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
44
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
45
+ - name: build html
46
+ run: |
47
+ docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc html
48
+ - name: build pdf
49
+ run: |
50
+ docker run --rm -v "$(pwd)/tmp":/work -w /work vvakame/review:${{ matrix.review-version }} rake preproc pdf
51
+ # artifacts
52
+ - name: artifacts
53
+ uses: actions/upload-artifact@v1
54
+ with:
55
+ name: mybook
56
+ path: tmp/mybook.pdf
57
+ # - name: artifacts
58
+ # uses: actions/upload-artifact@v1
59
+ # with:
60
+ # name: mybook
61
+ # path: tmp/mybook.epub
data/.gitignore CHANGED
@@ -5,11 +5,11 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
- /tmp/
8
+ tmp/
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  .rakeTasks
13
13
  .idea
14
14
 
15
- *.gem
15
+ *.gem
@@ -0,0 +1 @@
1
+ 2.5.5
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM vvakame/review:3.2
1
+ FROM vvakame/review:5.0
2
2
 
3
3
  RUN gem install review-retrovert
4
4
 
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem 'aruba', '~> 1.0.2'
@@ -1,41 +1,106 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- review-retrovert (0.3.2)
5
- review (>= 3.2.0, < 4.0)
4
+ review-retrovert (0.9.4)
5
+ review (>= 3.0.0)
6
6
  thor
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- diff-lcs (1.3)
12
- image_size (2.0.2)
11
+ activesupport (6.1.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ aruba (1.0.4)
18
+ childprocess (>= 2.0, < 5.0)
19
+ contracts (~> 0.16.0)
20
+ cucumber (>= 2.4, < 6.0)
21
+ rspec-expectations (~> 3.4)
22
+ thor (~> 1.0)
23
+ builder (3.2.4)
24
+ childprocess (4.0.0)
25
+ concurrent-ruby (1.1.7)
26
+ contracts (0.16.0)
27
+ cucumber (5.2.0)
28
+ builder (~> 3.2, >= 3.2.4)
29
+ cucumber-core (~> 8.0, >= 8.0.1)
30
+ cucumber-create-meta (~> 2.0, >= 2.0.2)
31
+ cucumber-cucumber-expressions (~> 10.3, >= 10.3.0)
32
+ cucumber-gherkin (~> 15.0, >= 15.0.2)
33
+ cucumber-html-formatter (~> 9.0, >= 9.0.0)
34
+ cucumber-messages (~> 13.1, >= 13.1.0)
35
+ cucumber-wire (~> 4.0, >= 4.0.1)
36
+ diff-lcs (~> 1.4, >= 1.4.4)
37
+ multi_test (~> 0.1, >= 0.1.2)
38
+ sys-uname (~> 1.2, >= 1.2.1)
39
+ cucumber-core (8.0.1)
40
+ cucumber-gherkin (~> 15.0, >= 15.0.2)
41
+ cucumber-messages (~> 13.0, >= 13.0.1)
42
+ cucumber-tag-expressions (~> 2.0, >= 2.0.4)
43
+ cucumber-create-meta (2.0.4)
44
+ cucumber-messages (~> 13.1, >= 13.1.0)
45
+ sys-uname (~> 1.2, >= 1.2.1)
46
+ cucumber-cucumber-expressions (10.3.0)
47
+ cucumber-gherkin (15.0.2)
48
+ cucumber-messages (~> 13.0, >= 13.0.1)
49
+ cucumber-html-formatter (9.0.0)
50
+ cucumber-messages (~> 13.0, >= 13.0.1)
51
+ cucumber-messages (13.2.1)
52
+ protobuf-cucumber (~> 3.10, >= 3.10.8)
53
+ cucumber-tag-expressions (2.0.4)
54
+ cucumber-wire (4.0.1)
55
+ cucumber-core (~> 8.0, >= 8.0.1)
56
+ cucumber-cucumber-expressions (~> 10.3, >= 10.3.0)
57
+ cucumber-messages (~> 13.0, >= 13.0.1)
58
+ diff-lcs (1.4.4)
59
+ ffi (1.14.2)
60
+ i18n (1.8.7)
61
+ concurrent-ruby (~> 1.0)
62
+ image_size (2.1.0)
63
+ middleware (0.1.0)
64
+ minitest (5.14.3)
65
+ multi_test (0.1.2)
66
+ protobuf-cucumber (3.10.8)
67
+ activesupport (>= 3.2)
68
+ middleware
69
+ thor
70
+ thread_safe
13
71
  rake (12.3.3)
14
- review (3.2.0)
72
+ review (5.0.0)
15
73
  image_size
16
74
  rouge
17
75
  rubyzip
18
- rouge (3.20.0)
19
- rspec (3.9.0)
20
- rspec-core (~> 3.9.0)
21
- rspec-expectations (~> 3.9.0)
22
- rspec-mocks (~> 3.9.0)
23
- rspec-core (3.9.1)
24
- rspec-support (~> 3.9.1)
25
- rspec-expectations (3.9.1)
76
+ rouge (3.26.0)
77
+ rspec (3.10.0)
78
+ rspec-core (~> 3.10.0)
79
+ rspec-expectations (~> 3.10.0)
80
+ rspec-mocks (~> 3.10.0)
81
+ rspec-core (3.10.1)
82
+ rspec-support (~> 3.10.0)
83
+ rspec-expectations (3.10.1)
26
84
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.9.0)
28
- rspec-mocks (3.9.1)
85
+ rspec-support (~> 3.10.0)
86
+ rspec-mocks (3.10.1)
29
87
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.9.0)
31
- rspec-support (3.9.2)
88
+ rspec-support (~> 3.10.0)
89
+ rspec-support (3.10.1)
32
90
  rubyzip (2.3.0)
91
+ sys-uname (1.2.2)
92
+ ffi (~> 1.1)
33
93
  thor (1.0.1)
94
+ thread_safe (0.3.6)
95
+ tzinfo (2.0.4)
96
+ concurrent-ruby (~> 1.0)
97
+ zeitwerk (2.4.2)
34
98
 
35
99
  PLATFORMS
36
100
  ruby
37
101
 
38
102
  DEPENDENCIES
103
+ aruba (~> 1.0.2)
39
104
  rake (~> 12.0)
40
105
  review-retrovert!
41
106
  rspec (~> 3.0)
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  # ReVIEW::Retrovert
6
6
 
7
+ [Re:VIEW Starter](https://kauplan.org/reviewstarter/) Project convert to [Re:VIEW](https://reviewml.org/ja/) 3.X/4.X/5.X
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -20,9 +22,68 @@ Or install it yourself as:
20
22
 
21
23
  $ gem install review-retrovert
22
24
 
23
- ## Usage
25
+ ## Commands
26
+
27
+ ```sh
28
+ Commands:
29
+ review-retrovert convert {review_starter_configfile} {outdir} # convert Re:VIEW Starter project to Re:VIEW project
30
+ review-retrovert help [COMMAND] # Describe available commands or one specific command
31
+ review-retrovert version # show version
32
+ ```
33
+
34
+ ### Convert
35
+
36
+ e.g.
37
+
38
+ ```sh
39
+ review-retrovert convert /path/to/dir/review-starter/config.yml <output directory>
40
+ ```
41
+
42
+ Options
43
+
44
+ ```sh
45
+ Usage:
46
+ review-retrovert convert {review_starter_configfile} {outdir}
47
+
48
+ Options:
49
+ f, [--force] # Force output
50
+ [--strict], [--no-strict] # Only process files registered in the catalog
51
+ [--preproc], [--no-preproc] # Execute preproc after conversion
52
+ [--tabwidth=N] # Preproc tabwidth option value
53
+ # Default: 0
54
+ [--table-br-replace=TABLE-BR-REPLACE] # @<br>{} in table replace string (Default: empty)
55
+ [--table-empty-replace=TABLE-EMPTY-REPLACE] # empty cell(.) in table replace string (Default full-width space)
56
+ # Default:  
57
+
58
+ convert Re:VIEW Starter project to Re:VIEW project
59
+ ```
60
+
61
+ #### retrovert config
24
62
 
25
- TODO: Write usage instructions here
63
+ If the retrovert key is present in config.yml, the subordinate elements will take effect after convert.
64
+
65
+ If you have a setting that you want to enable only after retrovert, use inherit as shown below.
66
+
67
+ * config-retrovert.yml
68
+
69
+ ```yml
70
+ retrovert:
71
+ chapterlink: null
72
+ ```
73
+
74
+ * config-base.yml
75
+
76
+ ```yml
77
+ chapterlink: true
78
+ ```
79
+
80
+ * config.yml
81
+
82
+ ```yml
83
+ inherit: ["config-base.yml", "config-starter.yml", "config-retrovert.yml"]
84
+
85
+ #chapterlink: true
86
+ ```
26
87
 
27
88
  ## Development
28
89
 
@@ -34,10 +95,9 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
34
95
 
35
96
  Bug reports and pull requests are welcome on GitHub at https://github.com/srz-zumix/review-retrovert.
36
97
 
37
-
38
98
  ## Develop
39
99
 
40
- docker run -it --rm -v $(pwd)/../:/github vvakame/review:3.2 bash
100
+ docker run -it --rm -v $(pwd)/:/work -w /work vvakame/review:5.0 bash
41
101
 
42
102
  ## License
43
103
 
@@ -7,6 +7,10 @@ module ReVIEW
7
7
  desc "convert {review_starter_configfile} {outdir}", "convert Re:VIEW Starter project to Re:VIEW project"
8
8
  method_option "force", aliases: "f", desc: 'Force output', type: :boolean
9
9
  method_option "strict", desc: 'Only process files registered in the catalog', type: :boolean
10
+ method_option "preproc", desc: 'Execute preproc after conversion', type: :boolean
11
+ method_option "tabwidth", desc: 'Preproc tabwidth option value', type: :numeric, default: 0
12
+ method_option "table-br-replace", desc: '@<br>{} in table replace string (Default: empty)', type: :string, default: ''
13
+ method_option "table-empty-replace", desc: 'empty cell(.) in table replace string (Default full-width space)', type: :string, default: ' '
10
14
  def convert(review_starter_configfile, outdir)
11
15
  Converter.execute(review_starter_configfile, outdir, options)
12
16
  end
@@ -13,6 +13,8 @@ module ReVIEW
13
13
  @outimagedir = nil
14
14
  @logger = ReVIEW.logger
15
15
  @configs = YamlConfig.new
16
+ @embeded_contents = []
17
+ @catalog_contents = []
16
18
  end
17
19
 
18
20
  def error(msg)
@@ -67,10 +69,45 @@ module ReVIEW
67
69
  @configs.rewrite_yml('contentdir', '.')
68
70
  @configs.rewrite_yml('hook_beforetexcompile', 'null')
69
71
  @configs.rewrite_yml('texstyle', '["reviewmacro"]')
72
+ # @configs.rewrite_yml('chapterlink', 'null')
73
+ pagesize = @config['starter']['pagesize'].downcase
74
+ @configs.rewrite_yml_array('texdocumentclass', "[\"review-jsbook\", \"media=print,paper=#{pagesize}\"]")
75
+ @config['retrovert'].each{ |k,v|
76
+ unless v..is_a?(Hash)
77
+ @configs.commentout_root_yml(k)
78
+ end
79
+ }
80
+ end
81
+
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
88
+ end
89
+
90
+ def replace_compatible_block_command_to_outside(content, command, new_command, option_count, add_options="", new_body="")
91
+ body = new_body
92
+ body += '\n' unless body.empty?
93
+ content.gsub!(/^\/\/#{command}(?<option>(\[[^\r\n]*?\]){0,#{option_count}})(\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>#{add_options}{\n#{new_body}//}\\k<inner>")
70
94
  end
71
95
 
72
- def replace_inline_command(content, command, sub)
96
+ def replace_block_command_outline(content, command, new_command, use_option)
97
+ if use_option
98
+ content.gsub!(/^\/\/#{command}(?<option>\[[^\r\n]*\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}\\k<option>{\\k<inner>//}")
99
+ else
100
+ content.gsub!(/^\/\/#{command}(?<option>\[[^\r\n]*?\])*{(?<inner>.*?)\/\/}/m, "//#{new_command}{\\k<inner>//}")
101
+ end
102
+ end
73
103
 
104
+ def delete_block_command_outer(content, command)
105
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\])*{(?<inner>.*?)\/\/}\R/m, '\k<inner>')
106
+ end
107
+
108
+ def delete_block_command(content, command)
109
+ content.gsub!(/^\/\/#{command}(\[[^\r\n]*?\])*{.*?\/\/}\R/m, '')
110
+ content.gsub!(/^\/\/#{command}(\[.*?\])*\s*\R/, '')
74
111
  end
75
112
 
76
113
  def delete_inline_command(content, command)
@@ -78,6 +115,185 @@ module ReVIEW
78
115
  content.gsub!(/@<#{command}>(?:(\$)|(?:({)|(\|)))((?:.*@<\w*>[\|${].*?[\|$}].*?|.*?)*)(?(1)(\$)|(?(2)(})|(\|)))/){"#{$4}"}
79
116
  end
80
117
 
118
+ def replace_inline_command(content, command, new_command)
119
+ content.gsub!(/@<#{command}>/, "@<#{new_command}>")
120
+ end
121
+
122
+ def replace_block_command_nested_boxed_article_i(content, box, depth)
123
+ found = false
124
+ content.dup.scan(/(^\/\/#{box})(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)).*?[\r\n]+)/m) { |m|
125
+ matched = m[0..-1].join
126
+ inner = m[5]
127
+ # info depth
128
+ im = inner.match(/^\/\/(\w+)((\[.*?\])*)([$|{])/)
129
+ 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 = ""
135
+
136
+ # is_commentout = false
137
+ 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}\\]"
144
+ end
145
+ end
146
+ end
147
+ cmd_begin = m[0..4].join
148
+ cmd_end = m[6..-1].join
149
+ # check other fence inner block (block command has fence??)
150
+ if inner_open == m[2..4].join
151
+ # if same fence then cmd_end == inner_end
152
+ if is_commentout
153
+ inner.gsub!(/(^\/\/(\w+(\[.*?\]|))*#{inner_open})/, '#@#\1')
154
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#@##{cmd_end}")
155
+ else
156
+ imb = inner.match(/(\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/#{inner_cmd}#{first_opt}(\[.*?\])*#{inner_open}.*)\R/m)
157
+ to_out_block = imb[1]
158
+ inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
159
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
160
+ end
161
+ else
162
+ close = inner_open == '{' ? '}' : inner_open
163
+ 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}")
166
+ else
167
+ imb = inner.match(/\R((^\/\/\w+(\[.*?\])*)\s*)*^\/\/(#{inner_cmd})#{first_opt}(\[[^\r\n]*?\])*(?:(\$)|(?:({)|(\|)))(.*?)(^\/\/)(?(3)(\$)|(?(4)(})|(\|)))/m)
168
+ to_out_block = imb[0]
169
+ inner.gsub!(/#{Regexp.escape(to_out_block)}/m, '')
170
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{cmd_begin}#{inner}#{cmd_end}#{to_out_block}")
171
+ end
172
+ end
173
+ found = true
174
+ end
175
+ }
176
+ if found
177
+ replace_block_command_nested_boxed_article_i(content, box, depth+1)
178
+ end
179
+ end
180
+
181
+ def replace_block_command_nested_boxed_article(content, box)
182
+ replace_block_command_nested_boxed_article_i(content, box, 0)
183
+ end
184
+
185
+ def replace_block_command_nested_boxed_articles(content)
186
+ unless Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('5.0.0')
187
+ replace_block_command_nested_boxed_article(content, 'note')
188
+ replace_block_command_nested_boxed_article(content, 'memo')
189
+ replace_block_command_nested_boxed_article(content, 'tip')
190
+ replace_block_command_nested_boxed_article(content, 'info')
191
+ replace_block_command_nested_boxed_article(content, 'warning')
192
+ replace_block_command_nested_boxed_article(content, 'important')
193
+ replace_block_command_nested_boxed_article(content, 'caution')
194
+ replace_block_command_nested_boxed_article(content, 'notice')
195
+ end
196
+ end
197
+
198
+ def replace_block_commentout(content)
199
+ d = content.dup
200
+ d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
201
+ matched = m[0..-1].join
202
+ inner = m[2]
203
+ inner.gsub!(/(^.)/, '#@#\1')
204
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
205
+ }
206
+ end
207
+
208
+ def replace_block_commentout_without_sampleout(content)
209
+ d = content.dup
210
+ d.gsub!(/(^\/\/sampleoutputbegin\[)(.*?)(\])(.*?)(^\/\/sampleoutputend)/m, '')
211
+ d.scan(/(^#@)(\++)(.*?)(^#@)(-+)/m) { |m|
212
+ matched = m[0..-1].join
213
+ inner = m[2]
214
+ inner.gsub!(/(^.)/, '#@#\1')
215
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#@##{m[1]}#{inner}#@##{m[4]}")
216
+ }
217
+ end
218
+
219
+ def replace_sampleoutput(content)
220
+ # replace_block_commentout_without_sampleout(content)
221
+ content.dup.scan(/(^\/\/sampleoutputbegin\[)(.*?)(\].*?\R)(.*?)(^\/\/sampleoutputend)/m) { |m|
222
+ matched = m[0..-1].join
223
+ sampleoutputbegin = m[0..2].join
224
+ sampleoutputend = m[4]
225
+ option = m[1]
226
+ inner = m[3]
227
+ # inner.gsub!(/^\/\//, '//@<nop>{}')
228
+ content.gsub!(/#{Regexp.escape(matched)}/m, "#{option}\n#@##{sampleoutputbegin}#{inner}#@##{sampleoutputend}")
229
+ }
230
+ end
231
+
232
+ def replace_auto_ids(content, command, require_option_count)
233
+ index = -1
234
+ content.gsub!(/^\/\/#{command}\[(|\?)\]/) { |s| index += 1; "//#{command}[starter_auto_id_#{command}_#{index}]" }
235
+ if require_option_count > 0
236
+ while !content.gsub!(/(^\/\/#{command}(\[[^\[\]]*?\]){0,#{require_option_count-1}})($|{)/, '\1[]\3').nil?
237
+ end
238
+ end
239
+ end
240
+
241
+ def fix_deprecated_list(content)
242
+ if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
243
+ content.gsub!(/^: (.*)/, ' : \1')
244
+ end
245
+ end
246
+
247
+ def remove_starter_refid(content)
248
+ # note - noteref
249
+ content.dup.scan(/(@<noteref>)(?:(\$)|(?:({)|(\|)))(.*?)(?(2)(\$)|(?(3)(})|(\|)))/) { |m|
250
+ matched = m[0..-1].join
251
+ ref = m[4]
252
+ n = content.match(/^\/\/note\[#{ref}\](\[.*?\])/)
253
+ unless n.nil?
254
+ content.gsub!(/#{Regexp.escape(matched)}/, n[1])
255
+ content.gsub!(/^\/\/note\[#{ref}\](\[.*?\])/, '//note\1')
256
+ else
257
+ # content.gsub!(/#{Regexp.escape(matched)}/, "noteref<#{ref}>")
258
+ end
259
+ }
260
+ end
261
+
262
+ def remove_starter_options(content)
263
+ # image border
264
+ content.gsub!(/(^\/\/image\[.*?\]\[.*?\]\[.*?)((,|)border=[^,\]]*)(.*?\])/, '\1\4')
265
+ # 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
283
+ end
284
+ 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
290
+ end
291
+ }
292
+ if found
293
+ expand_nested_inline_command(content)
294
+ end
295
+ end
296
+
81
297
  def copy_embedded_contents(outdir, content)
82
298
  content.scan(/\#@mapfile\((.*?)\)/).each do |filepath|
83
299
  srcpath = File.join(@basedir, filepath)
@@ -85,21 +301,125 @@ module ReVIEW
85
301
  outpath = File.join(File.absolute_path(outdir), filepath)
86
302
  FileUtils.mkdir_p(File.dirname(outpath))
87
303
  FileUtils.cp(srcpath, outpath)
304
+ @embeded_contents.push(filepath[0])
88
305
  update_content(outpath, outpath)
89
306
  end
90
307
  end
91
308
  end
92
309
 
310
+ def add_linkurl_footnote(content)
311
+ urls = {}
312
+ content.dup.scan(/(^.*)(@<href>{)(.*?)(,)(.*?)(})(.*)$/) { |m|
313
+ unless m[0].match(/^#@#/)
314
+ matched = m.join
315
+ prev = m[0]
316
+ url = m[2]
317
+ text = m[4]
318
+ post = m[6]
319
+ id = "link_auto_footnote#{urls.length}"
320
+ urls[id] = url
321
+ content.sub!(/#{Regexp.escape(matched)}$/, "#{prev}@<href>{#{url},#{text}} @<fn>{#{id}} #{post}")
322
+ end
323
+ }
324
+
325
+ urls.each { |k,v|
326
+ content.sub!(/(@<href>{#{v},.*?} @<fn>{#{k}}.*?\R\R)/m, "\\1//footnote[#{k}][#{v}]\n")
327
+ }
328
+
329
+ urls.each { |k,v|
330
+ unless content.match(/\/\/footnote\[#{k}\]\[#{v}\]/)
331
+ content << "//footnote[#{k}][#{v}]\n"
332
+ end
333
+ }
334
+ end
335
+
93
336
  def update_content(outdir, contentfile)
94
337
  info contentfile
95
338
  content = File.read(contentfile)
96
- content.gsub!(/(\/\/sideimage\[.*?\]\[.*?\])\[.*?\]/, '\1')
97
- content.gsub!(/\/\/sideimage/, '//image')
339
+ content.gsub!(/@<href>{(.*?)#.*?,(.*?)}/, '@<href>{\1,\2}')
98
340
  content.gsub!(/@<href>{(.*?)#.*?}/, '@<href>{\1}')
99
- while !content.gsub!(/(\/\/table.*)@<br>(.*?\/\/})/m, '\1\2').nil? do
341
+ linkurl_footnote = @config['starter']['linkurl_footnote']
342
+ # table 内の @ コマンドは不安定らしい
343
+ while !content.gsub!(/(\/\/table.*)@<br>{}(.*?\/\/})/m, "\\1#{@table_br_replace}\\2").nil? do
100
344
  end
101
- delete_inline_command(content , 'xsmall')
102
- delete_inline_command(content , 'weak')
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)
351
+ replace_compatible_block_command_to_outside(content, 'sideimage', 'image', 1, '[]')
352
+ replace_block_command_outline(content, 'abstract', 'lead', true)
353
+ delete_block_command(content, 'needvspace')
354
+ delete_block_command(content, 'clearpage')
355
+ delete_block_command(content, 'flushright')
356
+ delete_block_command(content, 'centering')
357
+ delete_block_command(content, 'noindent')
358
+ delete_block_command(content, 'paragraphend')
359
+
360
+ replace_inline_command(content, 'secref', 'hd')
361
+ replace_inline_command(content, 'file', 'kw')
362
+ replace_inline_command(content, 'hlink', 'href')
363
+ replace_inline_command(content, 'B', 'strong')
364
+ delete_inline_command(content, 'userinput')
365
+ delete_inline_command(content, 'weak')
366
+ delete_inline_command(content, 'cursor')
367
+ # font size
368
+ delete_inline_command(content, 'small')
369
+ delete_inline_command(content, 'xsmall')
370
+ delete_inline_command(content, 'xxsmall')
371
+ delete_inline_command(content, 'large')
372
+ delete_inline_command(content, 'xlarge')
373
+ delete_inline_command(content, 'xxlarge')
374
+
375
+ # fixed lack of options
376
+ content.gsub!(/^\/\/list{/, '//list[][]{')
377
+
378
+ if Gem::Version.new(ReVIEW::VERSION) >= Gem::Version.new('4.0.0')
379
+ # empty caption is not allow
380
+ content.gsub!(/^\/\/image\[(.*)\]\[\]{/, '//image[\1][ ]{')
381
+ end
382
+
383
+ # special command
384
+ replace_sampleoutput(content)
385
+
386
+ if linkurl_footnote
387
+ add_linkurl_footnote(content)
388
+ end
389
+
390
+ # # br to blankline
391
+ # content.gsub!(/(.*)@<br>{}(.*)/, '\1\n//blankline\n\2')
392
+
393
+ # nested command
394
+ replace_block_command_nested_boxed_articles(content)
395
+
396
+ # empty ids
397
+ replace_auto_ids(content, 'list', 2)
398
+ replace_auto_ids(content, 'listnum', 2)
399
+
400
+ # remove starter extension
401
+ remove_starter_refid(content)
402
+ remove_starter_options(content)
403
+
404
+ # replace block comment
405
+ replace_block_commentout(content)
406
+
407
+ # special charactor
408
+ content.gsub!('@<LaTeX>{}', 'LaTeX')
409
+ content.gsub!('@<TeX>{}', 'TeX')
410
+ content.gsub!('@<hearts>{}', '!HEART!')
411
+
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)
419
+
420
+ # fix deprecated
421
+ fix_deprecated_list(content)
422
+
103
423
  File.write(contentfile, content)
104
424
  copy_embedded_contents(outdir, content)
105
425
  end
@@ -108,8 +428,13 @@ module ReVIEW
108
428
  files = contentfiles.is_a?(String) ? contentfiles.split(/\R/) : contentfiles
109
429
  files.each do |content|
110
430
  contentpath = File.join(contentdir, content)
431
+ srccontentpath = File.join(@srccontentsdir, content)
432
+ if @embeded_contents.include?(srccontentpath)
433
+ info "skip copy maped file #{contentpath}"
434
+ next
435
+ end
111
436
  unless File.exist?(contentpath)
112
- srcpath = File.join(File.join(@basedir, @srccontentsdir), content)
437
+ srcpath = File.join(@basedir, srccontentpath)
113
438
  # info srcpath
114
439
  if File.exist?(srcpath)
115
440
  FileUtils.cp(srcpath, contentdir)
@@ -123,18 +448,50 @@ module ReVIEW
123
448
  yamlfile = @config['catalogfile']
124
449
  abspath = File.absolute_path(outdir)
125
450
  contentdir = abspath
126
- info 'replace //sideimage to //image'
451
+ info 'replace starter block command'
127
452
  info 'replace starter inline command'
453
+ catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
454
+ update_content_files(outdir, contentdir, @catalog_contents)
455
+ unless options['strict']
456
+ all_contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
457
+ contentsfiles = all_contentsfiles.select{ |path| ! @catalog_contents.include?(path.to_s) }
458
+ update_content_files(outdir, contentdir, contentsfiles)
459
+ end
460
+ end
461
+
462
+ def preproc_content_files(outdir, pp, contentdir, contentfiles)
463
+ files = contentfiles.is_a?(String) ? contentfiles.split(/\R/) : contentfiles
464
+ files.each do |content|
465
+ contentpath = File.join(contentdir, content)
466
+ if File.exist?(contentpath)
467
+ info "preproc #{contentpath}"
468
+ buf = StringIO.new
469
+ pwd = Dir.pwd
470
+ Dir.chdir(outdir)
471
+ File.open(contentpath) { |f| pp.process(f, buf) }
472
+ Dir.chdir(pwd)
473
+ content = buf.string
474
+ content.gsub!(/^#[@]map.*$/, '')
475
+ content.gsub!(/^#[@]end$/, '')
476
+ File.write(contentpath, content)
477
+ end
478
+ end
479
+ end
480
+
481
+ def preproc_contents(outdir, options)
482
+ yamlfile = @config['catalogfile']
483
+ abspath = File.absolute_path(outdir)
484
+ contentdir = abspath
485
+ param = {}
486
+ param['tabwidth'] = options['tabwidth'].to_i
487
+ pp = ReVIEW::Preprocessor.new(ReVIEW::Repository.new(param), param)
488
+
128
489
  if options['strict']
129
490
  catalog = ReVIEW::Catalog.new(File.open(File.join(abspath, yamlfile)))
130
- update_content_files(outdir, contentdir, catalog.predef())
131
- update_content_files(outdir, contentdir, catalog.chaps())
132
- update_content_files(outdir, contentdir, catalog.appendix())
133
- update_content_files(outdir, contentdir, catalog.postdef())
491
+ preproc_content_files(outdir, pp, contentdir, @catalog_contents)
134
492
  else
135
- # copy_contents(outdir)
136
493
  contentsfiles = Pathname.glob(File.join(File.join(@basedir, @srccontentsdir), '*.re')).map(&:basename)
137
- update_content_files(outdir, contentdir, contentsfiles)
494
+ preproc_content_files(outdir, pp, contentdir, contentsfiles)
138
495
  end
139
496
  end
140
497
 
@@ -145,11 +502,22 @@ module ReVIEW
145
502
  FileUtils.rm(Dir.glob(File.join(outdir, '*.re')))
146
503
  end
147
504
 
505
+ def add_catalog_contents(contentfiles)
506
+ files = contentfiles.is_a?(String) ? contentfiles.split(/\R/) : contentfiles
507
+ @catalog_contents.concat(files)
508
+ end
509
+
148
510
  def load_config(yamlfile)
149
511
  @configs.open(yamlfile)
150
512
  @config = @configs.config
151
513
  @basedir = @configs.basedir
152
514
  @srccontentsdir = @config['contentdir']
515
+
516
+ catalog = ReVIEW::Catalog.new(File.open(@configs.catalogfile()))
517
+ add_catalog_contents(catalog.predef())
518
+ add_catalog_contents(catalog.chaps())
519
+ add_catalog_contents(catalog.appendix())
520
+ add_catalog_contents(catalog.postdef())
153
521
  end
154
522
 
155
523
  def create_initial_project(outdir, options)
@@ -159,6 +527,8 @@ module ReVIEW
159
527
  end
160
528
 
161
529
  def execute(yamlfile, outdir, options)
530
+ @table_br_replace = options['table-br-replace']
531
+ @table_empty_replace = options['table-empty-replace']
162
532
  load_config(yamlfile)
163
533
  create_initial_project(outdir, options)
164
534
 
@@ -173,8 +543,16 @@ module ReVIEW
173
543
  updater = ReVIEW::Update.new
174
544
  updater.force = true
175
545
  # updater.backup = false
176
- updater.execute()
546
+ begin
547
+ updater.execute()
548
+ rescue
549
+ end
177
550
  Dir.chdir(pwd)
551
+
552
+ if options['preproc']
553
+ info 'preproc'
554
+ preproc_contents(outdir, options)
555
+ end
178
556
  end
179
557
 
180
558
  def self.execute(yamlfile, outdir, options)