bin/nokogiri
#!/usr/bin/env ruby
# frozen_string_literal: true
require "optparse"
require "open-uri"
require "uri"
require "rubygems"
require "nokogiri"
autoload :IRB, "irb"
parse_class = Nokogiri
encoding = nil
# This module provides some tunables with the nokogiri CLI for use in
# your ~/.nokogirirc.
module Nokogiri
module CLI
class << self
# Specify the console engine, defaulted to IRB.
#
# call-seq:
# require 'pry'
# Nokogiri::CLI.console = Pry
attr_writer :console
def console
case @console
when Symbol
Kernel.const_get(@console)
else
@console
end
end
attr_accessor :rcfile
end
self.rcfile = File.expand_path("~/.nokogirirc")
self.console = :IRB
end
end
def safe_read(uri_or_path)
uri = URI.parse(uri_or_path)
case uri
when URI::HTTP
uri.read
when URI::File
File.read(uri.path)
else
File.read(uri_or_path)
end
end
opts = OptionParser.new do |opts|
opts.banner = "Nokogiri: an HTML, XML, SAX, and Reader parser"
opts.define_head("Usage: nokogiri <uri|path> [options]")
opts.separator("")
opts.separator("Examples:")
opts.separator(" nokogiri https://www.ruby-lang.org/")
opts.separator(" nokogiri ./public/index.html")
opts.separator(" curl -s http://www.nokogiri.org | nokogiri -e'p $_.css(\"h1\").length'")
opts.separator("")
opts.separator("Options:")
opts.on("--type type", "Parse as type: xml or html (default: auto)", [:xml, :html]) do |v|
parse_class = { xml: Nokogiri::XML, html: Nokogiri::HTML }[v]
end
opts.on("-C file", "Specifies initialization file to load (default #{Nokogiri::CLI.rcfile})") do |v|
Nokogiri::CLI.rcfile = v
end
opts.on("-E", "--encoding encoding", "Read as encoding (default: #{encoding || "none"})") do |v|
encoding = v
end
opts.on("-e command", "Specifies script from command-line.") do |v|
@script = v
end
opts.on("--rng <uri|path>", "Validate using this rng file.") do |v|
@rng = Nokogiri::XML::RelaxNG(safe_read(v))
end
opts.on_tail("-?", "--help", "Show this message") do
puts opts
exit
end
opts.on_tail("-v", "--version", "Show version") do
puts Nokogiri::VersionInfo.instance.to_markdown
exit
end
end
opts.parse!
url = ARGV.shift
if url.to_s.strip.empty? && $stdin.tty?
puts opts
exit 1
end
if File.file?(Nokogiri::CLI.rcfile)
load Nokogiri::CLI.rcfile
end
@doc = if url || $stdin.tty?
parse_class.parse(safe_read(url), url, encoding)
else
parse_class.parse($stdin, nil, encoding)
end
$_ = @doc
if @rng
@rng.validate(@doc).each do |error|
puts error.message
end
elsif @script
begin
eval(@script, binding, "<main>") # rubocop:disable Security/Eval
rescue Exception => e # rubocop:disable Lint/RescueException
warn("ERROR: Exception raised while evaluating '#{@script}'")
raise e
end
else
puts "Your document is stored in @doc..."
Nokogiri::CLI.console.start
end