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.
- checksums.yaml +7 -0
- data/.gemspec +19 -0
- data/.gitignore +1 -0
- data/LICENSE +13 -0
- data/README.md +12 -0
- data/Rakefile +19 -0
- data/TODO.md +14 -0
- data/VERSION +1 -0
- data/bin/html2ansi +248 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -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
|
data/.gemspec
ADDED
@@ -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
|
data/.gitignore
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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)
|
data/Rakefile
ADDED
@@ -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
|
data/bin/html2ansi
ADDED
@@ -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: []
|