diff --git a/assets/javascripts/news.json b/assets/javascripts/news.json
index 043a0401..b5340a3c 100644
--- a/assets/javascripts/news.json
+++ b/assets/javascripts/news.json
@@ -1,4 +1,8 @@
[
+ [
+ "2024-01-20",
+ "New documentation: htmx"
+ ],
[
"2024-01-12",
"New documentation: Hammerspoon"
diff --git a/lib/docs/filters/htmx/clean_html.rb b/lib/docs/filters/htmx/clean_html.rb
new file mode 100644
index 00000000..4c14c6aa
--- /dev/null
+++ b/lib/docs/filters/htmx/clean_html.rb
@@ -0,0 +1,13 @@
+module Docs
+ class Htmx
+ class CleanHtmlFilter < Filter
+ def call
+ css('.zola-anchor').remove
+ doc.prepend_child("
htmx
") if root_page?
+ css('div:contains("NEWS:")').remove
+ css('h2:contains("sponsors"), #sponsor-table').remove
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/htmx/entries.rb b/lib/docs/filters/htmx/entries.rb
new file mode 100644
index 00000000..fc5053c6
--- /dev/null
+++ b/lib/docs/filters/htmx/entries.rb
@@ -0,0 +1,31 @@
+module Docs
+ class Htmx
+ class EntriesFilter < Docs::EntriesFilter
+ def get_name
+ at_css('h1').content
+ end
+
+ def get_type
+ if slug.start_with?('attributes')
+ 'Attributes'
+ elsif slug.start_with?('headers')
+ 'Headers'
+ elsif slug.start_with?('events')
+ 'Events'
+ elsif slug.start_with?('extensions')
+ 'Extensions'
+ else
+ get_name
+ end
+ end
+
+ def additional_entries
+ css('h3[id]:has(code)').each_with_object [] do |node, entries|
+ name = node.at_css('code').content
+ id = node['id']
+ entries << [name, id]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/htmx.rb b/lib/docs/scrapers/htmx.rb
new file mode 100644
index 00000000..6e6f638e
--- /dev/null
+++ b/lib/docs/scrapers/htmx.rb
@@ -0,0 +1,35 @@
+module Docs
+ class Htmx < UrlScraper
+ self.name = 'htmx'
+ self.type = 'simple'
+ self.slug = 'htmx'
+ self.links = {
+ home: 'https://htmx.org/',
+ code: 'https://github.com/bigskysoftware/htmx'
+ }
+ self.release = '1.9.10'
+ self.base_url = "https://htmx.org/"
+ self.initial_paths = %w(reference/)
+
+ html_filters.push 'htmx/entries', 'htmx/clean_html'
+
+ options[:trailing_slash] = true
+ options[:container] = '.content'
+ options[:download_images] = false
+ options[:skip_patterns] = [
+ /\Aessays/,
+ /\Aexamples/,
+ /\Amigration-guide/,
+ /\Aposts/,
+ ]
+
+ # https://github.com/bigskysoftware/htmx/blob/master/LICENSE
+ options[:attribution] = <<-HTML
+ Licensed under the Zero-Clause BSD
+ HTML
+
+ def get_latest_version(opts)
+ get_npm_version('htmx.org', opts)
+ end
+ end
+end
diff --git a/public/icons/docs/htmx/16.png b/public/icons/docs/htmx/16.png
new file mode 100644
index 00000000..8f98938f
Binary files /dev/null and b/public/icons/docs/htmx/16.png differ
diff --git a/public/icons/docs/htmx/16@2x.png b/public/icons/docs/htmx/16@2x.png
new file mode 100644
index 00000000..9f2fcf87
Binary files /dev/null and b/public/icons/docs/htmx/16@2x.png differ
diff --git a/public/icons/docs/htmx/SOURCE b/public/icons/docs/htmx/SOURCE
new file mode 100644
index 00000000..bfba7d6d
--- /dev/null
+++ b/public/icons/docs/htmx/SOURCE
@@ -0,0 +1 @@
+https://github.com/bigskysoftware/htmx/blob/v1.9.10/www/static/img/htmx_logo.2.png