source2md 0.0.10 → 0.0.12

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -22
  3. data/Rakefile +1 -1
  4. data/doc/0100_top.rb +5 -5
  5. data/doc/0110_code_small.rb +11 -1
  6. data/doc/0120_code_long.rb +9 -1
  7. data/doc/0130_hidden.rb +3 -1
  8. data/doc/0140_code_include.rb +9 -1
  9. data/doc/0150_raw_include.rb +2 -1
  10. data/doc/0160_title.rb +1 -1
  11. data/doc/{0180_table.rb → 0170_table.rb} +1 -1
  12. data/doc/{0190_method.rb → 0180_method.rb} +3 -3
  13. data/doc/{0200_alert.rb → 0190_alert.rb} +8 -1
  14. data/doc/{0210_text.rb → 0200_text.rb} +3 -1
  15. data/doc/{0220_text_oneline.rb → 0210_text_oneline.rb} +2 -1
  16. data/doc/{0230_text_squish.rb → 0220_text_squish.rb} +2 -1
  17. data/doc/{0240_text_hankaku_kana.rb → 0230_text_hankaku_kana.rb} +2 -1
  18. data/doc/{0250_parse_include.rb → 0240_parse_include.rb} +2 -1
  19. data/doc/setup.rb +3 -0
  20. data/examples/output.md +26 -7
  21. data/lib/source2md/cli.rb +12 -0
  22. data/lib/source2md/code_block.rb +6 -6
  23. data/lib/source2md/element.rb +7 -4
  24. data/lib/source2md/formatter/type_method.rb +1 -1
  25. data/lib/source2md/formatter/type_source_block.rb +3 -3
  26. data/lib/source2md/formatter/type_table.rb +2 -2
  27. data/lib/source2md/formatter/type_text.rb +1 -1
  28. data/lib/source2md/generator.rb +20 -8
  29. data/lib/source2md/re.rb +3 -0
  30. data/lib/source2md/regexp_builder.rb +33 -0
  31. data/lib/source2md/scanner.rb +20 -15
  32. data/lib/source2md/text_helper.rb +2 -2
  33. data/lib/source2md/version.rb +1 -1
  34. data/lib/source2md.rb +1 -0
  35. data/spec/generator_spec.rb +51 -0
  36. data/spec/scanner_spec.rb +0 -16
  37. data/spec/spec_helper.rb +8 -0
  38. metadata +15 -13
  39. data/doc/0170_md_like_title.rb +0 -24
  40. data/output.md +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ac00b7cc8674c792566d8d08c5d2f1b8f5cf755ceca1479b2ac8248ad6dac3e
4
- data.tar.gz: e7c61a968ca24419cc5a62c86437388f77cd865895ac038a5565b1a4ab4c180d
3
+ metadata.gz: 562135200c7492a703d690fe621a77ef6341567ef499a0a868033db4c93f0d72
4
+ data.tar.gz: 9bb67852ae6ae568edded0478116ea78e9e24ce58d58ce16df0c6b692f515f59
5
5
  SHA512:
6
- metadata.gz: 25222fde61442a0fceba5daa0e0ff09e7343c0fcacf7123670d85ee66f3a4df50533ec40b211b851eea0870bf64f781b9dd283dc26650a1d7a004d27a95dd513
7
- data.tar.gz: c89ccfdb613ee1a8fa95eef6a1524be3fe7534a2e5c2fd18fceba4895f87711febc078292f4b974c1ae7a525d75af8e2e528c10b59a55678c7f2730814776077
6
+ metadata.gz: 619ff51efb9c41fe3cbeea92774fc3e853e5c915fde446f9118f1af9c5dc6262ea510430c7e48bf338f822d3f6f58d9f2d69e095c04c035d02d63c84c6f82a1b
7
+ data.tar.gz: cf9e28c97304ba30b623a5d7f66a4c79ba47231f5ce8d3ac1c8452e5beeaba9c1f77f379be37412bc94eddceafd53261f5cf6e99020d4d7a4a230a80daf45cf1
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  # Source2MD: Markdown generator from source code #
2
4
 
3
5
  ## Logic ##
@@ -75,6 +77,14 @@ puts Source2MD::Section.new(<<~EOS).to_md
75
77
  EOS
