mdless 2.0.17 → 2.0.19
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 +4 -4
- data/README.md +0 -6
- data/lib/mdless/array.rb +11 -0
- data/lib/mdless/colors.rb +13 -5
- data/lib/mdless/console.rb +105 -94
- data/lib/mdless/converter.rb +140 -103
- data/lib/mdless/string.rb +94 -8
- data/lib/mdless/taskpaper.rb +79 -9
- data/lib/mdless/version.rb +1 -1
- data/lib/mdless.rb +46 -0
- metadata +17 -2
data/lib/mdless/taskpaper.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module CLIMarkdown
|
4
4
|
module TaskPaper
|
5
5
|
TASK_RX = /^(?<indent>(?: |\t)*?)(?<marker>-)(?<task>\s+\S.*?)$/
|
6
|
-
PROJECT_RX = /^(?<indent>(?: |\t)*?)(?<project>[^- \t].*?:)(?<tags>
|
6
|
+
PROJECT_RX = /^(?<indent>(?: |\t)*?)(?<project>[^- \t].*?:)(?<tags> +@\S+)*$/
|
7
7
|
NOTE_RX = /^(?<indent>(?: |\t)+)(?<note>(?<!- ).*?(?!:))$/
|
8
8
|
|
9
9
|
class << self
|
@@ -13,8 +13,8 @@ module CLIMarkdown
|
|
13
13
|
def color(key)
|
14
14
|
val = nil
|
15
15
|
keys = key.split(/[ ,>]/)
|
16
|
-
if
|
17
|
-
val =
|
16
|
+
if MDLess.theme.key?(keys[0])
|
17
|
+
val = MDLess.theme[keys.shift]
|
18
18
|
else
|
19
19
|
@log.error("Invalid theme key: #{key}") unless keys[0] =~ /^text/
|
20
20
|
return c([:reset])
|
@@ -36,25 +36,95 @@ module CLIMarkdown
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def remove_meta(input)
|
40
|
+
first_line = input.split("\n").first
|
41
|
+
if first_line =~ /(?i-m)^---[ \t]*?$/
|
42
|
+
input.sub!(/(?im)^---[ \t]*\n([\s\S]*?)\n[-.]{3}[ \t]*\n/, '')
|
43
|
+
elsif first_line =~ /(?i-m)^[\w ]+:\s+\S+/
|
44
|
+
input.sub!(/(?im)^([\S ]+:[\s\S]*?)+(?=\n\n)/, '')
|
45
|
+
end
|
46
|
+
input
|
47
|
+
end
|
48
|
+
|
39
49
|
def is_taskpaper?(input)
|
40
|
-
|
50
|
+
return true if MDLess.file =~ /\.taskpaper$/
|
51
|
+
|
52
|
+
projects = sections(input)
|
53
|
+
|
41
54
|
tasks = 0
|
42
55
|
if projects.count > 1
|
43
|
-
projects.each do |proj|
|
44
|
-
tasks +=
|
56
|
+
projects.each do |proj, content|
|
57
|
+
tasks += content['content'].scan(TASK_RX).count
|
45
58
|
end
|
46
59
|
end
|
47
60
|
|
48
|
-
tasks >= 6
|
61
|
+
if tasks >= 6
|
62
|
+
return true
|
63
|
+
else
|
64
|
+
tst = remove_meta(input)
|
65
|
+
tst = tst.gsub(PROJECT_RX, '')
|
66
|
+
tst = tst.gsub(TASK_RX, '')
|
67
|
+
tst = tst.gsub(/^ *\n$/, '')
|
68
|
+
return tst.strip.length == 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def section(input, string)
|
73
|
+
sects = sections(input)
|
74
|
+
sects_to_s(sects.filter { |k, _| k.downcase =~ string.downcase.to_rx })
|
75
|
+
end
|
76
|
+
|
77
|
+
def sects_to_s(sects)
|
78
|
+
sects.map do |k, v|
|
79
|
+
"#{k}#{v['content']}"
|
80
|
+
end.join("\n")
|
81
|
+
end
|
82
|
+
|
83
|
+
def indent(input, idnt)
|
84
|
+
input.split(/\n/).map do |line|
|
85
|
+
line.sub(/^#{idnt}/, '')
|
86
|
+
end.join("\n")
|
87
|
+
end
|
88
|
+
|
89
|
+
def sections(input)
|
90
|
+
heirarchy = {}
|
91
|
+
sects = input.to_enum(:scan, /(?mix)
|
92
|
+
(?<=\n|\A)(?<indent>(?: |\t)*?)
|
93
|
+
(?<project>[^- \t\n].*?:)\s*(?=\n)
|
94
|
+
(?<content>.*?)
|
95
|
+
(?=\n\k<indent>\S.*?:|\Z)$/).map { Regexp.last_match }
|
96
|
+
sects.each do |sect|
|
97
|
+
heirarchy[sect['project']] = {}
|
98
|
+
heirarchy[sect['project']]['content'] = indent(sect['content'], sect['indent'])
|
99
|
+
heirarchy = heirarchy.merge(sections(sect['content']))
|
100
|
+
end
|
101
|
+
|
102
|
+
heirarchy
|
49
103
|
end
|
50
104
|
|
51
|
-
def
|
52
|
-
|
105
|
+
def list_projects(input)
|
106
|
+
projects = input.to_enum(:scan, PROJECT_RX).map { Regexp.last_match }
|
107
|
+
projects.delete_if { |proj| proj['project'] =~ /^[ \n]*$/ }
|
108
|
+
projects.map! { |proj| "#{color('taskpaper marker')}#{proj['indent']}- #{color('taskpaper project')}#{proj['project'].sub(/:$/, '')}" }
|
109
|
+
projects.join("\n")
|
110
|
+
end
|
111
|
+
|
112
|
+
def highlight(input)
|
53
113
|
mc = color('taskpaper marker')
|
54
114
|
tc = color('taskpaper task')
|
55
115
|
pc = color('taskpaper project')
|
56
116
|
nc = color('taskpaper note')
|
57
117
|
|
118
|
+
if MDLess.options[:section]
|
119
|
+
matches = []
|
120
|
+
MDLess.options[:section].each do |sect|
|
121
|
+
matches << section(input, sect)
|
122
|
+
end
|
123
|
+
input = matches.join("\n")
|
124
|
+
end
|
125
|
+
|
126
|
+
input.gsub!(/\t/, ' ')
|
127
|
+
|
58
128
|
input.gsub!(PROJECT_RX) do
|
59
129
|
m = Regexp.last_match
|
60
130
|
"#{m['indent']}#{pc}#{m['project']}#{m['tags']}"
|
data/lib/mdless/version.rb
CHANGED
data/lib/mdless.rb
CHANGED
@@ -4,11 +4,13 @@ require 'open3'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'logger'
|
6
6
|
require 'tty-which'
|
7
|
+
require 'tty-screen'
|
7
8
|
require 'mdless/version.rb'
|
8
9
|
require 'mdless/colors'
|
9
10
|
require 'mdless/tables'
|
10
11
|
require 'mdless/hash'
|
11
12
|
require 'mdless/string'
|
13
|
+
require 'mdless/array'
|
12
14
|
require 'mdless/taskpaper'
|
13
15
|
require 'mdless/theme'
|
14
16
|
require 'redcarpet'
|
@@ -18,3 +20,47 @@ require 'mdless/converter'
|
|
18
20
|
module CLIMarkdown
|
19
21
|
EXECUTABLE_NAME = 'mdless'
|
20
22
|
end
|
23
|
+
|
24
|
+
module MDLess
|
25
|
+
class << self
|
26
|
+
include CLIMarkdown::Theme
|
27
|
+
attr_accessor :options, :cols, :file
|
28
|
+
|
29
|
+
def log
|
30
|
+
@log ||= Logger.new($stderr)
|
31
|
+
end
|
32
|
+
|
33
|
+
def log_level(level)
|
34
|
+
@log.level = level
|
35
|
+
end
|
36
|
+
|
37
|
+
def theme
|
38
|
+
@theme ||= load_theme(@options[:theme])
|
39
|
+
end
|
40
|
+
|
41
|
+
def pygments_styles
|
42
|
+
@pygments_styles ||= read_pygments_styles
|
43
|
+
end
|
44
|
+
|
45
|
+
def pygments_lexers
|
46
|
+
@pygments_lexers ||= read_pygments_lexers
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_pygments_styles
|
50
|
+
MDLess.log.info 'Reading Pygments styles'
|
51
|
+
pyg = TTY::Which.which('pygmentize')
|
52
|
+
res = `#{pyg} -L styles`
|
53
|
+
res.scan(/\* ([\w-]+):/).map { |l| l[0] }
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_pygments_lexers
|
57
|
+
MDLess.log.info 'Reading Pygments lexers'
|
58
|
+
pyg = TTY::Which.which('pygmentize')
|
59
|
+
res = `#{pyg} -L lexers`
|
60
|
+
lexers = res.scan(/\* ([\w-]+(?:, [\w-]+)*):/).map { |l| l[0] }
|
61
|
+
lexers_a = []
|
62
|
+
lexers.each { |l| lexers_a.concat(l.split(/, /)) }
|
63
|
+
lexers_a
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mdless
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redcarpet
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-screen
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.8'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,6 +92,7 @@ files:
|
|
78
92
|
- README.md
|
79
93
|
- bin/mdless
|
80
94
|
- lib/mdless.rb
|
95
|
+
- lib/mdless/array.rb
|
81
96
|
- lib/mdless/colors.rb
|
82
97
|
- lib/mdless/console.rb
|
83
98
|
- lib/mdless/converter.rb
|