html2ansi 0.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.
Files changed (10) hide show
  1. checksums.yaml +7 -0
  2. data/.gemspec +19 -0
  3. data/.gitignore +1 -0
  4. data/LICENSE +13 -0
  5. data/README.md +12 -0
  6. data/Rakefile +19 -0
  7. data/TODO.md +14 -0
  8. data/VERSION +1 -0
  9. data/bin/html2ansi +248 -0
  10. metadata +68 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 45fe5d736315b620fa3fe9fe74e34aaa577c07a8f6a21fc94de38a97ec4a24f5
4
+ data.tar.gz: fe481aa5b73264cc995bdbf51c1b6678ab91da6defc555434715235278328c92
5
+ SHA512:
6
+ metadata.gz: 645a5edb05dcedc588d576a30823461a792c602d5eab24a2bc92da2bf98cae6f0d47560a89c296f9e7d93e59b002d9a7bb1570cfdc6416b9dccbf6a18d029fe2
7
+ data.tar.gz: 1901264055eaf8d09245667db01538e193344e1c12eeb3b69b6aa88a5f2a25096b97ca31cd4f13092aa8b32e57be83b82d4bb409fc44349f20e615d7f1d62764
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "html2ansi"
6
+ s.version = File.read "VERSION"
7
+ s.date = File.mtime("VERSION").strftime("%Y-%m-%d")
8
+ s.summary = "html2ansi is readability for the terminal (renders html documents to text, with terminal colors)"
9
+ s.homepage = "http://github.com/epitron/html2ansi/"
10
+ s.licenses = ["WTFPL"]
11
+ s.email = "chris@ill-logic.com"
12
+ s.authors = ["epitron"]
13
+
14
+ s.files = `git ls`.lines.map(&:strip)
15
+ s.executables = ['html2ansi']
16
+ s.extra_rdoc_files = ["README.md", "LICENSE"]
17
+
18
+ s.add_dependency "html-renderer", "~> 0.1.0"
19
+ end
@@ -0,0 +1 @@
1
+ /pkg/
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar
5
+ 14 rue de Plaisance, 75014 Paris, France
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1,12 @@
1
+ # HTML Renderer
2
+
3
+ ## Overview
4
+
5
+ Allows you to subclass `HTMLRenderer::Base`, add some methods, and then parse HTML to generate custom output.
6
+
7
+ (Uses a similar API to the [RedCarpet](https://github.com/vmg/redcarpet) gem.)
8
+
9
+ ## Examples
10
+
11
+ * [HTML to Plain Text Renderer](https://github.com/epitron/html-renderer/blob/master/examples/plain_text_renderer.rb)
12
+ * [HTML to ANSI Renderer](https://github.com/epitron/html-renderer/blob/master/examples/ansi_renderer.rb)
@@ -0,0 +1,19 @@
1
+ gem = eval(File.read '.gemspec')
2
+
3
+ gemfile = "#{gem.name}-#{gem.version}.gem"
4
+
5
+ task :build do
6
+ system "gem build .gemspec"
7
+ system "mkdir pkg/" unless File.directory? "pkg"
8
+ system "mv #{gemfile} pkg/"
9
+ end
10
+
11
+ task :release => :build do
12
+ system "gem push pkg/#{gemfile}"
13
+ end
14
+
15
+ task :gem => :build
16
+
17
+ task :install => :build do
18
+ system "gem install pkg/#{gemfile}"
19
+ end
data/TODO.md ADDED
@@ -0,0 +1,14 @@
1
+ # TODO list
2
+
3
+ ## Base class
4
+
5
+ ! add HTMLRenderer.reflow_paragraph
6
+ * #render takes options (and passes them to subclasses)
7
+ * :debug option (hide parse errors unless 'true')
8
+
9
+ ## ANSI renderer
10
+
11
+ * use HTMLRenderer.reflow_paragraph
12
+ * :wrap option (with optional terminal width)
13
+ * Better table renderer (with line-drawing)
14
+ * Follow `<table>` style attributes when drawing tables (eg: borders)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env ruby
2
+ #######################################################################################
3
+ require 'html-renderer'
4
+ require 'terminal-table'
5
+ require 'term/ansicolor'
6
+ require 'coderay'
7
+ #######################################################################################
8
+
9
+ class String
10
+ # include ANSI::Mixin
11
+ include Term::ANSIColor
12
+
13
+ def grey; self.black.bold; end
14
+ end
15
+
16
+ #######################################################################################
17
+
18
+ def lesspipe(*args)
19
+ if args.any? and args.last.is_a?(Hash)
20
+ options = args.pop
21
+ else
22
+ options = {}
23
+ end
24
+
25
+ output = args.first if args.any?
26
+
27
+ params = []
28
+ params << "-R" unless options[:color] == false
29
+ params << "-S" unless options[:wrap] == true
30
+ params << "-F" unless options[:always] == true
31
+ if options[:tail] == true
32
+ params << "+\\>"
33
+ $stderr.puts "Seeking to end of stream..."
34
+ end
35
+ params << "-X"
36
+
37
+ IO.popen("less #{params * ' '}", "w") do |less|
38
+ if output
39
+ less.puts output
40
+ else
41
+ yield less
42
+ end
43
+ end
44
+ rescue Errno::EPIPE, Interrupt
45
+ # less just quit -- eat the exception.
46
+ end
47
+
48
+ #######################################################################################
49
+
50
+ class ANSIRenderer < HTMLRenderer::Base
51
+
52
+ private
53
+
54
+ def indented?(text)
55
+ indent_sizes = text.lines.map{ |line| if line =~ /^(\s+)/ then $1 else '' end }.map(&:size)
56
+ indent_sizes.all? {|dent| dent > 0 }
57
+ end
58
+
59
+ def unwrap(text)
60
+ return text unless indented? text
61
+ text.lines.to_a.map(&:strip).join ' '
62
+ end
63
+
64
+ def indent(text,amount=2)
65
+ text.lines.map{|line| " "*amount + line }.join
66
+ end
67
+
68
+ def smash(s)
69
+ s&.downcase&.scan(/\w+/)&.join
70
+ end
71
+
72
+ def subscript(s)
73
+ "[#{s}]"
74
+ end
75
+
76
+ public
77
+
78
+ def normal_text(text)
79
+ text
80
+ end
81
+
82
+ def underline(content)
83
+ content.magenta.bold
84
+ end
85
+
86
+ def superscript(content)
87
+ "^(#{content})"
88
+ end
89
+
90
+ def link(link, title, content)
91
+ unless content&.[] /^Back /
92
+ str = ""
93
+ # str += "<15>#{content}</15>" if content
94
+ str += content.white.bold if content
95
+ if smash(link) != smash(content)
96
+ # str += " <8>(</8><11>#{link}</11><8>)</8>"
97
+ str += " #{"(".grey}#{link&.cyan&.bold}#{")".grey}"
98
+ end
99
+
100
+ str
101
+ end
102
+ end
103
+
104
+ def anchor(name, title=nil, content=nil)
105
+ result = "Anchor: ##{name}"
106
+ result << " (#{title})" if title
107
+ result << "\n"
108
+ result << "#{content}\n" if content
109
+ result
110
+ end
111
+
112
+ def image(link, title, content)
113
+ link(link, nil, title)
114
+ end
115
+
116
+ def italic(text)
117
+ text.yellow.bold
118
+ end
119
+
120
+ def block_code(code, language)
121
+ language ||= :ruby
122
+
123
+ language = language[1..-1] if language[0] == "." # strip leading "."
124
+ language = :cpp if language == "C++"
125
+
126
+ require 'coderay'
127
+ "#{indent CodeRay.scan(code, language).term, 4}\n"
128
+ end
129
+
130
+ def block_quote(text)
131
+ indent paragraph(text)
132
+ end
133
+
134
+ def codespan(code)
135
+ code.cyan
136
+ end
137
+
138
+ def header(title, level, anchor=nil)
139
+ bar = ("-"*(title.size+4)).grey
140
+
141
+ title = case level
142
+ when 1 then title.bold.yellow
143
+ when 2 then title.bold.cyan
144
+ when 3 then title.bold.blue
145
+ else title.magenta
146
+ end
147
+
148
+ "#{bar}\n #{title}\n#{bar}\n\n"
149
+ end
150
+
151
+ def double_emphasis(text)
152
+ text.bold.green
153
+ end
154
+
155
+ def emphasis(text)
156
+ text.green
157
+ end
158
+
159
+ def linebreak
160
+ "\n"
161
+ end
162
+
163
+ def paragraph(text)
164
+ div(text) + "\n"
165
+ end
166
+
167
+ def div(text)
168
+ "#{indented?(text) ? text : unwrap(text)}\n"
169
+ end
170
+
171
+ def list(content, list_type)
172
+ case list_type
173
+ when :ordered
174
+ @counter = 0
175
+ "#{content}\n"
176
+ when :unordered
177
+ "#{content}\n"
178
+ end
179
+ end
180
+
181
+ def list_item(content, list_type)
182
+ case list_type
183
+ when :ordered
184
+ @counter ||= 0
185
+ @counter += 1
186
+ # " <8>#{@counter}.</8> #{content.strip}\n".colorize
187
+ " #{@counter.to_s.grey}. #{content.strip}\n"
188
+ when :unordered
189
+ # " <8>*</8> #{content.strip}\n".colorize
190
+ " #{"*".grey} #{content.strip}\n"
191
+ end
192
+ end
193
+
194
+ def definition_list(defs)
195
+ defs.each do |dt, dd|
196
+ puts "<15>#{dt}<7>:".colorize
197
+ puts " #{dd}"
198
+ puts
199
+ end
200
+ end
201
+
202
+ def table(header, rows)
203
+ if header
204
+ table = Terminal::Table.new(headings: header, rows: rows)
205
+ else
206
+ table = Terminal::Table.new(rows: rows)
207
+ end
208
+ "#{table}\n\n"
209
+ end
210
+
211
+ def separator
212
+ "_____________________________\n\n"
213
+ end
214
+
215
+ end
216
+
217
+ #######################################################################################
218
+
219
+ def render(stream, paged=false)
220
+ output = ANSIRenderer.render(stream)
221
+ if paged
222
+ lesspipe { |less| less.puts output }
223
+ else
224
+ puts output
225
+ end
226
+ end
227
+
228
+ #######################################################################################
229
+
230
+ opts, args = ARGV.partition { |arg| arg[/^--?\w/] }
231
+
232
+ if opts.include?("-h") or opts.include?("--help")
233
+ puts "usage:"
234
+ puts " html2ansi [options] <file.html>"
235
+ puts " or"
236
+ puts " curl http://host/path.html | html2ansi [options]"
237
+ puts
238
+ puts "options:"
239
+ puts " -p Paged (redirect output to less)"
240
+ puts
241
+ else
242
+ paged = opts.include?("-p") or opts.include?("--paged")
243
+ if args.empty?
244
+ render($stdin, paged)
245
+ else
246
+ args.each { |arg| render(open(arg), paged) }
247
+ end
248
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html2ansi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - epitron
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: html-renderer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.0
27
+ description:
28
+ email: chris@ill-logic.com
29
+ executables:
30
+ - html2ansi
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - README.md
34
+ - LICENSE
35
+ files:
36
+ - ".gemspec"
37
+ - ".gitignore"
38
+ - LICENSE
39
+ - README.md
40
+ - Rakefile
41
+ - TODO.md
42
+ - VERSION
43
+ - bin/html2ansi
44
+ homepage: http://github.com/epitron/html2ansi/
45
+ licenses:
46
+ - WTFPL
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubygems_version: 3.1.2
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: html2ansi is readability for the terminal (renders html documents to text,
67
+ with terminal colors)
68
+ test_files: []