76
78
  ```
77
79
 
80
+ ```ruby
81
+ puts Source2MD::Section.new(<<~EOS).to_md
82
+ #+BEGIN_SRC hidden!
83
+ p "This paragraph is not displayed"
84
+ #+END_SRC
85
+ EOS
86
+ ```
87
+
78
88
  ### Code include ###
79
89
 
80
90
  Insert inside the code block.
@@ -135,28 +145,6 @@ EOS
135
145
  ### Title Level 3 ###
136
146
  ```
137
147
 
138
- ### Markdown style title ###
139
-
140
- The condition is that there are the same number of sharps on the back.
141
-
142
- ```ruby
143
- puts Source2MD::Section.new(<<~EOS).to_md
144
- # Title Level 1 #
145
-
146
- ## Title Level 2 ##
147
-
148
- ### Title Level 3 ###
149
- EOS
150
- ```
151
-
152
- ```
153
- # Title Level 1 #
154
-
155
- ## Title Level 2 ##
156
-
157
- ### Title Level 3 ###
158
- ```
159
-
160
148
  ### Org-mode table style ###
161
149
 
162
150
  ```ruby
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ namespace :doc do
11
11
  task "generate" do
12
12
  Rake::Task["doc:renum"].execute
13
13
  system "sh", "-vec", <<~EOT, exception: true
14
- .bin/source2md generate --no-debug --no-xmp-out-exclude -o README.md doc/0*
14
+ .bin/source2md generate --no-debug --xmp-out-exclude --prefix_re '^' -o README.md doc/0*
15
15
  EOT
16
16
  end
17
17
 
data/doc/0100_top.rb CHANGED
@@ -1,24 +1,24 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- # Source2MD: Markdown generator from source code #
4
+ #+title1: Source2MD: Markdown generator from source code
5
5
 
6
- ## Logic ##
6
+ #+title2: Logic
7
7
 
8
8
  # 1. Divide the source code into paragraphs using blank lines as separations.
9
9
  # 1. Remove comments from the comment blocks.
10
10
  # 1. Include the code within the code block.
11
11
 
12
- ## Install ##
12
+ #+title2: Install
13
13
 
14
14
  # ```
15
15
  # $ gem i source2md
16
16
  # ```
17
17
 
18
- ## CLI ##
18
+ #+title2: CLI
19
19
 
20
20
  # ```
21
21
  # $ source2md generate -o README.md README.rb
22
22
  # ```
23
23
 
24
- ## Rules ##
24
+ #+title2: Rules
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Code snippet ###
4
+ #+title3: Code snippet
5
5
 
6
6
  # Separated by blank lines.
7
7
 
@@ -24,3 +24,13 @@ EOS
24
24
  # > ```ruby
25
25
  # > hello.call
26
26
  # > ```
27
+ # >> ```ruby
28
+ # >> hello = -> {
29
+ # >> "Hello, world!"
30
+ # >> }
31
+ # >> ```
32
+ # >>
33
+ # >>
34
+ # >> ```ruby
35
+ # >> hello.call
36
+ # >> ```
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Source block with many lines ###
4
+ #+title3: Source block with many lines
5
5
 
6
6
  #+BEGIN_SRC
7
7
  puts Source2MD::Section.new(<<~EOS).to_md
@@ -22,3 +22,11 @@ EOS
22
22
  # >
23
23
  # > hello.call
24
24
  # > ```
25
+ # >> ["/Users/ikeda/src/zenn/source2md/lib/source2md/scanner.rb:14", :to_a, /(?m-ix:(?-mix:(?-mix:^)(?:(?-mix:#|\/\/)))\+BEGIN_SRC.*?(?-mix:(?-mix:^)(?:(?-mix:#|\/\/)))\+END_SRC)|(?m-ix:.*?\R{2,})/]
26
+ # >> ```ruby
27
+ # >> hello = -> {
28
+ # >> "Hello, world!"
29
+ # >> }
30
+ # >>
31
+ # >> hello.call
32
+ # >> ```
data/doc/0130_hidden.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Hide paragraph ###
4
+ #+title3: Hide paragraph
5
5
 
6
6
  #+BEGIN_SRC
7
7
  puts Source2MD::Section.new(<<~EOS).to_md
@@ -17,3 +17,5 @@ puts Source2MD::Section.new(<<~EOS).to_md
17
17
  #+END_SRC
18
18
  EOS
