dnote 1.1.4 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +29 -0
- data/bin/dnote +2 -2
- data/lib/dnote.rb +2 -3
- data/lib/dnote/format.rb +26 -69
- data/lib/dnote/note.rb +57 -0
- data/lib/dnote/notes.rb +158 -97
- data/lib/dnote/session.rb +277 -0
- data/lib/dnote/templates/html.erb +4 -4
- data/lib/dnote/templates/html/file.erb +40 -0
- data/lib/dnote/templates/html/label.erb +41 -0
- data/lib/dnote/templates/html/list.erb +33 -0
- data/lib/dnote/templates/json.erb +8 -0
- data/lib/dnote/templates/json/file.erb +8 -0
- data/lib/dnote/templates/json/label.erb +8 -0
- data/lib/dnote/templates/json/list.erb +8 -0
- data/lib/dnote/templates/md.erb +18 -0
- data/lib/dnote/templates/md/file.erb +13 -0
- data/lib/dnote/templates/md/label.erb +18 -0
- data/lib/dnote/templates/md/list.erb +9 -0
- data/lib/dnote/templates/rdoc.erb +3 -3
- data/lib/dnote/templates/rdoc/file.erb +9 -0
- data/lib/dnote/templates/rdoc/label.erb +11 -0
- data/lib/dnote/templates/rdoc/list.erb +6 -0
- data/lib/dnote/templates/soap.erb +4 -0
- data/lib/dnote/templates/soap/file.erb +4 -0
- data/lib/dnote/templates/soap/label.erb +4 -0
- data/lib/dnote/templates/soap/list.erb +4 -0
- data/lib/dnote/templates/text.erb +11 -0
- data/lib/dnote/templates/text/file.erb +10 -0
- data/lib/dnote/templates/text/label.erb +11 -0
- data/lib/dnote/templates/text/list.erb +7 -0
- data/lib/dnote/templates/xml.erb +6 -6
- data/lib/dnote/templates/xml/file.erb +15 -0
- data/lib/dnote/templates/xml/label.erb +15 -0
- data/lib/dnote/templates/xml/list.erb +6 -0
- data/lib/dnote/templates/xoxo.erb +4 -0
- data/lib/dnote/templates/xoxo/file.erb +4 -0
- data/lib/dnote/templates/xoxo/label.erb +4 -0
- data/lib/dnote/templates/xoxo/list.erb +6 -0
- data/lib/dnote/templates/yaml.erb +1 -0
- data/lib/dnote/templates/yaml/file.erb +1 -0
- data/lib/dnote/templates/yaml/label.erb +1 -0
- data/lib/dnote/templates/yaml/list.erb +1 -0
- data/lib/plugins/syckle/dnote.rb +35 -8
- data/meta/version +1 -1
- data/test/cases/notes_case.rb +20 -31
- metadata +44 -14
- data/MANIFEST +0 -33
- data/lib/dnote/command.rb +0 -134
- data/lib/dnote/site.rb +0 -140
- data/lib/dnote/templates/gnu.erb +0 -8
- data/lib/dnote/templates/markdown.erb +0 -17
data/HISTORY
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
= RELEASE HISTORY
|
2
2
|
|
3
|
+
== 1.2 / 2010-02-18
|
4
|
+
|
5
|
+
By request this release adds additional formats, allowing notes to be
|
6
|
+
sorted by filename as well a label. In addition, paths can now be
|
7
|
+
excluded from the search. To implement these changes it was necessary
|
8
|
+
to makes some significant under-the-hood adjustments, and this required
|
9
|
+
making some adjustments to the design of the templates and the
|
10
|
+
command-line interface.
|
11
|
+
|
12
|
+
If are using any of your own custom templates you will have to make
|
13
|
+
adjustments accordingly --which basically entails exchanging +notes.each+
|
14
|
+
for +notes.by_label_file.each+. Also, notice that the serialization formats
|
15
|
+
have changed accordingly to match the improved underlying model.
|
16
|
+
|
17
|
+
On the command-line, the format type itself is no longer used as the
|
18
|
+
option name, e.g. "--yaml", but instead use "-f", e.g. "-f yaml". This
|
19
|
+
opens DNote up to many more templates. Use "-T" to get a list of all
|
20
|
+
template format available.
|
21
|
+
|
22
|
+
Changes:
|
23
|
+
|
24
|
+
* Improve underlying model by adding a Note class.
|
25
|
+
* Add --exclude and --ignore options.
|
26
|
+
* Add new formats and rename "gnu" formats to "text".
|
27
|
+
* Use --format/-f to designate formats.
|
28
|
+
* Renamed --template/-t option to --custom/-c.
|
29
|
+
* Add --templates/-T to list all format templates.
|
30
|
+
|
31
|
+
|
3
32
|
== 1.1 / 2010-02-06
|
4
33
|
|
5
34
|
This relase primarily adjusts the way output it rendered
|
data/bin/dnote
CHANGED
data/lib/dnote.rb
CHANGED
data/lib/dnote/format.rb
CHANGED
@@ -24,6 +24,9 @@ module DNote
|
|
24
24
|
#
|
25
25
|
attr_accessor :format
|
26
26
|
|
27
|
+
#
|
28
|
+
attr_accessor :subtype
|
29
|
+
|
27
30
|
#
|
28
31
|
attr_accessor :output
|
29
32
|
|
@@ -38,12 +41,12 @@ module DNote
|
|
38
41
|
|
39
42
|
#
|
40
43
|
def initialize(notes, options={})
|
41
|
-
@notes
|
42
|
-
@format
|
43
|
-
@
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
@notes = notes
|
45
|
+
@format = 'text'
|
46
|
+
@subtype = 'label'
|
47
|
+
@title = "Developer's Notes"
|
48
|
+
options.each{ |k,v| __send__("#{k}=", v) if v }
|
49
|
+
yield(self) if block_given?
|
47
50
|
end
|
48
51
|
|
49
52
|
#
|
@@ -51,78 +54,32 @@ module DNote
|
|
51
54
|
if notes.empty?
|
52
55
|
$stderr << "No #{notes.labels.join(', ')} notes.\n"
|
53
56
|
else
|
54
|
-
|
55
|
-
|
57
|
+
case format
|
58
|
+
when 'custom'
|
59
|
+
render_custom
|
60
|
+
else
|
61
|
+
render_template
|
62
|
+
end
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
|
-
#
|
60
|
-
|
61
|
-
def render_yaml
|
62
|
-
result = notes.to_yaml
|
63
|
-
publish(result)
|
64
|
-
end
|
65
|
-
|
66
|
-
def render_json
|
67
|
-
result = notes.to_json
|
68
|
-
publish(result)
|
69
|
-
end
|
70
|
-
|
71
|
-
# M L M A R K U P
|
72
|
-
|
73
|
-
def render_soap
|
74
|
-
result = notes.to_soap
|
75
|
-
publish(result)
|
76
|
-
end
|
77
|
-
|
78
|
-
def render_xoxo
|
79
|
-
result = notes.to_xoxo
|
80
|
-
publish(result)
|
81
|
-
end
|
82
|
-
|
83
|
-
def render_xml
|
84
|
-
template = File.join(File.dirname(__FILE__), 'templates/xml.erb')
|
85
|
-
result = erb(template)
|
86
|
-
publish(result)
|
87
|
-
end
|
88
|
-
|
89
|
-
def render_html
|
90
|
-
template = File.join(File.dirname(__FILE__), 'templates/html.erb')
|
91
|
-
result = erb(template)
|
92
|
-
publish(result)
|
93
|
-
end
|
94
|
-
|
95
|
-
def render_index
|
96
|
-
template = File.join(File.dirname(__FILE__), 'templates/html.erb')
|
97
|
-
result = erb(template)
|
98
|
-
publish(result, 'index.html')
|
99
|
-
end
|
100
|
-
|
101
|
-
# W I K I M A R K U P
|
102
|
-
|
103
|
-
def render_gnu
|
104
|
-
template = File.join(File.dirname(__FILE__), 'templates/gnu.erb')
|
105
|
-
result = erb(template)
|
106
|
-
publish(result)
|
107
|
-
end
|
66
|
+
# C U S T O M
|
108
67
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
publish(result)
|
113
|
-
end
|
114
|
-
|
115
|
-
def render_markdown
|
116
|
-
template = File.join(File.dirname(__FILE__), 'templates/markdown.erb')
|
68
|
+
#
|
69
|
+
def render_custom
|
70
|
+
#raise ArgumentError unless File.exist?(template)
|
117
71
|
result = erb(template)
|
118
|
-
publish(result)
|
72
|
+
publish(result)
|
119
73
|
end
|
120
74
|
|
121
|
-
#
|
75
|
+
# T E M P L A T E
|
122
76
|
|
123
|
-
|
77
|
+
#
|
78
|
+
def render_template
|
79
|
+
template = File.join(File.dirname(__FILE__), 'templates', "#{format}.erb")
|
80
|
+
raise "No such format - #{format}" unless File.exist?(template)
|
124
81
|
result = erb(template)
|
125
|
-
publish(result)
|
82
|
+
publish(result)
|
126
83
|
end
|
127
84
|
|
128
85
|
private
|
data/lib/dnote/note.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module DNote
|
2
|
+
|
3
|
+
#
|
4
|
+
class Note
|
5
|
+
attr :file
|
6
|
+
attr :label
|
7
|
+
attr :line
|
8
|
+
attr :text
|
9
|
+
|
10
|
+
def initialize(file, label, line, text)
|
11
|
+
@file = file
|
12
|
+
@label = label
|
13
|
+
@line = line
|
14
|
+
@text = text.rstrip
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
def to_s
|
19
|
+
"#{label}: #{text}"
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
def to_str
|
24
|
+
"#{label}: #{text}"
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
def textline
|
29
|
+
text.gsub("\n", " ")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sort by file name and line number.
|
33
|
+
def <=>(other)
|
34
|
+
s = file <=> other.file
|
35
|
+
return s unless s == 0
|
36
|
+
line <=> other.line
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_h
|
40
|
+
{ 'label'=>label, 'text'=>textline, 'file'=>file, 'line'=>line }
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_h_raw
|
44
|
+
{ 'label'=>label, 'text'=>text, 'file'=>file, 'line'=>line }
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_json(*args)
|
48
|
+
to_h_raw.to_json(*args)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_yaml(*args)
|
52
|
+
to_h_raw.to_yaml(*args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
data/lib/dnote/notes.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
require 'pathname'
|
2
|
+
require 'dnote/note'
|
2
3
|
|
3
4
|
module DNote
|
4
5
|
|
5
6
|
# = Developer Notes
|
6
7
|
#
|
7
8
|
# This class goes through you source files and compiles a list
|
8
|
-
# of any labeled comments. Labels are single word prefixes
|
9
|
-
# a comment ending in a colon.
|
9
|
+
# of any labeled comments. Labels are all-cap single word prefixes
|
10
|
+
# to a comment ending in a colon.
|
10
11
|
#
|
11
|
-
#
|
12
|
-
# and DEPRECATE
|
12
|
+
# Special labels do require the colon. By default these are +TODO+,
|
13
|
+
# +FIXME+, +OPTIMIZE+ and +DEPRECATE+.
|
13
14
|
#
|
14
15
|
#--
|
15
16
|
# TODO: Add ability to read header notes. They often
|
@@ -21,59 +22,58 @@ module DNote
|
|
21
22
|
# Default paths (all ruby scripts).
|
22
23
|
DEFAULT_PATHS = ["**/*.rb"]
|
23
24
|
|
24
|
-
# Default note labels to look for in source code.
|
25
|
+
# Default note labels to look for in source code. (NOT CURRENTLY USED!)
|
25
26
|
DEFAULT_LABELS = ['TODO', 'FIXME', 'OPTIMIZE', 'DEPRECATE']
|
26
27
|
|
27
|
-
#
|
28
|
-
attr_accessor :
|
28
|
+
# Files to search for notes.
|
29
|
+
attr_accessor :files
|
29
30
|
|
30
|
-
# Labels to document. Defaults are: TODO
|
31
|
+
# Labels to document. Defaults are: +TODO+, +FIXME+, +OPTIMIZE+ and +DEPRECATE+.
|
31
32
|
attr_accessor :labels
|
32
33
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
# Require label colon? Default is +true+.
|
35
|
+
attr_accessor :colon
|
36
|
+
|
37
|
+
# New set of notes for give +files+ and optional special labels.
|
38
|
+
def initialize(files, options={})
|
39
|
+
@files = [files].flatten
|
40
|
+
@labels = [options[:labels]].flatten.compact
|
41
|
+
@colon = options[:colon].nil? ? true : options[:colon]
|
37
42
|
parse
|
38
43
|
end
|
39
44
|
|
40
|
-
#
|
45
|
+
# Array of notes.
|
41
46
|
def notes
|
42
47
|
@notes
|
43
48
|
end
|
44
49
|
|
45
|
-
#
|
50
|
+
# Notes counts by label.
|
46
51
|
def counts
|
47
|
-
@counts
|
52
|
+
@counts ||= (
|
53
|
+
h = {}
|
54
|
+
by_label.each do |label, notes|
|
55
|
+
h[label] = notes.size
|
56
|
+
end
|
57
|
+
h
|
58
|
+
)
|
48
59
|
end
|
49
60
|
|
50
|
-
#
|
61
|
+
# Iterate through notes.
|
51
62
|
def each(&block)
|
52
63
|
notes.each(&block)
|
53
64
|
end
|
54
65
|
|
55
|
-
#
|
66
|
+
# No notes?
|
56
67
|
def empty?
|
57
68
|
notes.empty?
|
58
69
|
end
|
59
70
|
|
60
|
-
#
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
when String
|
65
|
-
labels.split(/[:;,]/)
|
66
|
-
else
|
67
|
-
labels = [labels].flatten.compact.uniq.map{ |s| s.to_s }
|
68
|
-
end
|
69
|
-
)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Gather and count notes. This returns two elements,
|
73
|
-
# a hash in the form of label=>notes and a counts hash.
|
74
|
-
|
71
|
+
# Gather notes.
|
72
|
+
#--
|
73
|
+
# TODO: Play gold with Notes#parse.
|
74
|
+
#++
|
75
75
|
def parse
|
76
|
-
records
|
76
|
+
records = []
|
77
77
|
files.each do |fname|
|
78
78
|
next unless File.file?(fname)
|
79
79
|
#next unless fname =~ /\.rb$/ # TODO: should this be done?
|
@@ -81,13 +81,12 @@ module DNote
|
|
81
81
|
lineno, save, text = 0, nil, nil
|
82
82
|
while line = f.gets
|
83
83
|
lineno += 1
|
84
|
-
save =
|
84
|
+
save = match(line, lineno, fname)
|
85
85
|
if save
|
86
86
|
#file = fname
|
87
|
-
text = save
|
87
|
+
text = save.text
|
88
88
|
#save = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text}
|
89
89
|
records << save
|
90
|
-
counts[save['label']] += 1
|
91
90
|
else
|
92
91
|
if text
|
93
92
|
if line =~ /^\s*[#]{0,1}\s*$/ or line !~ /^\s*#/ or line =~ /^\s*#[+][+]/
|
@@ -105,98 +104,160 @@ module DNote
|
|
105
104
|
end
|
106
105
|
end
|
107
106
|
end
|
108
|
-
|
109
|
-
notes
|
110
|
-
#
|
111
|
-
@notes, @counts = notes, counts
|
107
|
+
|
108
|
+
@notes = records.sort
|
112
109
|
end
|
113
110
|
|
114
111
|
#
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
Dir.glob(path)
|
122
|
-
end
|
123
|
-
end.flatten.uniq
|
124
|
-
)
|
112
|
+
def match(line, lineno, file)
|
113
|
+
if labels.empty?
|
114
|
+
match_general(line, lineno, file)
|
115
|
+
else
|
116
|
+
match_special(line, lineno, file)
|
117
|
+
end
|
125
118
|
end
|
126
119
|
|
127
|
-
#
|
128
|
-
def
|
120
|
+
# Match special notes.
|
121
|
+
def match_special(line, lineno, file)
|
129
122
|
rec = nil
|
130
123
|
labels.each do |label|
|
131
|
-
if md =
|
124
|
+
if md = match_special_regex(label).match(line)
|
132
125
|
text = md[1]
|
133
|
-
rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text}
|
126
|
+
#rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text}
|
127
|
+
rec = Note.new(file, label, lineno, text)
|
134
128
|
end
|
135
129
|
end
|
136
|
-
|
130
|
+
rec
|
137
131
|
end
|
138
132
|
|
139
|
-
|
140
|
-
|
133
|
+
#--
|
134
|
+
# TODO: ruby-1.9.1-p378 reports: `match': invalid byte sequence in UTF-8
|
135
|
+
#++
|
136
|
+
def match_special_regex(label)
|
137
|
+
if colon
|
138
|
+
/\#\s*#{Regexp.escape(label)}[:]\s*(.*?)$/
|
139
|
+
else
|
140
|
+
/\#\s*#{Regexp.escape(label)}[:]?\s*(.*?)$/
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Match notes that are labeled with a colon.
|
145
|
+
def match_general(line, lineno, file)
|
141
146
|
rec = nil
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
147
|
+
if md = match_general_regex.match(line)
|
148
|
+
label, text = md[1], md[2]
|
149
|
+
#rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text}
|
150
|
+
rec = Note.new(file, label, lineno, text)
|
147
151
|
end
|
148
152
|
return rec
|
149
153
|
end
|
150
154
|
|
151
|
-
# Organize records in heirarchical form.
|
152
155
|
#
|
153
|
-
def
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
line = record['line']
|
159
|
-
note = record['note'].rstrip
|
160
|
-
orecs[label] ||= {}
|
161
|
-
orecs[label][file] ||= []
|
162
|
-
orecs[label][file] << [line, note]
|
156
|
+
def match_general_regex
|
157
|
+
if colon
|
158
|
+
/\#\s*([A-Z]+)[:]\s+(.*?)$/
|
159
|
+
else
|
160
|
+
/\#\s*([A-Z]+)[:]?\s+(.*?)$/
|
163
161
|
end
|
164
|
-
orecs
|
165
162
|
end
|
166
163
|
|
167
|
-
#
|
168
|
-
def
|
169
|
-
|
164
|
+
# Organize notes into a hash with labels for keys.
|
165
|
+
def by_label
|
166
|
+
@by_label ||= (
|
167
|
+
list = {}
|
168
|
+
notes.each do |note|
|
169
|
+
list[note.label] ||= []
|
170
|
+
list[note.label] << note
|
171
|
+
list[note.label].sort #!{ |a,b| a.line <=> b.line }
|
172
|
+
end
|
173
|
+
list
|
174
|
+
)
|
170
175
|
end
|
171
176
|
|
172
|
-
#
|
173
|
-
def
|
174
|
-
|
175
|
-
|
177
|
+
# Organize notes into a hash with filename for keys.
|
178
|
+
def by_file
|
179
|
+
@by_file ||= (
|
180
|
+
list = {}
|
181
|
+
notes.each do |note|
|
182
|
+
list[note.file] ||= []
|
183
|
+
list[note.file] << note
|
184
|
+
list[note.file].sort! #!{ |a,b| a.line <=> b.line }
|
185
|
+
end
|
186
|
+
list
|
187
|
+
)
|
176
188
|
end
|
177
189
|
|
178
|
-
#
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
190
|
+
# Organize notes into a hash with labels for keys, followed
|
191
|
+
# by a hash with filename for keys.
|
192
|
+
def by_label_file
|
193
|
+
@by_label ||= (
|
194
|
+
list = {}
|
195
|
+
notes.each do |note|
|
196
|
+
list[note.label] ||= {}
|
197
|
+
list[note.label][note.file] ||= []
|
198
|
+
list[note.label][note.file] << note
|
199
|
+
list[note.label][note.file].sort! #{ |a,b| a.line <=> b.line }
|
200
|
+
end
|
201
|
+
list
|
202
|
+
)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Organize notes into a hash with filenames for keys, followed
|
206
|
+
# by a hash with labels for keys.
|
207
|
+
def by_file_label
|
208
|
+
@by_file ||= (
|
209
|
+
list = {}
|
210
|
+
notes.each do |note|
|
211
|
+
list[note.file] ||= {}
|
212
|
+
list[note.file][note.label] ||= []
|
213
|
+
list[note.file][note.label] << note
|
214
|
+
list[note.file][note.label].sort! #{ |a,b| a.line <=> b.line }
|
215
|
+
end
|
216
|
+
list
|
217
|
+
)
|
186
218
|
end
|
187
219
|
|
188
|
-
#
|
189
|
-
def
|
190
|
-
|
191
|
-
SOAP::Marshal.marshal(notes)
|
220
|
+
# Convert to an array of hashes.
|
221
|
+
def to_a
|
222
|
+
notes.map{ |n| n.to_h }
|
192
223
|
end
|
193
224
|
|
194
|
-
#
|
195
|
-
def
|
196
|
-
|
197
|
-
notes.to_xoxo
|
225
|
+
# Same as #by_label.
|
226
|
+
def to_h
|
227
|
+
by_label
|
198
228
|
end
|
199
229
|
|
230
|
+
# Convert to array of hashes then to YAML.
|
231
|
+
#def to_yaml
|
232
|
+
# require 'yaml'
|
233
|
+
# to_a.to_yaml
|
234
|
+
#end
|
235
|
+
|
236
|
+
# Convert to array of hashes then to JSON.
|
237
|
+
#def to_json
|
238
|
+
# begin
|
239
|
+
# require 'json'
|
240
|
+
# rescue LoadError
|
241
|
+
# require 'json_pure'
|
242
|
+
# end
|
243
|
+
# to_a.to_json
|
244
|
+
#end
|
245
|
+
|
246
|
+
# Convert to array of hashes then to a SOAP XML envelope.
|
247
|
+
#def to_soap
|
248
|
+
# require 'soap/marshal'
|
249
|
+
# SOAP::Marshal.marshal(to_a)
|
250
|
+
#end
|
251
|
+
|
252
|
+
# XOXO microformat.
|
253
|
+
#--
|
254
|
+
# TODO: Would to_xoxo be better organized by label and or file?
|
255
|
+
#++
|
256
|
+
#def to_xoxo
|
257
|
+
# require 'xoxo'
|
258
|
+
# to_a.to_xoxo
|
259
|
+
#end
|
260
|
+
|
200
261
|
end
|
201
262
|
|
202
263
|
end
|