mvz-dnote 1.7.2 → 1.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: eac8890fe30005d8b91d2435f22b6b147eb824e3
4
- data.tar.gz: 3095d7ed25f4a5bcf188c8d678a01567b8588934
2
+ SHA256:
3
+ metadata.gz: 8f69fc38b3682fab8db2aa937fcde974c166e74e0a72c7ce3fef709f9660fde7
4
+ data.tar.gz: f26dac2be30677f1ce05be309e4b41f178988dd926512fe534168fe4a5e44702
5
5
  SHA512:
6
- metadata.gz: 9d4b828d589ed5157db324540356362017e3be0f6cace8cedc548be8a5673da817d2e0daa91f8cf8cbd167ac03ecda97641a34e06177ae7d58316a7a19130d75
7
- data.tar.gz: a7e26ab03120551110e03e5a81154b7aa6064c6e70ae10d70a4b64eb03cf1b925ab6e41250f370fad735bd7227361683292bc29118ac578e46e681f62573a09a
6
+ metadata.gz: df50e819949330f599cdd53ecba7ef7751f4908336e7c26d9be747ea33f3144e465c993e5318bc653aaee70ba8259b70d73c1f0dc0313eb5de2f6cf1bbbc665e
7
+ data.tar.gz: 69256f599091253c91a76f36681960160cf08c0e6a6eb8bfdf811750ee1a9bc9b681d69212998f220853581c93e846249a215b433a3f3349c92a99e4d15165ad
data/HISTORY.rdoc CHANGED
@@ -1,5 +1,23 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 1.10.0 / 2022-04-10
4
+
5
+ * Add support for Ruby 3.1
6
+ * Drop support for Ruby 2.5
7
+ * Loosen development dependencies
8
+
9
+ == 1.9.0 / 2021-09-17
10
+
11
+ * Drop support for Ruby 2.3 and 2.4
12
+ * Officially support Ruby 2.7 and 3.0
13
+ * Update development dependencies
14
+ * Improve code quality
15
+
16
+ == 1.8.0 / 2018-12-29
17
+
18
+ * Officially support CRuby 2.5 and 2.6
19
+ * Drop support for CRuby 2.1 and 2.2
20
+
3
21
  == 1.7.2 / 2017-03-05
4
22
 
5
23
  * Support CRuby 2.4
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # DNote
2
+
3
+ * [Homepage](http://rubyworks.github.com/dnote)
4
+ * [Mailing List](http://googlegroups.com/group/rubyworks-mailinglist)
5
+ * [Source Code](http://github.com/rubyworks/dnote)
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/mvz-dnote.svg)](https://badge.fury.io/rb/mvz-dnote)
8
+ [![Maintainability](https://api.codeclimate.com/v1/badges/608621bbad5de3a98e3b/maintainability)](https://codeclimate.com/github/mvz/dnote/maintainability)
9
+
10
+ ## DESCRIPTION
11
+
12
+ Extract development notes from source code and generate some nice
13
+ output formats for them.
14
+
15
+
16
+ ## SYNOPSIS
17
+
18
+ ### Note Structure
19
+
20
+ DNote scans for the common note patterns used by developers of many languages in the form of an
21
+ all-caps labels followed by a colon. To be more specific, for DNote to recognize a note,
22
+ it needs to follow this simple set of rules:
23
+
24
+ 1. Notes start with an all-caps label punctuated with a colon, followed by the note's text.
25
+
26
+ # LABEL: description ...
27
+
28
+ 2. Any note that requires more than one line must remain flush to the left
29
+ margin (the margin is set by the first line). This is done because RDoc will mistake
30
+ the note for a `pre` block if it is indented.
31
+
32
+ # LABEL: description ...
33
+ # continue ...
34
+
35
+ 3. An alternative to the previous limitation is to indent the whole note, making it
36
+ a `<pre>` block when rendered by RDoc. Then the text layout is free-form.
37
+
38
+ # This is a description of something...
39
+ #
40
+ # LABEL: description ...
41
+ # continue ...
42
+
43
+ That's all there is to it, if I can convince the developers of RDoc to recognize labels,
44
+ we may eventually be able to relax the flush rule too, which would be very nice.
45
+
46
+ There is also a command-line option, `--no-colon`, which deactives the need for
47
+ a colon after the note label. However this often produces false positives, so its use is
48
+ discouraged.
49
+
50
+ ### Generating Notes
51
+
52
+ As you can see the commandline interface is pretty straight-forward.
53
+
54
+ USAGE:
55
+
56
+ dnote [OPTIONS] path1 [path2 ...]
57
+
58
+ OUTPUT FORMAT: (choose one)
59
+ -f, --format NAME select a format [text]
60
+ -c, --custom FILE use a custom ERB template
61
+ --file shortcut for text/file format
62
+ --list shortcut for text/list format
63
+
64
+ OTHER OPTIONS:
65
+ -l, --label LABEL labels to collect
66
+ --[no-]colon match labels with/without colon suffix
67
+ -m, --marker MARK alternative remark marker
68
+ -u --url TEMPLATE url template for line entries (for HTML)
69
+ -x, --exclude PATH exclude file or directory
70
+ -i, --ignore NAME ignore based on any part of the pathname
71
+ -t, --title TITLE title to use in header
72
+ -o, --output PATH name of file or directory
73
+ -n, --dryrun do not actually write to disk
74
+ --debug debug mode
75
+
76
+ COMMAND OPTIONS:
77
+ -T, --templates list available format templates
78
+ -h, --help show this help information
79
+
80
+ The default path is `**/*.rb` and the default format is `-f text`.
81
+ Here is an example of DNote's current notes in RDoc format:
82
+
83
+ = Development Notes
84
+
85
+ == TODO
86
+
87
+ === file://lib/dnote/notes.rb
88
+
89
+ * TODO: Add ability to read header notes. They often
90
+ have a outline format, rather then the single line. (19)
91
+ * TODO: Need good CSS file. (22)
92
+ * TODO: Need XSL? (24)
93
+
94
+ === file://plug/syckle/services/dnote.rb
95
+
96
+ * TODO: Should this service be part of the +site+ cycle? (18)
97
+
98
+ (4 TODOs)
99
+
100
+
101
+ ## INSTALLATION
102
+
103
+ The usual rubygems command will do the trick.
104
+
105
+ $ gem install mvz-dnote
106
+
107
+
108
+ ## COPYRIGHT
109
+
110
+ Copyright (c) 2006 Thomas Sawyer, Rubyworks
111
+
112
+ Copyright (c) 2017-2018 Matijs van Zuijlen
113
+
114
+ DNote is distributable in accordance with the terms of the *FreeBSD* license.
115
+
116
+ See COPYING.rdoc for details.
data/bin/dnote CHANGED
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require "dnote"
3
- DNote::Session.main(*ARGV)
4
5
 
6
+ begin
7
+ DNote::Session.main(*ARGV)
8
+ rescue StandardError => e
9
+ raise e if $DEBUG
10
+
11
+ puts e
12
+ exit 1
13
+ end
@@ -1,92 +1,36 @@
1
- module Enumerable
2
-
3
- # Taken from Ruby Facets.
4
- def group_by #:yield:
5
- #h = k = e = nil
6
- r = Hash.new
7
- each{ |e| (r[yield(e)] ||= []) << e }
8
- r
9
- end unless method_defined?(:group_by)
10
-
11
- end
1
+ # frozen_string_literal: true
12
2
 
13
3
  module DNote
14
-
15
4
  # Extensions for String class.
16
5
  # These methods are taken directly from Ruby Facets.
17
6
  #
18
7
  module StringExt
19
-
20
- # Provides a margin controlled string.
21
- #
22
- # x = %Q{
23
- # | This
24
- # | is
25
- # | margin controlled!
26
- # }.margin
27
- #
28
- #
29
- # NOTE: This may still need a bit of tweaking.
30
- #
31
- # CREDIT: Trans
32
-
33
- def margin(n=0)
34
- #d = /\A.*\n\s*(.)/.match( self )[1]
35
- #d = /\A\s*(.)/.match( self)[1] unless d
36
- d = ((/\A.*\n\s*(.)/.match(self)) ||
37
- (/\A\s*(.)/.match(self)))[1]
38
- return '' unless d
39
- if n == 0
40
- gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, '')
41
- else
42
- gsub(/\n\s*\Z/,'').gsub(/^\s*[#{d}]/, ' ' * n)
43
- end
44
- end
45
-
46
- # Preserves relative tabbing.
47
- # The first non-empty line ends up with n spaces before nonspace.
48
- #
49
- # CREDIT: Gavin Sinclair
50
-
51
- def tabto(n)
52
- if self =~ /^( *)\S/
53
- indent(n - $1.length)
54
- else
55
- self
56
- end
57
- end
58
-
59
- # Indent left or right by n spaces.
8
+ # Indent left or right by num spaces.
60
9
  # (This used to be called #tab and aliased as #indent.)
61
10
  #
62
11
  # CREDIT: Gavin Sinclair
63
12
  # CREDIT: Trans
64
13
 
65
- def indent(n)
66
- if n >= 0
67
- gsub(/^/, ' ' * n)
14
+ def indent(num)
15
+ if num >= 0
16
+ gsub(/^/, " " * num)
68
17
  else
69
- gsub(/^ {0,#{-n}}/, "")
18
+ gsub(/^ {0,#{-num}}/, "")
70
19
  end
71
20
  end
72
21
 
73
- #
74
- #
75
- def tabset(n)
22
+ def tabset(num)
76
23
  i = lines.map do |line|
77
24
  line.strip.empty? ? nil : line.index(/\S/)
78
25
  end
79
26
  x = i.compact.min
80
- t = n - x.to_i
27
+ t = num - x.to_i
81
28
  t = 0 if t < 0
82
29
  indent(t)
83
30
  end
84
-
85
31
  end
86
-
87
- class ::String #:nodoc:
88
- include DNote::StringExt
89
- end
90
-
91
32
  end
92
33
 
34
+ String.class_eval do
35
+ include DNote::StringExt
36
+ end
data/lib/dnote/format.rb CHANGED
@@ -1,5 +1,6 @@
1
- module DNote
1
+ # frozen_string_literal: true
2
2
 
3
+ module DNote
3
4
  # = Notes Formatter
4
5
  #
5
6
  #--
@@ -8,55 +9,35 @@ module DNote
8
9
  # TODO: Need XSL?
9
10
  #++
10
11
  class Format
11
-
12
- require 'fileutils'
13
- require 'erb'
14
- require 'rexml/text'
15
- require 'dnote/core_ext'
16
-
17
- #DEFAULT_OUTPUT_DIR = "log/dnote"
18
-
19
- EXTENSIONS = { 'text'=>'txt', 'soap'=>'xml', 'xoxo'=>'xml' }
20
-
21
- #
22
- attr :notes
23
-
24
- #
25
- attr_accessor :format
26
-
27
- #
28
- attr_accessor :subtype
29
-
30
- #
31
- attr_accessor :output
32
-
33
- #
34
- attr_accessor :template
35
-
36
- #
37
- attr_accessor :title
38
-
39
- #
40
- attr_accessor :dryrun
41
-
42
- #
43
- def initialize(notes, options={})
44
- @notes = notes
45
- @format = 'text'
46
- @subtype = 'label'
47
- @title = "Developer's Notes"
48
- @dryrun = false
49
- options.each{ |k,v| __send__("#{k}=", v) if v }
50
- yield(self) if block_given?
12
+ require "fileutils"
13
+ require "erb"
14
+ require "rexml/text"
15
+ require "dnote/core_ext"
16
+
17
+ EXTENSIONS = {"text" => "txt", "soap" => "xml", "xoxo" => "xml"}.freeze
18
+
19
+ attr_reader :notes, :format, :output, :template, :title, :dryrun
20
+
21
+ def initialize(notes,
22
+ format: "text",
23
+ title: "Developer's Notes",
24
+ template: nil,
25
+ output: nil,
26
+ dryrun: false)
27
+ @notes = notes
28
+ @format = format
29
+ @title = title
30
+ @dryrun = dryrun
31
+ @template = template
32
+ @output = output
51
33
  end
52
34
 
53
- #
54
35
  def render
55
36
  if notes.empty?
56
- $stderr << "No #{notes.labels.join(', ')} notes.\n"
37
+ $stderr << "No #{notes.labels.join(", ")} notes.\n"
57
38
  else
58
39
  case format
59
- when 'custom'
40
+ when "custom"
60
41
  render_custom
61
42
  else
62
43
  render_template
@@ -64,48 +45,43 @@ module DNote
64
45
  end
65
46
  end
66
47
 
48
+ private
49
+
67
50
  # C U S T O M
68
51
 
69
- #
70
52
  def render_custom
71
- #raise ArgumentError unless File.exist?(template)
72
53
  result = erb(template)
73
- publish(result)
54
+ publish(result)
74
55
  end
75
56
 
76
57
  # T E M P L A T E
77
58
 
78
- #
79
59
  def render_template
80
- template = File.join(File.dirname(__FILE__), 'templates', "#{format}.erb")
60
+ template = File.join(File.dirname(__FILE__), "templates", "#{format}.erb")
81
61
  raise "No such format - #{format}" unless File.exist?(template)
62
+
82
63
  result = erb(template)
83
- publish(result)
64
+ publish(result)
84
65
  end
85
66
 
86
- private
87
-
88
- #
89
67
  def erb(file)
90
- scope = ErbScope.new(:notes=>notes, :title=>title)
68
+ scope = ErbScope.new(notes: notes, title: title)
91
69
  scope.render(file)
92
70
  end
93
71
 
94
- #
95
- def publish(result, fname=nil)
72
+ def publish(result, fname = nil)
96
73
  if output
97
74
  write(result, fname)
98
75
  else
99
76
  puts(result)
100
77
  end
101
- $stderr << "(" + notes.counts.map{|l,n| "#{n} #{l}s"}.join(', ') + ")\n"
78
+ $stderr << "(#{notes.counts.map { |l, n| "#{n} #{l}s" }.join(", ")})\n"
102
79
  end
103
80
 
104
- #
105
- def write(result, fname=nil)
106
- if output.to_s[-1,1] == '/' || File.directory?(output)
107
- fmt = format.split('/').first
108
- ext = EXTENSIONS[fmt] || fmt
81
+ def write(result, fname = nil)
82
+ if output.to_s[-1, 1] == "/" || File.directory?(output)
83
+ fmt = format.split("/").first
84
+ ext = EXTENSIONS[fmt] || fmt
109
85
  file = File.join(output, fname || "notes.#{ext}")
110
86
  else
111
87
  file = output
@@ -116,25 +92,22 @@ module DNote
116
92
  else
117
93
  dir = File.dirname(file)
118
94
  fu.mkdir(dir) unless File.exist?(dir)
119
- File.open(file, 'w'){ |f| f << result }
95
+ File.open(file, "w") { |f| f << result }
120
96
  end
121
- return file
97
+ file
122
98
  end
123
99
 
124
- #
125
100
  def dryrun?
126
101
  @dryrun
127
102
  end
128
103
 
129
- #
130
104
  def debug?
131
105
  $DEBUG
132
106
  end
133
107
 
134
- #
135
108
  def fu
136
- @fu ||= (
137
- if dryrun? and debug?
109
+ @fu ||=
110
+ if dryrun? && debug?
138
111
  FileUtils::DryRun
139
112
  elsif dryrun?
140
113
  FileUtils::Noop
@@ -143,31 +116,34 @@ module DNote
143
116
  else
144
117
  FileUtils
145
118
  end
146
- )
147
119
  end
148
120
 
149
- #
150
- class ErbScope
151
- #
152
- def initialize(data={})
121
+ # Evaluation scope for ERB templates
122
+ class ErbScope
123
+ def initialize(data = {})
153
124
  @data = data
154
125
  end
155
- #
126
+
156
127
  def render(file)
157
- erb = ERB.new(File.read(file), nil, '<>')
128
+ contents = File.read(file)
129
+ erb = ERB.new(contents, trim_mode: "<>")
158
130
  erb.result(binding)
159
131
  end
160
- #
132
+
161
133
  def h(string)
162
134
  REXML::Text.normalize(string)
163
135
  end
164
- #
165
- def method_missing(s, *a)
166
- @data[s.to_sym]
136
+
137
+ def method_missing(method, *_args)
138
+ sym = method.to_sym
139
+ return @data.fetch(sym) if @data.key? sym
140
+
141
+ super
142
+ end
143
+
144
+ def respond_to_missing?(method)
145
+ @data.key?(method.to_sym) || super
167
146
  end
168
147
  end
169
-
170
148
  end
171
-
172
149
  end
173
-
data/lib/dnote/note.rb CHANGED
@@ -1,45 +1,41 @@
1
- module DNote
1
+ # frozen_string_literal: true
2
2
 
3
+ module DNote
3
4
  # The Note class encapsulates a single note made in a source file.
4
5
  #
5
6
  # Each note instance holds a reference, +notes+, to the set of notes
6
7
  # being generated for a given session. This allows the note to access
7
8
  # general options applicable to all notes.
8
9
  class Note
9
-
10
- # Number of lines to provide in source context.
11
- #CONTEXT_DEPTH = 5
12
-
13
10
  # Set of notes to which this note belongs.
14
- attr :notes
11
+ attr_reader :notes
15
12
 
16
13
  # The file in which the note is made.
17
- attr :file
14
+ attr_reader :file
18
15
 
19
16
  # The type of note.
20
- attr :label
17
+ attr_reader :label
21
18
 
22
19
  # The line number of the note.
23
- attr :line
20
+ attr_reader :line
24
21
 
25
22
  # The verbatim text of the note.
26
- attr :text
23
+ attr_reader :text
27
24
 
28
25
  # Remark marker used in parsing the note.
29
- attr :mark
26
+ attr_reader :mark
30
27
 
31
28
  # Contextual lines of code.
32
- attr :capture
29
+ attr_reader :capture
33
30
 
34
31
  # Initialize new Note instance.
35
32
  def initialize(notes, file, label, line, text, mark)
36
- @notes = notes
37
-
38
- @file = file
39
- @label = label
40
- @line = line
41
- @text = text.rstrip
42
- @mark = mark
33
+ @notes = notes
34
+ @file = file
35
+ @label = label
36
+ @line = line
37
+ @text = text.rstrip
38
+ @mark = mark
43
39
  @capture = []
44
40
  end
45
41
 
@@ -55,13 +51,14 @@ module DNote
55
51
 
56
52
  # Remove newlines from note text.
57
53
  def textline
58
- text.gsub("\n", " ")
54
+ text.tr("\n", " ")
59
55
  end
60
56
 
61
57
  # Sort by file name and line number.
62
58
  def <=>(other)
63
59
  s = file <=> other.file
64
60
  return s unless s == 0
61
+
65
62
  line <=> other.line
66
63
  end
67
64
 
@@ -71,12 +68,12 @@ module DNote
71
68
  # TODO: Add +code+? Problem is that xml needs code in CDATA.
72
69
  #++
73
70
  def to_h
74
- { 'label'=>label, 'text'=>textline, 'file'=>file, 'line'=>line }
71
+ {"label" => label, "text" => textline, "file" => file, "line" => line}
75
72
  end
76
73
 
77
74
  # Convert to Hash, leaving the note text verbatim.
78
75
  def to_h_raw
79
- { 'label'=>label, 'text'=>text, 'file'=>file, 'line'=>line, 'code'=>code }
76
+ {"label" => label, "text" => text, "file" => file, "line" => line, "code" => code}
80
77
  end
81
78
 
82
79
  # Convert to JSON.
@@ -91,15 +88,16 @@ module DNote
91
88
 
92
89
  # Return line URL based on URL template. If no template was set, then
93
90
  # returns the file.
91
+ #
92
+ # FIXME: Move out of Note so we can drop the reference to notes
94
93
  def url
95
94
  if notes.url
96
- notes.url % [file, line]
95
+ format(notes.url, file, line)
97
96
  else
98
97
  file
99
98
  end
100
99
  end
101
100
 
102
- #
103
101
  def code
104
102
  unindent(capture).join
105
103
  end
@@ -109,42 +107,20 @@ module DNote
109
107
  !capture.empty?
110
108
  end
111
109
 
112
- =begin
113
- # This isn't being used currently b/c the URL solution as deeemd better,
114
- # but the code is here for custom templates.
115
- def capture
116
- @context ||= (
117
- lines = file_cache(file) #.lines.to_a
118
- count = line()
119
- count +=1 while /^\s*#{mark}/ =~ lines[count]
120
- lines[count, context_depth]
121
- )
122
- end
123
-
124
- # Read in +file+, parse into lines and cache.
125
- def file_cache(file)
126
- @@file_cache ||= {}
127
- @@file_cache[file] ||= File.read(file).lines.to_a
128
- end
129
- =end
130
-
131
110
  private
132
111
 
133
112
  # Remove blank space from lines.
134
113
  def unindent(lines)
135
114
  dents = []
136
115
  lines.each do |line|
137
- if md = /^([\ ]*)/.match(line)
138
- size = md[1].size
116
+ if (md = /^(\ *)/.match(line))
139
117
  dents << md[1]
140
118
  end
141
119
  end
142
- dent = dents.min{ |a,b| a.size <=> b.size }
120
+ dent = dents.min_by(&:size)
143
121
  lines.map do |line|
144
- line.sub(dent, '')
122
+ line.sub(dent, "")
145
123
  end
146
124
  end
147
-
148
125
  end
149
-
150
126
  end