kramdown-man 0.1.9 → 1.0.1

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
  SHA256:
3
- metadata.gz: dda435844039b4d61396829d332060c2db27506a3a7eee5d9859e09d9bd49e42
4
- data.tar.gz: 46fcc59f2081b7aef517ab9e0e280c4961d370aecca163d78f69a8b3f26298dc
3
+ metadata.gz: 30fd9e9769c09ef4d6220ce37ee0a810624e996983ab83151f75c35aa573f420
4
+ data.tar.gz: ab547ca91944b0d38ef7c826a61c69d99a727541793691a2e936595a3c75f039
5
5
  SHA512:
6
- metadata.gz: d81ca83bdb40321fd8ab52f2c15dc7e94d585641bac442e214a5acb4e9840f2ac38c4e4cb180d6ac03fac6852c3aeacd723988ca93bf837a226912f30cbc2f9e
7
- data.tar.gz: 218ca5e6ee857373114abe7d50747cfa89337c0f7a172ee599fbc4e82e60cfb66f12e6ed291dc7d37d904713c0692bde5d8b1fa191d132c1578aa528832de7a8
6
+ metadata.gz: b2056c28f02cd6ce02a06e21872fa95c22963420ef7e5583f99af92d46767c5d57d23afa187c6587aa1077ee0f6871a54ed6e02e295bba1c7244333c4bbbf451
7
+ data.tar.gz: 64cb91e4c0c77aed3fca7dedf6d925cd81e35a6ad6b3acd721363b9391a18c8e0460655e88b094bf58b9ed7b85f04eb6f180eb96f89f2d5ca328f515dd2f3c51
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
- Gemfile.lock
2
- doc/
3
- pkg/
1
+ /Gemfile.lock
2
+ /coverage/
3
+ /doc/
4
+ /pkg/
data/.yardopts CHANGED
@@ -1 +1 @@
1
- --markup markdown --markup-provider kramdown --title "kramdown-man Documentation" --protected
1
+ --markup markdown --title "kramdown-man Documentation" --protected
data/ChangeLog.md CHANGED
@@ -1,3 +1,69 @@
1
+ ### 1.0.1 / 2023-12-05
2
+
3
+ * Treat markdown code-fence `kd:codespan`s the same as `kd:codeblock`s.
4
+
5
+ ```
6
+ puts "hello world"
7
+ ```
8
+ ```
9
+ puts "hello world"
10
+ ```
11
+
12
+ ### 1.0.0 / 2023-12-03
13
+
14
+ * Ignore `kd:blank` elements to reduce size of generated man pages.
15
+ * No longer output `.HP` paragraphs due to cross-platform compatibility issues
16
+ with `groff`, `nroff`, `troff`.
17
+ * Renamed `Kramdown::Converters::Man` to {Kramdown::Man::Converter}.
18
+ * Override {Kramdown::Document#to_man} to use our {Kramdown::Man::Converter}.
19
+
20
+ #### Syntax
21
+
22
+ * Added support for definition lists.
23
+ * Switched to using definition lists for documenting options and arguments.
24
+
25
+ ```markdown
26
+ ## ARGUMENTS
27
+
28
+ *ARG*
29
+ : Description goes here.
30
+
31
+ ...
32
+ ```
33
+
34
+ ```markdown
35
+ ## OPTIONS
36
+
37
+ `-o`, `--option` *VALUE
38
+ : Description goes here.
39
+
40
+ ...
41
+ ```
42
+ * Added support for rendering relative links to other markdown man pages
43
+ as `SEE ALSO` man page references.
44
+
45
+ Example:
46
+
47
+ ```markdown
48
+ [foo-bar](foo-bar.1.md)
49
+ ```
50
+
51
+ Will be converted into:
52
+
53
+ ```
54
+ foo-bar(1)
55
+ ```
56
+ * Ignore horizontal rule elements due to cross-platform compatibility issues
57
+ with `groff`, `nroff`, `troff`.
58
+
59
+ #### CLI
60
+
61
+ * Added the `-o`, `--output FILE` option.
62
+ * Added the `-V`, `--version` option.
63
+ * Display the `kramdown-man.1` man page when `--help` is given, if STDOUT is
64
+ a TTY. If STDOUT is not a TTY, then the usual `--help` information will be
65
+ printed.
66
+
1
67
  ### 0.1.9 / 2023-12-01
2
68
 
3
69
  * Allow markdown `man:file.ext` style links, since man pages can be named after
data/Gemfile CHANGED
@@ -4,7 +4,10 @@ gemspec
4
4
 
5
5
  group :development do
6
6
  gem 'rake'
7
- gem 'rubygems-tasks', '~> 0.2'
8
- gem 'rspec', '~> 3.0'
9
- gem 'yard', '~> 0.9'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ gem 'rspec', '~> 3.0'
9
+ gem 'simplecov', '~> 0.20'
10
+ gem 'redcarpet', platform: :mri
11
+ gem 'yard', '~> 0.9'
12
+ gem 'dead_end', require: false
10
13
  end
data/README.md CHANGED
@@ -1,134 +1,234 @@
1
1
  # kramdown-man
2
2
 
3
+ [![CI](https://github.com/postmodern/kramdown-man/actions/workflows/ruby.yml/badge.svg)](https://github.com/postmodern/kramdown-man/actions/workflows/ruby.yml)
4
+ [![Code Climate](https://codeclimate.com/github/postmodern/kramdown-man.svg)](https://codeclimate.com/github/postmodern/kramdown-man)
5
+ [![Gem Version](https://badge.fury.io/rb/kramdown-man.svg)](https://badge.fury.io/rb/kramdown-man)
6
+
3
7
  * [Homepage](https://github.com/postmodern/kramdown-man#readme)
4
8
  * [Issues](https://github.com/postmodern/kramdown-man/issues)
5
- * [Documentation](http://rubydoc.info/gems/kramdown-man/frames)
9
+ * [Documentation](https://rubydoc.info/gems/kramdown-man)
6
10
 
7
11
  ## Description
8
12
 
9
- A [Kramdown][kramdown] convert for converting Markdown files into man pages.
13
+ Allows you to write man pages for commands in pure Markdown and convert them to
14
+ roff using [Kramdown][kramdown].
10
15
 
11
16
  ## Features
12
17
 
13
18
  * Converts markdown to [roff]:
14
- * Supports codespans, emphasis and strong fonts.
15
- * Supports normal, hanging and tagged paragraphs.
16
- * Supports bullet lists.
19
+ * Supports codespans, emphasis, and strong fonts.
20
+ * Supports normal and tagged paragraphs.
21
+ * Supports codeblocks and blockquotes.
22
+ * Supports bullet, numbered, and definition lists.
17
23
  * Supports multi-paragraph list items and blockquotes.
18
- * Supports horizontal rules.
19
- * Supports converting `[bash](man:bash(1))` and `[bash](man:bash.1)` links
20
- into man page references.
21
- * Provides Rake task for converting `man/*.md` into man pages.
24
+ * Supports converting `[foo-bar](foo-bar.1.md)` and `[bash](man:bash(1))`
25
+ links into `SEE ALSO` man page references.
26
+ * Provides a handy `kramdown-man` command for converting or previewing
27
+ markdown man pages.
28
+ * Provides a rake task for converting `man/*.md` into man pages.
22
29
  * Uses the pure-Ruby [Kramdown][kramdown] markdown parser.
23
30
  * Supports [Ruby] 3.x, [JRuby], and [TruffleRuby].
24
31
 
25
32
  ## Synopsis
26
33
 
34
+ ```
35
+ usage: kramdown-man [options] MARKDOWN_FILE
36
+ -o, --output FILE Write the man page output to the file
37
+ -V, --version Print the version
38
+ -h, --help Print the help output
39
+
40
+ Examples:
41
+ kramdown-man -o man/myprogram.1 man/myprogram.1.md
42
+ kramdown-man man/myprogram.1.md
43
+
44
+ ```
45
+
27
46
  Render a man page from markdown:
28
47
 
29
- $ kramdown-man <man/myprog.1.md >man/myprog.1
48
+ ```shell
49
+ kramdown-man -o man/myprogram.1 man/myprogram.1.md
50
+ ```
51
+
52
+ Preview the rendered man page:
53
+
54
+ ```shell
55
+ kramdown-man man/myprogram.1.md
56
+ ```
30
57
 
31
58
  ## Examples
32
59
 
33
60
  Render a man page from a markdown file:
34
61
 
35
- require 'kramdown/man'
62
+ ```ruby
63
+ require 'kramdown/man'
64
+
65
+ doc = Kramdown::Document.new(File.read('man/kramdown-man.1.md'))
66
+ File.write('man/kramdown-man.1',doc.to_man)
36
67
 
37
- doc = Kramdown::Document.new(File.read('man/kramdown-man.1.md'))
38
- File.write('man/kramdown-man.1',doc.to_man)
68
+ system 'man', 'man/kramdown-man.1'
69
+ ```
39
70
 
40
- system 'man', 'man/kramdown-man.1'
71
+ ### Rake Task
41
72
 
42
73
  Define a `man` and file tasks which render all `*.md` files within the
43
74
  `man/` directory:
44
75
 
45
- require 'kramdown/man/task'
46
- Kramdown::Man::Task.new
76
+ ```ruby
77
+ require 'kramdown/man/task'
78
+ Kramdown::Man::Task.new
79
+ ```
80
+
81
+ Then you can generate man pages for all `*.md` in the `man/` directory:
82
+
83
+ ```shell
84
+ $ rake man
85
+ ```
47
86
 
48
87
  ## Syntax
49
88
 
50
- ### Formatting
89
+ ### Code
51
90
 
52
- `code`
91
+ ```markdown
92
+ `code`
93
+ ```
53
94
 
54
95
  `code`
55
96
 
56
- *emphasis*
97
+ ### Emphasis
57
98
 
99
+ ```markdown
58
100
  *emphasis*
101
+ ```
59
102
 
60
- **strong**
103
+ *emphasis*
61
104
 
105
+ ### Strong
106
+
107
+ ```markdown
62
108
  **strong**
109
+ ```
63
110
 
64
- ### Paragraphs
111
+ **strong**
65
112
 
66
- Normal paragraph.
113
+ ### Paragraph
67
114
 
115
+ ```markdown
68
116
  Normal paragraph.
117
+ ```
69
118
 
70
- `command` [`--foo`] **FILE**
119
+ Normal paragraph.
120
+
121
+ #### Usage String
122
+
123
+ ```markdown
124
+ `command` [`--foo`] **FILE**
125
+ ```
71
126
 
72
127
  `command` [`--foo`] **FILE**
73
128
 
74
- `--tagged`
75
- Text here.
129
+ #### Argument Definitions
130
+
131
+ ```markdown
132
+ *ARG*
133
+ : Description here.
134
+ ```
135
+
136
+ *ARG*
137
+ : Description here.
138
+
139
+ #### Option Definitions
140
+
141
+ ```markdown
142
+ `-o`, `--option` *VALUE*
143
+ : Description here.
144
+ ```
76
145
 
77
- `--tagged`
78
- Text here.
146
+ `-o`, `--option` *VALUE*
147
+ : Description here.
79
148
 
80
149
  ### Links
81
150
 
82
- [website](http://example.com/)
151
+ ```markdown
152
+ [website](http://example.com/)
153
+ ```
83
154
 
84
155
  [website](http://example.com/)
85
156
 
86
- [bash](man:bash(1))
157
+ #### Man Pages
158
+
159
+ Link to other man pages in a project:
160
+
161
+ ```markdown
162
+ [kramdown-man](kramdown-man.1.md)
163
+ ```
164
+
165
+ [kramdown-man](https://github.com/postmodern/kramdown-man/blob/main/man/kramdown-man.1.md)
166
+
167
+ Link to other system man page:
168
+
169
+ ```markdown
170
+ [bash](man:bash(1))
171
+ ```
87
172
 
88
173
  [bash](man:bash(1))
89
174
 
90
- Email <bob@example.com>
175
+ **Note:** only works on [firefox] on Linux.
176
+
177
+ [firefox]: https://www.mozilla.org/en-US/firefox/new/
178
+
179
+ #### Email Addresses
180
+
181
+ ```markdown
182
+ Email <bob@example.com>
183
+ ```
91
184
 
92
185
  Email <bob@example.com>
93
186
 
94
187
  ### Lists
95
188
 
96
- * one
97
- * two
98
- * three
99
-
100
- extra paragraph
101
-
189
+ ```markdown
190
+ * one
191
+ * two
192
+ * three
193
+ ```
102
194
 
103
195
  * one
104
196
  * two
105
197
  * three
106
198
 
107
- extra paragraph
199
+ #### Numbered Lists
108
200
 
109
- 1. one
110
- 2. two
111
- 3. three
112
-
113
- extra paragraph
201
+ ```markdown
202
+ 1. one
203
+ 2. two
204
+ 3. three
205
+ ```
114
206
 
115
207
  1. one
116
208
  2. two
117
209
  3. three
118
210
 
119
- extra paragraph
211
+ #### Definition Lists
120
212
 
121
- ### Horizontal Rule
213
+ ```markdown
214
+ ex·am·ple
215
+ : a thing characteristic of its kind or illustrating a general rule.
122
216
 
123
- -------------------------------------------------------------------------------
217
+ : a person or thing regarded in terms of their fitness to be imitated or the likelihood of their being imitated.
218
+ ```
124
219
 
125
- -------------------------------------------------------------------------------
220
+ ex·am·ple
221
+ : a thing characteristic of its kind or illustrating a general rule.
222
+
223
+ : a person or thing regarded in terms of their fitness to be imitated or the likelihood of their being imitated.
126
224
 
127
225
  ### Blockquotes
128
226
 
129
- > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
130
- >
131
- > --Antoine de Saint-Exupéry
227
+ ```markdown
228
+ > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
229
+ >
230
+ > --Antoine de Saint-Exupéry
231
+ ```
132
232
 
133
233
  > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
134
234
  >
@@ -136,13 +236,15 @@ Email <bob@example.com>
136
236
 
137
237
  ### Code Blocks
138
238
 
139
- #include <stdio.h>
140
-
141
- int main()
142
- {
143
- printf("hello world\n");
144
- return 0;
145
- }
239
+ ```markdown
240
+ #include <stdio.h>
241
+
242
+ int main()
243
+ {
244
+ printf("hello world\n");
245
+ return 0;
246
+ }
247
+ ```
146
248
 
147
249
  #include <stdio.h>
148
250
 
@@ -152,17 +254,29 @@ Email <bob@example.com>
152
254
  return 0;
153
255
  }
154
256
 
257
+ #### Code Fences
258
+
259
+ ```
260
+ puts "hello world"
261
+ ```
262
+
263
+ ```
264
+ puts "hello world"
265
+ ```
266
+
155
267
  ## Requirements
156
268
 
157
269
  * [kramdown] ~> 2.0
158
270
 
159
271
  ## Install
160
272
 
161
- $ gem install kramdown-man
273
+ ```shell
274
+ gem install kramdown-man
275
+ ```
162
276
 
163
277
  ## Alternatives
164
278
 
165
- * [Redcarpet::Render::ManPage](http://rubydoc.info/gems/redcarpet/Redcarpet/Render/ManPage)
279
+ * [Redcarpet::Render::ManPage](https://rubydoc.info/gems/redcarpet/Redcarpet/Render/ManPage)
166
280
  * [ronn](https://github.com/rtomayko/ronn#readme)
167
281
  * [md2man](https://github.com/sunaku/md2man#readme)
168
282
 
@@ -172,9 +286,9 @@ Copyright (c) 2013-2023 Hal Brodigan
172
286
 
173
287
  See {file:LICENSE.txt} for details.
174
288
 
175
- [kramdown]: http://kramdown.gettalong.org/
176
- [roff]: http://en.wikipedia.org/wiki/Roff
289
+ [kramdown]: https://kramdown.gettalong.org/
290
+ [roff]: https://en.wikipedia.org/wiki/Roff_(software)
177
291
 
178
- [Ruby]: http://www.ruby-lang.org/
179
- [JRuby]: http://jruby.org/
292
+ [Ruby]: https://www.ruby-lang.org/
293
+ [JRuby]: https://jruby.org/
180
294
  [TruffleRuby]: https://github.com/oracle/truffleruby#readme
data/bin/kramdown-man CHANGED
@@ -1,16 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- lib_dir = File.expand_path('../lib',File.dirname(__FILE__))
3
+ lib_dir = File.expand_path('../lib',__dir__)
4
4
  $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
5
 
6
- require 'kramdown'
7
- require 'kramdown/man'
8
-
9
- case ARGV[0]
10
- when '-h', '--help'
11
- warn "usage: #{File.dirname($0)} <INPUT.md >OUTPUT"
12
- exit
13
- end
14
-
15
- doc = Kramdown::Document.new(ARGF.read)
16
- puts doc.to_man
6
+ require 'kramdown/man/cli'
7
+ exit Kramdown::Man::CLI.run(ARGV)
data/gemspec.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  name: kramdown-man
2
- summary: Converts markdown to man pages
3
- description: A Kramdown converter for converting Markdown files into man pages.
2
+ summary: Allows you to write man pages in pure markdown.
3
+ description: |
4
+ Allows you to write man pages for commands in pure Markdown and convert them
5
+ to roff using Kramdown.
6
+
4
7
  license: MIT
5
8
  authors: Postmodern
6
9
  email: postmodern.mod3@gmail.com
@@ -0,0 +1,202 @@
1
+ require 'kramdown'
2
+ require 'kramdown/man'
3
+
4
+ require 'optparse'
5
+
6
+ module Kramdown
7
+ module Man
8
+ #
9
+ # Represents the `kramdown-man` command's logic.
10
+ #
11
+ # @api private
12
+ #
13
+ # @since 1.0.0
14
+ #
15
+ class CLI
16
+
17
+ # The program name.
18
+ PROGRAM_NAME = "kramdown-man"
19
+
20
+ # The URL to report bugs to.
21
+ BUG_REPORT_URL = "https://github.com/postmodern/kramdown-man/issues/new"
22
+
23
+ # The path to the man/ directory.
24
+ MAN_PAGE = File.join(__dir__,'..','..','..','man','kramdown-man.1')
25
+
26
+ # The command's option parser.
27
+ #
28
+ # @return [OptionParser]
29
+ attr_reader :option_parser
30
+
31
+ # The optional output file to write to.
32
+ #
33
+ # @return [String, nil]
34
+ attr_reader :output
35
+
36
+ #
37
+ # Initializes the command.
38
+ #
39
+ def initialize
40
+ @option_parser = option_parser
41
+
42
+ @output = nil
43
+ end
44
+
45
+ #
46
+ # Initializes and runs the command.
47
+ #
48
+ # @param [Array<String>] argv
49
+ # Command-line arguments.
50
+ #
51
+ # @return [Integer]
52
+ # The exit status of the command.
53
+ #
54
+ def self.run(argv)
55
+ new().run(argv)
56
+ rescue Interrupt
57
+ # https://tldp.org/LDP/abs/html/exitcodes.html
58
+ return 130
59
+ rescue Errno::EPIPE
60
+ # STDOUT pipe broken
61
+ return 0
62
+ end
63
+
64
+ #
65
+ # Runs the command.
66
+ #
67
+ # @param [Array<String>] argv
68
+ # Command-line arguments.
69
+ #
70
+ # @return [Integer]
71
+ # The return status code.
72
+ #
73
+ def run(argv=ARGV)
74
+ argv = begin
75
+ @option_parser.parse(argv)
76
+ rescue OptionParser::ParseError => error
77
+ print_error(error.message)
78
+ return -1
79
+ end
80
+
81
+ markdown = case argv.length
82
+ when 1
83
+ path = argv[0]
84
+
85
+ unless File.file?(path)
86
+ print_error "no such file or directory: #{path}"
87
+ return -1
88
+ end
89
+
90
+ File.read(path)
91
+ when 0
92
+ print_error "a MARKDOWN_FILE argument is required"
93
+ return -1
94
+ else
95
+ print_error "too many arguments given"
96
+ return -1
97
+ end
98
+
99
+ doc = Kramdown::Document.new(markdown)
100
+ man_page = doc.to_man
101
+
102
+ if @output
103
+ File.write(@output,man_page)
104
+ elsif $stdout.tty?
105
+ view_man_page(man_page)
106
+ else
107
+ puts man_page
108
+ end
109
+
110
+ return 0
111
+ rescue => error
112
+ print_backtrace(error)
113
+ return -1
114
+ end
115
+
116
+ #
117
+ # Displays the man page using the `man` command.
118
+ #
119
+ # @param [String] man_page
120
+ # The man page output.
121
+ #
122
+ def view_man_page(man_page)
123
+ io = IO.popen(%w[man -l -],'w')
124
+ pid = io.pid
125
+
126
+ begin
127
+ io.puts man_page
128
+ rescue Errno::EPIPE
129
+ ensure
130
+ io.close
131
+
132
+ begin
133
+ Process.waitpid(pid)
134
+ rescue Errno::EPIPE, Errno::ECHILD
135
+ end
136
+ end
137
+ end
138
+
139
+ #
140
+ # The option parser.
141
+ #
142
+ # @return [OptionParser]
143
+ #
144
+ def option_parser
145
+ OptionParser.new do |opts|
146
+ opts.banner = "usage: #{PROGRAM_NAME} [options] MARKDOWN_FILE"
147
+
148
+ opts.on('-o','--output FILE','Write the man page output to the file') do |file|
149
+ @output = file
150
+ end
151
+
152
+ opts.on('-V','--version','Print the version') do
153
+ puts "#{PROGRAM_NAME} #{VERSION}"
154
+ exit
155
+ end
156
+
157
+ opts.on('-h','--help','Print the help output') do
158
+ if $stdout.tty?
159
+ system('man',MAN_PAGE)
160
+ else
161
+ puts opts
162
+ end
163
+
164
+ exit
165
+ end
166
+
167
+ opts.separator ""
168
+ opts.separator "Examples:"
169
+ opts.separator " #{PROGRAM_NAME} -o man/myprogram.1 man/myprogram.1.md"
170
+ opts.separator " #{PROGRAM_NAME} man/myprogram.1.md"
171
+ opts.separator ""
172
+ end
173
+ end
174
+
175
+ #
176
+ # Prints an error message to stderr.
177
+ #
178
+ # @param [String] error
179
+ # The error message.
180
+ #
181
+ def print_error(error)
182
+ $stderr.puts "#{PROGRAM_NAME}: #{error}"
183
+ end
184
+
185
+ #
186
+ # Prints a backtrace to stderr.
187
+ #
188
+ # @param [Exception] exception
189
+ # The exception.
190
+ #
191
+ def print_backtrace(exception)
192
+ $stderr.puts "Oops! Looks like you've found a bug!"
193
+ $stderr.puts "Please report the following text to: #{BUG_REPORT_URL}"
194
+ $stderr.puts
195
+ $stderr.puts "```"
196
+ $stderr.puts "#{exception.full_message}"
197
+ $stderr.puts "```"
198
+ end
199
+
200
+ end
201
+ end
202
+ end