19
19
  #+END_SRC
20
+ # >>
21
+ # >>
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Code include ###
4
+ #+title3: Code include
5
5
 
6
6
  # Insert inside the code block.
7
7
 
@@ -24,3 +24,11 @@ EOS
24
24
  # > <p>Hello</p>
25
25
  # > ```
26
26
  # > ````
27
+ # >> ```html:hello.html
28
+ # >> <p>Hello</p>
29
+ # >> ```
30
+ # >>
31
+ # >>
32
+ # >> ```xml:OUTPUT
33
+ # >> <p>Hello</p>
34
+ # >> ```
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Raw include ###
4
+ #+title3: Raw include
5
5
 
6
6
  #+BEGIN_SRC
7
7
  File.write("/tmp/hello.html", "<p>Hello</p>")
@@ -14,3 +14,4 @@ EOS
14
14
  # > ```
15
15
  # > <p>Hello</p>
16
16
  # > ```
17
+ # >> <p>Hello</p>
data/doc/0160_title.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Title ###
4
+ #+title3: Title
5
5
 
6
6
  # No number limit.
7
7
 
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Org-mode table style ###
4
+ #+title3: Org-mode table style
5
5
 
6
6
  #+BEGIN_SRC
7
7
  puts Source2MD::Section.new(<<~EOS).to_md
@@ -1,19 +1,19 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Explain method simply ###
4
+ #+title3: Explain method simply
5
5
 
6
6
  #+BEGIN_SRC
7
7
  puts Source2MD::Section.new(<<~EOS).to_md
8
8
  #+name: String#size
9
9
  #+desc: Return the number of characters
10
10
  #+comment: Comments about size
11
- "abc".size # => 3
11
+ "abc".size # => 3
12
12
 
13
13
  #+name: String#reverse
14
14
  #+desc: reverse the sequence of characters
15
15
  #+comment: Comments about reverse
16
- "abc".reverse # => "cba"
16
+ "abc".reverse # => "cba"
17
17
  EOS
18
18
  #+END_SRC
19
19
 
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Warning and Alert message ###
4
+ #+title3: Warning and Alert message
5
5
 
6
6
  # Exclusive to Zenn
7
7
 
@@ -24,3 +24,10 @@ EOS
24
24
  # > this is alert message
25
25
  # > :::
26
26
  # > ```
27
+ # >> :::message
28
+ # >> this is warning message
29
+ # >> :::
30
+ # >>
31
+ # >> :::message alert
32
+ # >> this is alert message
33
+ # >> :::
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Raw Text ###
4
+ #+title3: Raw Text
5
5
 
6
6
  # If no rule applies and the text begins with `#`, remove the `#`.
7
7
 
@@ -16,3 +16,5 @@ EOS
16
16
  # > Lorem ipsum dolor sit amet, consectetur adipisicing elit,
17
17
  # > sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
18
18
  # > ```
19
+ # >> Lorem ipsum dolor sit amet, consectetur adipisicing elit,
20
+ # >> sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Oneline Text ###
4
+ #+title3: Oneline Text
5
5
 
6
6
  # Using this option allows you to split a line regardless of the markdown library.
7
7
 
@@ -16,3 +16,4 @@ EOS
16
16
  # > ```
17
17
  # > Lorem ipsum dolor sit amet, consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
18
18
  # > ```
19
+ # >> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Squish Text ###
4
+ #+title3: Squish Text
5
5
 
6
6
  # Single spaces for line breaks and consecutive spaces.
7
7
 
@@ -16,3 +16,4 @@ EOS
16
16
  # > ```
17
17
  # > Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
18
18
  # > ```
19
+ # >> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Hankaku Kana ###
4
+ #+title3: Hankaku Kana
5
5
 
6
6
  # JISX0208 Katakana to JISX0201 Katakana.
7
7
 
@@ -13,3 +13,4 @@ EOS
13
13
  #+END_SRC
14
14
 
15
15
  # > アア
16
+ # >> アア
@@ -1,7 +1,7 @@
1
1
  #+hidden: true
2
2
  require "./setup"
3
3
 
4
- ### Parse include ###
4
+ #+title3: Parse include
5
5
 
6
6
  # Paste the results of processing other files with the same rules.
7
7
 
@@ -16,3 +16,4 @@ EOS
16
16
  #+END_SRC
