markdown_helper 1.0.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9350e847948120c0b6cd8da04deb1eb77a915631
4
- data.tar.gz: f5eb9065d158d45ee87d0f4cb0e9e9e74529c48c
3
+ metadata.gz: d1147c20c56afc8ddb67b90b57845d59d08488c7
4
+ data.tar.gz: 0d4e6f2363d0921cdc206adc4c7c8d30a654ac1a
5
5
  SHA512:
6
- metadata.gz: e98b19de2d10445af71e05e271f73c0de7ea563c7d009e9870ab7783b3a8a20a33fae2463fc6ffa1ba841deda72df0edd97f1880352cf5e7fb7fed5e90073602
7
- data.tar.gz: c7f039f5e9ec548b713c23c759a6e34918eec4f25f20b900375d002c0f3caaa76124972bbd4a25310a4a84814061811436634a784b933c58773b5eb2f469a08b
6
+ metadata.gz: ec0b3a986477b6c9780a31073855358880375d6ccef61d669fb5b55ed121d9327c536e46f6d7cdf075dec5129c7b4c3c4be200fd7d8afbed9c128f4a11f5f518
7
+ data.tar.gz: a172ff12521ec4e2363d17d89b3149f303242fe7c506e17b376ab9499e7912a980905fc0463bb1bc84262165a3bfcc7b6e1d008ccd8e53f35c63f9414b488c8f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_helper (1.0.0)
4
+ markdown_helper (1.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -8,6 +8,10 @@
8
8
  <!-- <<<<<< END RESOLVED IMAGES: INPUT-LINE '![Gem Version](https://badge.fury.io/rb/markdown_helper.svg)
9
9
  ' -->
10
10
 
11
+ ## What's New?
12
+
13
+ Nested file inclusion is now supported, which means that an included file can include more files. This applies only to a file included verbatim, not to a file included as a code block or as a markdown comment.
14
+
11
15
  ## What's This?
12
16
 
13
17
  Class <code>MarkdownHelper</code> supports:
@@ -18,11 +22,11 @@ Class <code>MarkdownHelper</code> supports:
18
22
 
19
23
  ## How It Works
20
24
 
21
- The markdown helper reads a markdown document (template) and writes another markdown document.
25
+ The markdown helper is a preprocessor that reads a markdown document (template) and writes another markdown document.
22
26
 
23
27
  The template can contain certain instructions that call for file inclusions and image resolutions.
24
28
 
25
- ## Commented or Pristine?
29
+ ### Commented or Pristine?
26
30
 
27
31
  By default, the output markdown has added comments that show:
28
32
 
@@ -84,6 +88,8 @@ Comment text is written into the output between the comment delimiters <code>\<!
84
88
 
85
89
  Verbatim text is included unadorned. Most often, verbatim text is markdown to be rendered as part of the markdown page.
86
90
 
91
+ The verbatim text is itself scanned for nested includes.
92
+
87
93
  ### Usage
88
94
 
89
95
  #### CLI
@@ -91,7 +97,8 @@ Verbatim text is included unadorned. Most often, verbatim text is markdown to b
91
97
  <!-- >>>>>> BEGIN INCLUDED FILE (code_block): SOURCE readme_files/../bin/usage/include.txt -->
92
98
  <code>include.txt</code>
93
99
  ```
94
- Usage: bin/include [options] template_file_path markdown_file_page
100
+
101
+ Usage: include [options] template_file_path markdown_file_page
95
102
  --pristine No comments added
96
103
  --help Display help
97
104
 
data/bin/include CHANGED
@@ -6,17 +6,21 @@ require 'markdown_helper'
6
6
 
7
7
  options = {:pristine => false}
8
8
 
9
- parser = OptionParser.new do|opts|
10
- opts.banner = "Usage: #{__FILE__} [options] template_file_path markdown_file_page"
11
- opts.on('--pristine', 'No comments added') do |_|
9
+ # Save opts for use below.
10
+ opts = nil
11
+ parser = OptionParser.new do |_opts|
12
+ opts = _opts
13
+ _opts.banner = "Usage: #{File.basename(__FILE__)} [options] template_file_path markdown_file_page"
14
+ _opts.on('--pristine', 'No comments added') do |_|
12
15
  options[:pristine] = true
13
16
  end
14
- opts.on('--help', 'Display help') do
15
- usage(opts)
17
+ _opts.on('--help', 'Display help') do
18
+ usage(_opts)
16
19
  end
17
20
  end
18
21
 
19
22
  def usage(opts)
23
+ puts ''
20
24
  puts opts
21
25
  puts <<-EOT
22
26
 
@@ -37,8 +41,18 @@ parser.parse!
37
41
 
38
42
  template_file_path, markdown_file_path = ARGV
39
43
 
40
- usage(options) unless ARGV.size == 2
41
- usage(options) unless File.readable?(template_file_path)
42
- usage(options) unless File.writable?(File.dirname(markdown_file_path))
44
+ usage(opts) unless ARGV.size == 2
45
+ usage(opts) unless File.readable?(template_file_path)
46
+ usage(opts) unless File.writable?(File.dirname(markdown_file_path))
47
+
48
+ # This code, outside of a class, had interference from Module#include.
49
+ # So now it's in a class.
50
+ class AvoidModule
51
+ def initialize(template_file_path, markdown_file_path, options)
52
+ markdown_helper = MarkdownHelper.new(options)
53
+ markdown_helper.include(template_file_path, markdown_file_path)
54
+ end
55
+ end
56
+
57
+ AvoidModule.new(template_file_path, markdown_file_path, options)
43
58
 
44
- MarkdownHelper.new(options).include(template_file_path, markdown_file_path)
@@ -1,4 +1,5 @@
1
- Usage: bin/include [options] template_file_path markdown_file_page
1
+
2
+ Usage: include [options] template_file_path markdown_file_page
2
3
  --pristine No comments added
3
4
  --help Display help
4
5
 
@@ -1,3 +1,3 @@
1
1
  class MarkdownHelper
2
- VERSION = '1.0.0'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'pathname'
1
2
  require 'markdown_helper/version'
2
3
 
3
4
  # Helper class for working with GitHub markdown.
@@ -26,17 +27,6 @@ class MarkdownHelper
26
27
  end
27
28
  end
28
29
 
29
- # Get the user name and repository name from ENV.
30
- def repo_user_and_name
31
- repo_user = ENV['REPO_USER']
32
- repo_name = ENV['REPO_NAME']
33
- unless repo_user and repo_name
34
- message = 'ENV values for both REPO_USER and REPO_NAME must be defined.'
35
- raise RuntimeError.new(message)
36
- end
37
- [repo_user, repo_name]
38
- end
39
-
40
30
  # Merges external files into markdown text.
41
31
  # @param template_file_path [String] the path to the input template markdown file, usually containing include pragmas.
42
32
  # @param markdown_file_path [String] the path to the output merged markdown file.
@@ -52,29 +42,7 @@ class MarkdownHelper
52
42
  # @[:verbatim](foo.md)
53
43
  def include(template_file_path, markdown_file_path)
54
44
  output = send(:generate_file, template_file_path, markdown_file_path, __method__) do |input_lines, output_lines|
55
- input_lines.each do |input_line|
56
- match_data = input_line.match(INCLUDE_REGEXP)
57
- unless match_data
58
- output_lines.push(input_line)
59
- next
60
- end
61
- treatment = case match_data[1]
62
- when ':code_block'
63
- :code_block
64
- when ':verbatim'
65
- :verbatim
66
- when ':comment'
67
- :comment
68
- else
69
- match_data[1]
70
- end
71
- relative_file_path = match_data[2]
72
- include_file_path = File.join(
73
- File.dirname(template_file_path),
74
- relative_file_path,
75
- )
76
- send(:include_file, include_file_path, treatment, output_lines)
77
- end
45
+ send(:include_files, template_file_path, input_lines, output_lines, paths = [], realpaths = [])
78
46
  end
79
47
  output
80
48
  end
@@ -103,24 +71,27 @@ class MarkdownHelper
103
71
  def resolve(template_file_path, markdown_file_path)
104
72
  # Method :generate_file does the first things, yields the block, does the last things.
105
73
  output = send(:generate_file, template_file_path, markdown_file_path, __method__) do |input_lines, output_lines|
106
- input_lines.each do |input_line|
107
- scan_data = input_line.scan(IMAGE_REGEXP)
108
- if scan_data.empty?
109
- output_lines.push(input_line)
110
- next
111
- end
112
- send(:resolve_images, scan_data, input_line, output_lines)
113
- end
74
+ send(:resolve_images, input_lines, output_lines)
114
75
  end
115
76
  output
116
77
  end
117
78
  alias resolve_image_urls resolve
118
79
 
80
+ private
81
+
119
82
  def comment(text)
120
83
  "<!--#{text}-->\n"
121
84
  end
122
85
 
123
- private
86
+ def repo_user_and_name
87
+ repo_user = ENV['REPO_USER']
88
+ repo_name = ENV['REPO_NAME']
89
+ unless repo_user and repo_name
90
+ message = 'ENV values for both REPO_USER and REPO_NAME must be defined.'
91
+ raise RuntimeError.new(message)
92
+ end
93
+ [repo_user, repo_name]
94
+ end
124
95
 
125
96
  def generate_file(template_file_path, markdown_file_path, method)
126
97
  output_lines = []
@@ -137,65 +108,110 @@ class MarkdownHelper
137
108
  output
138
109
  end
139
110
 
140
- def include_file(include_file_path, treatment, output_lines)
141
- include_file = File.new(include_file_path, 'r')
142
- output_lines.push(comment(" >>>>>> BEGIN INCLUDED FILE (#{treatment}): SOURCE #{include_file.path} ")) unless pristine
143
- included_text = include_file.read
144
- unless included_text.match("\n")
145
- message = "Warning: Included file has no trailing newline: #{include_file_path}"
146
- warn(message)
111
+ def include_files(template_file_path, input_lines, output_lines, paths, realpaths)
112
+ realpath = Pathname.new(template_file_path).realpath
113
+ i = realpaths.index(realpath)
114
+ if i
115
+ old_path = paths[i]
116
+ new_path = template_file_path
117
+ realpath = realpaths[i]
118
+ message = <<EOT
119
+ Includes are circular:
120
+ Old path: #{old_path}
121
+ New path: #{new_path}
122
+ Real path: #{realpath}
123
+ EOT
124
+ raise RuntimeError.new(message)
147
125
  end
148
- case treatment
149
- when :verbatim
150
- # Pass through unadorned.
151
- output_lines.push(included_text)
152
- when :comment
153
- output_lines.push(comment(included_text))
154
- else
155
- # Use the file name as a label.
156
- file_name_line = format("<code>%s</code>\n", File.basename(include_file_path))
157
- output_lines.push(file_name_line)
158
- # Put into code block.
159
- language = treatment == :code_block ? '' : treatment
160
- output_lines.push("```#{language}\n")
161
- output_lines.push(included_text)
162
- output_lines.push("```\n")
126
+ paths.push(template_file_path)
127
+ realpaths.push(realpath)
128
+
129
+ input_lines.each do |input_line|
130
+ match_data = input_line.match(INCLUDE_REGEXP)
131
+ unless match_data
132
+ output_lines.push(input_line)
133
+ next
134
+ end
135
+ treatment = case match_data[1]
136
+ when ':code_block'
137
+ :code_block
138
+ when ':verbatim'
139
+ :verbatim
140
+ when ':comment'
141
+ :comment
142
+ else
143
+ match_data[1]
144
+ end
145
+ relative_file_path = match_data[2]
146
+ include_file_path = File.join(
147
+ File.dirname(template_file_path),
148
+ relative_file_path,
149
+ )
150
+ output_lines.push(comment(" >>>>>> BEGIN INCLUDED FILE (#{treatment}): SOURCE #{include_file_path} ")) unless pristine
151
+ include_lines = File.readlines(include_file_path)
152
+ unless include_lines.last.match("\n")
153
+ message = "Warning: Included file has no trailing newline: #{include_file_path}"
154
+ warn(message)
155
+ end
156
+ case treatment
157
+ when :verbatim
158
+ # Pass through unadorned, but honor any nested includes.
159
+ include_files(include_file_path, include_lines, output_lines, paths, realpaths)
160
+ when :comment
161
+ output_lines.push(comment(include_lines.join('')))
162
+ else
163
+ # Use the file name as a label.
164
+ file_name_line = format("<code>%s</code>\n", File.basename(include_file_path))
165
+ output_lines.push(file_name_line)
166
+ # Put into code block.
167
+ language = treatment == :code_block ? '' : treatment
168
+ output_lines.push("```#{language}\n")
169
+ output_lines.push(*include_lines)
170
+ output_lines.push("```\n")
171
+ end
172
+ output_lines.push(comment(" <<<<<< END INCLUDED FILE (#{treatment}): SOURCE #{include_file_path} ")) unless pristine
163
173
  end
164
- output_lines.push(comment(" <<<<<< END INCLUDED FILE (#{treatment}): SOURCE #{include_file.path} ")) unless pristine
165
174
  end
166
175
 
167
- def resolve_images(scan_data, input_line, output_lines)
168
- output_lines.push(comment(" >>>>>> BEGIN RESOLVED IMAGES: INPUT-LINE '#{input_line}' ")) unless pristine
169
- output_line = input_line
170
- scan_data.each do |alt_text, path_and_attributes|
171
- relative_file_path, attributes_s =path_and_attributes.split(/\s?\|\s?/, 2)
172
- attributes = attributes_s ? attributes_s.split(/\s+/) : []
173
- formatted_attributes = ['']
174
- attributes.each do |attribute|
175
- name, value = attribute.split('=', 2)
176
- formatted_attributes.push(format('%s="%s"', name, value))
176
+ def resolve_images(input_lines, output_lines)
177
+ input_lines.each do |input_line|
178
+ scan_data = input_line.scan(IMAGE_REGEXP)
179
+ if scan_data.empty?
180
+ output_lines.push(input_line)
181
+ next
177
182
  end
178
- formatted_attributes_s = formatted_attributes.join(' ')
179
- repo_user, repo_name = repo_user_and_name
180
- absolute_file_path = nil
181
- if relative_file_path.start_with?('http')
182
- absolute_file_path = relative_file_path
183
- else
184
- absolute_file_path = File.join(
185
- "https://raw.githubusercontent.com/#{repo_user}/#{repo_name}/master",
186
- relative_file_path,
183
+ output_lines.push(comment(" >>>>>> BEGIN RESOLVED IMAGES: INPUT-LINE '#{input_line}' ")) unless pristine
184
+ output_line = input_line
185
+ scan_data.each do |alt_text, path_and_attributes|
186
+ relative_file_path, attributes_s =path_and_attributes.split(/\s?\|\s?/, 2)
187
+ attributes = attributes_s ? attributes_s.split(/\s+/) : []
188
+ formatted_attributes = ['']
189
+ attributes.each do |attribute|
190
+ name, value = attribute.split('=', 2)
191
+ formatted_attributes.push(format('%s="%s"', name, value))
192
+ end
193
+ formatted_attributes_s = formatted_attributes.join(' ')
194
+ repo_user, repo_name = repo_user_and_name
195
+ absolute_file_path = nil
196
+ if relative_file_path.start_with?('http')
197
+ absolute_file_path = relative_file_path
198
+ else
199
+ absolute_file_path = File.join(
200
+ "https://raw.githubusercontent.com/#{repo_user}/#{repo_name}/master",
201
+ relative_file_path,
202
+ )
203
+ end
204
+ img_element = format(
205
+ '<img src="%s" alt="%s"%s>',
206
+ absolute_file_path,
207
+ alt_text,
208
+ formatted_attributes_s,
187
209
  )
210
+ output_line = output_line.sub(IMAGE_REGEXP, img_element)
188
211
  end
189
- img_element = format(
190
- '<img src="%s" alt="%s"%s>',
191
- absolute_file_path,
192
- alt_text,
193
- formatted_attributes_s,
194
- )
195
- output_line = output_line.sub(IMAGE_REGEXP, img_element)
212
+ output_lines.push(output_line)
213
+ output_lines.push(comment(" <<<<<< END RESOLVED IMAGES: INPUT-LINE '#{input_line}' ")) unless pristine
196
214
  end
197
- output_lines.push(output_line)
198
- output_lines.push(comment(" <<<<<< END RESOLVED IMAGES: INPUT-LINE '#{input_line}' ")) unless pristine
199
215
  end
200
216
 
201
217
  end
@@ -2,6 +2,10 @@
2
2
 
3
3
  ![Gem Version](https://badge.fury.io/rb/markdown_helper.svg)
4
4
 
5
+ ## What's New?
6
+
7
+ Nested file inclusion is now supported, which means that an included file can include more files. This applies only to a file included verbatim, not to a file included as a code block or as a markdown comment.
8
+
5
9
  ## What's This?
6
10
 
7
11
  Class <code>MarkdownHelper</code> supports:
@@ -12,11 +16,11 @@ Class <code>MarkdownHelper</code> supports:
12
16
 
13
17
  ## How It Works
14
18
 
15
- The markdown helper reads a markdown document (template) and writes another markdown document.
19
+ The markdown helper is a preprocessor that reads a markdown document (template) and writes another markdown document.
16
20
 
17
21
  The template can contain certain instructions that call for file inclusions and image resolutions.
18
22
 
19
- ## Commented or Pristine?
23
+ ### Commented or Pristine?
20
24
 
21
25
  By default, the output markdown has added comments that show:
22
26
 
@@ -56,6 +60,8 @@ Comment text is written into the output between the comment delimiters <code>\<!
56
60
 
57
61
  Verbatim text is included unadorned. Most often, verbatim text is markdown to be rendered as part of the markdown page.
58
62
 
63
+ The verbatim text is itself scanned for nested includes.
64
+
59
65
  ### Usage
60
66
 
61
67
  #### CLI
@@ -0,0 +1,14 @@
1
+ ### Evergreen Examples
2
+
3
+ Example code and output that's embedded in a markdown file is dead text that may no longer be correct.
4
+
5
+ Use the markdown helper to include example code and output -- but only after the project "build" has re-run the code and refreahed the output!
6
+
7
+ Here's how:
8
+
9
+ 1. Maintain each code example in a separate executable file.
10
+ 1. Maintain markdown files that have include desctiptions, rather than embedded code and output.
11
+ 1. At project "build time" (controlled by a suitable build tool):
12
+ 1. Execute each code example, capturing its output to one or more files.
13
+ 1. Check output for errors and validity.
14
+ 1. Run the markdown helper to re-assemble the markdown files.
@@ -0,0 +1,5 @@
1
+ ### Include Generated Text
2
+
3
+ Use the markdown helper to include text that is genrated at project "build time."
4
+
5
+ Example: Project build runs each executable with option <code>--help</code>, capturing the output into a file. That file can then be included into the markdown pages for the project.
@@ -0,0 +1,8 @@
1
+ ### Image Attributes
2
+
3
+ Use the markdown helper to assign attributes to images.
4
+
5
+ If you're using the markdown helper to [resolve image file paths for a Ruby gem](./rubygem_images.md), you'll be using the GitHub markdown image-description idiom (begins with exclamation point), and not the HTML <code>img</code> idiom.
6
+
7
+ The image description does not accept attributes (such as height and width), but the markdown helper does accept those, passing them through to an <code>img</code> HTML element.
8
+ s
@@ -0,0 +1,7 @@
1
+ ### Reusable Text
2
+
3
+ Use the markdown helper to stay DRY (Don't Repeat Yourself).
4
+
5
+ Text that will be needed in more than one place in the documentation can be maintained in a separate file, then included wherever it's needed.
6
+
7
+ Note that the included text may itself be markdown, which can be included verbatim, or it may be code or other example data, which can be included into a code block.
@@ -0,0 +1,9 @@
1
+ ### RubyGem Images
2
+
3
+ Use the markdown helper to resolve image paths for a Ruby gem.
4
+
5
+ When you release your GitHub project to gem at RubyGems.org, the documentation is rebuilt into files on RubyDoc.info. When YARD performs this rebuilding, it does some directory restructuring.
6
+
7
+ If a markdown file contains an image description that has a relative file path, that path will not be valid in the documentation on RubyDoc.info, and the image will not display in the documentation.
8
+
9
+ To avoid that error, use the markdown helper to resolve the relative path to an absolute path. This new absolute path points to a file that's automatically maintained in the GitHub project.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - burdettelamar
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-19 00:00:00.000000000 Z
11
+ date: 2018-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -109,6 +109,11 @@ files:
109
109
  - readme_files/include_usage.rb
110
110
  - readme_files/resolve.md
111
111
  - readme_files/resolve_usage.rb
112
+ - readme_files/use_cases/evergreen_examples.md
113
+ - readme_files/use_cases/generated_text.md
114
+ - readme_files/use_cases/image_attributes.md
115
+ - readme_files/use_cases/reusable_text.md
116
+ - readme_files/use_cases/rubygem_images.md
112
117
  - readme_files/verbatim_ruby_template.md
113
118
  homepage: https://github.com/BurdetteLamar/markdown_helper
114
119
  licenses: