diff options
-rw-r--r-- | lib/checks/anchors.rb | 175 | ||||
-rw-r--r-- | lib/gitlab/docs/document.rb | 16 | ||||
-rw-r--r-- | lib/gitlab/docs/element.rb | 32 | ||||
-rw-r--r-- | lib/gitlab/docs/link.rb | 71 | ||||
-rw-r--r-- | lib/gitlab/docs/nanoc.rb | 13 | ||||
-rw-r--r-- | lib/gitlab/docs/page.rb | 46 |
6 files changed, 179 insertions, 174 deletions
diff --git a/lib/checks/anchors.rb b/lib/checks/anchors.rb index 9d6121d16..a1e2b82e7 100644 --- a/lib/checks/anchors.rb +++ b/lib/checks/anchors.rb @@ -1,176 +1,3 @@ -module Gitlab - module Docs - module Nanoc - def self.config - @config ||= YAML.load(File.read('nanoc.yaml')) - end - - def self.output_dir - config.fetch('output_dir') - end - end - - class Element - def initialize(name, attributes) - @name = name - @attributes = attributes - end - - def link? - @name == 'a' && !href.to_s.empty? - end - - def has_id? - !id.to_s.empty? - end - - def href - @href ||= attribute('href') - end - - def id - @id ||= attribute('id') - end - - private - - def attribute(name) - @attributes.find { |attr| attr.first == name }&.last - end - end - - class Document < Nokogiri::XML::SAX::Document - def initialize(page) - @page = page - end - - def start_element(name, attributes = []) - Gitlab::Docs::Element.new(name, attributes).tap do |element| - @page.hrefs << element.href if element.link? - @page.ids << element.id if element.has_id? - end - end - end - - class Page - attr_reader :file - attr_accessor :hrefs, :ids - - def initialize(file) - @file = file - - @hrefs = [] - @ids = [] - - return unless exists? - - Nokogiri::HTML::SAX::Parser - .new(Gitlab::Docs::Document.new(self)) - .parse(File.read(file)) - end - - def exists? - File.exists?(@file) - end - - def directory - File.dirname(@file) - end - - def content - raise unless exists? - - @content ||= File.read(@file) - end - - def links - @links ||= @hrefs.map do |link| - Gitlab::Docs::Link.new(link, self) - end - end - - def has_anchor?(name) - @ids.include?(name) - end - - def self.build(path) - if path.end_with?('.html') - new(path) - else - new(File.join(path, 'index.html')) - end - end - end - - class Link - attr_reader :link, :href, :page - - def initialize(link, page) - @href = link - @page = page - end - - def to_anchor? - @href.to_s.include?('#') - end - - def anchor_name - raise ArguentError unless to_anchor? - - @href.to_s.partition('#').last.downcase - end - - def internal_anchor? - raise ArguentError unless to_anchor? - - @href.to_s.partition('#').first.empty? - end - - def internal? - @href.to_s.length > 0 && !@href.include?(':') - end - - def path - @href.to_s.partition('#').first - end - - def absolute_path - raise unless internal? - - if @href.start_with?('/') - Gitlab::Docs::Nanoc.output_dir + path - else - ::File.expand_path(path, @page.directory) - end - end - - def destination_page - if internal_anchor? - @page - else - Gitlab::Docs::Page.build(absolute_path) - end - end - - def source_file - @page.file - end - - def destination_file - destination_page.file - end - - def destination_page_not_found? - !destination_page.exists? - end - - def destination_anchor_not_found? - !destination_page.has_anchor?(anchor_name) - end - end - end -end - Nanoc::Check.define(:internal_anchors) do output_html_filenames.each do |file| Gitlab::Docs::Page.new(file).links.each do |link| @@ -182,8 +9,8 @@ Nanoc::Check.define(:internal_anchors) do add_issue <<~ERROR Destination page not found! - link `#{link.href}` - - destination `#{link.destination_file}` - source file `#{link.source_file}` + - destination `#{link.destination_file}` ERROR elsif link.destination_anchor_not_found? add_issue <<~ERROR diff --git a/lib/gitlab/docs/document.rb b/lib/gitlab/docs/document.rb new file mode 100644 index 000000000..d4e486b24 --- /dev/null +++ b/lib/gitlab/docs/document.rb @@ -0,0 +1,16 @@ +module Gitlab + module Docs + class Document < Nokogiri::XML::SAX::Document + def initialize(page) + @page = page + end + + def start_element(name, attributes = []) + Gitlab::Docs::Element.new(name, attributes).tap do |element| + @page.hrefs << element.href if element.link? + @page.ids << element.id if element.has_id? + end + end + end + end +end diff --git a/lib/gitlab/docs/element.rb b/lib/gitlab/docs/element.rb new file mode 100644 index 000000000..a78b9a011 --- /dev/null +++ b/lib/gitlab/docs/element.rb @@ -0,0 +1,32 @@ +module Gitlab + module Docs + class Element + def initialize(name, attributes) + @name = name + @attributes = attributes + end + + def link? + @name == 'a' && !href.to_s.empty? + end + + def has_id? + !id.to_s.empty? + end + + def href + @href ||= attribute('href') + end + + def id + @id ||= attribute('id') + end + + private + + def attribute(name) + @attributes.find { |attr| attr.first == name }&.last + end + end + end +end diff --git a/lib/gitlab/docs/link.rb b/lib/gitlab/docs/link.rb new file mode 100644 index 000000000..8509f0ca6 --- /dev/null +++ b/lib/gitlab/docs/link.rb @@ -0,0 +1,71 @@ +module Gitlab + module Docs + class Link + attr_reader :link, :href, :page + + def initialize(link, page) + @href = link + @page = page + end + + def to_anchor? + @href.to_s.include?('#') + end + + def anchor_name + raise ArgumentError unless to_anchor? + + @href.to_s.partition('#').last.downcase + end + + def internal_anchor? + raise ArgumentError unless to_anchor? + + @href.to_s.partition('#').first.empty? + end + + def internal? + @href.to_s.length > 0 && !@href.include?(':') + end + + def path + @href.to_s.partition('#').first + end + + def absolute_path + raise unless internal? + + if @href.start_with?('/') + Gitlab::Docs::Nanoc.output_dir + path + else + ::File.expand_path(path, @page.directory) + end + end + + def destination_page + if internal_anchor? + @page + else + Gitlab::Docs::Page.build(absolute_path) + end + end + + def source_file + @page.file + end + + def destination_file + destination_page.file + end + + def destination_page_not_found? + !destination_page.exists? + end + + def destination_anchor_not_found? + !destination_page.has_anchor?(anchor_name) + end + end + end +end + diff --git a/lib/gitlab/docs/nanoc.rb b/lib/gitlab/docs/nanoc.rb new file mode 100644 index 000000000..70b4c3977 --- /dev/null +++ b/lib/gitlab/docs/nanoc.rb @@ -0,0 +1,13 @@ +module Gitlab + module Docs + module Nanoc + def self.config + @config ||= YAML.load(File.read('nanoc.yaml')) + end + + def self.output_dir + config.fetch('output_dir') + end + end + end +end diff --git a/lib/gitlab/docs/page.rb b/lib/gitlab/docs/page.rb new file mode 100644 index 000000000..8bd5e9b98 --- /dev/null +++ b/lib/gitlab/docs/page.rb @@ -0,0 +1,46 @@ +module Gitlab + module Docs + class Page + attr_reader :file + attr_accessor :hrefs, :ids + + def initialize(file) + @file = file + @hrefs = [] + @ids = [] + + return unless exists? + + Nokogiri::HTML::SAX::Parser + .new(Gitlab::Docs::Document.new(self)) + .parse(File.read(file)) + end + + def exists? + File.exists?(@file) + end + + def directory + File.dirname(@file) + end + + def links + @links ||= @hrefs.map do |link| + Gitlab::Docs::Link.new(link, self) + end + end + + def has_anchor?(name) + @ids.include?(name) + end + + def self.build(path) + if path.end_with?('.html') + new(path) + else + new(File.join(path, 'index.html')) + end + end + end + end +end |