PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/emacspeak-29.0/lisp/emacspeak-w3.el

#
Emacs Lisp | 810 lines | 596 code | 93 blank | 121 comment | 16 complexity | 99439436db80e176629febf6c4c55a6e MD5 | raw file
Possible License(s): MIT
  1. ;;; emacspeak-w3.el --- Speech enable W3 WWW browser -- includes ACSS Support
  2. ;;; $Id: emacspeak-w3.el 5830 2008-08-25 03:10:44Z tv.raman.tv $
  3. ;;; $Author: tv.raman.tv $
  4. ;;; Description: Emacspeak enhancements for W3
  5. ;;; Keywords: Emacspeak, W3, WWW
  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-04 09:09:31 -0700 (Mon, 04 Aug 2008) $ |
  11. ;;; $Revision: 4671 $ |
  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. ;;{{{ Introduction:
  37. ;;; Commentary:
  38. ;;; Ensure that speech support for W3 gets installed and
  39. ;;; loaded correctly.
  40. ;;; The emacs W3 browser comes with builtin support for
  41. ;;; Emacspeak and ACSS
  42. ;;; Code:
  43. ;;}}}
  44. ;;{{{ requires
  45. ;;; Code:
  46. (require 'emacspeak-preamble)
  47. (require 'emacspeak-webutils)
  48. (require 'emacspeak-we)
  49. (require 'emacspeak-xslt)
  50. ;;}}}
  51. ;;{{{ custom
  52. (defgroup emacspeak-w3 nil
  53. "WWW browser for the Emacspeak Desktop."
  54. :group 'emacspeak
  55. :group 'w3
  56. :prefix "emacspeak-w3-")
  57. ;;}}}
  58. ;;{{{ additional advice
  59. (defadvice url-write-global-history (around emacspeak pre act comp)
  60. "Silence messages while this function executes"
  61. (let ((emacspeak-speak-messages nil))
  62. ad-do-it))
  63. ;;}}}
  64. ;;{{{ show http headers
  65. (defcustom emacspeak-w3-lwp-request "lwp-request"
  66. "LWP Request command from perl LWP."
  67. :type 'string
  68. :group 'emacspeak-w3)
  69. (defun emacspeak-w3-show-http-headers ()
  70. "Show HTTP headers using lwp-request"
  71. (interactive)
  72. (declare (special emacspeak-w3-lwp-request))
  73. (let ((url (if (eq major-mode 'w3-mode)
  74. (or (w3-view-this-url 'no-show)
  75. (url-view-url 'no-show))
  76. (read-from-minibuffer "URL: "
  77. "http://" nil nil nil
  78. "http://"))))
  79. (shell-command
  80. (format "%s -de %s"
  81. emacspeak-w3-lwp-request url))
  82. (emacspeak-auditory-icon 'task-done)
  83. (emacspeak-speak-other-window 1)))
  84. ;;}}}
  85. ;;{{{ setup
  86. (defcustom emacspeak-w3-punctuation-mode 'all
  87. "Pronunciation mode to use for W3 buffers."
  88. :type '(choice
  89. (const :tag "Ignore" nil)
  90. (const :tag "some" some)
  91. (const :tag "all" all))
  92. :group 'emacspeak-w3)
  93. (defcustom emacspeak-w3-create-imenu-index nil
  94. "Create IMenu index by default."
  95. :type 'boolean
  96. :group 'emacspeak-w3)
  97. (defun emacspeak-w3-speak-mode-hook ()
  98. "Updated emacspeak hook for W3 mode."
  99. (declare (special imenu-create-index-function
  100. emacspeak-web-post-process-hook
  101. emacspeak-w3-create-imenu-index
  102. emacspeak-w3-punctuation-mode))
  103. (set (make-local-variable 'voice-lock-mode) t)
  104. (modify-syntax-entry 10 " ")
  105. (modify-syntax-entry 160 " ")
  106. (when emacspeak-w3-punctuation-mode
  107. (setq dtk-punctuation-mode emacspeak-w3-punctuation-mode))
  108. (emacspeak-auditory-icon 'open-object)
  109. (when (featurep 'w3-imenu)
  110. (setq imenu-create-index-function 'w3-imenu-create-index))
  111. (when emacspeak-w3-create-imenu-index
  112. (imenu--make-index-alist t))
  113. (emacspeak-pronounce-refresh-pronunciations)
  114. (unless emacspeak-web-post-process-hook
  115. (emacspeak-speak-mode-line)))
  116. (add-hook 'w3-mode-hook 'emacspeak-w3-speak-mode-hook)
  117. (defun emacspeak-w3-load-hook ()
  118. "Setup Emacspeak keys in W3 mode."
  119. (declare (special w3-echo-link url-show-status
  120. emacspeak-w3-table-draw-border
  121. emacspeak-w3-table-silent-border
  122. w3-table-border-chars
  123. w3-reuse-buffers
  124. w3-mode-map
  125. emacspeak-pronounce-common-xml-namespace-uri-pronunciations
  126. emacspeak-pronounce-load-pronunciations-on-startup))
  127. (setq w3-reuse-buffers 'no)
  128. (unless emacspeak-w3-table-draw-border
  129. (setq w3-table-border-chars
  130. emacspeak-w3-table-silent-border))
  131. (when (locate-library "w3-speak") (require 'w3-speak))
  132. (when (and (locate-library "w3-speak-table")
  133. (not (featurep 'w3-speak-table)))
  134. (load-library "w3-speak-table")
  135. (provide 'w3-speak-table))
  136. (when emacspeak-pronounce-load-pronunciations-on-startup
  137. (emacspeak-pronounce-augment-pronunciations 'w3-mode
  138. emacspeak-pronounce-common-xml-namespace-uri-pronunciations)
  139. (emacspeak-pronounce-add-dictionary-entry 'w3-mode
  140. emacspeak-speak-rfc-3339-datetime-pattern
  141. (cons 're-search-forward
  142. 'emacspeak-speak-decode-rfc-3339-datetime)))
  143. (setq url-show-status nil)
  144. (setq w3-echo-link
  145. (list 'text 'title 'name 'url))
  146. (when (locate-library
  147. "w3-imenu")
  148. (require 'w3-imenu))
  149. (loop for binding in
  150. '(
  151. ( "\C-t" emacspeak-w3-toggle-table-borders)
  152. ("'" emacspeak-speak-rest-of-buffer)
  153. ("\"" emacspeak-speak-skim-buffer)
  154. ("/" emacspeak-webutils-google-similar-to-this-page)
  155. (":" emacspeak-w3-speak-this-element)
  156. ("J" w3-table-move-to-next-table-row)
  157. ("K" w3-table-move-to-previous-table-row)
  158. ("L" w3-table-move-to-next-table-column)
  159. ("H" w3-table-move-to-previous-table-column)
  160. ("\;" emacspeak-speak-face-interval-and-move)
  161. ("A" emacspeak-webutils-atom-display)
  162. ("F" emacspeak-webutils-fv)
  163. ("X" emacspeak-xslt-view-xml)
  164. ("C" emacspeak-webutils-google-extract-from-cache)
  165. ("\M-l" emacspeak-w3-lynx-url-under-point)
  166. ("N" emacspeak-speak-next-personality-chunk)
  167. ("P" emacspeak-speak-previous-personality-chunk)
  168. ("R" emacspeak-webutils-rss-display)
  169. ("\C-f" w3-table-focus-on-this-cell)
  170. ("\M- " emacspeak-imenu-speak-this-section)
  171. ("\M-n" emacspeak-imenu-goto-next-index-position)
  172. ("\M-p" emacspeak-imenu-goto-previous-index-position)
  173. ("\M-r" emacspeak-webutils-view-feed-via-google-reader)
  174. ("\M-;" emacspeak-webutils-play-media-at-point)
  175. ("\M-s" emacspeak-w3-jump-to-submit)
  176. ("c" emacspeak-w3-curl-url-under-point)
  177. ("e" emacspeak-we-xsl-map)
  178. ("g" emacspeak-webutils-google-on-this-site)
  179. ("hh" emacspeak-w3-show-http-headers)
  180. ("i" emacspeak-w3-next-parsed-item)
  181. ("j" imenu)
  182. ("l" emacspeak-webutils-google-who-links-to-this-page)
  183. ("n" emacspeak-w3-next-doc-element)
  184. ("p" emacspeak-w3-previous-doc-element)
  185. ("t" emacspeak-webutils-transcode-via-google)
  186. ("T" emacspeak-webutils-jump-to-title-in-content)
  187. ("y" emacspeak-we-url-rewrite-and-follow)
  188. ("z" emacspeak-w3-speak-next-block)
  189. ([C-Return] emacspeak-webutils-open-in-other-browser))
  190. do
  191. (emacspeak-keymap-update w3-mode-map binding))
  192. (w3-masquerade-stub 1 "Mozilla" "5.0"))
  193. (add-hook 'w3-load-hook 'emacspeak-w3-load-hook)
  194. ;;}}}
  195. ;;{{{ webutils variables
  196. (defun emacspeak-w3-setup-webutils ()
  197. "Setup webutils variables for using W3."
  198. (setq
  199. emacspeak-webutils-document-title 'buffer-name
  200. emacspeak-webutils-url-at-point #'(lambda nil (w3-view-this-url t))
  201. emacspeak-webutils-current-url #'(lambda nil (url-view-url t))))
  202. (add-hook
  203. 'w3-mode-hook
  204. 'emacspeak-w3-setup-webutils)
  205. ;;}}}
  206. ;;{{{ dump using lynx
  207. (defcustom emacspeak-w3-lynx-program "lynx"
  208. "Name of lynx executable"
  209. :type 'file
  210. :group 'emacspeak-w3)
  211. (defun emacspeak-w3-lynx-done-alert (process state)
  212. "Alert user when lynx is done dumping the document"
  213. (declare (special view-exit-action))
  214. (when (y-or-n-p
  215. "Lynx is done --switch to the results?")
  216. (pop-to-buffer (process-buffer process))
  217. (goto-char (point-min))
  218. (view-mode)
  219. (setq view-exit-action 'kill-buffer)
  220. (skip-syntax-forward " ")
  221. (emacspeak-speak-line)))
  222. (defun emacspeak-w3-lynx-url-under-point ()
  223. "Display contents of URL under point using LYNX. The
  224. document is displayed in a separate buffer. Note that the
  225. hyperlinks in that display are not active-- this facility is
  226. present only to help me iron out the remaining problems with
  227. the table structure extraction code in W3."
  228. (interactive )
  229. (unless (eq major-mode 'w3-mode)
  230. (error
  231. "This command should be called only in W3 buffers"))
  232. (let ((url (or (w3-view-this-url t)
  233. (url-view-url t)))
  234. (process nil))
  235. (unless url
  236. (error "No URL under point"))
  237. (setq process
  238. (start-process "lynx"
  239. (format "*lynx-%s*" url)
  240. emacspeak-w3-lynx-program
  241. "-dump"
  242. url))
  243. (set-process-sentinel process
  244. 'emacspeak-w3-lynx-done-alert)))
  245. ;;;###autoload
  246. (defun emacspeak-w3-curl-url-under-point ()
  247. "Display contents of URL under point using Curl and W3. The
  248. document is displayed in a separate buffer. "
  249. (interactive )
  250. (unless (eq major-mode 'w3-mode)
  251. (error
  252. "This command should be called only in W3 buffers"))
  253. (let ((url (or (w3-view-this-url t)
  254. (url-view-url t))))
  255. (unless url
  256. (error "No URL under point"))
  257. (emacspeak-curl url)))
  258. ;;}}}
  259. ;;{{{ toggle table borders:
  260. ;;;I'd rather make the borders inaudible-- but that is hard
  261. ;;;at present.
  262. ;;; In the meantime, here is a toggle that allows you to
  263. ;;; turn borders on and off:
  264. (defvar emacspeak-w3-table-draw-border nil
  265. "Reflects whether we allow W3 to draw table borders. ")
  266. (defvar emacspeak-w3-table-silent-border (make-vector 16 32)
  267. "Used to draw empty W3 table borders. ")
  268. (defun emacspeak-w3-toggle-table-borders ()
  269. "Toggle drawing of W3 table borders"
  270. (interactive)
  271. (declare (special w3-table-border-chars))
  272. (setq emacspeak-w3-table-draw-border (not emacspeak-w3-table-draw-border))
  273. (cond
  274. (emacspeak-w3-table-draw-border
  275. (setq w3-table-border-chars (w3-setup-terminal-chars)))
  276. (t (setq w3-table-border-chars
  277. emacspeak-w3-table-silent-border)))
  278. (message "W3 will %s draw table borders from now on"
  279. (if emacspeak-w3-table-draw-border "" "not")))
  280. ;;}}}
  281. ;;{{{ element navigation
  282. ;;;This should eventually be done via a DOM API
  283. (defsubst emacspeak-w3-html-stack () (get-text-property (point)
  284. 'html-stack))
  285. (defsubst emacspeak-w3-get-onclick ()
  286. "Return onclick handler if any at point."
  287. (cdr (assq 'onclick (cdar (emacspeak-w3-html-stack)))))
  288. (defsubst emacspeak-w3-get-class ()
  289. "Return class if any at point."
  290. (cdr (assq 'class (cdar (emacspeak-w3-html-stack)))))
  291. (defsubst emacspeak-w3-get-onchange ()
  292. "Return onchange handler if any at point."
  293. (cdr (assq 'onchange (cdar (emacspeak-w3-html-stack)))))
  294. (defsubst emacspeak-w3-get-style ()
  295. "Return style if any at point."
  296. (cdr (assq 'style (cdar (emacspeak-w3-html-stack)))))
  297. (defsubst emacspeak-w3-html-stack-top-element (&optional stack)
  298. (or stack (setq stack (emacspeak-w3-html-stack)))
  299. (first (first stack )))
  300. (defun emacspeak-w3-next-parsed-item ()
  301. "Move to and speak next parsed item."
  302. (interactive)
  303. (let ((current (emacspeak-w3-html-stack))
  304. (start (point))
  305. (end nil))
  306. (unless current ;move to parsed item if needed
  307. (goto-char
  308. (next-single-property-change (point)
  309. 'html-stack))
  310. (setq current (emacspeak-w3-html-stack)))
  311. (while current
  312. (goto-char (next-single-property-change (point)
  313. 'html-stack ))
  314. (setq current (emacspeak-w3-html-stack)))
  315. (setq end (point))
  316. (emacspeak-speak-region start end)
  317. (emacspeak-auditory-icon 'select-object)))
  318. (defun emacspeak-w3-next-doc-element (&optional count)
  319. "Move forward to the next document element.
  320. Optional interactive prefix argument COUNT
  321. specifies by how many eleemnts to move."
  322. (interactive "P")
  323. (cond
  324. ((null count)
  325. (goto-char
  326. (next-single-property-change (point)
  327. 'html-stack
  328. (current-buffer)
  329. (point-max)))
  330. (unless (emacspeak-w3-html-stack)
  331. ;skip over null region
  332. (goto-char
  333. (next-single-property-change (point)
  334. 'html-stack
  335. (current-buffer)
  336. (point-max)))))
  337. (t (message "Moving by more than 1 not yet
  338. implemented. ")))
  339. (let ((emacspeak-show-point t))
  340. (emacspeak-w3-speak-next-element)))
  341. (defun emacspeak-w3-previous-doc-element (&optional count)
  342. "Move back to the previous document element.
  343. Optional interactive prefix argument COUNT
  344. specifies by how many eleemnts to move."
  345. (interactive "P")
  346. (cond
  347. ((null count)
  348. (unless (emacspeak-w3-html-stack)
  349. ;skip over null region
  350. (goto-char
  351. (previous-single-property-change (point)
  352. 'html-stack
  353. (current-buffer)
  354. (point-min))))
  355. (goto-char
  356. (previous-single-property-change (point)
  357. 'html-stack
  358. (current-buffer)
  359. (point-min))))
  360. (t (message "Moving by more than 1 not yet
  361. implemented. ")))
  362. (let ((emacspeak-show-point t))
  363. (emacspeak-w3-speak-this-element)))
  364. (defun emacspeak-w3-speak-this-element ()
  365. "Speak document element under point."
  366. (interactive)
  367. (let ((start nil)
  368. (end nil))
  369. (save-excursion
  370. (goto-char (previous-single-property-change (point)
  371. 'html-stack
  372. (current-buffer)
  373. (point-min)))
  374. (setq start (point))
  375. (goto-char (next-single-property-change (point)
  376. 'html-stack
  377. (current-buffer)
  378. (point-max)))
  379. (setq end (point))
  380. (emacspeak-speak-region start end )
  381. (emacspeak-auditory-icon 'select-object))))
  382. (defun emacspeak-w3-speak-next-element ()
  383. "Speak next document element."
  384. (interactive)
  385. (let ((start (point))
  386. (end nil))
  387. (save-excursion
  388. (goto-char (next-single-property-change (point)
  389. 'html-stack
  390. (current-buffer)
  391. (point-max)))
  392. (setq end (point))
  393. (emacspeak-speak-region start end )
  394. (emacspeak-auditory-icon 'select-object))))
  395. ;;}}}
  396. ;;{{{ experimental --unravel javascript urls
  397. (defvar emacspeak-w3-javascript-cleanup-buffer " *javascript-cleanup*"
  398. "temporary scratch area")
  399. (defun emacspeak-w3-do-onclick ()
  400. "Do onclick action."
  401. (interactive)
  402. (unless (and (eq major-mode 'w3-mode)
  403. (widget-at (point)))
  404. (error "Not on a W3 link"))
  405. (let ((onclick (widget-get (widget-at (point)) :onclick))
  406. (url nil)
  407. (start nil)
  408. (end nil))
  409. (unless onclick
  410. (error "This link has no onclick attribute"))
  411. (message onclick)
  412. (when (setq start
  413. (string-match "http" onclick))
  414. (setq url (substring onclick start ))
  415. (when (setq end (string-match "'" url))
  416. (setq url (substring url 0 end)))
  417. (w3-fetch url))))
  418. (defun emacspeak-w3-javascript-follow-link ()
  419. "Follow URL hidden inside a javascript link"
  420. (interactive)
  421. (unless (eq major-mode 'w3-mode)
  422. (error "Not in a W3 buffer."))
  423. (let ((j-url (w3-view-this-url 'no-show))
  424. (url nil)
  425. (start nil)
  426. (end nil))
  427. (setq start (string-match "'" j-url))
  428. (setq url (substring j-url (1+ start)))
  429. (setq end (string-match "'" url))
  430. (setq url (substring url 0 end))
  431. (when (string-match "http" url)
  432. (w3-fetch url))
  433. (w3-relative-link url)))
  434. ;;}}}
  435. ;;{{{ experimental --show class attribute from anchors
  436. (defun emacspeak-w3-show-anchor-class ()
  437. "Display any class attributes set on corresponding anchor
  438. element. "
  439. (interactive)
  440. (when (and (eq major-mode 'w3-mode)
  441. (widget-at (point)))
  442. (message (mapconcat #'identity
  443. (widget-get (widget-at (point)) :class ) " "))))
  444. ;;}}}
  445. ;;{{{ load realaudio if available
  446. (when (locate-library "emacspeak-realaudio")
  447. (require 'emacspeak-realaudio))
  448. ;;}}}
  449. ;;{{{ url rewrite
  450. ;;}}}
  451. ;;{{{ jump to submit button
  452. (defun emacspeak-w3-jump-to-submit ()
  453. "Jump to next available submit button."
  454. (interactive)
  455. (let ((start (point))
  456. (found nil))
  457. (forward-char 1)
  458. (while (and (not found)
  459. (< start (point)))
  460. (condition-case nil
  461. (widget-forward 1)
  462. (error "No buttons found."))
  463. (when
  464. (eq (aref (widget-get (widget-at (point)) :w3-form-data) 0)
  465. 'submit)
  466. (w3-speak-summarize-form-field)
  467. (emacspeak-auditory-icon 'large-movement)
  468. (setq found t)))
  469. (message "Could not find submit button.")))
  470. ;;}}}
  471. ;;{{{ enable post processor functionality
  472. (defadvice w3-notify-when-ready (after emacspeak pre act comp)
  473. "Call w3 post-processor hook if set."
  474. (emacspeak-webutils-run-post-process-hook))
  475. ;;}}}
  476. ;;{{{ advice focus on cell
  477. (defadvice w3-table-focus-on-this-cell (around emacspeak pre act comp)
  478. "Clone any url rewrite rules."
  479. (let ((rule emacspeak-we-url-rewrite-rule))
  480. ad-do-it
  481. (when rule
  482. (setq emacspeak-we-url-rewrite-rule rule))))
  483. ;;}}}
  484. ;;{{{ fix bug in W3 under emacs 21
  485. (defadvice w3-nasty-disgusting-http-equiv-handling (around fix-bug pre act comp)
  486. (let ((emacspeak-use-auditory-icons nil))
  487. (condition-case nil
  488. ad-do-it
  489. (error (message "caught an error")))))
  490. ;;}}}
  491. ;;{{{ silence url history save
  492. (defadvice url-history-save-history (around emacspeak pre act comp)
  493. "Silence spoken messages while url history is being saved."
  494. (let ((emacspeak-speak-messages nil))
  495. ad-do-it))(provide 'emacspeak-w3)
  496. ;;}}}
  497. ;;{{{ silence url package
  498. (declaim (special url-http-version))
  499. (setq url-http-version "1.0")
  500. (defadvice w3-fetch-callback
  501. (around emacspeak pre act comp)
  502. "silence spoken messages."
  503. (let ((emacspeak-speak-messages nil))
  504. ad-do-it))
  505. (defadvice url-http-content-length-after-change-function
  506. (around emacspeak pre act comp)
  507. "silence spoken messages."
  508. (let ((emacspeak-speak-messages nil))
  509. ad-do-it))
  510. (defadvice url-http-chunked-encoding-after-change-function
  511. (around emacspeak pre act comp)
  512. "silence spoken messages."
  513. (let ((emacspeak-speak-messages nil))
  514. ad-do-it))
  515. ;; (defadvice url-http-wait-for-headers-change-function
  516. ;; (around emacspeak pre act comp)
  517. ;; "silence spoken messages."
  518. ;; (let ((emacspeak-speak-messages nil))
  519. ;; ad-do-it))
  520. (defadvice url-cookie-handle-set-cookie
  521. (around emacspeak pre act comp)
  522. "silence spoken messages."
  523. (let ((emacspeak-speak-messages nil))
  524. ad-do-it
  525. ad-return-value))
  526. (defadvice url-lazy-message
  527. (around emacspeak pre act comp)
  528. "silence spoken messages."
  529. (let ((emacspeak-speak-messages nil))
  530. ad-do-it))
  531. ;;}}}
  532. ;;{{{ pull RSS feed
  533. ;;;###autoload
  534. ;;}}}
  535. ;;{{{ backward compatibility
  536. ;;; this will go away
  537. (defalias 'make-dtk-speech-style 'make-acss)
  538. (defalias 'dtk-personality-from-speech-style 'acss-personality-from-speech-style)
  539. (provide 'dtk-css-speech)
  540. ;;}}}
  541. ;;{{{ define pronunciation for document's base URI
  542. (defcustom emacspeak-w3-base-uri-pronunciation
  543. " base "
  544. "Custom pronunciation for base URIs in w3 buffers."
  545. :type '(choice :tag "Base URI Pronunciation"
  546. (const :tag "None" :value nil)
  547. (string :tag "Custom pronunciation" :value " base "))
  548. :group 'emacspeak-w3)
  549. (defun emacspeak-w3-customize-base-uri-pronunciation ()
  550. "Defines custom buffer local pronunciation for base URI."
  551. (interactive)
  552. (declare (special emacspeak-w3-base-uri-pronunciation))
  553. (let ((base-url (url-view-url 'no-show)))
  554. (when emacspeak-w3-base-uri-pronunciation
  555. (emacspeak-pronounce-add-buffer-local-dictionary-entry
  556. base-url
  557. emacspeak-w3-base-uri-pronunciation ))))
  558. (defadvice url-view-url (around emacspeak pre act comp)
  559. (cond
  560. ((interactive-p)
  561. (let ((save-pronunciations emacspeak-pronounce-pronunciation-table))
  562. (setq emacspeak-pronounce-pronunciation-table nil)
  563. ad-do-it
  564. (setq emacspeak-pronounce-pronunciation-table save-pronunciations)))
  565. (t ad-do-it))
  566. ad-return-value)
  567. ;;}}}
  568. ;;{{{ jump by block level elements (experimental:
  569. (defun emacspeak-w3-next-block ()
  570. "Move by block level displays."
  571. (interactive)
  572. (cond
  573. ((w3-table-info 0 'no-error) (w3-table-move-to-table-end))
  574. (t
  575. (while (and (not (eobp))
  576. (emacspeak-w3-html-stack))
  577. (goto-char
  578. (next-single-property-change (point) 'html-stack)))))
  579. (when (null (emacspeak-w3-html-stack))
  580. (goto-char (next-single-property-change (point) 'html-stack)))
  581. (when (interactive-p)
  582. (emacspeak-speak-line)
  583. (emacspeak-auditory-icon 'large-movement)))
  584. (defun emacspeak-w3-speak-next-block ()
  585. "Move to next block and speak it."
  586. (interactive)
  587. (let ((start nil))
  588. (emacspeak-w3-next-block)
  589. (save-excursion
  590. (setq start (point))
  591. (emacspeak-w3-next-block)
  592. (emacspeak-auditory-icon 'select-object)
  593. (emacspeak-speak-region start (point)))))
  594. ;;}}}
  595. ;;{{{ make wget aware of emacspeak w3 url rewrite functionality
  596. (defadvice w3-wget (before emacspeak pre act comp)
  597. "Become aware of emacspeak w3 url rewrite rule,
  598. and make the redirect available via the minibuffer history.
  599. If a rewrite rule is defined in the current buffer, we change
  600. this command to behave as if it were called with an
  601. interactive prefix."
  602. (when (and (interactive-p)
  603. emacspeak-we-url-rewrite-rule)
  604. (ad-set-arg 0 t)
  605. (let ((url (w3-view-this-url t))
  606. (redirect nil))
  607. (unless url
  608. (error "Not on a link."))
  609. (setq redirect
  610. (replace-regexp-in-string
  611. (first emacspeak-we-url-rewrite-rule)
  612. (second emacspeak-we-url-rewrite-rule)
  613. url))
  614. (push redirect minibuffer-history))))
  615. ;;}}}
  616. ;;{{{ cleanup with tidy:
  617. (defcustom emacspeak-w3-tidy-program "tidy"
  618. "Name of tidy executable"
  619. :type 'file
  620. :group 'emacspeak-w3)
  621. (defcustom emacspeak-w3-tidy-options
  622. (list "--show-warnings" "no" "--show-errors" "0" "--force-output" "yes"
  623. "-asxml" "-quiet" "-bare" "-omit"
  624. "--drop-proprietary-attributes" "yes" "--hide-comments"
  625. "yes"
  626. "-utf8")
  627. "Options to pass to tidy program"
  628. :type '(repeat string)
  629. :group 'emacspeak-w3)
  630. (defcustom emacspeak-w3-tidy-html t
  631. "Tidy HTML before rendering."
  632. :type 'boolean
  633. :group 'emacspeak-w3)
  634. (defun emacspeak-w3-cleanup-bogus-quotes ()
  635. "hack to fix magic quotes."
  636. (goto-char (point-min))
  637. (while (search-forward "&\#147\;" nil t)
  638. (replace-match "\""))
  639. (goto-char (point-min))
  640. (while (search-forward "&\#148\;" nil t)
  641. (replace-match "\""))
  642. (goto-char (point-min))
  643. (while (search-forward "&\#180\;" nil t)
  644. (replace-match "\'")))
  645. (defun emacspeak-w3-tidy (&optional buff)
  646. "Use html tidy to clean up the HTML in the current buffer."
  647. (declare (special emacspeak-w3-tidy-html
  648. emacspeak-w3-tidy-program emacspeak-w3-tidy-options))
  649. (when emacspeak-w3-tidy-html
  650. (save-excursion
  651. (if buff
  652. (set-buffer buff)
  653. (setq buff (current-buffer)))
  654. (setq buffer-undo-list t)
  655. (widen)
  656. (when emacspeak-we-cleanup-bogus-quotes
  657. (emacspeak-w3-cleanup-bogus-quotes))
  658. (apply 'call-process-region
  659. (point-min) (point-max)
  660. emacspeak-w3-tidy-program
  661. t
  662. (list buff nil)
  663. nil
  664. emacspeak-w3-tidy-options))))
  665. (add-hook 'w3-parse-hooks 'emacspeak-w3-tidy)
  666. ;;}}}
  667. ;;{{{ utf-8
  668. (defadvice w3-slow-parse-buffer (around emacspeak pre act comp)
  669. "Force buffer encoding to utf-8."
  670. (let ((coding-system-for-read 'utf-8)
  671. (coding-system-for-write 'utf-8))
  672. ad-do-it
  673. ad-return-value))
  674. ;;}}}
  675. ;;{{{ advice to call xslt
  676. (defadvice w3-parse-buffer (before emacspeak pre act comp)
  677. "Apply requested XSL transform if any before displaying the
  678. HTML."
  679. (when (and emacspeak-we-cleanup-bogus-quotes
  680. (not emacspeak-w3-tidy-html))
  681. (emacspeak-w3-cleanup-bogus-quotes))
  682. (unless
  683. (or emacspeak-we-xsl-p
  684. (string-match "temp"
  685. (buffer-name)))
  686. (emacspeak-we-build-id-cache)
  687. (emacspeak-we-build-class-cache)
  688. (emacspeak-we-build-role-cache))
  689. (when (and emacspeak-we-xsl-p
  690. emacspeak-we-xsl-transform
  691. (not (string-match "temp" (buffer-name))))
  692. (emacspeak-xslt-region
  693. emacspeak-we-xsl-transform
  694. (point-min)
  695. (point-max)
  696. emacspeak-we-xsl-params)
  697. (emacspeak-we-build-id-cache)
  698. (emacspeak-we-build-class-cache)
  699. (when emacspeak-we-xsl-keep-result
  700. (clone-buffer
  701. (format "xslt-%s"
  702. (buffer-name))))))
  703. ;;}}}
  704. ;;{{{ fix css bug:
  705. (defadvice css-expand-value (around fix-bug pre act comp )
  706. "Fix problem where bad CSS breaks W3."
  707. (condition-case nil
  708. ad-do-it
  709. (error nil)))
  710. ;;}}}
  711. ;;{{{ emacs local variables
  712. ;;; local variables:
  713. ;;; folded-file: t
  714. ;;; byte-compile-dynamic: t
  715. ;;; end:
  716. ;;}}}