dnote 1.4.0 → 1.6.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.
@@ -34,16 +34,26 @@ module DNote
34
34
  # Require label colon? Default is +true+.
35
35
  attr_accessor :colon
36
36
 
37
- # Alternate remark marker. Default is '#'.
37
+ # Specific remark marker (+nil+ for auto).
38
38
  attr_accessor :marker
39
39
 
40
+ # Link template.
41
+ attr_accessor :url
42
+
43
+ # Number of lines of context to show.
44
+ attr_accessor :context
45
+
40
46
  # New set of notes for give +files+ and optional special labels.
41
47
  def initialize(files, options={})
42
- @files = [files].flatten
43
- @labels = [options[:labels] || DEFAULT_LABELS].flatten.compact
44
- @colon = options[:colon].nil? ? true : options[:colon]
45
- @marker = options[:marker] #|| '#'
46
- @remark = {}
48
+ @files = [files].flatten
49
+ @labels = [options[:labels] || DEFAULT_LABELS].flatten.compact
50
+ @colon = options[:colon].nil? ? true : options[:colon]
51
+ @marker = options[:marker] #|| '#'
52
+ @url = options[:url]
53
+ @context = options[:context] || 0
54
+
55
+ @remark = {}
56
+
47
57
  parse
48
58
  end
49
59
 
@@ -75,7 +85,7 @@ module DNote
75
85
 
76
86
  # Gather notes.
77
87
  #--
78
- # TODO: Play gold with Notes#parse.
88
+ # TODO: Play golf with Notes#parse.
79
89
  #++
80
90
  def parse
81
91
  records = []
@@ -83,39 +93,47 @@ module DNote
83
93
  next unless File.file?(fname)
84
94
  #next unless fname =~ /\.rb$/ # TODO: should this be done?
85
95
  mark = remark(fname)
86
- File.open(fname) do |f|
87
- lineno, save, text = 0, nil, nil
88
- while line = f.gets
96
+ lineno, note, text, capt = 0, nil, nil, nil
97
+ File.readlines(fname).each do |line|
98
+ #while line = f.gets
89
99
  lineno += 1
90
- save = match(line, lineno, fname)
91
- if save
100
+ note = match(line, lineno, fname)
101
+ if note
92
102
  #file = fname
93
- text = save.text
94
- #save = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text}
95
- records << save
103
+ text = note.text
104
+ capt = note.capture
105
+ #note = {'label'=>label,'file'=>file,'line'=>line_no,'note'=>text}
106
+ records << note
96
107
  else
97
108
  if text
98
109
  case line
99
- when /^\s*#{mark}+\s*$/, /(?!^\s*#{mark})/, /^\s*#{mark}[+][+]/
110
+ when /^\s*#{mark}+\s*$/, /^\s*#{mark}\-\-/, /^\s*#{mark}\+\+/
100
111
  text.strip!
101
112
  text = nil
102
- else
113
+ when /^\s*#{mark}/
103
114
  if text[-1,1] == "\n"