17
17
 
18
18
  # > foo
19
+ # >> foo
data/doc/setup.rb CHANGED
@@ -2,3 +2,6 @@ $LOAD_PATH.unshift("#{__dir__}/../lib")
2
2
  require "source2md"
3
3
  Source2MD.logger.level = :debug if false
4
4
 
5
+ # Source2MD::RE.update do |e|
6
+ # e.prefix_re = %r{^}
7
+ # end
data/examples/output.md CHANGED
@@ -1,11 +1,30 @@
1
+ ## (title) ##
2
+
3
+ ### (name1) ###
4
+
5
+ (desc1)
6
+
7
+ ```ruby
8
+ "foo1".size # => 4
9
+ ```
10
+
11
+ (comment1)
12
+
13
+ ### (name2) ###
14
+
15
+ (desc2)
16
+
1
17
  ```ruby
2
- # ```yaml:config.yml
3
- # frequencies: frequencies1.rb
4
- # ```
18
+ "foo2".size # => 4
5
19
  ```
6
20
 
7
- ```ruby:frequencies1.rb
8
- def frequencies(words)
9
- words.tally.sort_by { -_2 }.take(25)
10
- end
21
+ (comment2)
22
+
23
+ | x | x | x |
24
+ |---|---|---|
25
+ | x | x | x |
26
+ | x | x | x |
27
+
28
+ ```ruby
29
+ 1 + 2 # => 3
11
30
  ```
data/lib/source2md/cli.rb CHANGED
@@ -4,6 +4,8 @@ module Source2MD
4
4
  class_option :xmp_out_exclude, type: :boolean, aliases: "-x", default: false
5
5
  class_option :readonly, type: :boolean, aliases: "-r", default: true
6
6
  class_option :default_lang, type: :string, aliases: "-l", default: "ruby"
7
+ class_option :prefix_re, type: :string
8
+ class_option :comment_re, type: :string
7
9
 
8
10
  def initialize(...)
9
11
  super
@@ -16,6 +18,15 @@ module Source2MD
16
18
  Source2MD.xmp_out_exclude = options[:xmp_out_exclude]
17
19
  Source2MD.readonly = options[:readonly]
18
20
  Source2MD.default_lang = options[:default_lang]
21
+
22
+ Source2MD::RE.update do |e|
23
+ if v = options[:prefix_re]
24
+ e.prefix_re = v
25
+ end
26
+ if v = options[:comment_re]
27
+ e.comment_re = v
28
+ end
29
+ end
19
30
  end
20
31
 
21
32
  # default_command :generate
@@ -23,6 +34,7 @@ module Source2MD
23
34
  map "g" => :generate
24
35
  desc "generate [files]", "Markdown generation"
25
36
  option :output_file, type: :string, aliases: "-o", default: nil
37
+ option :glob, type: :string, aliases: "-g"
26
38
  def generate(*files)
27
39
  Generator.new(options.to_options.merge(files: files)).call
28
40
  end
@@ -1,7 +1,7 @@
1
1
  module Source2MD
2
2
  class CodeBlock
3
3
  PADDING_KEEP = 2
