mvz-dnote 1.7.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/COPYING.rdoc +31 -0
- data/HISTORY.rdoc +171 -0
- data/README.rdoc +113 -0
- data/bin/dnote +4 -0
- data/lib/dnote.rb +4 -0
- data/lib/dnote.yml +1 -0
- data/lib/dnote/core_ext.rb +92 -0
- data/lib/dnote/format.rb +173 -0
- data/lib/dnote/note.rb +150 -0
- data/lib/dnote/notes.rb +320 -0
- data/lib/dnote/rake/dnotetask.rb +116 -0
- data/lib/dnote/session.rb +269 -0
- data/lib/dnote/templates/html.erb +49 -0
- data/lib/dnote/templates/html/file.erb +48 -0
- data/lib/dnote/templates/html/label.erb +49 -0
- data/lib/dnote/templates/html/list.erb +42 -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 +19 -0
- data/lib/dnote/templates/md/file.erb +14 -0
- data/lib/dnote/templates/md/label.erb +19 -0
- data/lib/dnote/templates/md/list.erb +10 -0
- data/lib/dnote/templates/rdoc.erb +12 -0
- data/lib/dnote/templates/rdoc/file.erb +10 -0
- data/lib/dnote/templates/rdoc/label.erb +12 -0
- data/lib/dnote/templates/rdoc/list.erb +7 -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 +12 -0
- data/lib/dnote/templates/text/file.erb +11 -0
- data/lib/dnote/templates/text/label.erb +11 -0
- data/lib/dnote/templates/text/list.erb +8 -0
- data/lib/dnote/templates/xml.erb +23 -0
- data/lib/dnote/templates/xml/file.erb +23 -0
- data/lib/dnote/templates/xml/label.erb +23 -0
- data/lib/dnote/templates/xml/list.erb +14 -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/dnote/version.rb +17 -0
- data/test/notes_case.rb +59 -0
- data/try/sample.bas +7 -0
- data/try/sample.js +11 -0
- data/try/sample.rb +11 -0
- metadata +131 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
module DNote
|
2
|
+
|
3
|
+
# = Developmer's Notes Rake Task
|
4
|
+
#
|
5
|
+
class RakeTask < Rake::TaskLib
|
6
|
+
|
7
|
+
require 'rake/clean'
|
8
|
+
|
9
|
+
# Default note labels to looked for in source code.
|
10
|
+
DEFAULT_LABELS = ['TODO', 'FIXME', 'OPTIMIZE', 'DEPRECATE']
|
11
|
+
|
12
|
+
# File paths to search.
|
13
|
+
attr_accessor :files
|
14
|
+
|
15
|
+
# Labels to document. Defaults are: TODO, FIXME, OPTIMIZE and DEPRECATE.
|
16
|
+
attr_accessor :labels
|
17
|
+
|
18
|
+
# Formats (xml, html, rdoc, rdoc/list and so on).
|
19
|
+
attr_accessor :formats
|
20
|
+
|
21
|
+
# Exclude paths.
|
22
|
+
attr_accessor :exclude
|
23
|
+
|
24
|
+
# Ignore paths based on any part of pathname.
|
25
|
+
attr_accessor :ignore
|
26
|
+
|
27
|
+
# Output directory to save notes file. Defaults to <tt>dnote/</tt> under
|
28
|
+
# the project log directory (eg. <tt>log/dnote/</tt>).
|
29
|
+
attr_accessor :output
|
30
|
+
|
31
|
+
# Title to use if temaplte can use it.
|
32
|
+
attr_accessor :title
|
33
|
+
|
34
|
+
#
|
35
|
+
def output=(path)
|
36
|
+
@output = Pathname.new(path)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
def init
|
41
|
+
require 'dnote'
|
42
|
+
require 'dnote/format'
|
43
|
+
@files = "**/*.rb"
|
44
|
+
@output = 'log/dnote'
|
45
|
+
@formats = ['index']
|
46
|
+
@labels = nil #DEFAULT_LABELS
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
def define
|
51
|
+
desc "Collect Developer's Notes"
|
52
|
+
task 'dnote' do
|
53
|
+
document
|
54
|
+
end
|
55
|
+
task 'dnote:clobber' do
|
56
|
+
clean
|
57
|
+
end
|
58
|
+
task :clobber => ['dnote:clobber']
|
59
|
+
end
|
60
|
+
|
61
|
+
# Generate notes document(s).
|
62
|
+
def document
|
63
|
+
abort "dnote: #{output} is not a directory" unless output.directory?
|
64
|
+
|
65
|
+
session = ::DNote::Session.new do |s|
|
66
|
+
s.paths = files
|
67
|
+
s.exclude = exclude
|
68
|
+
s.ignore = ignore
|
69
|
+
s.labels = labels #|| DEFAULT_LABELS
|
70
|
+
s.title = title
|
71
|
+
s.output = output
|
72
|
+
s.dryrun = application.options.dryrun #trial?
|
73
|
+
end
|
74
|
+
|
75
|
+
formats.each do |format|
|
76
|
+
if format == 'index'
|
77
|
+
session.format = 'html'
|
78
|
+
session.output = File.join(self.output, 'index.html')
|
79
|
+
else
|
80
|
+
session.format = format
|
81
|
+
end
|
82
|
+
session.run
|
83
|
+
report "Updated #{output.to_s.sub(Dir.pwd+'/','')}" unless trial?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reset output directory, marking it as out-of-date.
|
88
|
+
def reset
|
89
|
+
#if File.directory?(output)
|
90
|
+
File.utime(0,0,output) unless $NOOP
|
91
|
+
puts "Marked #{output} as out-of-date"
|
92
|
+
#end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Remove output files.
|
96
|
+
def clean
|
97
|
+
#if File.directory?(output)
|
98
|
+
formats.each do |format|
|
99
|
+
if format == 'index'
|
100
|
+
file = (output + "index.html").to_s
|
101
|
+
else
|
102
|
+
ext = ::DNote::Format::EXTENSIONS[format] || format
|
103
|
+
file = (output + "notes.#{ext}").to_s
|
104
|
+
end
|
105
|
+
rm(file)
|
106
|
+
report "Removed #{output}"
|
107
|
+
end
|
108
|
+
#else
|
109
|
+
# rm(output)
|
110
|
+
# report "Removed #{output}"
|
111
|
+
#end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
module DNote
|
2
|
+
|
3
|
+
require 'dnote/core_ext'
|
4
|
+
require 'dnote/notes'
|
5
|
+
require 'dnote/format'
|
6
|
+
|
7
|
+
# User session which is used by commandline interface.
|
8
|
+
#
|
9
|
+
# By making this a class it makes it easy for external
|
10
|
+
# libraries to use this library just as if they were
|
11
|
+
# calling the commandline, but without the need to shellout.
|
12
|
+
#
|
13
|
+
class Session
|
14
|
+
|
15
|
+
# Directory relative to this script. This is used
|
16
|
+
# to lookup the available format templates.
|
17
|
+
DIR = File.dirname(__FILE__)
|
18
|
+
|
19
|
+
# Default format.
|
20
|
+
DEFAULT_FORMAT = "text"
|
21
|
+
|
22
|
+
# Default title.
|
23
|
+
DEFAULT_TITLE = "Developer's Notes"
|
24
|
+
|
25
|
+
# Paths to include.
|
26
|
+
attr_accessor :paths
|
27
|
+
|
28
|
+
# Paths to exclude (match by pathname).
|
29
|
+
attr_reader :exclude
|
30
|
+
|
31
|
+
# Paths to ignore (match by basename).
|
32
|
+
attr_reader :ignore
|
33
|
+
|
34
|
+
# Labels to lookup.
|
35
|
+
# By default these are TODO, FIXME and OPTIMIZE.
|
36
|
+
attr_accessor :labels
|
37
|
+
|
38
|
+
# Selected labels can optionally do without the colon.
|
39
|
+
attr_accessor :colon
|
40
|
+
|
41
|
+
# Alternate remark marker. Useful to other languages besides Ruby.
|
42
|
+
attr_accessor :marker
|
43
|
+
|
44
|
+
# Output format.
|
45
|
+
attr_accessor :format
|
46
|
+
|
47
|
+
# If custom format, specify template file.
|
48
|
+
attr_accessor :template
|
49
|
+
|
50
|
+
# Some format put a title at the top of the output.
|
51
|
+
# The default is "Developer's Notes".
|
52
|
+
attr_accessor :title
|
53
|
+
|
54
|
+
# Output to a file instead of STDOUT.
|
55
|
+
attr_accessor :output
|
56
|
+
|
57
|
+
# If output path given, don't actually write to disk.
|
58
|
+
attr_accessor :dryrun
|
59
|
+
|
60
|
+
# String template for line URLs (mainly for HTML format). For example,
|
61
|
+
# DNote uses GitHub so we could use a link template:
|
62
|
+
#
|
63
|
+
# "https://github.com/rubyworks/dnote/blob/master/%s#L%s"
|
64
|
+
#
|
65
|
+
attr_accessor :url
|
66
|
+
|
67
|
+
# Number of lines of context to display. The default is zero.
|
68
|
+
attr_accessor :context
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# New Session.
|
73
|
+
def initialize(options={})
|
74
|
+
options ||= {}
|
75
|
+
initialize_defaults
|
76
|
+
options.each{ |k,v| __send__("#{k}=", v) }
|
77
|
+
yield(self) if block_given?
|
78
|
+
end
|
79
|
+
|
80
|
+
# Set default values for attributes.
|
81
|
+
def initialize_defaults
|
82
|
+
@paths = []
|
83
|
+
@labels = []
|
84
|
+
@exclude = []
|
85
|
+
@ignore = []
|
86
|
+
@format = DEFAULT_FORMAT
|
87
|
+
@title = DEFAULT_TITLE
|
88
|
+
@dryrun = false
|
89
|
+
@marker = nil
|
90
|
+
@url = nil
|
91
|
+
@context = 0
|
92
|
+
end
|
93
|
+
|
94
|
+
public
|
95
|
+
|
96
|
+
# Set exclude list ensuring that the value is an array.
|
97
|
+
def exclude=(list)
|
98
|
+
@exclude = [list].compact.flatten.compact
|
99
|
+
end
|
100
|
+
|
101
|
+
# Set ignore list ensuring that the value is an array.
|
102
|
+
def ignore=(list)
|
103
|
+
@ignore = [list].compact.flatten.compact
|
104
|
+
end
|
105
|
+
|
106
|
+
# Run session.
|
107
|
+
def run
|
108
|
+
notes = Notes.new(files, :labels=>labels, :colon=>colon, :marker=>marker, :url=>url, :context=>context)
|
109
|
+
formatter = Format.new(notes) do |f|
|
110
|
+
f.format = format
|
111
|
+
f.template = template
|
112
|
+
f.title = title
|
113
|
+
f.output = output
|
114
|
+
end
|
115
|
+
formatter.render
|
116
|
+
end
|
117
|
+
|
118
|
+
# Collect path globs and remove exclusions.
|
119
|
+
# This method uses #paths, #exclude and #ignore to
|
120
|
+
# compile the list of files.
|
121
|
+
def files
|
122
|
+
list = [paths].flatten.compact
|
123
|
+
list = ['**/*.rb'] if list.empty?
|
124
|
+
list = glob(list)
|
125
|
+
list = list - glob(exclude)
|
126
|
+
list.reject do |path|
|
127
|
+
path.split('/').any?{ |part| ignore.any?{ |ig| File.fnmatch?(ig, part) } }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Collect the file glob of each path given. If
|
132
|
+
# a path is a directory, inclue all content.
|
133
|
+
def glob(paths)
|
134
|
+
paths.map do |path|
|
135
|
+
if File.directory?(path)
|
136
|
+
Dir.glob(File.join(path, '**/*'))
|
137
|
+
else
|
138
|
+
Dir.glob(path)
|
139
|
+
end
|
140
|
+
end.flatten.uniq
|
141
|
+
end
|
142
|
+
|
143
|
+
# Set special labels.
|
144
|
+
#def labels=(labels)
|
145
|
+
# @labels = (
|
146
|
+
# case labels
|
147
|
+
# when String
|
148
|
+
# labels.split(/[:;,]/)
|
149
|
+
# else
|
150
|
+
# labels = [labels].flatten.compact.uniq.map{ |s| s.to_s }
|
151
|
+
# end
|
152
|
+
# )
|
153
|
+
#end
|
154
|
+
|
155
|
+
# Commandline interface.
|
156
|
+
def self.main(*argv)
|
157
|
+
require 'optparse'
|
158
|
+
|
159
|
+
session = Session.new
|
160
|
+
|
161
|
+
opts = OptionParser.new do |opt|
|
162
|
+
opt.banner = "DNote v#{DNote::VERSION}"
|
163
|
+
|
164
|
+
opt.separator(" ")
|
165
|
+
opt.separator("USAGE:\n dnote [OPTIONS] path1 [path2 ...]")
|
166
|
+
|
167
|
+
opt.separator(" ")
|
168
|
+
opt.separator("OUTPUT FORMAT: (choose one)")
|
169
|
+
|
170
|
+
opt.on("--format", "-f NAME", "select a format [text]") do |format|
|
171
|
+
session.format = format
|
172
|
+
end
|
173
|
+
|
174
|
+
opt.on("--custom", "-C FILE", "use a custom ERB template") do |file|
|
175
|
+
session.format = 'custom'
|
176
|
+
session.template = file
|
177
|
+
end
|
178
|
+
|
179
|
+
opt.on("--file", "shortcut for text/file format") do
|
180
|
+
session.format = 'text/file'
|
181
|
+
end
|
182
|
+
|
183
|
+
opt.on("--list", "shortcut for text/list format") do
|
184
|
+
session.format = 'text/list'
|
185
|
+
end
|
186
|
+
|
187
|
+
opt.separator(" ")
|
188
|
+
opt.separator("OTHER OPTIONS:")
|
189
|
+
|
190
|
+
opt.on("--label", "-l LABEL", "labels to collect") do |lbl|
|
191
|
+
session.labels.concat(lbl.split(':'))
|
192
|
+
end
|
193
|
+
|
194
|
+
opt.on("--[no-]colon", "match labels with/without colon suffix") do |val|
|
195
|
+
session.colon = val
|
196
|
+
end
|
197
|
+
|
198
|
+
opt.on("--marker", "-m MARK", "alternative remark marker") do |mark|
|
199
|
+
session.marker = mark
|
200
|
+
end
|
201
|
+
|
202
|
+
opt.on("--url", "-u TEMPLATE", "url template for line entries (for HTML)") do |url|
|
203
|
+
session.url = url
|
204
|
+
end
|
205
|
+
|
206
|
+
opt.on("--context", "-c INTEGER", "number of lines of context to display") do |int|
|
207
|
+
session.context = int.to_i
|
208
|
+
end
|
209
|
+
|
210
|
+
opt.on("--exclude", "-x PATH", "exclude file or directory") do |path|
|
211
|
+
session.exclude << path
|
212
|
+
end
|
213
|
+
|
214
|
+
opt.on("--ignore", "-i NAME", "ignore file based on any part of pathname") do |name|
|
215
|
+
session.ignore << name
|
216
|
+
end
|
217
|
+
|
218
|
+
opt.on("--title", "-t TITLE", "title to use in header") do |title|
|
219
|
+
session.title = title
|
220
|
+
end
|
221
|
+
|
222
|
+
opt.on("--output", "-o PATH", "save to file or directory") do |path|
|
223
|
+
session.output = path
|
224
|
+
end
|
225
|
+
|
226
|
+
opt.on("--dryrun", "-n", "do not actually write to disk") do
|
227
|
+
session.dryrun = true
|
228
|
+
end
|
229
|
+
|
230
|
+
opt.on("--debug", "debug mode") do
|
231
|
+
$DEBUG = true
|
232
|
+
$VERBOSE = true
|
233
|
+
end
|
234
|
+
|
235
|
+
opt.separator(" ")
|
236
|
+
opt.separator("COMMAND OPTIONS:")
|
237
|
+
|
238
|
+
opt.on_tail('--templates', "-T", "list available format templates") do
|
239
|
+
tdir = File.join(DIR, 'templates')
|
240
|
+
tfiles = Dir[File.join(tdir, '**/*.erb')]
|
241
|
+
tnames = tfiles.map{ |tname| tname.sub(tdir+'/', '').chomp('.erb') }
|
242
|
+
groups = tnames.group_by{ |tname| tname.split('/').first }
|
243
|
+
groups.sort.each do |(type, names)|
|
244
|
+
puts("%-18s " * names.size % names.sort)
|
245
|
+
end
|
246
|
+
exit
|
247
|
+
end
|
248
|
+
|
249
|
+
opt.on_tail('--help', '-h', "show this help information") do
|
250
|
+
puts opt
|
251
|
+
exit
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
begin
|
256
|
+
opts.parse!(argv)
|
257
|
+
session.paths.replace(argv)
|
258
|
+
session.run
|
259
|
+
rescue => err
|
260
|
+
raise err if $DEBUG
|
261
|
+
puts err
|
262
|
+
exit 1
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title><%= title %></title>
|
4
|
+
<style>
|
5
|
+
body { margin: 0; padding: 0; font-size: 0.8em; }
|
6
|
+
.main {
|
7
|
+
width: 800px;
|
8
|
+
margin: 0 auto;
|
9
|
+
border: 0px solid #ccc;
|
10
|
+
padding: 0 20px 20px 20px;
|
11
|
+
}
|
12
|
+
h1 { margin: 25px 0; font-size: 3em; }
|
13
|
+
h2,h3,h4 { margin: 5px 0; padding: 0; color: #444; }
|
14
|
+
h2 { letter-spacing: 2px; border-top: 4px solid #ddd; padding: 5px 0; }
|
15
|
+
ul { margin: 0; padding: 0; text-align: left; }
|
16
|
+
li { margin: 0; padding: 0; text-align: left; }
|
17
|
+
a { color: #4488ff; }
|
18
|
+
sup { font-size: 0.8em; }
|
19
|
+
</style>
|
20
|
+
<link rel="stylesheet" href="notes.css" type="text/css">
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
<div class="main">
|
24
|
+
<h1><%= title %></h1>
|
25
|
+
<div class="notes">
|
26
|
+
<% notes.by_label_file.each do |label, per_file| %>
|
27
|
+
<h2 class="<%= label %>"><%= label %></h2>
|
28
|
+
<ol class="set <%= label.downcase %>">
|
29
|
+
<% per_file.each do |file, line_notes| %>
|
30
|
+
<li><h3><a href="<%= file %>"><%= file %></a></h3><ol class="file" href="<%= file %>">
|
31
|
+
<% line_notes.sort!{ |a,b| a.line <=> b.line } %>
|
32
|
+
<% line_notes.each do |note| %>
|
33
|
+
<li class="note <%= label.downcase %>" ref="<%= note.line %>">
|
34
|
+
<%= h note.text %> <sup><a href="<%= note.url %>"><%= note.line %></a></sup>
|
35
|
+
<% if note.code? %>
|
36
|
+
<pre>
|
37
|
+
<%= note.code %>
|
38
|
+
</pre>
|
39
|
+
<% end %>
|
40
|
+
</li>
|
41
|
+
<% end %>
|
42
|
+
</ol></li>
|
43
|
+
<% end %>
|
44
|
+
</ol>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
</body>
|
49
|
+
</html>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title><%= title %></title>
|
4
|
+
<style>
|
5
|
+
body { margin: 0; padding: 0; font-size: 0.8em; }
|
6
|
+
.main {
|
7
|
+
width: 800px;
|
8
|
+
margin: 0 auto;
|
9
|
+
border: 0px solid #ccc;
|
10
|
+
padding: 0 20px 20px 20px;
|
11
|
+
}
|
12
|
+
h1 { margin: 25px 0; font-size: 3em; }
|
13
|
+
h2,h3,h4 { margin: 5px 0; padding: 0; color: #444; }
|
14
|
+
h2 { letter-spacing: 2px; border-top: 4px solid #ddd; padding: 5px 0; }
|
15
|
+
ul { margin: 0; padding: 0; text-align: left; }
|
16
|
+
li { margin: 0; padding: 0; text-align: left; }
|
17
|
+
a { color: #4488ff; }
|
18
|
+
sup { font-size: 0.8em; }
|
19
|
+
</style>
|
20
|
+
<link rel="stylesheet" href="notes.css" type="text/css">
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
<div class="main">
|
24
|
+
<h1><%= title %></h1>
|
25
|
+
<div class="notes">
|
26
|
+
<% notes.by_file_label.each do |file, per_label| %>
|
27
|
+
<h2><a href="<%= file %>"><%= file %></a></h2>
|
28
|
+
<ol class="file">
|
29
|
+
<% per_label.each do |label, lnotes| %>
|
30
|
+
<li><h3><%= label %></h3><ol class="label">
|
31
|
+
<% lnotes.each do |note| %>
|
32
|
+
<li class="note <%= label.downcase %>" ref="<%= note.line %>">
|
33
|
+
<%= h note.textline %> <sup><a href="<%= note.url %>"><%= note.line %></a></sup>
|
34
|
+
<% if note.code? %>
|
35
|
+
<pre>
|
36
|
+
<%= note.code %>
|
37
|
+
</pre>
|
38
|
+
<% end %>
|
39
|
+
</li>
|
40
|
+
<% end %>
|
41
|
+
</ol></li>
|
42
|
+
<% end %>
|
43
|
+
</ol>
|
44
|
+
<% end %>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</body>
|
48
|
+
</html>
|