#!/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 [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 ", "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, "
") # 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