;;;;;; $Id$;;;;;; Adrian Aichner, aichner@ecf.teradyne.com, Teradyne GmbH, 2000-07-16.;;;(require'psgml)(require'psgml-parse);;; for sgml-element-context-string(defconstpsgml-validate-conform"<small>Conform with ""Phrase to insert for conforming SGML document.")(defconstpsgml-validate-non-conform"<small><strong>Not</strong> conform with ""Phrase to insert for non-conforming SGML document.")(defunbatch-psgml-validate(&optionalfile-or-dir)"Uses `sgml-next-trouble-spot' from the PSGML package to validateconformance of files in FILE-OR-DIR with the specified DTD. See`batch-psgml-validate-buffer'. If FILE-OR-DIR is missing,`batch-psgml-validate' is performed for each `command-line-args-left'."(interactive"DHTML directory to validate: ")(if(nullfile-or-dir)(progn(let(file-or-dir)(whilecommand-line-args-left(setqfile-or-dir(expand-file-name(carcommand-line-args-left)))(batch-psgml-validatefile-or-dir)(setqcommand-line-args-left(cdrcommand-line-args-left)))))(dolist(file(directory-filesfile-or-dirtnilnilnil))(cond((member(file-name-nondirectoryfile)(list"."".."))nil)((file-directory-pfile)(batch-psgml-validatefile))((and(member(file-name-extensionfile)(list"htm""html"))(null(backup-file-name-pfile)))(message"validating %s"file)(batch-psgml-validate-filefilett))))(message"batch-psgml-validate %s is done"file-or-dir)))(defunbatch-psgml-validate-file(file&optionalinsert-resultindent)"Uses `sgml-next-trouble-spot' from the PSGML package to validateconformance of FILE with the specified DTD. See`batch-psgml-validate-buffer'."(interactive(list(read-file-name"HTML file to validate: ")(yes-or-no-p"insert compliance text ")(yes-or-no-p"indent buffer ")))(with-current-buffer(find-file-noselectfile)(batch-psgml-validate-bufferinsert-resultindent)))(defunbatch-psgml-validate-buffer(&optionalinsert-resultindent)"Uses `sgml-next-trouble-spot' from the PSGML package to validateconformance of buffer with the specified DTD. INSERT-RESULT inserts a\(non-\)compliance messsage before \"</BODY>\". INDENT will`indent-according-to-mode' as well. The buffer is saved in the end ifnot called interactively."(interactive(list(yes-or-no-p"insert compliance text ")(yes-or-no-p"indent buffer ")))(let(old-result-beginold-result-endnew-result-beginresultfileline)(goto-char(point-min))(condition-caseerr(progn(setqresult(sgml-next-trouble-spot))(unless(string=result"Ok")(setffile(buffer-file-name))(setqline(count-lines(point-min)(point)))))(error(message">> Error: %s"(prin1-to-stringerr)))(t(message"trouble: %s"(prin1-to-stringerr))))(wheninsert-result(goto-char(point-max))(setqold-result-end(re-search-backward"^\\s-*</body>"(point-min)t))(while(re-search-backward(format"^\\s-*\\(%s\\|%s\\)"psgml-validate-conformpsgml-validate-non-conform)(point-min)t)(setqold-result-begin(point)))(andold-result-beginold-result-end(delete-regionold-result-beginold-result-end))(insert(format"%s"(if(string=result"Ok")psgml-validate-conformpsgml-validate-non-conform)))(setqnew-result-begin(point))(unless(string=result"Ok")(ifsgml-last-element(message"validation error in %s"(sgml-element-context-stringsgml-last-element)))(message"at %s line %d."fileline))(inserthtml-helper-htmldtd-version)(html-quote-regionnew-result-begin(point))(insert", PSGML "psgml-version", "emacs-version".</small>\n"))(whenindent(indent-region(point-min)(point-max)nil))(if(noninteractive)(if(buffer-modified-p)(progn(message"Saving modified %s"(buffer-file-name))(save-buffer))))))