4
- MARK = %r{(?:#|//) =>}
4
+ ARROW_MARK = %r{(?:#{RE.comment_re}) =>}
5
5
 
6
6
  def initialize(text, options = {})
7
7
  @text = text
@@ -45,15 +45,15 @@ module Source2MD
45
45
  # if @options[:single_sharp_replace_to_blank_line]
46
46
  # line = single_sharp_replace_to_blank_line(line)
47
47
  # end
48
- comment_mark_justfiy(line)
48
+ comment_re_justfiy(line)
49
49
  end
50
50
 
51
51
  # def single_sharp_replace_to_blank_line(line)
52
52
  # line.gsub(/\A#\z/, "")
53
53
  # end
54
54
 
55
- def comment_mark_justfiy(line)
56
- line.gsub(/(.*?)\s*(#{MARK})(.*)/) {
55
+ def comment_re_justfiy(line)
56
+ line.gsub(/(.*?)\s*(#{ARROW_MARK})(.*)/) {
57
57
  a, b, c = Regexp.last_match.captures
58
58
  space = " " * (PADDING_KEEP + (max - a.size))
59
59
  [a, space, b, c].join
@@ -71,8 +71,8 @@ module Source2MD
71
71
  def max
72
72
  @max ||= yield_self do
73
73
  av = lines
74
- av = av.find_all { |e| e.match?(MARK) }
75
- av = av.collect { |e| e.gsub(/\s*#{MARK}.*\R/, "").size }
74
+ av = av.find_all { |e| e.match?(ARROW_MARK) }
75
+ av = av.collect { |e| e.gsub(/\s*#{ARROW_MARK}.*\R/, "").size }
76
76
  av.max
77
77
  end
78
78
  end
@@ -1,7 +1,5 @@
1
1
  module Source2MD
2
2
  class Element
3
- KEY_VALUE_REGEXP = /^\s*(?:#|\/\/)\+(\S+):\s*(.*)\R?/ # #+key: value
4
-
5
3
  PLUGINS = [
6
4
  Formatter::TypeHidden, # #+hidden: true
7
5
  Formatter::TypeCodeInclude, # #+code_include: path/to/foo.html xml:SAMPLE.xml
@@ -29,11 +27,11 @@ module Source2MD
29
27
  end
30
28
 
31
29
  def head
32
- @head ||= @content.scan(KEY_VALUE_REGEXP).to_h.freeze
30
+ @head ||= @content.scan(key_value_regexp).to_h.freeze
33
31
  end
34
32
 
35
33
  def body
36
- @body ||= @content.remove(KEY_VALUE_REGEXP).freeze
34
+ @body ||= @content.remove(key_value_regexp).freeze
37
35
  end
38
36
 
39
37
  private
@@ -65,5 +63,10 @@ module Source2MD
65
63
  s.gsub(/^/, "> ")
66
64
  end
67
65
  end
66
+
67
+ # #+key: value
68
+ def key_value_regexp
69
+ /^#{RE.meta_re}\+(\S+):\s*(.*)\R?/
70
+ end
68
71
  end
69
72
  end
@@ -25,7 +25,7 @@ module Source2MD
25
25
  private
26
26
 
27
27
  def body
28
- element.body.gsub(%r{(#|//)$}, "")
28
+ element.body.gsub(%r{(#{RE.comment_re})$}, "")
29
29
  end
30
30
  end
31
31
  end
@@ -2,7 +2,7 @@ module Source2MD
2
2
  module Formatter
3
3
  class TypeSourceBlock < Base
4
4
  def self.accept?(element)
5
- element.body.match?(%r{(?:#|//)\+BEGIN_SRC})
5
+ element.body.match?(%r{#{RE.meta_re}\+BEGIN_SRC})
6
6
  end
7
7
 
8
8
  def to_md
@@ -15,11 +15,11 @@ module Source2MD
15
15
  private
16
16
 
17
17
  def body
18
- element.body.match(%r{(?:#|//)\+BEGIN_SRC.*?\R(.*)(?:#|//)\+END_SRC}m).captures.first
18
+ element.body.match(%r{#{RE.meta_re}\+BEGIN_SRC.*?\R(.*)#{RE.meta_re}\+END_SRC}m).captures.first
19
19
  end
20
20
 
21
21
  def code_block_desc
22
- if md = element.body.match(%r{(?:#|//)\+BEGIN_SRC (.+)\R})
22
+ if md = element.body.match(%r{#{RE.meta_re}\+BEGIN_SRC (.+)\R})
23
23
  md.captures.first
24
24
  end
25
25
  end
@@ -2,12 +2,12 @@ module Source2MD
2
2
  module Formatter
3
3
  class TypeTable < Base
4
4
  def self.accept?(element)
5
- !element.body.empty? && element.body.lines.all? { |e| e.match?(%r{^\s*(#|//) \|.*\|$}) }
5
+ !element.body.empty? && element.body.lines.all? { |e| e.match?(%r{#{RE.meta_re} \|.*\|$}) }
6
6
  end
7
7
 
8
8
  def to_md
9
9
  element.body
10
- .remove(%r{^\s*(#|//) })
10
+ .remove(%r{#{RE.meta_re} })
11
11
  .remove(/\A\|-.*?-\|\R/) # top
12
12
  .remove(/^\|-.*?-\|\R\z/) # bottom
13
13
  .gsub(/-\+-/, "-|-")
@@ -3,7 +3,7 @@ module Source2MD
3
3
  class TypeText < Base
4
4
  # "# xxx"
5
5
  # "#"
6
- REGEXP = %r{^\s*(?:#|//)( |$)}
6
+ REGEXP = %r{#{RE.meta_re}( |$)}
7
7
 
8
8
  def self.accept?(element)
9
9
  if element.body.present?
@@ -12,14 +12,10 @@ module Source2MD
12
12
  end
13
13
 
14
14
  if output_file
15
- if output_file.exist?
16
- FileUtils.chmod("a+w", output_file)
15
+ temporarily_disable_write_protection do
16
+ output_file.write(to_md)
17
+ puts "write: #{output_file}"
17
18
  end
18
- output_file.write(to_md)
19
- if Source2MD.readonly
20
- FileUtils.chmod("a-w", output_file)
21
- end
22
- puts "write: #{output_file}"
23
19
  end
24
20
  end
25
21
 
@@ -36,7 +32,13 @@ module Source2MD
36
32
  end
37
33
 
38
34
  def files
39
- @files ||= Array(params[:files]).collect { |e| Pathname(e).expand_path }
35
+ @files ||= yield_self do
36
+ if params[:glob]
37
+ Pathname.glob(params[:glob])
38
+ else
39
+ Array(params[:files]).collect { |e| Pathname(e).expand_path }
40
+ end
41
+ end
40
42
  end
41
43
 
42
44
  def output_file
@@ -46,5 +48,15 @@ module Source2MD
46
48
  end
47
49
  end
48
50
  end
51
+
52
+ def temporarily_disable_write_protection
53
+ if output_file.exist?
54
+ FileUtils.chmod("a+w", output_file)
55
+ end
56
+ yield
57
+ if Source2MD.readonly
58
+ FileUtils.chmod("a-w", output_file)
59
+ end
60
+ end
49
61
  end
50
62
  end
@@ -0,0 +1,3 @@
1
+ module Source2MD
2
+ RE = RegexpBuilder.new
3
+ end
@@ -0,0 +1,33 @@
1
+ module Source2MD
2
+ class RegexpBuilder
3
+ attr_accessor :prefix_re
4
+ attr_accessor :comment_re
5
+
6
+ def initialize
7
+ update do |e|
8
+ e.prefix_re = %r{^\s*}
9
+ e.comment_re = %r{#|//}
10
+ end
11
+ end
12
+
13
+ def update(&block)
14
+ yield self
15
+ reset
16
+ end
17
+
18
+ def meta_re
19
+ @meta_re ||= %r{#{prefix_re}(?:#{comment_re})}
20
+ end
21
+
22
+ def stdout_re
23
+ @stdout_re ||= %r{^(?:#{comment_re}) >>.*$}
24
+ end
25
+
26
+ private
27
+
28
+ def reset
29
+ @meta_re = nil
30
+ @stdout_re = nil
31
+ end
32
+ end
33
+ end
@@ -1,18 +1,5 @@
1
1
  module Source2MD
2
2
  class Scanner
3
- SEPARATOR = "\\R{2,}"
4
-
5
- SRC_BEGIN_KEY = "BEGIN_SRC"
6
- SRC_END_KEY = "END_SRC"
7
- SRC_BLOCK_RE = %r{^\s*(?:#|//)\+#{SRC_BEGIN_KEY}.*?^\s*(?:#|//)\+#{SRC_END_KEY}}m
8
-
9
- NORMAL_BLOCK_RE = /.*?#{SEPARATOR}/m
10
-
11
- PARAGRAPH_RE = Regexp.union [
12
- SRC_BLOCK_RE,
13
- NORMAL_BLOCK_RE,
14
- ]
15
-
16
3
  def initialize(content)
17
4
  @content = content
18
5
  end
@@ -21,11 +8,29 @@ module Source2MD
21
8
  v = @content
22
9
  v = v.rstrip + "\n\n"
23
10
  if Source2MD.xmp_out_exclude
24
- v = v.remove(%r{^(?:#|//) >>.*$})
11
+ v = v.remove(RE.stdout_re)
25
12
  end
26
- v = v.scan(PARAGRAPH_RE)
13
+ v = v.scan(paragraph_re)
27
14
  v = v.collect { |e| e.rstrip + "\n" }
28
15
  v = v.find_all(&:present?)
29
16
  end
17
+
18
+ private
19
+
20
+ def paragraph_re
21
+ Regexp.union(src_block_re, normal_block_re)
22
+ end
23
+
24
+ def src_block_re
25
+ %r{#{RE.meta_re}\+BEGIN_SRC.*?#{RE.meta_re}\+END_SRC}m
26
+ end
27
+
28
+ def normal_block_re
29
+ /.*?#{separator}/m
30
+ end
31
+
32
+ def separator
33
+ "\\R{2,}"
34
+ end
30
35
  end
31
36
  end
@@ -18,8 +18,8 @@ module Source2MD
18
18
  NKF.nkf("-wxZ4", text)
19
19
  end
20
20
 
21
- def indent(text)
22
- text.gsub(/^/, " ")
21
+ def indent(text, size = 2)
22
+ text.gsub(/^/, " " * size)
23
23
  end
24
24
 
25
25
  def eol_enter(text)
@@ -1,3 +1,3 @@
1
1
  module Source2MD
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.12"
3
3
  end
data/lib/source2md.rb CHANGED
@@ -23,6 +23,7 @@ loader = Zeitwerk::Loader.for_gem
23
23
  loader.ignore("#{__dir__}/source2md/logger.rb")
24
24
  loader.ignore("#{__dir__}/source2md/**/_*.rb")
25
25
  loader.inflector.inflect("source2md" => "Source2MD")
26
+ loader.inflector.inflect("re" => "RE")
26
27
  loader.log! if false
27
28
  loader.setup
28
29
 
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ module Source2MD
4
+ describe Generator do
5
+ before do
6
+ Pathname("_input.rb").write("# (content)")
7
+ end
8
+
9
+ after do
10
+ Pathname("_input.rb").delete
11
+ Pathname("_output.md").delete rescue nil
12
+ end
13
+
14
+ it "files option" do
15
+ output = capture("stdout") do
16
+ Generator.new(files: ["_input.rb"]).call
17
+ end
18
+ assert { output == "(content)\n" }
19
+ end
20
+
21
+ it "glob option" do
22
+ output = capture("stdout") do
23
+ Generator.new(glob: "_i*.rb").call
24
+ end
25
+ assert { output == "(content)\n" }
26
+ end
27
+
28
+ it "output file is write protected" do
29
+ capture("stdout") do
30
+ Generator.new(files: ["_input.rb"], output_file: "_output.md").call
31
+ end
32
+ assert { Pathname("_output.md").stat.writable? == false }
33
+ end
34
+ end
35
+ end
36
+ # >> .F
37
+ # >>
38
+ # >> Failures:
39
+ # >>
40
+ # >> 1) Source2MD::Generator glob option
41
+ # >> Failure/Error: Unable to find - to read failed line
42
+ # >> Test::Unit::AssertionFailedError:
43
+ # >> # -:25:in `block (2 levels) in <module:Source2MD>'
44
+ # >>
45
+ # >> Finished in 0.01412 seconds (files took 0.28313 seconds to load)
46
+ # >> 2 examples, 1 failure
47
+ # >>
48
+ # >> Failed examples:
49
+ # >>
50
+ # >> rspec -:21 # Source2MD::Generator glob option
51
+ # >>
data/spec/scanner_spec.rb CHANGED
@@ -25,19 +25,3 @@ module Source2MD
25
25
  end
26
26
  end
27
27
  end
28
- # >> F
29
- # >>
30
- # >> Failures:
31
- # >>
32
- # >> 1) Source2MD::Scanner works
33
- # >> Failure/Error: Unable to find - to read failed line
34
- # >> Test::Unit::AssertionFailedError:
35
- # >> # -:25:in `block (2 levels) in <module:Source2MD>'
36
- # >>
37
- # >> Finished in 0.01112 seconds (files took 0.26074 seconds to load)
38
- # >> 1 example, 1 failure
39
- # >>
40
- # >> Failed examples:
41
- # >>
42
- # >> rspec -:5 # Source2MD::Scanner works
43
- # >>
data/spec/spec_helper.rb CHANGED
@@ -18,3 +18,11 @@ RSpec.configure do |config|
18
18
  config.expect_with :test_unit
19
19
  config.example_status_persistence_file_path = "#{__dir__}/.all_test_result.txt"
20
20
  end
21
+
22
+ if true
23
+ require "tempfile" # for capture
24
+ require "active_support/testing/stream"
25
+ RSpec.configure do |config|
26
+ config.include ActiveSupport::Testing::Stream
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: source2md
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira Ikeda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-12 00:00:00.000000000 Z
11
+ date: 2023-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -155,15 +155,14 @@ files:
155
155
  - doc/0140_code_include.rb
156
156
  - doc/0150_raw_include.rb
157
157
  - doc/0160_title.rb
158
- - doc/0170_md_like_title.rb
159
- - doc/0180_table.rb
160
- - doc/0190_method.rb
161
- - doc/0200_alert.rb
162
- - doc/0210_text.rb
163
- - doc/0220_text_oneline.rb
164
- - doc/0230_text_squish.rb
165
- - doc/0240_text_hankaku_kana.rb
166
- - doc/0250_parse_include.rb
158
+ - doc/0170_table.rb
159
+ - doc/0180_method.rb
160
+ - doc/0190_alert.rb
161
+ - doc/0200_text.rb
162
+ - doc/0210_text_oneline.rb
163
+ - doc/0220_text_squish.rb
164
+ - doc/0230_text_hankaku_kana.rb
165
+ - doc/0240_parse_include.rb
167
166
  - doc/setup.rb
168
167
  - examples/cli-test.rs
169
168
  - examples/cli-test.sh
@@ -205,13 +204,14 @@ files:
205
204
  - lib/source2md/formatter/type_warn.rb
206
205
  - lib/source2md/generator.rb
207
206
  - lib/source2md/logger.rb
207
+ - lib/source2md/re.rb
208
+ - lib/source2md/regexp_builder.rb
208
209
  - lib/source2md/scanner.rb
209
210
  - lib/source2md/section.rb
210
211
  - lib/source2md/tasks/about.rake
211
212
  - lib/source2md/tasks/test.rake
212
213
  - lib/source2md/text_helper.rb
213
214
  - lib/source2md/version.rb
214
- - output.md
215
215
  - source2md.gemspec
216
216
  - spec/code_block_spec.rb
217
217
  - spec/formatter/sample.yml
@@ -227,6 +227,7 @@ files:
227
227
  - spec/formatter/type_text_spec.rb
228
228
  - spec/formatter/type_title_spec.rb
229
229
  - spec/formatter/type_warn_spec.rb
230
+ - spec/generator_spec.rb
230
231
  - spec/scanner_spec.rb
231
232
  - spec/spec_helper.rb
232
233
  - spec/text_helper_spec.rb
@@ -249,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
250
  - !ruby/object:Gem::Version
250
251
  version: '0'
251
252
  requirements: []
252
- rubygems_version: 3.4.18
253
+ rubygems_version: 3.4.19
253
254
  signing_key:
254
255
  specification_version: 4
255
256
  summary: Markdown generator from source code
@@ -268,6 +269,7 @@ test_files:
268
269
  - spec/formatter/type_text_spec.rb
269
270
  - spec/formatter/type_title_spec.rb
270
271
  - spec/formatter/type_warn_spec.rb
272
+ - spec/generator_spec.rb
271
273
  - spec/scanner_spec.rb
272
274
  - spec/spec_helper.rb
273
275
  - spec/text_helper_spec.rb
@@ -1,24 +0,0 @@
1
- #+hidden: true
2
- require "./setup"
3
-
4
- ### Markdown style title ###
5
-
6
- # The condition is that there are the same number of sharps on the back.
7
-
8
- #+BEGIN_SRC
9
- puts Source2MD::Section.new(<<~EOS).to_md
10
- # Title Level 1 #
11
-
12
- ## Title Level 2 ##
13
-
14
- ### Title Level 3 ###
15
- EOS
16
- #+END_SRC
17
-
18
- # ```
19
- # # Title Level 1 #
20
- #
21
- # ## Title Level 2 ##
22
- #
23
- # ### Title Level 3 ###
24
- # ```
data/output.md DELETED
@@ -1,13 +0,0 @@
1
- ```ruby
2
- a
3
- ```
4
-
5
- ```ruby
6
- r.xy(); // => Vec2(0.0, 0.0)
7
- r.xy(); // => Vec2(0.0, 0.0)
8
- r.xy(); // => Vec2(0.0, 0.0)
9
- ```
10
-
11
- ```ruby
12
- b
13
- ```