;;; W3C HTML Validator
(require 'seq)
(defvar validate-html-input-filename
(make-local-variable 'validate-html-input-filename))
(defvar validate-html-output-buffer
(make-local-variable 'validate-html-output-buffer))
(defun validate-html ()
"Send the current buffer's file to the W3C HTML Validator and
display the resuls. Requires Curl."
(interactive)
(when (buffer-modified-p)
(when (y-or-n-p "Save buffer first?")
(save-buffer)))
(let ((output-buffer (get-buffer-create "*W3C HTML Validator*"))
(retrieval-buffer (get-buffer-create " *W3C HTML Validator (JSON)*"))
(filename (buffer-file-name)))
(with-current-buffer output-buffer
(setq buffer-read-only nil)
(erase-buffer)
(display-buffer output-buffer))
(with-current-buffer retrieval-buffer
(setq buffer-read-only nil)
(setq validate-html-input-filename filename)
(setq validate-html-output-buffer output-buffer)
(erase-buffer)
(make-process
:name "W3C HTML Validator"
:buffer retrieval-buffer
:command (list "curl"
"-s"
"-H"
"Content-Type: text/html; charset=utf-8"
"--data-binary"
(format "@%s" filename)
"https://validator.w3.org/nu/?out=json&level=error")
:sentinel (lambda (process event)
(when (string-equal event "finished\n")
(let ((json
(with-current-buffer (process-buffer process)
(goto-char (point-min))
(json-read))))
(with-current-buffer validate-html-output-buffer
(insert
(format "Output from W3C HTML Validator on \"%s\"\n"
validate-html-input-filename))
(seq-do
(lambda (m)
(insert
(format "%s:%d: %s\n"
validate-html-input-filename
(cdr (assq 'lastLine m))
(cdr (assq 'message m)))))
(cdr (assq 'messages json)))
(compilation-mode)
(setq next-error-last-buffer (current-buffer))
(message "Done.")))))))
(message "Sending current buffer to W3C HTML Validator.")))