104
115
  text << line.gsub(/^\s*#{mark}\s*/,'')
105
116
  else
106
117
  text << "\n" << line.gsub(/^\s*#{mark}\s*/,'')
107
118
  end
119
+ else
120
+ text.strip!
121
+ text = nil
122
+ end
123
+ else
124
+ if line !~ /^\s*#{mark}/
125
+ capt << line if capt && capt.size < context
108
126
  end
109
127
  end
110
128
  end
111
- end
129
+ #end
112
130
  end
113
131
  end
114
132
 
115
133
  @notes = records.sort
116
134
  end
117
135
 
118
- #
136
+ # Is this line a note?
119
137
  def match(line, lineno, file)
120
138
  if labels.empty?
121
139
  match_general(line, lineno, file)
@@ -131,7 +149,7 @@ module DNote
131
149
  if md = match_special_regex(label, file).match(line)
132
150
  text = md[1]
133
151
  #rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text}
134
- rec = Note.new(file, label, lineno, text)
152
+ rec = Note.new(self, file, label, lineno, text, remark(file))
135
153
  end
136
154
  end
137
155
  rec
@@ -143,9 +161,9 @@ module DNote
143
161
  def match_special_regex(label, file)
144
162
  mark = remark(file)
145
163
  if colon
146
- /#{mark}\s*#{Regexp.escape(label)}[:]\s*(.*?)$/
164
+ /#{mark}\s*#{Regexp.escape(label)}[:]\s+(.*?)$/
147
165
  else
148
- /#{mark}\s*#{Regexp.escape(label)}[:]?\s*(.*?)$/
166
+ /#{mark}\s*#{Regexp.escape(label)}[:]?\s+(.*?)$/
149
167
  end
150
168
  end
151
169
 
@@ -155,18 +173,19 @@ module DNote
155
173
  if md = match_general_regex(file).match(line)
156
174
  label, text = md[1], md[2]
157
175
  #rec = {'label'=>label,'file'=>file,'line'=>lineno,'note'=>text}
158
- rec = Note.new(file, label, lineno, text)
176
+ rec = Note.new(self, file, label, lineno, text, remark(file))
159
177
  end
160
178
  return rec
161
179
  end
162
180
 
163
- #
181
+ # Keep in mind that general non-colon matches have a higher potential
182
+ # of false positives.
164
183
  def match_general_regex(file)
165
184
  mark = remark(file)
166
185
  if colon
167
186
  /#{mark}\s*([A-Z]+)[:]\s+(.*?)$/
168
- else
169
- /#{mark}\s*([A-Z]+)[:]?\s+(.*?)$/
187
+ else
188
+ /#{mark}\s*([A-Z]+)\s+(.*?)$/
170
189
  end
171
190
  end
172
191
 
@@ -26,10 +26,10 @@ module DNote
26
26
  attr_accessor :paths
27
27
 
28
28
  # Paths to exclude (match by pathname).
29
- attr_accessor :exclude
29
+ attr_reader :exclude
30
30
 
31
31
  # Paths to ignore (match by basename).
32
- attr_accessor :ignore
32
+ attr_reader :ignore
33
33
 
34
34
  # Labels to lookup.
35
35
  # By default these are TODO, FIXME and OPTIMIZE.
@@ -57,6 +57,16 @@ module DNote
57
57
  # If output path given, don't actually write to disk.
58
58
  attr_accessor :dryrun
59
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
+
60
70
  private
61
71
 
62
72
  # New Session.
@@ -77,6 +87,8 @@ module DNote
77
87
  @title = DEFAULT_TITLE
78
88
  @dryrun = false
79
89
  @marker = nil
90
+ @url = nil
91
+ @context = 0
80
92
  end
81
93
 
82
94
  public
@@ -93,7 +105,7 @@ module DNote
93
105
 
94
106
  # Run session.
95
107
  def run
96
- notes = Notes.new(files, :labels=>labels, :colon=>colon, :marker=>marker)
108
+ notes = Notes.new(files, :labels=>labels, :colon=>colon, :marker=>marker, :url=>url, :context=>context)
97
109
  formatter = Format.new(notes) do |f|
98
110
  f.format = format
99
111
  f.template = template
@@ -147,7 +159,6 @@ module DNote
147
159
  session = Session.new
148
160
 
149
161
  opts = OptionParser.new do |opt|
150
-
151
162
  opt.banner = "DNote v#{DNote::VERSION}"
152
163
 
153
164
  opt.separator(" ")
@@ -184,10 +195,18 @@ module DNote
184
195
  session.colon = val
185
196
  end
186
197
 
187
- opt.on("--marker", '-m MARK', "Alternative remark marker") do |mark|
198
+ opt.on("--marker", "-m MARK", "alternative remark marker") do |mark|
188
199
  session.marker = mark
189
200
  end
190
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
+
191
210
  opt.on("--exclude", "-x PATH", "exclude file or directory") do |path|
192
211
  session.exclude << path
193
212
  end
@@ -222,7 +241,7 @@ module DNote
222
241
  tnames = tfiles.map{ |tname| tname.sub(tdir+'/', '').chomp('.erb') }
223
242
  groups = tnames.group_by{ |tname| tname.split('/').first }
224
243
  groups.sort.each do |(type, names)|
225
- puts("%-18s " * names.size) % names.sort
244
+ puts("%-18s " * names.size % names.sort)
226
245
  end
227
246
  exit
228
247
  end
@@ -2,19 +2,20 @@
2
2
  <head>
3
3
  <title><%= title %></title>
4
4
  <style>
5
- body { margin: 0; padding: 0; }
5
+ body { margin: 0; padding: 0; font-size: 0.8em; }
6
6
  .main {
7
7
  width: 800px;
8
8
  margin: 0 auto;
9
- border: 1px solid #ccc;
9
+ border: 0px solid #ccc;
10
10
  padding: 0 20px 20px 20px;
11
11
  }
12
- h1 { margin: 25px 0; }
13
- h2,h3,h4 { margin: 5px 0; padding: 0; color: 880044; }
14
- h3 { color: 004488; }
15
- h4 { color: 888844; }
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; }
16
15
  ul { margin: 0; padding: 0; text-align: left; }
17
16
  li { margin: 0; padding: 0; text-align: left; }
17
+ a { color: #4488ff; }
18
+ sup { font-size: 0.8em; }
18
19
  </style>
19
20
  <link rel="stylesheet" href="notes.css" type="text/css">
20
21
  </head>
@@ -23,13 +24,20 @@
23
24
  <h1><%= title %></h1>
24
25
  <div class="notes">
25
26
  <% notes.by_label_file.each do |label, per_file| %>
26
- <h2><%= label %></h2>
27
+ <h2 class="<%= label %>"><%= label %></h2>
27
28
  <ol class="set <%= label.downcase %>">
28
29
  <% per_file.each do |file, line_notes| %>
29
30
  <li><h3><a href="<%= file %>"><%= file %></a></h3><ol class="file" href="<%= file %>">
30
31
  <% line_notes.sort!{ |a,b| a.line <=> b.line } %>
31
32
  <% line_notes.each do |note| %>
32
- <li class="note <%= label.downcase %>" ref="<%= note.line %>"><%= h note.text %> <sup><%= note.line %></sup></li>
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>
33
41
  <% end %>
34
42
  </ol></li>
35
43
  <% end %>
@@ -2,19 +2,20 @@
2
2
  <head>
3
3
  <title><%= title %></title>
4
4
  <style>
5
- body { margin: 0; padding: 0; }
5
+ body { margin: 0; padding: 0; font-size: 0.8em; }
6
6
  .main {
7
7
  width: 800px;
8
8
  margin: 0 auto;
9
- border: 1px solid #ccc;
9
+ border: 0px solid #ccc;
10
10
  padding: 0 20px 20px 20px;
11
11
  }
12
- h1 { margin: 25px 0; }
13
- h2,h3,h4 { margin: 5px 0; padding: 0; color: 880044; }
14
- h3 { color: 004488; }
15
- h4 { color: 888844; }
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; }
16
15
  ul { margin: 0; padding: 0; text-align: left; }
17
16
  li { margin: 0; padding: 0; text-align: left; }
17
+ a { color: #4488ff; }
18
+ sup { font-size: 0.8em; }
18
19
  </style>
19
20
  <link rel="stylesheet" href="notes.css" type="text/css">
20
21
  </head>
@@ -28,7 +29,14 @@
28
29
  <% per_label.each do |label, lnotes| %>
29
30
  <li><h3><%= label %></h3><ol class="label">
30
31
  <% lnotes.each do |note| %>
31
- <li class="note <%= label.downcase %>" ref="<%= note.line %>"><%= h note.textline %> <sup><%= note.line %></sup></li>
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>
32
40
  <% end %>
33
41
  </ol></li>
34
42
  <% end %>
@@ -2,19 +2,20 @@
2
2
  <head>
3
3
  <title><%= title %></title>
4
4
  <style>
5
- body { margin: 0; padding: 0; }
5
+ body { margin: 0; padding: 0; font-size: 0.8em; }
6
6
  .main {
7
7
  width: 800px;
8
8
  margin: 0 auto;
9
- border: 1px solid #ccc;
9
+ border: 0px solid #ccc;
10
10
  padding: 0 20px 20px 20px;
11
11
  }
12
- h1 { margin: 25px 0; }
13
- h2,h3,h4 { margin: 5px 0; padding: 0; color: 880044; }
14
- h3 { color: 004488; }
15
- h4 { color: 888844; }
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; }
16
15
  ul { margin: 0; padding: 0; text-align: left; }
17
16
  li { margin: 0; padding: 0; text-align: left; }
17
+ a { color: #4488ff; }
18
+ sup { font-size: 0.8em; }
18
19
  </style>
19
20
  <link rel="stylesheet" href="notes.css" type="text/css">
20
21
  </head>
@@ -29,7 +30,14 @@
29
30
  <li><h3><a href="<%= file %>"><%= file %></a></h3><ol class="file" href="<%= file %>">
30
31
  <% line_notes.sort!{ |a,b| a.line <=> b.line } %>
31
32
  <% line_notes.each do |note| %>
32
- <li class="note <%= label.downcase %>" ref="<%= note.line %>"><%= h note.text %> <sup><%= note.line %></sup></li>
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>
33
41
  <% end %>
34
42
  </ol></li>
35
43
  <% end %>
@@ -2,19 +2,20 @@
2
2
  <head>
3
3
  <title><%= title %></title>
4
4
  <style>
5
- body { margin: 0; padding: 0; }
5
+ body { margin: 0; padding: 0; font-size: 0.8em; }
6
6
  .main {
7
7
  width: 800px;
8
8
  margin: 0 auto;
9
- border: 1px solid #ccc;
9
+ border: 0px solid #ccc;
10
10
  padding: 0 20px 20px 20px;
11
11
  }
12
- h1 { margin: 25px 0; }
13
- h2,h3,h4 { margin: 5px 0; padding: 0; color: 880044; }
14
- h3 { color: 004488; }
15
- h4 { color: 888844; }
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; }
16
15
  ul { margin: 0; padding: 0; text-align: left; }
17
16
  li { margin: 0; padding: 0; text-align: left; }
17
+ a { color: #4488ff; }
18
+ sup { font-size: 0.8em; }
18
19
  </style>
19
20
  <link rel="stylesheet" href="notes.css" type="text/css">
20
21
  </head>
@@ -24,7 +25,15 @@
24
25
  <div class="notes">
25
26
  <ol>
26
27
  <% notes.each do |note| %>
27
- <li class="note <%= note.label.downcase %>" ref="<%= note.line %>"><%= note.label %>: <%= h note.text %> <sup><%= note.file %>: <%= note.line %></sup></li>
28
+ <li class="note <%= note.label.downcase %>" ref="<%= note.line %>">
29
+ <%= note.label %>: <%= h note.text %>
30
+ <sup><a href="<%= note.url %>"><%= note.file %>: <%= note.line %></a></sup>
31
+ <% if note.code? %>
32
+ <pre>
33
+ <%= note.code %>
34
+ </pre>
35
+ <$ end %>
36
+ </li>
28
37
  <% end %>
29
38
  </ol>
30
39
  </div>
@@ -0,0 +1,3 @@
1
+ module DNote
2
+ VERSION = '1.5.0'
3
+ end
@@ -1,9 +1,9 @@
1
- module Syckle::Plugins
1
+ module Redline::Plugins
2
2
 
3
3
  # = Developmer's Notes Plugin
4
4
  #
5
5
  # This plugin goes through you source files and compiles
6
- # an lit of any labeled comments. Labels are single word
6
+ # a list of any labeled comments. Labels are single word
7
7
  # prefixes to a comment ending in a colon. For example,
8
8
  # you might note somewhere in your code:
9
9
  #
@@ -15,24 +15,24 @@ module Syckle::Plugins
15
15
  # is a +notes/+ directory in the project's log directory.
16
16
  #
17
17
  #--
18
- # TODO: Should this service be part of the +site+ cycle?
18
+ # TODO: Should this service be part of the +site+ track?
19
19
  #++
20
20
  class DNote < Service
21
21
 
22
- cycle :main, :document
23
- cycle :main, :reset
24
- cycle :main, :clean
22
+ stop :main, :document
23
+ stop :main, :reset
24
+ stop :main, :clean
25
25
 
26
26
  # not that this is necessary, but ...
27
- available do |project|
28
- begin
29
- require 'dnote'
30
- require 'dnote/format'
31
- true
32
- rescue LoadError
33
- false
34
- end
35
- end
27
+ #available do |project|
28
+ # begin
29
+ # require 'dnote'
30
+ # require 'dnote/format'
31
+ # true
32
+ # rescue LoadError
33
+ # false
34
+ # end
35
+ #end
36
36
 
37
37
  ## autorun if log/notes exists
38
38
  #autorun do |project|
@@ -56,7 +56,7 @@ module Syckle::Plugins
56
56
 
57
57
  # Output directory to save notes file. Defaults to <tt>dnote/</tt> under
58
58
  # the project log directory (eg. <tt>log/dnote/</tt>).
59
- attr_accessor :output
59
+ attr_reader :output
60
60
 
61
61
  # Formats (xml, html, rdoc).
62
62
  attr_accessor :formats
@@ -64,6 +64,9 @@ module Syckle::Plugins
64
64
  # Title to use if temaplte can use it.
65
65
  attr_accessor :title
66
66
 
67
+ # Number of context lines to display.
68
+ attr_accessor :lines
69
+
67
70
  #
68
71
  def output=(path)
69
72
  @output = Pathname.new(path)
@@ -85,6 +88,7 @@ module Syckle::Plugins
85
88
  s.ignore = ignore
86
89
  s.labels = labels #|| DEFAULT_LABELS
87
90
  s.title = title
91
+ s.context = lines
88
92
  s.output = output
89
93
  s.dryrun = trial?
90
94
  end
@@ -134,6 +138,12 @@ module Syckle::Plugins
134
138
 
135
139
  private
136
140
 
141
+ #
142
+ def initialize_requires
143
+ require 'dnote'
144
+ require 'dnote/format'
145
+ end
146
+
137
147
  #
138
148
  def initialize_defaults
139
149
  @files = "**/*.rb"