Permalink
Browse files

Initial implementation

Will parse XML files to check for duplicate ids and too-long lines in programlistings

Check out the specs.

I'll be back after din-dins to write a little CLI for it.
  • Loading branch information...
0 parents commit 591fb97b1605e6419d450697a5d6c68b2deaeb3f @radar committed Jun 27, 2012
17 .gitignore
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
4 Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in manning-docbook-validator.gemspec
+gemspec
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Ryan Bigg
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 README.md
@@ -0,0 +1,29 @@
+# Manning::Docbook::Validator
+
+TODO: Write a gem description
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+ gem 'manning-docbook-validator'
+
+And then execute:
+
+ $ bundle
+
+Or install it yourself as:
+
+ $ gem install manning-docbook-validator
+
+## Usage
+
+TODO: Write usage instructions here
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
2 Rakefile
@@ -0,0 +1,2 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
50 lib/manning-docbook-validator.rb
@@ -0,0 +1,50 @@
+require "manning-docbook-validator/version"
+require "manning-docbook-validator/error"
+require "nokogiri"
+
+module Manning
+ module Docbook
+ class Validator
+ attr_accessor :file, :document, :errors
+
+ def initialize(path)
+ @errors = []
+ @file = File.read(path)
+ @document = Nokogiri::XML(@file)
+ end
+
+ def validate!
+ check_for_duplicate_ids!
+ check_line_lengths!
+ self
+ end
+
+ private
+
+ def check_for_duplicate_ids!
+ ids = {}
+ document.css("*[id]").each do |el|
+ id = el[:id]
+ line = el.line
+ if ids[id]
+ errors << Error.new("Duplicate id located on line ##{line}: #{id}. First seen on line ##{ids[id]}.")
+ else
+ ids[el[:id]] = el.line
+ end
+ end
+ end
+
+ def check_line_lengths!
+ document.css("programlisting").each do |el|
+ parent = el.parent
+ lines = el.text.split("\n")
+ lines.each_with_index do |line, i|
+ if line.length > 72
+ errors << Error.new("Code on line #{i+1} of #{parent.name}##{parent[:id]} is too long. Line limit is 72 characters.")
+ end
+ end
+ end
+ end
+ end
+ end
+end
12 lib/manning-docbook-validator/error.rb
@@ -0,0 +1,12 @@
+module Manning
+ module Docbook
+ class Validator
+ class Error
+ attr_accessor :message
+ def initialize(message)
+ @message = message
+ end
+ end
+ end
+ end
+end
7 lib/manning-docbook-validator/version.rb
@@ -0,0 +1,7 @@
+module Manning
+ module Docbook
+ class Validator
+ VERSION = "0.0.1"
+ end
+ end
+end
21 manning-docbook-validator.gemspec
@@ -0,0 +1,21 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/manning-docbook-validator/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Ryan Bigg"]
+ gem.email = ["radarlistener@gmail.com"]
+ gem.description = %q{TODO: Write a gem description}
+ gem.summary = %q{TODO: Write a gem summary}
+ gem.homepage = ""
+
+ gem.files = `git ls-files`.split($\)
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.name = "manning-docbook-validator"
+ gem.require_paths = ["lib"]
+ gem.version = Manning::Docbook::Validator::VERSION
+
+ gem.add_dependency 'nokogiri', '~> 1.5.5'
+ gem.add_development_dependency 'rspec', '~> 2.10'
+
+end
22 spec/fixtures/example.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<chapter>
+ <informalexample id="ch01_1">
+ <programlisting>*************************************************************************</programlisting>
+ </informalexample>
+ <example id="ch01_2">
+ <programlisting>*************************************************************************</programlisting>
+ </example>
+ <informalexample id="ch01_3">
+ <programlisting>************************************************************************</programlisting>
+ </informalexample>
+ <example id="ch01_4">
+ <programlisting>************************************************************************</programlisting>
+ </example>
+ <example id="ch01_5">
+ <programlisting>************************************************************************
+<co id="ch01_4_1"/>************************************************************************
+************************************************************************
+************************************************************************
+</programlisting>
+ </example>
+</chapter>
105 spec/validator_spec.rb
@@ -0,0 +1,105 @@
+require 'manning-docbook-validator'
+
+describe 'validator' do
+ before do
+ FileUtils.rm_rf("spec/fixtures")
+ FileUtils.mkdir_p("spec/fixtures")
+ end
+
+ let(:path) { "spec/fixtures/example.xml" }
+
+ context 'errors on' do
+ context 'duplicate id attributes' do
+ before do
+ builder = Nokogiri::XML::Builder.new do |xml|
+ xml.chapter do
+ xml.para(:id => "ch01_1") { "content" }
+ xml.para(:id => "ch01_1") { "other content" }
+ xml.para(:id => "ch01_1") { "more content" }
+ end
+ end
+
+ File.open(path, "w+") do |f|
+ f.write builder.to_xml
+ end
+ end
+
+ let(:validator) do
+ Manning::Docbook::Validator.new(path).validate!
+ end
+
+ specify do
+ validator.errors.count.should == 2
+ validator.errors[0].message.should == "Duplicate id located on line #4: ch01_1. First seen on line #3."
+ validator.errors[1].message.should == "Duplicate id located on line #5: ch01_1. First seen on line #3."
+ end
+
+ end
+
+ context 'listing lines over 72 characters' do
+ before do
+ builder = Nokogiri::XML::Builder.new do |xml|
+ xml.chapter do
+ # FAIL
+ xml.informalexample(:id => "ch01_1") do
+ xml.programlisting do
+ xml.text "*" * 73
+ end
+ end
+
+ # FAIL
+ xml.example(:id => "ch01_2") do
+ xml.programlisting do
+ xml.text "*" * 73
+ end
+ end
+
+ # OK
+ xml.informalexample(:id => "ch01_3") do
+ xml.programlisting do
+ xml.text "*" * 72
+ end
+ end
+
+ # OK
+ xml.example(:id => "ch01_4") do
+ xml.programlisting do
+ xml.text "*" * 72
+ end
+ end
+
+ # OK
+ # Manning's own parser is a bit of a jerk about this.
+ # They are checking full-line-lengths probably using Regex or some other BS
+ # A callout doesn't count as an "official" count, so it should be ignored.
+ xml.example(:id => "ch01_5") do
+ xml.programlisting do
+ xml.text ("*" * 72) + "\n"
+ xml.co(:id => "ch01_4_1")
+ xml.text(("*" * 72) + "\n" +
+ ("*" * 72) + "\n" +
+ ("*" * 72) + "\n")
+ end
+ end
+ end
+ end
+
+ File.open(path, "w+") do |f|
+ f.write builder.to_xml
+ end
+ end
+
+ let(:validator) do
+ Manning::Docbook::Validator.new(path).validate!
+ end
+
+ specify do
+ validator.errors.count.should == 2
+ validator.errors[0].message.should == "Code on line 1 of informalexample#ch01_1 is too long. Line limit is 72 characters."
+ validator.errors[1].message.should == "Code on line 1 of example#ch01_2 is too long. Line limit is 72 characters."
+ end
+
+
+ end
+ end
+end

0 comments on commit 591fb97

Please sign in to comment.