Beautiful Code [336]
Context-sensitive rendering rules for HTML form controls. As an example, given a group of radio buttons for answering the question:
Do you accept?
Emacspeak extends Emacs W3 to produce a spoken message of the form:
Radio group Do you accept? has Yes pressed.
and:
Press this to change radio group Do you accept? from Yes to No.
A before advice defined for the Emacs W3 function w3-parse-buffer that applies user-requested XSLT transforms to HTML pages.
31.3.2. The emacspeak-websearch Module for Task-Oriented Search
By 1997, interactive sites on the Web, ranging from Altavista for searching to Yahoo! Maps for online directions, required the user to go through a highly visual process that included:
Filling in a set of form fields
Submitting the resulting form
Spotting the results in the resulting complex HTML page
The first and third of these steps were the ones that took time when using spoken output. I needed to first locate the various form fields on a visually busy page and wade through a lot of complex boilerplate material on result pages before I found the answer.
Notice that from the software design point of view, these steps neatly map into pre-action and post-action hooks. Because web interaction follows a very simple architecture based on URIs, the pre-action step of prompting the user for the right pieces of input can be factored out of a web site and placed in a small piece of code that runs locally; this obviates the need for the user to open the initial launch page and seek out the various input fields.
Similarly, the post-action step of spotting the actual results amid the rest of the noise on the resulting page can also be delegated to software.
Finally, notice that even though these pre-action and post-action steps are each specific to particular web sites, the overall design pattern is one that can be generalized. This insight led to the emacspeak-websearch module, a collection of task-oriented web tools that:
Prompted the user
Constructed an appropriate URI and pulled the content at that URI
Filtered the result before rendering the relevant content via Emacs W3
Here is the emacspeak-websearch tool for accessing directions from Yahoo! Maps:
Code View: Scroll / Show All
(defsubst emacspeak-websearch-yahoo-map-directions-get-locations ( )
"Convenience function for prompting and constructing the route component."
(concat
(format "&newaddr=%s"
(emacspeak-url-encode (read-from-minibuffer "Start Address: ")))
(format "&newcsz=%s"
(emacspeak-url-encode (read-from-minibuffer "City/State or Zip:")))
(format "&newtaddr=%s"
(emacspeak-url-encode (read-from-minibuffer "Destination Address: ")))
(format "&newtcsz=%s"
(emacspeak-url-encode (read-from-minibuffer "City/State or Zip:")))))
(defun emacspeak-websearch-yahoo-map-directions-search (query )
"Get driving directions from Yahoo."
(interactive
(list (emacspeak-websearch-yahoo-map-directions-get-locations))
(emacspeak-w3-extract-table-by-match
"Start"
(concat emacspeak-websearch-yahoo-maps-uri query))))
A brief explanation of the previous code follows:
Pre-action
The emacspeak-websearch-yahoo-map-directions-get-locations function prompts the user for the start and end locations. Notice that this function hardwires the names of the query parameters used by Yahoo! Maps. On the surface, this looks like a kluge that is guaranteed to break. In fact, this kluge has not broken since it was first defined in 1997. The reason is obvious: once a web application has published a set of query parameters, those parameters get hardcoded in a number of places, including within a large number of HTML pages on the originating web site. Depending on parameter names may feel brittle to the software architect used to structured, top-down APIs, but the use of such URL parameters to define bottom-up web services leads to the notion of RESTful web APIs.
Retrieve content
The URL for retrieving