markdown_helper 1.0.0 → 1.5.0

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.
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: