readme 0.1.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.
- data/.ruby +71 -0
- data/HISTORY.md +10 -0
- data/README.md +52 -0
- data/bin/readme +3 -0
- data/lib/readme.rb +287 -0
- data/lib/readme/cli.rb +59 -0
- data/lib/readme/version.rb +3 -0
- metadata +140 -0
data/.ruby
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- var
|
4
|
+
authors:
|
5
|
+
- name: Trans
|
6
|
+
email: transfire@gmail.com
|
7
|
+
copyrights:
|
8
|
+
- holder: Rubyworks
|
9
|
+
year: '2011'
|
10
|
+
license: BSD-2-Clause
|
11
|
+
replacements: []
|
12
|
+
alternatives: []
|
13
|
+
requirements:
|
14
|
+
- name: detroit
|
15
|
+
groups:
|
16
|
+
- build
|
17
|
+
development: true
|
18
|
+
- name: reap
|
19
|
+
groups:
|
20
|
+
- build
|
21
|
+
development: true
|
22
|
+
- name: mast
|
23
|
+
groups:
|
24
|
+
- test
|
25
|
+
development: true
|
26
|
+
- name: rubytest
|
27
|
+
groups:
|
28
|
+
- test
|
29
|
+
development: true
|
30
|
+
- name: citron
|
31
|
+
groups:
|
32
|
+
- test
|
33
|
+
development: true
|
34
|
+
- name: ae
|
35
|
+
groups:
|
36
|
+
- test
|
37
|
+
development: true
|
38
|
+
- name: simplecov
|
39
|
+
groups:
|
40
|
+
- test
|
41
|
+
development: true
|
42
|
+
dependencies: []
|
43
|
+
conflicts: []
|
44
|
+
repositories:
|
45
|
+
- uri: git://github.com/rubyworks/readme.git
|
46
|
+
scm: git
|
47
|
+
name: upstream
|
48
|
+
resources:
|
49
|
+
home: http://rubyworks.github.com/readme
|
50
|
+
code: http://github.com/rubyworks/readme
|
51
|
+
bugs: http://github.com/rubyworks/readme/issues
|
52
|
+
mail: http://groups.google.com/groups/rubyworks-mailinglist
|
53
|
+
extra: {}
|
54
|
+
load_path:
|
55
|
+
- lib
|
56
|
+
revision: 0
|
57
|
+
created: '2009-07-22'
|
58
|
+
summary: Extract information from README files.
|
59
|
+
title: Readme
|
60
|
+
version: 0.1.0
|
61
|
+
name: readme
|
62
|
+
description: ! 'Ever thought perhaps that all the effect in creating a good README,
|
63
|
+
while
|
64
|
+
|
65
|
+
great for your end-userss, did''t every do you a hill of beans worth of good
|
66
|
+
|
67
|
+
when it came to constructing your project''s metadata. Well, hang on to your
|
68
|
+
|
69
|
+
nerd glasses! Here comes a gem that does just that!'
|
70
|
+
organization: rubyworks
|
71
|
+
date: '2012-02-08'
|
data/HISTORY.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# README
|
2
|
+
|
3
|
+
[Website](http://rubyworks.github.com/readme) /
|
4
|
+
[Development](http://github.com/rubyworks/readme) /
|
5
|
+
[Issue Tracker](http://github.com/rubyworks/readme/issues) /
|
6
|
+
[Mailing List](http://groups.google.com/groups/rubyworks-mailinglist)
|
7
|
+
|
8
|
+
[](http://travis-ci.org/rubyworks/readme)
|
9
|
+
|
10
|
+
|
11
|
+
## Description
|
12
|
+
|
13
|
+
Ever thought perhaps that all the effect in creating a good README, while
|
14
|
+
great for your end-users, didn't every do you a hill of beans worth of good
|
15
|
+
when it came to constructing your project's metadata. Well, hang on to your
|
16
|
+
nerd glasses! Here comes a gem that does just that!
|
17
|
+
|
18
|
+
Okay, don't get too excited just yet. Readme's heuristics are rather limited
|
19
|
+
thus far, but with time and contribution she'll be right fine in the not
|
20
|
+
to distant future.
|
21
|
+
|
22
|
+
|
23
|
+
## Instruction
|
24
|
+
|
25
|
+
The library is about as easy to use as you can imagine.
|
26
|
+
|
27
|
+
require 'readme'
|
28
|
+
|
29
|
+
readme = Readme.file
|
30
|
+
|
31
|
+
readme.name
|
32
|
+
readme.description
|
33
|
+
readme.copyright
|
34
|
+
|
35
|
+
It also come with a command line client to pump out the data into variant
|
36
|
+
formats, such a YAML, JSON and even Ruby code.
|
37
|
+
|
38
|
+
$ readme --yaml
|
39
|
+
|
40
|
+
$ readme description
|
41
|
+
|
42
|
+
See the [API documentation](http:/rubydoc.info/gems/readme) and `readme --help` for more information.
|
43
|
+
|
44
|
+
|
45
|
+
## Copyright
|
46
|
+
|
47
|
+
Copyright (c) 2009 Rubyworks. All rights reserved.
|
48
|
+
|
49
|
+
Readme can be redistributed in accordance with the **BSD-2-Clause** license.
|
50
|
+
|
51
|
+
See COPYING.md file for details.
|
52
|
+
|
data/bin/readme
ADDED
data/lib/readme.rb
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
# Readme is designed to parse a README file applying various hueristics
|
2
|
+
# in order to descern metadata about a project.
|
3
|
+
#
|
4
|
+
# The heuristics are fairly simplistic at this point, but will improve
|
5
|
+
# with time and contribution.
|
6
|
+
#
|
7
|
+
class Readme
|
8
|
+
|
9
|
+
if RUBY_VERSION < '1.9'
|
10
|
+
require 'readme/version'
|
11
|
+
require 'readme/cli'
|
12
|
+
else
|
13
|
+
require_relative 'readme/version'
|
14
|
+
require_relative 'readme/cli'
|
15
|
+
end
|
16
|
+
|
17
|
+
# File glob for matching README file.
|
18
|
+
FILE_PATTERN = "README{,.*}"
|
19
|
+
|
20
|
+
#
|
21
|
+
def self.file(path=Dir.pwd)
|
22
|
+
if File.directory?(path)
|
23
|
+
path = Dir.glob(File.join(path, FILE_PATTERN), File::FNM_CASEFOLD).first
|
24
|
+
end
|
25
|
+
if path
|
26
|
+
new(File.read(path), path)
|
27
|
+
else
|
28
|
+
raise IOError, "no such README -- #{path}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
def initialize(text, file=nil)
|
34
|
+
@text = text
|
35
|
+
@file = file
|
36
|
+
@data = {}
|
37
|
+
parse
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# The ERADME file path, if provided.
|
42
|
+
#
|
43
|
+
attr :file
|
44
|
+
|
45
|
+
#
|
46
|
+
# The README text.
|
47
|
+
#
|
48
|
+
attr :text
|
49
|
+
|
50
|
+
#
|
51
|
+
# Location of README file, if file was provided.
|
52
|
+
#
|
53
|
+
# @return [String] Directory of README file
|
54
|
+
#
|
55
|
+
def root
|
56
|
+
File.dirname(file) if file
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# The full README text.
|
61
|
+
#
|
62
|
+
# @return [String] The complete README text.
|
63
|
+
#
|
64
|
+
def to_s
|
65
|
+
text.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Access to underlying parse table.
|
70
|
+
#
|
71
|
+
def [](name)
|
72
|
+
@data[name.to_s]
|
73
|
+
#return nil unless file
|
74
|
+
#if respond_to?(name)
|
75
|
+
# __send__(name)
|
76
|
+
#else
|
77
|
+
# nil
|
78
|
+
#end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
def name
|
83
|
+
@data['name']
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
def title
|
88
|
+
@data['title']
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
def description
|
93
|
+
@data['description']
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
def license
|
98
|
+
@data['license']
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
def copyright
|
103
|
+
@data['copyright']
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
def authors
|
108
|
+
@data['authors']
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
def resources
|
113
|
+
@data['resources'] ||= {}
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
def homepage
|
118
|
+
resources['home']
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
def wiki
|
123
|
+
resources['wiki']
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
def issues
|
128
|
+
resources['issues']
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Return file extension of README. Even if the file has no extension,
|
133
|
+
# this method will look at the contents and try to determine it.
|
134
|
+
#
|
135
|
+
# @todo Improve type heuristics.
|
136
|
+
#
|
137
|
+
# @return [String] Extension type, e.g. `.md`.
|
138
|
+
#
|
139
|
+
def extname
|
140
|
+
ext = File.extname(file)
|
141
|
+
if ext.empty?
|
142
|
+
ext = '.rdoc' if /^\=/ =~ text
|
143
|
+
ext = '.md' if /^\#/ =~ text
|
144
|
+
end
|
145
|
+
return ext
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Access to a copy of the underlying parse table.
|
150
|
+
#
|
151
|
+
# @return [Hash] Copy of the underlying table.
|
152
|
+
#
|
153
|
+
def to_h
|
154
|
+
@data.dup
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
|
159
|
+
#
|
160
|
+
def parse
|
161
|
+
parse_title
|
162
|
+
parse_description
|
163
|
+
parse_license
|
164
|
+
parse_copyright
|
165
|
+
parse_resources
|
166
|
+
end
|
167
|
+
|
168
|
+
#
|
169
|
+
def parse_title
|
170
|
+
if md = /^[=#]\s*(.*?)$/m.match(text)
|
171
|
+
title = md[1].strip
|
172
|
+
@data['title'] = title
|
173
|
+
@data['name'] = title.downcase.gsub(/\s+/, '_')
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
def parse_description
|
179
|
+
if md = /[=#]+\s*(DESCRIPTION|ABSTRACT)[:]*(.*?)[=#]/mi.match(text)
|
180
|
+
@data['description'] = md[2].strip #.sub("\n", ' ') # unfold instead of sub?
|
181
|
+
else
|
182
|
+
d = []
|
183
|
+
o = false
|
184
|
+
text.split("\n").each do |line|
|
185
|
+
if o
|
186
|
+
if /^(\w|\s*$)/ !~ line
|
187
|
+
break d
|
188
|
+
else
|
189
|
+
d << line
|
190
|
+
end
|
191
|
+
else
|
192
|
+
if /^\w/ =~ line
|
193
|
+
d << line
|
194
|
+
o = true
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
@data['description'] = d.join(' ').strip
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
#
|
203
|
+
def parse_license
|
204
|
+
if md = /[=]+\s*(LICENSE)/i.match(text)
|
205
|
+
section = md.post_match
|
206
|
+
@data['license'] = (
|
207
|
+
case section
|
208
|
+
when /LGPL/
|
209
|
+
"LGPL"
|
210
|
+
when /GPL/
|
211
|
+
"GPL"
|
212
|
+
when /MIT/
|
213
|
+
"MIT"
|
214
|
+
when /BSD/
|
215
|
+
"BSD"
|
216
|
+
end
|
217
|
+
)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
def parse_copyright
|
223
|
+
md = /Copyright.*?\d+(.*?)$/.match(text)
|
224
|
+
if md
|
225
|
+
copyright = md[0]
|
226
|
+
|
227
|
+
authors = md[1].split(/(and|\&|\,)/).map{|a|a.strip}
|
228
|
+
authors = authors.map{ |a| a.sub(/all rights reserved\.?/i, '').strip.chomp('.') }
|
229
|
+
|
230
|
+
@data['copyright'] = copyright
|
231
|
+
@data['authors'] = authors
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
#
|
236
|
+
def parse_resources
|
237
|
+
@data['resources'] = {}
|
238
|
+
|
239
|
+
scan_for_github
|
240
|
+
scan_for_google_groups
|
241
|
+
|
242
|
+
text.scan(/(\w+)\:\s*(http:.*?[\w\/])$/) do |m|
|
243
|
+
@data['resources'][$1] = $2
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
#
|
248
|
+
# TODO: Improve on github matching.
|
249
|
+
def scan_for_github
|
250
|
+
text.scan(/http\:.*?github\.com.*?[">)\s]/) do |m|
|
251
|
+
case m
|
252
|
+
when /wiki/
|
253
|
+
@data['resources']['wiki'] = m[0...-1]
|
254
|
+
when /issues/
|
255
|
+
@data['resources']['issues'] = m[0...-1]
|
256
|
+
else
|
257
|
+
if m[0] =~ /:\/\/github/
|
258
|
+
@data['resources']['code'] = m[0...-1]
|
259
|
+
else
|
260
|
+
@data['resources']['home'] = m[0...-1]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
#
|
267
|
+
def scan_for_google_groups
|
268
|
+
if m = /http\:.*?groups\.google\.com.*?[">)\s]/.match(text)
|
269
|
+
@data['resources']['mail'] = m[0][0...-1]
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
#
|
274
|
+
# TODO: parse readme into sections of [label, text].
|
275
|
+
#def sections
|
276
|
+
# @sections ||= (
|
277
|
+
# secs = text.split(/^(==|##)/)
|
278
|
+
# secs.map do |sec|
|
279
|
+
# i = sec.index("\n")
|
280
|
+
# n = sec[0..i].sub(/^[=#]*/, '')
|
281
|
+
# t = sec[i+1..-1]
|
282
|
+
# [n, t]
|
283
|
+
# end
|
284
|
+
# )
|
285
|
+
#end
|
286
|
+
end
|
287
|
+
|
data/lib/readme/cli.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
class Readme
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
def self.cli(*argv)
|
6
|
+
format = nil
|
7
|
+
name = nil
|
8
|
+
|
9
|
+
OptionParser.new do |opt|
|
10
|
+
opt.banner = 'Usage: readme [option] [field]'
|
11
|
+
opt.on('-y', '--yml', '--yaml', 'return in YAML format') do
|
12
|
+
format = :yaml
|
13
|
+
end
|
14
|
+
opt.on('-j', '--json', 'return in JSON format') do
|
15
|
+
format = :json
|
16
|
+
end
|
17
|
+
opt.on('-r', '--ruby', 'return in Ruby code format') do
|
18
|
+
format = :ruby
|
19
|
+
end
|
20
|
+
opt.on_tail('-h', '--help', 'show this help message') do
|
21
|
+
puts opt
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end.parse!(argv)
|
25
|
+
|
26
|
+
if argv.first
|
27
|
+
name = argv.shift
|
28
|
+
data = Readme.file[name]
|
29
|
+
else
|
30
|
+
if format
|
31
|
+
data = Readme.file.to_h
|
32
|
+
else
|
33
|
+
data = Readme.file
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
case format
|
38
|
+
when :yaml
|
39
|
+
require 'yaml'
|
40
|
+
puts data.to_yaml
|
41
|
+
when :json
|
42
|
+
require 'json'
|
43
|
+
puts data.to_json
|
44
|
+
when :ruby
|
45
|
+
data = {name => data} if name
|
46
|
+
data.each do |k,v|
|
47
|
+
case v
|
48
|
+
when Hash
|
49
|
+
puts "#{k} #{v.inspect[1...-1]}"
|
50
|
+
else
|
51
|
+
puts "#{k} #{v.inspect}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
puts data #Readme.file.to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: readme
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Trans
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: detroit
|
16
|
+
requirement: &20548700 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *20548700
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: reap
|
27
|
+
requirement: &20548060 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *20548060
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mast
|
38
|
+
requirement: &20547460 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *20547460
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rubytest
|
49
|
+
requirement: &20546860 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *20546860
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: citron
|
60
|
+
requirement: &20546260 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *20546260
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ae
|
71
|
+
requirement: &20545680 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *20545680
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: simplecov
|
82
|
+
requirement: &20545100 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *20545100
|
91
|
+
description: ! 'Ever thought perhaps that all the effect in creating a good README,
|
92
|
+
while
|
93
|
+
|
94
|
+
great for your end-userss, did''t every do you a hill of beans worth of good
|
95
|
+
|
96
|
+
when it came to constructing your project''s metadata. Well, hang on to your
|
97
|
+
|
98
|
+
nerd glasses! Here comes a gem that does just that!'
|
99
|
+
email:
|
100
|
+
- transfire@gmail.com
|
101
|
+
executables:
|
102
|
+
- readme
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files:
|
105
|
+
- HISTORY.md
|
106
|
+
- README.md
|
107
|
+
files:
|
108
|
+
- .ruby
|
109
|
+
- bin/readme
|
110
|
+
- lib/readme/cli.rb
|
111
|
+
- lib/readme/version.rb
|
112
|
+
- lib/readme.rb
|
113
|
+
- HISTORY.md
|
114
|
+
- README.md
|
115
|
+
homepage: http://rubyworks.github.com/readme
|
116
|
+
licenses:
|
117
|
+
- BSD-2-Clause
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 1.8.11
|
137
|
+
signing_key:
|
138
|
+
specification_version: 3
|
139
|
+
summary: Extract information from README files.
|
140
|
+
test_files: []
|