md-reader 0.1.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 +7 -0
- data/bin/md-reader +40 -0
- data/lib/md_reader/version.rb +5 -0
- data/lib/md_reader.rb +142 -0
- data/md_reader.gemspec +22 -0
- metadata +77 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 05f44183513c5dc93bb333082f7c528e3de2e3f6ccb3d4760618d20d95ec52c0
|
|
4
|
+
data.tar.gz: 31ac81531635c283b620339f132fba0c28fc91df3392c7f773c7adb129972deb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3f70219ea013ecc72a40e06d243d7ff57aa263ae648b4e590faaa4eca65875469b20ae320502cd5a27450037288cd15324c1ba76e0607b739d3cbb611bfe0e3a
|
|
7
|
+
data.tar.gz: c25aa48ac21ee51976274869c59fcd65e7a9933fe406128e1f055f354b0f6b461fcd22f657ef80b7fe07306edffffd613fe24874b982cae6e01893ccc4a976a2
|
data/bin/md-reader
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
|
5
|
+
|
|
6
|
+
require "md_reader"
|
|
7
|
+
require "launchy"
|
|
8
|
+
require "tmpdir"
|
|
9
|
+
|
|
10
|
+
if ARGV.empty?
|
|
11
|
+
warn "Usage: md-reader <arquivo.md>"
|
|
12
|
+
exit 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
file_path = ARGV[0]
|
|
16
|
+
|
|
17
|
+
unless File.exist?(file_path)
|
|
18
|
+
warn "Erro: arquivo '#{file_path}' não encontrado."
|
|
19
|
+
exit 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
unless File.readable?(file_path)
|
|
23
|
+
warn "Erro: sem permissão para ler '#{file_path}'."
|
|
24
|
+
exit 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
content = File.read(file_path, encoding: "utf-8")
|
|
28
|
+
title = File.basename(file_path)
|
|
29
|
+
html = MdReader::Converter.new.call(content, title)
|
|
30
|
+
|
|
31
|
+
basename_no_ext = File.basename(file_path, File.extname(file_path))
|
|
32
|
+
tmp_path = File.join(Dir.tmpdir, "md_reader_#{basename_no_ext}_#{Process.pid}.html")
|
|
33
|
+
|
|
34
|
+
File.write(tmp_path, html, encoding: "utf-8")
|
|
35
|
+
at_exit { File.delete(tmp_path) rescue nil }
|
|
36
|
+
|
|
37
|
+
puts "Abrindo #{title} no browser..."
|
|
38
|
+
Launchy.open("file://#{tmp_path}")
|
|
39
|
+
|
|
40
|
+
sleep 3
|
data/lib/md_reader.rb
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "redcarpet"
|
|
4
|
+
require "md_reader/version"
|
|
5
|
+
|
|
6
|
+
module MdReader
|
|
7
|
+
class Converter
|
|
8
|
+
MARKDOWN_EXTENSIONS = {
|
|
9
|
+
fenced_code_blocks: true,
|
|
10
|
+
tables: true,
|
|
11
|
+
autolink: true,
|
|
12
|
+
strikethrough: true,
|
|
13
|
+
superscript: true,
|
|
14
|
+
highlight: true,
|
|
15
|
+
footnotes: true,
|
|
16
|
+
no_intra_emphasis: true
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
def call(content, title = "Document")
|
|
20
|
+
renderer = Redcarpet::Render::HTML.new(hard_wrap: true, with_toc_data: true)
|
|
21
|
+
markdown = Redcarpet::Markdown.new(renderer, MARKDOWN_EXTENSIONS)
|
|
22
|
+
body = markdown.render(content)
|
|
23
|
+
html_template(body, title)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def html_template(body, title)
|
|
29
|
+
<<~HTML
|
|
30
|
+
<!DOCTYPE html>
|
|
31
|
+
<html lang="pt-BR">
|
|
32
|
+
<head>
|
|
33
|
+
<meta charset="UTF-8">
|
|
34
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
35
|
+
<title>#{title}</title>
|
|
36
|
+
<style>
|
|
37
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
38
|
+
|
|
39
|
+
body {
|
|
40
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
41
|
+
font-size: 16px;
|
|
42
|
+
line-height: 1.6;
|
|
43
|
+
color: #24292e;
|
|
44
|
+
background: #ffffff;
|
|
45
|
+
max-width: 860px;
|
|
46
|
+
margin: 0 auto;
|
|
47
|
+
padding: 2rem 3rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
h1, h2, h3, h4, h5, h6 {
|
|
51
|
+
margin-top: 1.5rem;
|
|
52
|
+
margin-bottom: 0.75rem;
|
|
53
|
+
font-weight: 600;
|
|
54
|
+
line-height: 1.25;
|
|
55
|
+
}
|
|
56
|
+
h1 { font-size: 2em; padding-bottom: 0.3em; border-bottom: 1px solid #eaecef; }
|
|
57
|
+
h2 { font-size: 1.5em; padding-bottom: 0.3em; border-bottom: 1px solid #eaecef; }
|
|
58
|
+
h3 { font-size: 1.25em; }
|
|
59
|
+
h4 { font-size: 1em; }
|
|
60
|
+
h5 { font-size: 0.875em; }
|
|
61
|
+
h6 { font-size: 0.85em; color: #6a737d; }
|
|
62
|
+
|
|
63
|
+
p { margin-top: 0; margin-bottom: 1rem; }
|
|
64
|
+
|
|
65
|
+
a { color: #0366d6; text-decoration: none; }
|
|
66
|
+
a:hover { text-decoration: underline; }
|
|
67
|
+
|
|
68
|
+
code {
|
|
69
|
+
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
|
70
|
+
font-size: 85%;
|
|
71
|
+
background: #f6f8fa;
|
|
72
|
+
border-radius: 3px;
|
|
73
|
+
padding: 0.2em 0.4em;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
pre {
|
|
77
|
+
background: #f6f8fa;
|
|
78
|
+
border-radius: 6px;
|
|
79
|
+
padding: 1rem;
|
|
80
|
+
overflow: auto;
|
|
81
|
+
line-height: 1.45;
|
|
82
|
+
margin-bottom: 1rem;
|
|
83
|
+
}
|
|
84
|
+
pre code {
|
|
85
|
+
background: transparent;
|
|
86
|
+
padding: 0;
|
|
87
|
+
font-size: 100%;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
blockquote {
|
|
91
|
+
margin: 0 0 1rem 0;
|
|
92
|
+
padding: 0 1em;
|
|
93
|
+
color: #6a737d;
|
|
94
|
+
border-left: 0.25em solid #dfe2e5;
|
|
95
|
+
}
|
|
96
|
+
blockquote > p { margin-bottom: 0; }
|
|
97
|
+
|
|
98
|
+
ul, ol {
|
|
99
|
+
padding-left: 2em;
|
|
100
|
+
margin-top: 0;
|
|
101
|
+
margin-bottom: 1rem;
|
|
102
|
+
}
|
|
103
|
+
li + li { margin-top: 0.25rem; }
|
|
104
|
+
|
|
105
|
+
table {
|
|
106
|
+
border-collapse: collapse;
|
|
107
|
+
width: 100%;
|
|
108
|
+
margin-bottom: 1rem;
|
|
109
|
+
overflow: auto;
|
|
110
|
+
display: block;
|
|
111
|
+
}
|
|
112
|
+
table th {
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
background: #f6f8fa;
|
|
115
|
+
}
|
|
116
|
+
table th, table td {
|
|
117
|
+
padding: 6px 13px;
|
|
118
|
+
border: 1px solid #dfe2e5;
|
|
119
|
+
}
|
|
120
|
+
table tr:nth-child(even) { background: #f6f8fa; }
|
|
121
|
+
|
|
122
|
+
img { max-width: 100%; height: auto; }
|
|
123
|
+
|
|
124
|
+
hr {
|
|
125
|
+
height: 0.25em;
|
|
126
|
+
padding: 0;
|
|
127
|
+
margin: 1.5rem 0;
|
|
128
|
+
background-color: #e1e4e8;
|
|
129
|
+
border: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
mark { background: #fff3b8; border-radius: 2px; padding: 0.1em 0.2em; }
|
|
133
|
+
</style>
|
|
134
|
+
</head>
|
|
135
|
+
<body>
|
|
136
|
+
#{body}
|
|
137
|
+
</body>
|
|
138
|
+
</html>
|
|
139
|
+
HTML
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
data/md_reader.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/md_reader/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |gem|
|
|
6
|
+
gem.name = "md-reader"
|
|
7
|
+
gem.version = MdReader::VERSION
|
|
8
|
+
gem.summary = "Abre arquivos Markdown no browser como HTML formatado."
|
|
9
|
+
gem.description = "Comando de terminal que converte Markdown em HTML com estilo GitHub e abre no browser."
|
|
10
|
+
gem.authors = ["Italo Matos"]
|
|
11
|
+
gem.email = ["italomatos@gmail.com"]
|
|
12
|
+
gem.license = "MIT"
|
|
13
|
+
|
|
14
|
+
gem.files = Dir["lib/**/*.rb"] + %w[md_reader.gemspec]
|
|
15
|
+
gem.executables = ["md-reader"]
|
|
16
|
+
gem.require_paths = ["lib"]
|
|
17
|
+
|
|
18
|
+
gem.required_ruby_version = ">= 3.0"
|
|
19
|
+
|
|
20
|
+
gem.add_dependency "redcarpet", "~> 3.6"
|
|
21
|
+
gem.add_dependency "launchy", "~> 2.5"
|
|
22
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: md-reader
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Italo Matos
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-06-11 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: redcarpet
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.6'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.6'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: launchy
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.5'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.5'
|
|
41
|
+
description: Comando de terminal que converte Markdown em HTML com estilo GitHub e
|
|
42
|
+
abre no browser.
|
|
43
|
+
email:
|
|
44
|
+
- italomatos@gmail.com
|
|
45
|
+
executables:
|
|
46
|
+
- md-reader
|
|
47
|
+
extensions: []
|
|
48
|
+
extra_rdoc_files: []
|
|
49
|
+
files:
|
|
50
|
+
- bin/md-reader
|
|
51
|
+
- lib/md_reader.rb
|
|
52
|
+
- lib/md_reader/version.rb
|
|
53
|
+
- md_reader.gemspec
|
|
54
|
+
homepage:
|
|
55
|
+
licenses:
|
|
56
|
+
- MIT
|
|
57
|
+
metadata: {}
|
|
58
|
+
post_install_message:
|
|
59
|
+
rdoc_options: []
|
|
60
|
+
require_paths:
|
|
61
|
+
- lib
|
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3.0'
|
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - ">="
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '0'
|
|
72
|
+
requirements: []
|
|
73
|
+
rubygems_version: 3.5.3
|
|
74
|
+
signing_key:
|
|
75
|
+
specification_version: 4
|
|
76
|
+
summary: Abre arquivos Markdown no browser como HTML formatado.
|
|
77
|
+
test_files: []
|