kramdown-man 0.1.9 → 1.0.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
  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