Online Book Reader

Home Category

Beautiful Code [338]

By Root 5282 0
of content based on user input. As examples, Major League Baseball constructs the URL for retrieving scores for a given game by piecing together the date and the names of the home and visiting teams, and NPR creates URLs by piecing together the date with the program code of a given NPR show.

To enable fast access to such services, I added an emacspeak-url-template module in late 2000. This module has become a powerful companion to the emacspeak-websearch module described in the previous section. Together, these modules turn the Emacs minibuffer into a powerful web command line that provides rapid access to web content.

Many web services require the user to specify a date. One can usefully default the date by using the user's calendar to provide the context. Thus, Emacspeak tools for playing an NPR program or retrieving MLB scores default to using the date under the cursor when invoked from within the Emacs calendar buffer.

URL templates in Emacspeak are implemented using the following data structure:

Code View: Scroll / Show All

(defstruct (emacspeak-url-template (:constructor emacspeak-ut-constructor))

name ;; Human-readable name

template ;; template URL string

generators;; list of param generator

post-action ;; action to perform after opening

documentation ;; resource documentation

fetcher)

Users invoke URL templates via the Emacspeak command emacspeak-url-template-fetch command, which prompts for a URL template and:

Looks up the named template.

Prompts the user by calling the specified generator.

Applies the Lisp function format to the template string and the collected arguments to create the final URI.

Sets up any post actions performed after the content has been rendered.

Applies the specified fetcher to render the content.

The use of this structure is best explained with an example. The following is the URL template for playing NPR programs:

Code View: Scroll / Show All

(emacspeak-url-template-define

"NPR On Demand"

"http://www.npr.org/dmg/dmg.php?prgCode=%s&showDate=%s&segNum=%s&mediaPref=RM"

(list

#'(lambda ( ) (upcase (read-from-minibuffer "Program code:")))

#'(lambda ( )

(emacspeak-url-template-collect-date "Date:" "%d-%b-%Y"))

"Segment:")

nil; no post actions

"Play NPR shows on demand.

Program is specified as a program code:

ME Morning Edition

ATC All Things Considered

day Day To Day

newsnotes News And Notes

totn Talk Of The Nation

fa Fresh Air

wesat Weekend Edition Saturday

wesun Weekend Edition Sunday

fool The Motley Fool

Segment is specified as a two digit number --specifying a blank value

plays entire program."

#'(lambda (url)

(funcall emacspeak-media-player url 'play-list)

(emacspeak-w3-browse-xml-url-with-style

(expand-file-name "smil-anchors.xsl" emacspeak-xslt-directory)

url)))

In this example, the custom fetcher performs two actions:

Launches a media player to start playing the audio stream.

Filters the associated SMIL document via the XSLT file smil-anchors.xsl.

31.3.4. The Advent of Feed Readers

When I implemented the emacspeak-websearch and emacspeak-url-template modules, Emacspeak needed to screen-scrape HTML pages to speak the relevant information. But as the Web grew in complexity, the need to readily get beyond the superficial presentation of pages to the real content took on a wider value than eyes-free access. Even users capable of working with complex visual interfaces found themselves under a serious information overload. This led to the advent of RSS and Atom feeds, and the concomitant arrival of feed reading software.

These developments have had a very positive effect on the Emacspeak code base. During the past few years, the code has become more beautiful as I have progressively deleted screen-scraping logic and replaced it with direct content access. As an example, here is the Emacspeak URL template for retrieving the weather for a given city/state:

(emacspeak-url-template-define

"rss weather from wunderground"

"http://www.wunderground.com/auto/rss_full/%s.xml?units=both"

Return Main Page Previous Page Next Page

®Online Book Reader