Skip to content

Instantly share code, notes, and snippets.

@marian13
Last active May 14, 2023 15:31
Show Gist options
  • Save marian13/78478a647238fcaaa332438497980476 to your computer and use it in GitHub Desktop.
Save marian13/78478a647238fcaaa332438497980476 to your computer and use it in GitHub Desktop.

Format and highlight HTML from Ruby

Usage

Copy monkey_patch.rb or util.rb content into your project.

API

string.to_pretty_html
string.to_pretty_html(skip_validation: false) # default
string.to_pretty_html(skip_validation: true)

Example

  • Create a file named example.rb.

  • Copy its content from gist.

  • Run it.

ruby example.rb
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "htmlbeautifier"
gem "nokogiri"
gem "rouge"
##
# Uncomment if need to debug.
#
gem "byebug"
end
class String
##
# Returns formatted and highlighted html string.
#
# If html is malformed - returns unmodified original string.
#
# @param skip_validation [Boolean]
# @return [String]
#
# @note Expected to be called on html string.
#
def to_pretty_html(skip_validation: false)
original_html = self
##
# - https://nokogiri.org/tutorials/ensuring_well_formed_markup.html
# - https://stackoverflow.com/a/24579476/12201472
#
validate = proc { |html| ::Nokogiri::XML(html) { |config| config.strict } rescue return html unless skip_validation }
##
# - https://github.com/threedaymonk/htmlbeautifier
#
format = proc { |html| ::HtmlBeautifier.beautify(html) }
##
# - https://github.com/rouge-ruby/rouge
# - https://gist.github.com/marian13/5dade20a431d7254db30e543167058ce
#
highlight = proc { |html| ::Rouge::Formatters::Terminal256.new(::Rouge::Themes::Monokai.new).format(::Rouge::Lexers::HTML.new.lex(html)) }
original_html.tap(&validate).then(&format).then(&highlight)
end
end
##
# Happy path example.
#
html = <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
HTML
##
# Returns formatted and highlighted html string.
#
puts html.to_pretty_html
##
# Unhappy path example.
#
ruby = <<~RUBY
##
# @return [Hash{Symbol => ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::MiddlewareCreators::Observable::Entities::Event}]
#
def events
@events ||= ::Hash.new { |hash, key| hash[key] = Entities::Event.new(type: key) }
end
##
# @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
#
def decorated_middleware
middleware.to_observable_middleware
end
RUBY
##
# Returns unmodified original string.
#
puts ruby.to_pretty_html
##
# Try on your own risk.
#
# puts ruby.to_pretty_html(skip_validation: true)
class String
##
# Returns formatted and highlighted html string.
#
# If html is malformed - returns unmodified original string.
#
# @param skip_validation [Boolean]
# @return [String]
#
# @note Expected to be called on html string.
#
def to_pretty_html(skip_validation: false)
original_html = self
##
# - https://nokogiri.org/tutorials/ensuring_well_formed_markup.html
# - https://stackoverflow.com/a/24579476/12201472
#
validate = proc { |html| ::Nokogiri::XML(html) { |config| config.strict } rescue return html unless skip_validation }
##
# - https://github.com/threedaymonk/htmlbeautifier
#
format = proc { |html| ::HtmlBeautifier.beautify(html) }
##
# - https://github.com/rouge-ruby/rouge
# - https://gist.github.com/marian13/5dade20a431d7254db30e543167058ce
#
highlight = proc { |html| ::Rouge::Formatters::Terminal256.new(::Rouge::Themes::Monokai.new).format(::Rouge::Lexers::HTML.new.lex(html)) }
original_html.tap(&validate).then(&format).then(&highlight)
end
end
##
# Returns formatted and highlighted html string.
#
# If html is malformed - returns unmodified original string.
#
# @param original_html [String]
# @param skip_validation [Boolean]
# @return [String]
#
# @note Expected to be called on html string.
#
def to_pretty_html(original_html, skip_validation: false)
##
# - https://nokogiri.org/tutorials/ensuring_well_formed_markup.html
# - https://stackoverflow.com/a/24579476/12201472
#
validate = proc { |html| ::Nokogiri::XML(html) { |config| config.strict } rescue return html unless skip_validation }
##
# - https://github.com/threedaymonk/htmlbeautifier
#
format = proc { |html| ::HtmlBeautifier.beautify(html) }
##
# - https://github.com/rouge-ruby/rouge
# - https://gist.github.com/marian13/5dade20a431d7254db30e543167058ce
#
highlight = proc { |html| ::Rouge::Formatters::Terminal256.new(::Rouge::Themes::Monokai.new).format(::Rouge::Lexers::HTML.new.lex(html)) }
original_html.tap(&validate).then(&format).then(&highlight)
end
@marian13
Copy link
Author

Screenshot 2023-05-14 at 17 59 48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment