docbook_files 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/.gitignore +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +26 -0
- data/History.txt +3 -0
- data/README.md +65 -0
- data/Rakefile +21 -0
- data/bin/docbook_files +85 -0
- data/lib/docbook_files/docbook.rb +120 -0
- data/lib/docbook_files/file_data.rb +148 -0
- data/lib/docbook_files.rb +60 -0
- data/spec/docbook_files_spec.rb +6 -0
- data/spec/spec_helper.rb +15 -0
- data/test/.DS_Store +0 -0
- data/test/docbook_files/test_docbook.rb +62 -0
- data/test/docbook_files/test_file_data.rb +82 -0
- data/test/fixtures/book-nonexisting.xml +16 -0
- data/test/fixtures/bookxi.xml +16 -0
- data/test/fixtures/c4/chapter4xi.xml +8 -0
- data/test/fixtures/chapter2xi.xml +11 -0
- data/test/fixtures/chapter3xi.xml +8 -0
- data/test/fixtures/no-ns.xml +8 -0
- data/test/fixtures/no-xml.xml +1 -0
- data/test/fixtures/section1xi.xml +9 -0
- data/test/test_docbook_files.rb +6 -0
- data/version.txt +1 -0
- metadata +89 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
bones (3.7.1)
|
5
|
+
little-plugger (>= 1.1.2)
|
6
|
+
loquacious (>= 1.8.1)
|
7
|
+
rake (>= 0.8.7)
|
8
|
+
libxml-ruby (2.2.2)
|
9
|
+
little-plugger (1.1.2)
|
10
|
+
loquacious (1.9.0)
|
11
|
+
mime-types (1.16)
|
12
|
+
rake (0.9.2)
|
13
|
+
safe_shell (1.0.1)
|
14
|
+
term-ansicolor (1.0.6)
|
15
|
+
wand (0.4)
|
16
|
+
mime-types
|
17
|
+
safe_shell (~> 1.0.0)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
bones
|
24
|
+
libxml-ruby
|
25
|
+
term-ansicolor
|
26
|
+
wand
|
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
docbook_files
|
2
|
+
===========
|
3
|
+
|
4
|
+
docbook_files lists and checks all files related to a DocBook writing project.
|
5
|
+
|
6
|
+
Features
|
7
|
+
--------
|
8
|
+
|
9
|
+
* lists and checks included files
|
10
|
+
|
11
|
+
Synopsis
|
12
|
+
--------
|
13
|
+
|
14
|
+
docbook_files is a command line application, bin/docbook_files, which checks the files that are included or referenced in a DocBook 5 project. (Note: In version 0.1.0 we are only checking included files, but that will change.)
|
15
|
+
|
16
|
+
docbook_files myproject.xml
|
17
|
+
|
18
|
+
This will result in a indentet list of the file names, starting from file _myproject.xml_ and following every XInclude link. Files that could not be found are shown in red.
|
19
|
+
|
20
|
+
Using options the output can be enhanced with more file information, use the classical _docbook_files --help_ to see all available options. They range from file size to MIME types and XML namespaces. Example:
|
21
|
+
|
22
|
+
docbook_files --ts --namespace myproject.xml
|
23
|
+
|
24
|
+
would result in a list with the added information of the last modified timestamp and the XML namespace of each file.
|
25
|
+
|
26
|
+
Requirements
|
27
|
+
------------
|
28
|
+
|
29
|
+
* libxml2
|
30
|
+
|
31
|
+
Install
|
32
|
+
-------
|
33
|
+
|
34
|
+
* gem install docbook_files
|
35
|
+
|
36
|
+
Author
|
37
|
+
------
|
38
|
+
|
39
|
+
Rainer Volz
|
40
|
+
|
41
|
+
License
|
42
|
+
-------
|
43
|
+
|
44
|
+
The MIT License
|
45
|
+
|
46
|
+
Copyright (c) 2011 Rainer Volz
|
47
|
+
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
49
|
+
a copy of this software and associated documentation files (the
|
50
|
+
'Software'), to deal in the Software without restriction, including
|
51
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
52
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
53
|
+
permit persons to whom the Software is furnished to do so, subject to
|
54
|
+
the following conditions:
|
55
|
+
|
56
|
+
The above copyright notice and this permission notice shall be
|
57
|
+
included in all copies or substantial portions of the Software.
|
58
|
+
|
59
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
60
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
61
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
62
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
63
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
64
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
65
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#-*- encoding: utf-8 ; mode:ruby -*-
|
2
|
+
begin
|
3
|
+
require 'bones'
|
4
|
+
rescue LoadError
|
5
|
+
abort '### Please install the "bones" gem ###'
|
6
|
+
end
|
7
|
+
|
8
|
+
task :default => 'test:run'
|
9
|
+
task 'gem:release' => 'test:run'
|
10
|
+
|
11
|
+
Bones {
|
12
|
+
name 'docbook_files'
|
13
|
+
authors 'Rainer Volz'
|
14
|
+
email 'dev@textmulch.de'
|
15
|
+
url 'http://github.com/rvolz/docbook_files/'
|
16
|
+
ignore_file '.gitignore'
|
17
|
+
ignore_file 'About.org'
|
18
|
+
depends_on 'libxml-ruby'
|
19
|
+
depends_on 'term-ansicolor'
|
20
|
+
depends_on 'wand'
|
21
|
+
}
|
data/bin/docbook_files
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*-encoding:utf-8 ; mode:ruby-*-
|
3
|
+
##
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
#require "bundler/setup"
|
8
|
+
require 'optparse'
|
9
|
+
#require 'yaml'
|
10
|
+
#require 'json'
|
11
|
+
require 'term/ansicolor'
|
12
|
+
|
13
|
+
class String
|
14
|
+
include Term::ANSIColor
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib docbook_files]))
|
19
|
+
|
20
|
+
banner = <<EOB
|
21
|
+
docbook_files, Version #{DocbookFiles::VERSION}
|
22
|
+
|
23
|
+
Displays the include hierarchy of a DocBook 5 project.
|
24
|
+
Use the options to see additional information about each file.
|
25
|
+
Files that could not be found are shown in red.
|
26
|
+
|
27
|
+
Usage: docbook_files [options] <DOCBOOK-FILE>
|
28
|
+
EOB
|
29
|
+
|
30
|
+
@output_format = :screen
|
31
|
+
|
32
|
+
props = []
|
33
|
+
opts = OptionParser.new
|
34
|
+
ivs = DocbookFiles::FileData.init_vars
|
35
|
+
ivs.each do |k,v|
|
36
|
+
opts.on("--#{k.to_s}","#{v}") {|val| props << k}
|
37
|
+
end
|
38
|
+
opts.banner = banner
|
39
|
+
rest = opts.parse(ARGV)
|
40
|
+
|
41
|
+
# Print banner if called without arguments
|
42
|
+
if rest.length < 1
|
43
|
+
puts opts.to_s
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
|
47
|
+
unless File.exists?(rest[0])
|
48
|
+
STDERR.puts "Error: File #{rest[0]} not found."
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
|
52
|
+
# The main routine
|
53
|
+
puts("docbook_status, Version #{DocbookFiles::VERSION}") if @output_format == :screen
|
54
|
+
dbf = DocbookFiles::Docbook.new(rest[0])
|
55
|
+
table = dbf.list_as_table([:name,:exists]+props)
|
56
|
+
puts '-'*10
|
57
|
+
puts
|
58
|
+
output_string = "%s %s" + props.map{|p| " %s"}.join
|
59
|
+
|
60
|
+
|
61
|
+
table.each_with_index do |t,index|
|
62
|
+
vals = ['-'*t[:level],t[:name]] + props.map {|p|
|
63
|
+
if (t[p].nil? || t[p].empty?)
|
64
|
+
'<>'
|
65
|
+
else
|
66
|
+
t[p]
|
67
|
+
end
|
68
|
+
}
|
69
|
+
#vals = ([' '*t[:level],t[:name]] + props.map{|p| t[p]})
|
70
|
+
output = output_string % vals
|
71
|
+
if (index == 0)
|
72
|
+
output = "+" + output
|
73
|
+
elsif (index == table.length-1)
|
74
|
+
output = "+" + output
|
75
|
+
else
|
76
|
+
output = "|" + output
|
77
|
+
end
|
78
|
+
if t[:exists] == false
|
79
|
+
puts output.red
|
80
|
+
else
|
81
|
+
puts output
|
82
|
+
end
|
83
|
+
end
|
84
|
+
puts
|
85
|
+
exit 0
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'xml'
|
2
|
+
module DocbookFiles
|
3
|
+
|
4
|
+
# Analyzes a DocBook 5 file for included and referenced files.
|
5
|
+
class Docbook
|
6
|
+
|
7
|
+
# The DocBook 5 namespace URL
|
8
|
+
#
|
9
|
+
DOCBOOK_NS = 'http://docbook.org/ns/docbook'
|
10
|
+
|
11
|
+
# The XInclude namespace URL
|
12
|
+
#
|
13
|
+
XINCLUDE_NS = 'http://www.w3.org/2001/XInclude'
|
14
|
+
|
15
|
+
# The FileData tree representing the file hierarchy
|
16
|
+
attr_reader :fd_tree
|
17
|
+
|
18
|
+
def initialize(fname)
|
19
|
+
@main_name = fname
|
20
|
+
@fd_tree = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return the FileData tree representing the include
|
24
|
+
# hierarchy.
|
25
|
+
#
|
26
|
+
def list
|
27
|
+
@fd_tree ||= analyze_file(@main_name,File.dirname(@main_name))
|
28
|
+
@fd_tree
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return all file names in a tree
|
32
|
+
def list_names
|
33
|
+
fl = self.list()
|
34
|
+
fl.names
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return a _flat_ array of FileDatas, a table with
|
38
|
+
# level indicator. The format is easier for tabular output.
|
39
|
+
#
|
40
|
+
def list_as_table(props)
|
41
|
+
tree = self.list()
|
42
|
+
tree.traverse_as_table(props)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
# Check whether the document has a DocBook default namespace
|
47
|
+
def docbook?(doc)
|
48
|
+
dbns = doc.root.namespaces.default
|
49
|
+
(!dbns.nil? && (dbns.href.casecmp(DOCBOOK_NS) == 0))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Get the default namespace string for the document,
|
53
|
+
# or an empty string if there is none
|
54
|
+
def namespace(doc)
|
55
|
+
ns = doc.root.namespaces.default
|
56
|
+
unless ns.nil?
|
57
|
+
ns.href
|
58
|
+
else
|
59
|
+
""
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the start tag of the XML document
|
64
|
+
def start_tag(doc)
|
65
|
+
doc.root.name
|
66
|
+
end
|
67
|
+
|
68
|
+
# Reads the _version_ attribute of the root node,
|
69
|
+
# mainly for DocBook 5+
|
70
|
+
def version(doc)
|
71
|
+
doc.root['version']
|
72
|
+
end
|
73
|
+
|
74
|
+
# Check whether the document has a XInclude namespace
|
75
|
+
def has_xinclude?(doc)
|
76
|
+
ret = false
|
77
|
+
doc.root.namespaces.each do |ns|
|
78
|
+
if (ns.href.casecmp(XINCLUDE_NS) == 0)
|
79
|
+
ret = true
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
ret
|
84
|
+
end
|
85
|
+
|
86
|
+
# Finds and returns all XInclude files/URLs in a document.
|
87
|
+
#
|
88
|
+
# OPTIMIZE implement xpointer and fallback handling for
|
89
|
+
# xi:include? see http://www.w3.org/TR/xinclude/
|
90
|
+
#
|
91
|
+
def find_xincludes(doc)
|
92
|
+
if has_xinclude?(doc)
|
93
|
+
xincs = doc.find('//xi:include', "xi:"+XINCLUDE_NS)
|
94
|
+
xincs.map {|x| x.attributes['href'] }
|
95
|
+
else
|
96
|
+
[]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# Opens a XML document and looks for included or referenced files.
|
102
|
+
# Returns a FileData object with its include-tree
|
103
|
+
#
|
104
|
+
def analyze_file(fname, parent_dir, parent_fd=nil)
|
105
|
+
fl = FileData.new(fname, parent_dir, parent_fd)
|
106
|
+
begin
|
107
|
+
doc = XML::Document.file(fl.full_name)
|
108
|
+
fl.namespace = namespace(doc)
|
109
|
+
fl.docbook = true if docbook?(doc)
|
110
|
+
fl.version = version(doc) if fl.docbook
|
111
|
+
fl.tag = start_tag(doc)
|
112
|
+
files = find_xincludes(doc)
|
113
|
+
rescue Exception => e
|
114
|
+
files = []
|
115
|
+
end
|
116
|
+
fl.includes = files.map {|f| analyze_file(f,parent_dir,fl)}
|
117
|
+
fl
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module DocbookFiles
|
2
|
+
require 'date'
|
3
|
+
require 'digest/sha1'
|
4
|
+
require 'wand'
|
5
|
+
|
6
|
+
# Data about a member file of a DocBook project
|
7
|
+
class FileData
|
8
|
+
|
9
|
+
# file name, full file path, existence flag, last modified timestamp, size in bytes
|
10
|
+
# SHA1 checksum, MIME type, array of included FileDatas
|
11
|
+
#attr_accessor :name, :full_name, :exists, :ts, :size, :checksum, :mime, :includes
|
12
|
+
|
13
|
+
# XML namespace, Flag for DocBook NS, DocBook version, start tag
|
14
|
+
#attr_accessor :namespace, :docbook, :version, :tag
|
15
|
+
|
16
|
+
attr_accessor :name, :exists, :includes
|
17
|
+
|
18
|
+
def FileData.init_vars()
|
19
|
+
x = {:full_name => "file name + path",
|
20
|
+
:ts => "last modified timestamp",
|
21
|
+
:size => "file size",
|
22
|
+
:checksum => "file checksum",
|
23
|
+
:mime => "the file's MIME type",
|
24
|
+
:namespace => "XML namespace, if applicable",
|
25
|
+
:docbook => "DocBook type flag",
|
26
|
+
:version => "DocBook version number, if applicable",
|
27
|
+
:tag => "XML start tag, if applicable",
|
28
|
+
:parent => "parent file, if included or referenced"}
|
29
|
+
x.each { |s,ex|
|
30
|
+
attr_accessor s
|
31
|
+
}
|
32
|
+
x
|
33
|
+
end
|
34
|
+
|
35
|
+
@@vars = init_vars()
|
36
|
+
|
37
|
+
|
38
|
+
def initialize(name,parent_dir=".",parent_file=nil)
|
39
|
+
@name = name
|
40
|
+
@full_name = get_full_name(name, parent_dir)
|
41
|
+
@name = File.basename(name)
|
42
|
+
@namespace = ""
|
43
|
+
@docbook = false
|
44
|
+
@version = ""
|
45
|
+
@tag = ""
|
46
|
+
@parent = (parent_file.nil? ? nil : parent_file.name)
|
47
|
+
if (File.exists?(@full_name))
|
48
|
+
@exists = true
|
49
|
+
@ts = File.mtime(full_name)
|
50
|
+
@size = File.size(full_name)
|
51
|
+
@checksum = calc_checksum()
|
52
|
+
@mime = get_mime_type()
|
53
|
+
else
|
54
|
+
@exists = false
|
55
|
+
@ts = Time.now
|
56
|
+
@size = 0
|
57
|
+
@checksum = ""
|
58
|
+
@mime = ""
|
59
|
+
end
|
60
|
+
@includes = []
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Does the really file exist?
|
65
|
+
def exists?
|
66
|
+
@exists
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return the names and parent files of non-existing files
|
70
|
+
def find_non_existing_files
|
71
|
+
files = traverse([:name, :exists, :parent])
|
72
|
+
files.flatten.reject{|f| f[:exists] == true}.map{|f| f.delete(:exists); f}
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return a tree-like array with all names
|
76
|
+
def names
|
77
|
+
self.traverse([:name])
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return a hash with the values for the passed symbols.
|
81
|
+
# If the property list is empty all instance variables
|
82
|
+
# are used, except the include.
|
83
|
+
#
|
84
|
+
# Example: to_hash([:name, :mime]) would return
|
85
|
+
# {:name => "name", :mime => "application/xml"}.
|
86
|
+
#
|
87
|
+
def to_hash(props=[])
|
88
|
+
me_hash = {}
|
89
|
+
if (props.empty?)
|
90
|
+
ivs = self.instance_variables
|
91
|
+
ivs.delete(:@includes)
|
92
|
+
props = ivs.map {|iv| ivs = iv.to_s; ivs[1,ivs.length].to_sym}
|
93
|
+
end
|
94
|
+
props.each {|p| me_hash[p] = self.send(p)}
|
95
|
+
me_hash
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return a tree-like array of maps with the
|
99
|
+
# requested properties (symbols)
|
100
|
+
def traverse(props=[])
|
101
|
+
me = self.to_hash(props)
|
102
|
+
if @includes.empty?()
|
103
|
+
[me]
|
104
|
+
else
|
105
|
+
[me] + @includes.map {|i| i.traverse(props)}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return a table-like array of maps with the
|
110
|
+
# requested properties (symbols). Each entry gets a level
|
111
|
+
# indicator (:level) to show the tree-level.
|
112
|
+
#
|
113
|
+
def traverse_as_table(props=[],level=0)
|
114
|
+
me = self.to_hash(props)
|
115
|
+
me[:level] = level
|
116
|
+
if @includes.empty?()
|
117
|
+
ret = [me]
|
118
|
+
else
|
119
|
+
ret = [me] + @includes.map {|i| i.traverse_as_table(props,level+1)}
|
120
|
+
end
|
121
|
+
ret.flatten
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
# Calculate the SHA1 checksum for the file
|
127
|
+
def calc_checksum
|
128
|
+
Digest::SHA1.hexdigest(IO.binread(@full_name))
|
129
|
+
end
|
130
|
+
|
131
|
+
# Produce the full path for a filename
|
132
|
+
def get_full_name(fname, parent_dir)
|
133
|
+
dir = File.dirname(fname)
|
134
|
+
file = File.basename(fname)
|
135
|
+
full_name = File.expand_path(file,dir)
|
136
|
+
unless File.exists?(full_name)
|
137
|
+
full_name = File.expand_path(fname, parent_dir)
|
138
|
+
end
|
139
|
+
full_name
|
140
|
+
end
|
141
|
+
|
142
|
+
# Try to find the file's MIME type
|
143
|
+
def get_mime_type
|
144
|
+
Wand.wave(@full_name)
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module DocbookFiles
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
6
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
7
|
+
VERSION = ::File.read(PATH + 'version.txt').strip
|
8
|
+
# :startdoc:
|
9
|
+
|
10
|
+
# Returns the library path for the module. If any arguments are given,
|
11
|
+
# they will be joined to the end of the libray path using
|
12
|
+
# <tt>File.join</tt>.
|
13
|
+
#
|
14
|
+
def self.libpath( *args )
|
15
|
+
rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
16
|
+
if block_given?
|
17
|
+
begin
|
18
|
+
$LOAD_PATH.unshift LIBPATH
|
19
|
+
rv = yield
|
20
|
+
ensure
|
21
|
+
$LOAD_PATH.shift
|
22
|
+
end
|
23
|
+
end
|
24
|
+
return rv
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the lpath for the module. If any arguments are given,
|
28
|
+
# they will be joined to the end of the path using
|
29
|
+
# <tt>File.join</tt>.
|
30
|
+
#
|
31
|
+
def self.path( *args )
|
32
|
+
rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
33
|
+
if block_given?
|
34
|
+
begin
|
35
|
+
$LOAD_PATH.unshift PATH
|
36
|
+
rv = yield
|
37
|
+
ensure
|
38
|
+
$LOAD_PATH.shift
|
39
|
+
end
|
40
|
+
end
|
41
|
+
return rv
|
42
|
+
end
|
43
|
+
|
44
|
+
# Utility method used to require all files ending in .rb that lie in the
|
45
|
+
# directory below this file that has the same name as the filename passed
|
46
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
47
|
+
# the _filename_ does not have to be equivalent to the directory.
|
48
|
+
#
|
49
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
50
|
+
dir ||= ::File.basename(fname, '.*')
|
51
|
+
search_me = ::File.expand_path(
|
52
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
53
|
+
|
54
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
55
|
+
end
|
56
|
+
|
57
|
+
end # module DocbookFiles
|
58
|
+
|
59
|
+
DocbookFiles.require_all_libs_relative_to(__FILE__)
|
60
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(
|
3
|
+
File.join(File.dirname(__FILE__), %w[.. lib docbook_files]))
|
4
|
+
|
5
|
+
Spec::Runner.configure do |config|
|
6
|
+
# == Mock Framework
|
7
|
+
#
|
8
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
9
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
10
|
+
#
|
11
|
+
# config.mock_with :mocha
|
12
|
+
# config.mock_with :flexmock
|
13
|
+
# config.mock_with :rr
|
14
|
+
end
|
15
|
+
|
data/test/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require "docbook_files"
|
5
|
+
require 'turn'
|
6
|
+
|
7
|
+
module DocbookFiles
|
8
|
+
describe Docbook do
|
9
|
+
|
10
|
+
it "can cope with invalid xml files" do
|
11
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/no-xml.xml")
|
12
|
+
actual = dbf.list()
|
13
|
+
actual.must_be_kind_of(DocbookFiles::FileData)
|
14
|
+
actual.name.must_equal("no-xml.xml")
|
15
|
+
actual.size.must_equal(15)
|
16
|
+
actual.docbook.must_equal(false)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds namespace, DocBook-ness, version" do
|
20
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/bookxi.xml")
|
21
|
+
actual = dbf.list()
|
22
|
+
actual.namespace.must_equal("http://docbook.org/ns/docbook")
|
23
|
+
actual.docbook.must_equal(true)
|
24
|
+
actual.version.must_equal("5.0")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "finds no namespace, DocBook-ness, version" do
|
28
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/no-ns.xml")
|
29
|
+
actual = dbf.list()
|
30
|
+
actual.namespace.must_equal("")
|
31
|
+
actual.docbook.must_equal(false)
|
32
|
+
actual.version.must_equal("")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "finds a tag" do
|
36
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/bookxi.xml")
|
37
|
+
actual = dbf.list()
|
38
|
+
actual.tag.must_equal("book")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "lists" do
|
42
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/bookxi.xml")
|
43
|
+
actual = dbf.list()
|
44
|
+
expected = [{:name=>"bookxi.xml"},
|
45
|
+
[{:name=>"chapter2xi.xml"}, [{:name=>"section1xi.xml"}]],
|
46
|
+
[{:name=>"chapter3xi.xml"}], [{:name=>"chapter4xi.xml"}]]
|
47
|
+
actual.names.must_equal(expected)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "lists as a table" do
|
51
|
+
dbf = DocbookFiles::Docbook.new("test/fixtures/bookxi.xml")
|
52
|
+
actual = dbf.list_as_table([:name])
|
53
|
+
expected = [{:name=>"bookxi.xml", :level=>0},
|
54
|
+
{:name=>"chapter2xi.xml", :level=>1},
|
55
|
+
{:name=>"section1xi.xml", :level=>2},
|
56
|
+
{:name=>"chapter3xi.xml", :level=>1},
|
57
|
+
{:name=>"chapter4xi.xml", :level=>1}]
|
58
|
+
actual.must_equal(expected)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require "docbook_files"
|
5
|
+
require 'date'
|
6
|
+
require 'turn'
|
7
|
+
|
8
|
+
module DocbookFiles
|
9
|
+
describe FileData do
|
10
|
+
it "initializes" do
|
11
|
+
end
|
12
|
+
|
13
|
+
it "calculates a checksum" do
|
14
|
+
f = FileData.new("test/fixtures/bookxi.xml")
|
15
|
+
f.checksum.must_equal("7d240e7a084c16665ac59e5b927acd6a06953897")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "finds a XML MIME type" do
|
19
|
+
f = FileData.new("test/fixtures/bookxi.xml")
|
20
|
+
f.mime.must_equal("application/xml")
|
21
|
+
end
|
22
|
+
|
23
|
+
it "finds a plain text MIME type" do
|
24
|
+
skip "Different MIME lib?"
|
25
|
+
f = FileData.new("test/fixtures/no-xml.xml")
|
26
|
+
f.mime.wont_equal("application/xml")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "converts a single FileData instance to a hash" do
|
30
|
+
f = FileData.new("test/fixtures/bookxi.xml")
|
31
|
+
actual = f.to_hash([:name,:mime,:size])
|
32
|
+
actual.must_equal({:name=>"bookxi.xml", :mime=>"application/xml", :size=>481})
|
33
|
+
actual = f.to_hash()
|
34
|
+
expected = {:name=>"bookxi.xml",
|
35
|
+
:full_name=>"/Users/rv/Documents/Projekte/docbook_files/test/fixtures/bookxi.xml",
|
36
|
+
:namespace=>"", :docbook=>false, :version=>"", :tag=>"", :parent=>nil, :exists=>true,
|
37
|
+
:ts=>Time.parse("2011-10-06 20:45:01 +0200"), :size=>481,
|
38
|
+
:checksum=>"7d240e7a084c16665ac59e5b927acd6a06953897", :mime=>"application/xml"}
|
39
|
+
actual.must_equal(expected)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "converts a FileData tree to an array of hashes" do
|
43
|
+
f1 = FileData.new("test/fixtures/bookxi.xml")
|
44
|
+
f2 = FileData.new("test/fixtures/chapter2xi.xml")
|
45
|
+
f3 = FileData.new("test/fixtures/chapter3xi.xml")
|
46
|
+
f1.includes = [f2]
|
47
|
+
f2.includes = [f3]
|
48
|
+
expected = [{:name=>"bookxi.xml", :mime=>"application/xml", :size=>481},
|
49
|
+
[{:name=>"chapter2xi.xml", :mime=>"application/xml", :size=>366},
|
50
|
+
[{:name=>"chapter3xi.xml", :mime=>"application/xml", :size=>286}]]]
|
51
|
+
actual = f1.traverse([:name,:mime,:size])
|
52
|
+
actual.must_equal(expected)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "converts a FileData tree to a table of hashes" do
|
56
|
+
f1 = FileData.new("test/fixtures/bookxi.xml")
|
57
|
+
f2 = FileData.new("test/fixtures/chapter2xi.xml")
|
58
|
+
f3 = FileData.new("test/fixtures/chapter3xi.xml")
|
59
|
+
f1.includes = [f2]
|
60
|
+
f2.includes = [f3]
|
61
|
+
expected = [{:name=>"bookxi.xml", :mime=>"application/xml", :size=>481, :level=>0},
|
62
|
+
{:name=>"chapter2xi.xml", :mime=>"application/xml", :size=>366, :level=>1},
|
63
|
+
{:name=>"chapter3xi.xml", :mime=>"application/xml", :size=>286, :level=>2}]
|
64
|
+
actual = f1.traverse_as_table([:name,:mime,:size])
|
65
|
+
actual.must_equal(expected)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "finds non-existing files" do
|
69
|
+
f1 = FileData.new("test/fixtures/bookxi.xml")
|
70
|
+
f2 = FileData.new("test/fixtures/chapter2xi.xml",".",f1)
|
71
|
+
f3 = FileData.new("test/fixtures/chapter3xi.xml",".",f2)
|
72
|
+
f5 = FileData.new("test/fixtures/non-existing.xml",".",f2)
|
73
|
+
f1.includes = [f2]
|
74
|
+
f2.includes = [f3,f5]
|
75
|
+
expected = [{:name=>"non-existing.xml", :parent=>"chapter2xi.xml"}]
|
76
|
+
actual = f1.find_non_existing_files()
|
77
|
+
actual.must_equal(expected)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<book xmlns="http://docbook.org/ns/docbook"
|
3
|
+
xmlns:xi="http://www.w3.org/2001/XInclude"
|
4
|
+
version="5.0">
|
5
|
+
<title>B1</title>
|
6
|
+
<chapter>
|
7
|
+
<title>C1</title>
|
8
|
+
<para>
|
9
|
+
Dies ist ein Test .. Dies ist ein Test.
|
10
|
+
In den Jahren 1900-1901 geschahen viele Überfälle von O`Reillys.
|
11
|
+
</para>
|
12
|
+
</chapter>
|
13
|
+
<xi:include href="chapter2xi.xml"/>
|
14
|
+
<xi:include href="non-existing.xml"/>
|
15
|
+
<xi:include href="c4/chapter4xi.xml"/>
|
16
|
+
</book>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<book xmlns="http://docbook.org/ns/docbook"
|
3
|
+
xmlns:xi="http://www.w3.org/2001/XInclude"
|
4
|
+
version="5.0">
|
5
|
+
<title>B1</title>
|
6
|
+
<chapter>
|
7
|
+
<title>C1</title>
|
8
|
+
<para>
|
9
|
+
Dies ist ein Test .. Dies ist ein Test.
|
10
|
+
In den Jahren 1900-1901 geschahen viele Überfälle von O`Reillys.
|
11
|
+
</para>
|
12
|
+
</chapter>
|
13
|
+
<xi:include href="chapter2xi.xml"/>
|
14
|
+
<xi:include href="chapter3xi.xml"/>
|
15
|
+
<xi:include href="c4/chapter4xi.xml"/>
|
16
|
+
</book>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<chapter xmlns="http://docbook.org/ns/docbook"
|
2
|
+
xmlns:xi="http://www.w3.org/2001/XInclude"
|
3
|
+
version="5.0">
|
4
|
+
<title>C2</title>
|
5
|
+
<para>
|
6
|
+
Dies ist ein Test .. Dies ist ein Test.
|
7
|
+
In den Jahren 1900-1901 geschahen viele Überfälle von O`Reillys.
|
8
|
+
<remark>FIXME Ausbauen.</remark>
|
9
|
+
</para>
|
10
|
+
<xi:include href="section1xi.xml"/>
|
11
|
+
</chapter>
|
@@ -0,0 +1 @@
|
|
1
|
+
bla bla bla...
|
data/version.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docbook_files
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rainer Volz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-07 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bones
|
16
|
+
requirement: &2165106040 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.7.1
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2165106040
|
25
|
+
description: docbook_files lists and checks all files related to a DocBook writing
|
26
|
+
project.
|
27
|
+
email: dev@textmulch.de
|
28
|
+
executables:
|
29
|
+
- docbook_files
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files:
|
32
|
+
- History.txt
|
33
|
+
- bin/docbook_files
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- Gemfile
|
37
|
+
- Gemfile.lock
|
38
|
+
- History.txt
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- bin/docbook_files
|
42
|
+
- lib/docbook_files.rb
|
43
|
+
- lib/docbook_files/docbook.rb
|
44
|
+
- lib/docbook_files/file_data.rb
|
45
|
+
- spec/docbook_files_spec.rb
|
46
|
+
- spec/spec_helper.rb
|
47
|
+
- test/.DS_Store
|
48
|
+
- test/docbook_files/test_docbook.rb
|
49
|
+
- test/docbook_files/test_file_data.rb
|
50
|
+
- test/fixtures/book-nonexisting.xml
|
51
|
+
- test/fixtures/bookxi.xml
|
52
|
+
- test/fixtures/c4/chapter4xi.xml
|
53
|
+
- test/fixtures/chapter2xi.xml
|
54
|
+
- test/fixtures/chapter3xi.xml
|
55
|
+
- test/fixtures/no-ns.xml
|
56
|
+
- test/fixtures/no-xml.xml
|
57
|
+
- test/fixtures/section1xi.xml
|
58
|
+
- test/test_docbook_files.rb
|
59
|
+
- version.txt
|
60
|
+
homepage: http://github.com/rvolz/docbook_files/
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options:
|
64
|
+
- --main
|
65
|
+
- README.md
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project: docbook_files
|
82
|
+
rubygems_version: 1.8.10
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: docbook_files lists and checks all files related to a DocBook writing project.
|
86
|
+
test_files:
|
87
|
+
- test/docbook_files/test_docbook.rb
|
88
|
+
- test/docbook_files/test_file_data.rb
|
89
|
+
- test/test_docbook_files.rb
|