PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/emacspeak-29.0/lisp/emacspeak-xslt.el

#
Emacs Lisp | 390 lines | 296 code | 27 blank | 67 comment | 2 complexity | c39c1d568ee3b85c14c776270438a79b MD5 | raw file
Possible License(s): MIT
  1. ;;; emacspeak-xslt.el --- Implements Emacspeak xslt transform engine
  2. ;;; $Id: emacspeak-xslt.el 6034 2008-11-06 14:44:14Z tv.raman.tv $
  3. ;;; $Author: tv.raman.tv $
  4. ;;; Description: xslt transformation routines
  5. ;;; Keywords: Emacspeak, Audio Desktop XSLT
  6. ;;{{{ LCD Archive entry:
  7. ;;; LCD Archive Entry:
  8. ;;; emacspeak| T. V. Raman |raman@cs.cornell.edu
  9. ;;; A speech interface to Emacs |
  10. ;;; $Date: 2008-08-12 10:48:54 -0700 (Tue, 12 Aug 2008) $ |
  11. ;;; $Revision: 4562 $ |
  12. ;;; Location undetermined
  13. ;;;
  14. ;;}}}
  15. ;;{{{ Copyright:
  16. ;;;Copyright (C) 1995 -- 2007, T. V. Raman
  17. ;;; Copyright (c) 1994, 1995 by Digital Equipment Corporation.
  18. ;;; All Rights Reserved.
  19. ;;;
  20. ;;; This file is not part of GNU Emacs, but the same permissions apply.
  21. ;;;
  22. ;;; GNU Emacs is free software; you can redistribute it and/or modify
  23. ;;; it under the terms of the GNU General Public License as published by
  24. ;;; the Free Software Foundation; either version 2, or (at your option)
  25. ;;; any later version.
  26. ;;;
  27. ;;; GNU Emacs is distributed in the hope that it will be useful,
  28. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  29. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  30. ;;; GNU General Public License for more details.
  31. ;;;
  32. ;;; You should have received a copy of the GNU General Public License
  33. ;;; along with GNU Emacs; see the file COPYING. If not, write to
  34. ;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  35. ;;}}}
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37. ;;{{{ introduction
  38. ;;; libxml and libxsl are XML libraries for GNOME.
  39. ;;; xsltproc is a xslt processor using libxsl
  40. ;;; this module defines routines for applying xsl transformations
  41. ;;; using xsltproc
  42. ;;}}}
  43. ;;{{{ Required modules
  44. (require 'emacspeak-preamble)
  45. (require 'emacspeak-webutils)
  46. ;;}}}
  47. ;;{{{ xslt Environment:
  48. (defgroup emacspeak-xslt nil
  49. "XSL transformation group."
  50. :group 'emacspeak)
  51. (defsubst emacspeak-xslt-params-from-xpath (path base)
  52. "Return params suitable for passing to emacspeak-xslt-region"
  53. (list
  54. (cons "path"
  55. (format "\"'%s'\""
  56. (shell-quote-argument path)))
  57. (cons "locator"
  58. (format "'%s'"
  59. path))
  60. (cons "base"
  61. (format "\"'%s'\""
  62. base))))
  63. ;;;###autoload
  64. (defsubst emacspeak-xslt-get (style)
  65. "Return fully qualified stylesheet path."
  66. (declare (special emacspeak-xslt-directory))
  67. (expand-file-name style emacspeak-xslt-directory))
  68. (defsubst emacspeak-xslt-read ()
  69. "Read XSLT transformation name from minibuffer."
  70. (declare (special emacspeak-xslt-directory))
  71. (expand-file-name
  72. (read-file-name "XSL Transformation: "
  73. emacspeak-xslt-directory
  74. emacspeak-we-xsl-transform)))
  75. (defcustom emacspeak-xslt-program "xsltproc"
  76. "Name of XSLT transformation engine."
  77. :type 'string
  78. :group 'emacspeak-xslt)
  79. ;;;###autoload
  80. (defcustom emacspeak-xslt-options
  81. "--html --nonet --novalid"
  82. "Options passed to xsltproc."
  83. :type 'string
  84. :group 'emacspeak-xslt)
  85. (defcustom emacspeak-xslt-keep-errors nil
  86. "If non-nil, xslt errors will be preserved in an errors buffer."
  87. :type 'boolean
  88. :group 'emacspeak-xslt)
  89. (defcustom emacspeak-xslt-nuke-null-char t
  90. "If T null chars in the region will be nuked.
  91. This is useful when handling bad HTML."
  92. :type 'boolean
  93. :group 'emacspeak-xslt)
  94. ;;}}}
  95. ;;{{{ Functions:
  96. (defvar emacspeak-xslt-last-command nil
  97. "Cache last xsltproc command we exectued.")
  98. ;;;###autoload
  99. (defun emacspeak-xslt-region (xsl start end &optional params no-comment)
  100. "Apply XSLT transformation to region and replace it with
  101. the result. This uses XSLT processor xsltproc available as
  102. part of the libxslt package."
  103. (declare (special emacspeak-xslt-program emacspeak-xslt-options
  104. emacspeak-xslt-last-command
  105. emacspeak-xslt-keep-errors modification-flag ))
  106. (let ((command nil)
  107. (parameters (when params
  108. (mapconcat
  109. #'(lambda (pair)
  110. (format "--param %s %s "
  111. (car pair)
  112. (cdr pair)))
  113. params
  114. " ")))
  115. (coding-system-for-write 'utf-8)
  116. (coding-system-for-read 'utf-8)
  117. (buffer-file-coding-system 'utf-8))
  118. (setq command
  119. (format
  120. "%s %s %s %s - %s"
  121. emacspeak-xslt-program
  122. (or emacspeak-xslt-options "")
  123. (or parameters "")
  124. xsl
  125. (if emacspeak-xslt-keep-errors
  126. ""
  127. " 2>/dev/null ")))
  128. (setq emacspeak-xslt-last-command
  129. command)
  130. (shell-command-on-region start end
  131. command
  132. (current-buffer)
  133. 'replace
  134. (when emacspeak-xslt-keep-errors
  135. "*xslt errors*"))
  136. (when (get-buffer "*xslt errors*")
  137. (bury-buffer "*xslt errors*"))
  138. (unless no-comment
  139. (goto-char (point-max))
  140. (insert
  141. (format "<!--\n %s \n-->\n"
  142. command)))
  143. (setq modification-flag nil)
  144. (set-buffer-multibyte t)
  145. (current-buffer)))
  146. ;;;###autoload
  147. (defsubst emacspeak-xslt-run (xsl start end)
  148. "Run xslt on region, and return output filtered by sort -u"
  149. (declare (special emacspeak-xslt-program emacspeak-xslt-options))
  150. (let ((coding-system-for-read 'utf-8)
  151. (coding-system-for-write 'utf-8)
  152. (buffer-file-coding-system 'utf-8))
  153. (shell-command-on-region
  154. start end
  155. (format "%s %s %s - 2>/dev/null | sort -u"
  156. emacspeak-xslt-program emacspeak-xslt-options xsl)
  157. (current-buffer) 'replace)
  158. (set-buffer-multibyte t)
  159. (current-buffer)))
  160. ;;; uses wget in a pipeline to avoid libxml2 bug:
  161. ;;;###autoload
  162. (defcustom emacspeak-xslt-use-wget-to-download nil
  163. "Set to T if you want to avoid URL downloader bugs in libxml2.
  164. There is a bug that bites when using Yahoo Maps that wget can
  165. work around."
  166. :group 'emacspeak-xslt
  167. :type 'boolean)
  168. ;;;###autoload
  169. (defun emacspeak-xslt-url (xsl url &optional params no-comment)
  170. "Apply XSLT transformation to url
  171. and return the results in a newly created buffer.
  172. This uses XSLT processor xsltproc available as
  173. part of the libxslt package."
  174. (declare (special emacspeak-xslt-program
  175. emacspeak-xslt-use-wget-to-download
  176. modification-flag
  177. emacspeak-xslt-keep-errors))
  178. (let ((result (get-buffer-create " *xslt result*"))
  179. (command nil)
  180. (parameters (when params
  181. (mapconcat
  182. #'(lambda (pair)
  183. (format "--param %s %s "
  184. (car pair)
  185. (cdr pair)))
  186. params
  187. " "))))
  188. (if emacspeak-xslt-use-wget-to-download
  189. (setq command (format
  190. "wget -U mozilla -q -O - '%s' | %s %s --html --novalid %s '%s' %s"
  191. url
  192. emacspeak-xslt-program
  193. (or parameters "")
  194. xsl "-"
  195. (if emacspeak-xslt-keep-errors
  196. ""
  197. " 2>/dev/null ")))
  198. (setq command (format
  199. "%s %s --html --novalid %s '%s' %s"
  200. emacspeak-xslt-program
  201. (or parameters "")
  202. xsl url
  203. (if emacspeak-xslt-keep-errors
  204. ""
  205. " 2>/dev/null "))))
  206. (save-excursion
  207. (set-buffer result)
  208. (kill-all-local-variables)
  209. (erase-buffer)
  210. (setq buffer-undo-list t)
  211. (let ((coding-system-for-write 'utf-8)
  212. (coding-system-for-read 'utf-8)
  213. (buffer-file-coding-system 'utf-8))
  214. (shell-command command (current-buffer)
  215. (when emacspeak-xslt-keep-errors
  216. "*xslt errors*"))
  217. (when emacspeak-xslt-nuke-null-char
  218. (goto-char (point-min))
  219. (while (search-forward
  220. ( format "%c" 0)
  221. nil t)
  222. (replace-match " "))))
  223. (when (get-buffer "*xslt errors*")
  224. (bury-buffer "*xslt errors*"))
  225. (goto-char (point-max))
  226. (unless no-comment
  227. (insert
  228. (format "<!--\n %s \n-->\n"
  229. command)))
  230. (setq modification-flag nil)
  231. (set-buffer-multibyte t)
  232. (goto-char (point-min))
  233. result)))
  234. ;;;###autoload
  235. (defun emacspeak-xslt-xml-url (xsl url &optional params)
  236. "Apply XSLT transformation to XML url
  237. and return the results in a newly created buffer.
  238. This uses XSLT processor xsltproc available as
  239. part of the libxslt package."
  240. (declare (special emacspeak-xslt-program
  241. emacspeak-xslt-use-wget-to-download
  242. modification-flag
  243. emacspeak-xslt-keep-errors))
  244. (let ((result (get-buffer-create " *xslt result*"))
  245. (command nil)
  246. (parameters (when params
  247. (mapconcat
  248. #'(lambda (pair)
  249. (format "--param %s %s "
  250. (car pair)
  251. (cdr pair)))
  252. params
  253. " "))))
  254. (if emacspeak-xslt-use-wget-to-download
  255. (setq command (format
  256. "wget -q -O - '%s' | %s %s --novalid %s %s %s"
  257. url
  258. emacspeak-xslt-program
  259. (or parameters "")
  260. xsl "-"
  261. (if emacspeak-xslt-keep-errors
  262. ""
  263. " 2>/dev/null ")))
  264. (setq command
  265. (format
  266. "%s %s --novalid %s '%s' %s"
  267. emacspeak-xslt-program
  268. (or parameters "")
  269. xsl url
  270. (if emacspeak-xslt-keep-errors
  271. ""
  272. " 2>/dev/null "))))
  273. (save-excursion
  274. (set-buffer result)
  275. (kill-all-local-variables)
  276. (erase-buffer)
  277. (let ((coding-system-for-write 'utf-8)
  278. (coding-system-for-read 'utf-8)
  279. (buffer-file-coding-system 'utf-8))
  280. (shell-command command
  281. (current-buffer)
  282. (when emacspeak-xslt-keep-errors
  283. "*xslt errors*")))
  284. (when (get-buffer "*xslt errors*")
  285. (bury-buffer "*xslt errors*"))
  286. (goto-char (point-max))
  287. (insert
  288. (format "<!--\n %s \n-->\n"
  289. command))
  290. (setq modification-flag nil)
  291. (goto-char (point-min))
  292. (set-buffer-multibyte t)
  293. result)))
  294. ;;}}}
  295. ;;{{{ interactive commands:
  296. ;;;###autoload
  297. (defun emacspeak-xslt-view (style url)
  298. "Browse URL with specified XSL style."
  299. (interactive
  300. (list
  301. (expand-file-name
  302. (read-file-name "XSL Transformation: "
  303. emacspeak-xslt-directory))
  304. (read-string "URL: " (browse-url-url-at-point))))
  305. (declare (special emacspeak-xslt-options))
  306. (emacspeak-webutils-with-xsl-environment
  307. style
  308. nil
  309. emacspeak-xslt-options
  310. url))
  311. ;;;###autoload
  312. (defun emacspeak-xslt-view-xml (style url &optional unescape-charent)
  313. "Browse XML URL with specified XSL style."
  314. (interactive
  315. (list
  316. (emacspeak-xslt-read)
  317. (emacspeak-webutils-read-this-url)
  318. current-prefix-arg))
  319. (let ((src-buffer
  320. (emacspeak-xslt-xml-url
  321. style
  322. url
  323. (list
  324. (cons "base"
  325. (format "\"'%s'\""
  326. url))))))
  327. (when (interactive-p)
  328. (emacspeak-webutils-autospeak))
  329. (save-excursion
  330. (set-buffer src-buffer)
  331. (when unescape-charent
  332. (emacspeak-webutils-unescape-charent (point-min) (point-max)))
  333. (emacspeak-webutils-without-xsl
  334. (browse-url-of-buffer)))
  335. (kill-buffer src-buffer)))
  336. ;;;###autoload
  337. (defun emacspeak-xslt-view-region (style start end &optional unescape-charent)
  338. "Browse XML region with specified XSL style."
  339. (interactive
  340. (list
  341. (emacspeak-xslt-read)
  342. (point)
  343. (mark)
  344. current-prefix-arg))
  345. (let ((src-buffer
  346. (ems-modify-buffer-safely
  347. (emacspeak-xslt-region style start end))))
  348. (save-excursion
  349. (set-buffer src-buffer)
  350. (when unescape-charent
  351. (emacspeak-webutils-unescape-charent (point-min) (point-max)))
  352. (emacspeak-webutils-without-xsl
  353. (browse-url-of-buffer)))
  354. (kill-buffer src-buffer)))
  355. ;;}}}
  356. (provide 'emacspeak-xslt)
  357. ;;{{{ end of file
  358. ;;; local variables:
  359. ;;; folded-file: t
  360. ;;; byte-compile-dynamic: t
  361. ;;; end:
  362. ;;}}}