kramdown-man 0.1.9 → 1.0.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
  SHA256:
3
- metadata.gz: dda435844039b4d61396829d332060c2db27506a3a7eee5d9859e09d9bd49e42
4
- data.tar.gz: 46fcc59f2081b7aef517ab9e0e280c4961d370aecca163d78f69a8b3f26298dc
3
+ metadata.gz: 2d53e0152c21c6a0e3e32b4f2dc2d185577eb01f34cd9cbfb8a300e5077e6648
4
+ data.tar.gz: c825469b0addc74ff69b1d1b53c54021d7020e9ae7284b94913187d58a61e6a9
5
5
  SHA512:
6
- metadata.gz: d81ca83bdb40321fd8ab52f2c15dc7e94d585641bac442e214a5acb4e9840f2ac38c4e4cb180d6ac03fac6852c3aeacd723988ca93bf837a226912f30cbc2f9e
7
- data.tar.gz: 218ca5e6ee857373114abe7d50747cfa89337c0f7a172ee599fbc4e82e60cfb66f12e6ed291dc7d37d904713c0692bde5d8b1fa191d132c1578aa528832de7a8
6
+ metadata.gz: fa320fdff23430cb680ad6aadae1b52a79a9eb78bd42ab58b802460c23892f0597a3b536744ffc40584c3309c441a6f8671a37ba9a149653f7ff27ced654f90d
7
+ data.tar.gz: 69465385b9ec09efcbe01ccb45c014c47dc04485687682167a68dc0f700e3009a34080d0048ffbc3612991fee9dc16f7445dca7078ab52c0c35860ec798a9f89
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,58 @@
1
+ ### 1.0.0 / 2023-12-03
2
+
3
+ * Ignore `kd:blank` elements to reduce size of generated man pages.
4
+ * No longer output `.HP` paragraphs due to cross-platform compatibility issues
5
+ with `groff`, `nroff`, `troff`.
6
+ * Renamed `Kramdown::Converters::Man` to {Kramdown::Man::Converter}.
7
+ * Override {Kramdown::Document#to_man} to use our {Kramdown::Man::Converter}.
8
+
9
+ #### Syntax
10
+
11
+ * Added support for definition lists.
12
+ * Switched to using definition lists for documenting options and arguments.
13
+
14
+ ```markdown
15
+ ## ARGUMENTS
16
+
17
+ *ARG*
18
+ : Description goes here.
19
+
20
+ ...
21
+ ```
22
+
23
+ ```markdown
24
+ ## OPTIONS
25
+
26
+ `-o`, `--option` *VALUE
27
+ : Description goes here.
28
+
29
+ ...
30
+ ```
31
+ * Added support for rendering relative links to other markdown man pages
32
+ as `SEE ALSO` man page references.
33
+
34
+ Example:
35
+
36
+ ```markdown
37
+ [foo-bar](foo-bar.1.md)
38
+ ```
39
+
40
+ Will be converted into:
41
+
42
+ ```
43
+ foo-bar(1)
44
+ ```
45
+ * Ignore horizontal rule elements due to cross-platform compatibility issues
46
+ with `groff`, `nroff`, `troff`.
47
+
48
+ #### CLI
49
+
50
+ * Added the `-o`, `--output FILE` option.
51
+ * Added the `-V`, `--version` option.
52
+ * Display the `kramdown-man.1` man page when `--help` is given, if STDOUT is
53
+ a TTY. If STDOUT is not a TTY, then the usual `--help` information will be
54
+ printed.
55
+
1
56
  ### 0.1.9 / 2023-12-01
2
57
 
3
58
  * 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,5 +1,9 @@
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
9
  * [Documentation](http://rubydoc.info/gems/kramdown-man/frames)
@@ -11,124 +15,209 @@ A [Kramdown][kramdown] convert for converting Markdown files into man pages.
11
15
  ## Features
12
16
 
13
17
  * Converts markdown to [roff]:
14
- * Supports codespans, emphasis and strong fonts.
15
- * Supports normal, hanging and tagged paragraphs.
16
- * Supports bullet lists.
18
+ * Supports codespans, emphasis, and strong fonts.
19
+ * Supports normal and tagged paragraphs.
20
+ * Supports codeblocks and blockquotes.
21
+ * Supports bullet, numbered, and definition lists.
17
22
  * 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.
23
+ * Supports converting `[foo-bar](foo-bar.1.md)` and `[bash](man:bash(1))`
24
+ links into `SEE ALSO` man page references.
21
25
  * Provides Rake task for converting `man/*.md` into man pages.
22
26
  * Uses the pure-Ruby [Kramdown][kramdown] markdown parser.
23
27
  * Supports [Ruby] 3.x, [JRuby], and [TruffleRuby].
24
28
 
25
29
  ## Synopsis
26
30
 
31
+ ```
32
+ usage: kramdown-man [options] MARKDOWN_FILE
33
+ -o, --output FILE Write the man page output to the file
34
+ -V, --version Print the version
35
+ -h, --help Print the help output
36
+
37
+ Examples:
38
+ kramdown-man -o man/myprogram.1 man/myprogram.1.md
39
+ kramdown-man man/myprogram.1.md
40
+
41
+ ```
42
+
27
43
  Render a man page from markdown:
28
44
 
29
- $ kramdown-man <man/myprog.1.md >man/myprog.1
45
+ ```shell
46
+ kramdown-man -o man/myprogram.1 man/myprogram.1.md
47
+ ```
48
+
49
+ Preview the rendered man page:
50
+
51
+ ```shell
52
+ kramdown-man man/myprogram.1.md
53
+ ```
30
54
 
31
55
  ## Examples
32
56
 
33
57
  Render a man page from a markdown file:
34
58
 
35
- require 'kramdown/man'
59
+ ```ruby
60
+ require 'kramdown/man'
36
61
 
37
- doc = Kramdown::Document.new(File.read('man/kramdown-man.1.md'))
38
- File.write('man/kramdown-man.1',doc.to_man)
62
+ doc = Kramdown::Document.new(File.read('man/kramdown-man.1.md'))
63
+ File.write('man/kramdown-man.1',doc.to_man)
39
64
 
40
- system 'man', 'man/kramdown-man.1'
65
+ system 'man', 'man/kramdown-man.1'
66
+ ```
41
67
 
42
68
  Define a `man` and file tasks which render all `*.md` files within the
43
69
  `man/` directory:
44
70
 
45
- require 'kramdown/man/task'
46
- Kramdown::Man::Task.new
71
+ ```ruby
72
+ require 'kramdown/man/task'
73
+ Kramdown::Man::Task.new
74
+ ```
47
75
 
48
76
  ## Syntax
49
77
 
50
- ### Formatting
78
+ ### Code
51
79
 
52
- `code`
80
+ ```markdown
81
+ `code`
82
+ ```
53
83
 
54
84
  `code`
55
85
 
56
- *emphasis*
86
+ ### Emphasis
57
87
 
88
+ ```markdown
58
89
  *emphasis*
90
+ ```
59
91
 
60
- **strong**
92
+ *emphasis*
93
+
94
+ ### Strong
95
+
96
+ ```markdown
97
+ **strong**
98
+ ```
61
99
 
62
100
  **strong**
63
101
 
64
- ### Paragraphs
102
+ ### Paragraph
65
103
 
66
- Normal paragraph.
104
+ ```markdown
105
+ Normal paragraph.
106
+ ```
67
107
 
68
108
  Normal paragraph.
69
109
 
70
- `command` [`--foo`] **FILE**
110
+ #### Usage String
111
+
112
+ ```markdown
113
+ `command` [`--foo`] **FILE**
114
+ ```
71
115
 
72
116
  `command` [`--foo`] **FILE**
73
117
 
74
- `--tagged`
75
- Text here.
118
+ #### Argument Definitions
119
+
120
+ ```markdown
121
+ *ARG*
122
+ : Description here.
123
+ ```
124
+
125
+ *ARG*
126
+ : Description here.
127
+
128
+ #### Option Definitions
76
129
 
77
- `--tagged`
78
- Text here.
130
+ ```markdown
131
+ `-o`, `--option` *VALUE*
132
+ : Description here.
133
+ ```
134
+
135
+ `-o`, `--option` *VALUE*
136
+ : Description here.
79
137
 
80
138
  ### Links
81
139
 
82
- [website](http://example.com/)
140
+ ```markdown
141
+ [website](http://example.com/)
142
+ ```
83
143
 
84
144
  [website](http://example.com/)
85
145
 
86
- [bash](man:bash(1))
146
+ #### Man Pages
147
+
148
+ Link to other man pages in a project:
87
149
 
150
+ ```markdown
151
+ [kramdown-man](kramdown-man.1.md)
152
+ ```
153
+
154
+ [kramdown-man](https://github.com/postmodern/kramdown-man/blob/main/man/kramdown-man.1.md)
155
+
156
+ Link to other system man page:
157
+
158
+ ```markdown
88
159
  [bash](man:bash(1))
160
+ ```
161
+
162
+ [bash](man:bash(1))
163
+
164
+ **Note:** only works on [firefox] on Linux.
89
165
 
90
- Email <bob@example.com>
166
+ [firefox]: https://www.mozilla.org/en-US/firefox/new/
167
+
168
+ #### Email Addresses
169
+
170
+ ```markdown
171
+ Email <bob@example.com>
172
+ ```
91
173
 
92
174
  Email <bob@example.com>
93
175
 
94
176
  ### Lists
95
177
 
96
- * one
97
- * two
98
- * three
99
-
100
- extra paragraph
101
-
178
+ ```markdown
179
+ * one
180
+ * two
181
+ * three
182
+ ```
102
183
 
103
184
  * one
104
185
  * two
105
186
  * three
106
187
 
107
- extra paragraph
188
+ #### Numbered Lists
108
189
 
109
- 1. one
110
- 2. two
111
- 3. three
112
-
113
- extra paragraph
190
+ ```markdown
191
+ 1. one
192
+ 2. two
193
+ 3. three
194
+ ```
114
195
 
115
196
  1. one
116
197
  2. two
117
198
  3. three
118
199
 
119
- extra paragraph
200
+ #### Definition Lists
201
+
202
+ ```markdown
203
+ ex·am·ple
204
+ : a thing characteristic of its kind or illustrating a general rule.
120
205
 
121
- ### Horizontal Rule
206
+ : a person or thing regarded in terms of their fitness to be imitated or the likelihood of their being imitated.
207
+ ```
122
208
 
123
- -------------------------------------------------------------------------------
209
+ ex·am·ple
210
+ : a thing characteristic of its kind or illustrating a general rule.
124
211
 
125
- -------------------------------------------------------------------------------
212
+ : a person or thing regarded in terms of their fitness to be imitated or the likelihood of their being imitated.
126
213
 
127
214
  ### Blockquotes
128
215
 
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
216
+ ```markdown
217
+ > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
218
+ >
219
+ > --Antoine de Saint-Exupéry
220
+ ```
132
221
 
133
222
  > Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
134
223
  >
@@ -136,13 +225,20 @@ Email <bob@example.com>
136
225
 
137
226
  ### Code Blocks
138
227
 
139
- #include <stdio.h>
140
-
141
- int main()
142
- {
143
- printf("hello world\n");
144
- return 0;
145
- }
228
+ ```markdown
229
+ Source code:
230
+
231
+ #include <stdio.h>
232
+
233
+ int main()
234
+ {
235
+ printf("hello world\n");
236
+ return 0;
237
+ }
238
+
239
+ ```
240
+
241
+ Source code:
146
242
 
147
243
  #include <stdio.h>
148
244
 
@@ -158,7 +254,9 @@ Email <bob@example.com>
158
254
 
159
255
  ## Install
160
256
 
161
- $ gem install kramdown-man
257
+ ```shell
258
+ gem install kramdown-man
259
+ ```
162
260
 
163
261
  ## Alternatives
164
262
 
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)
@@ -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