George Etheridge's Encomium on Henry VIII to Elizabeth I — British Library Royal MS 16 C X

Implementation Details of the Electronic Edition

Introduction

Presenting a 16th-century manuscript written in polytonic Greek using 21st-century technology posed some interesting challenges, not the least of which arose from our determination to ensure that the work was accessible to all[1] users, no matter where in the world, provided only that they had access to the Internet using a modern standards-compliant web browser.  We had to tread a very fine line, neither exploiting evolving standards that had not yet been fully ratified (and for which, therefore, widespread support could not be guaranteed :  e.g., HTML 5), nor basing our work on outdated technologies that would restrict our ability to present the work in the most effective manner.  We also chose to eschew proprietary technologies such as Flash and Silverlight, not because of any prejudice or for political reasons but simply to maximise the probability that our project would display as intended on any modern computer running any modern operating system.  We therefore decided to standardise on just five open standards :

  1. Unicode (Version 6 or later, ISO/IEC 10646:2011)
  2. The Hypertext Markup Language HTML (HTML 4.01 Strict)
  3. Cascading stylesheets (CSS 2.1, with the exception of the "accordion" menu which exploits some features from CSS 3)
  4. JavaScript/ECMAScript (ECMAscript 5).
  5. The W3C Document Object Model ("DOM") :  the glue that binds everything else together.

For those with a background in "Computing in the Humanities", it may seem strange that we have no underlying XML and/or TEI layer; this omission was made solely on pragmatic grounds — if we were to be sure of being able to deliver the project on schedule, we would need to use technologies with which all members of the research group were reasonably au fait, and in which our lead technical advisor had considerable existing expertise; had we elected to do otherwise, it would almost certainly have more than doubled the time to bring the project to completion, and might well have compromised the project's very chances of success.

Functional overview

When the Electronic Edition is first opened, it will be seen to be divided into two panes — on the left, an electronic facsimile of a single folio from the codex, and on the right the transcription of the folio.  Above the facsimile of the folio are a [Home] button (clicking on which will take the user to the project "home" page) and a series of navigation aids :  a direct text-entry field labelled "Folio :  " and an accompanying [Go ! ] button, two buttons labelled [« Prev] and [Next »], between which is a drop-down menu through which the desired folio can be directly selected, and finally a button labelled [View MS].  Above the transcription are two drop-down menus through which the desired text ("Edition", "Transcription" or "Translation") and line-reflow (for the edition only) :  "None", "Normal" and "Full" can be selected, and four further buttons labelled [Help], [Feedback], [Home] and [Debug].  The function of each of these will be described below.

Simultaneous highlighting of MS facsimile and text

With the MS facsimile and transcription displayed, moving the mouse cursor over a word in either the facsimile or the transcription will result in the word under the cursor changing its colour to red; this colour change will take place both in the text and  in the image.  The functionality is symmetric :  it matters not whether the cursor is in the text pane or the image pane — the corresponding word in both text and image will turn red.

Lexicographical analyses and online lexica

When the cursor is in the text pane, additional functionality is provided — clicking on any word in the text will result in a full lexicographical analysis being displayed in the footnote area.  For example, the opening word in f. 1r is "Τῇ ", and clicking on this word will cause the text "Τῇ: Article, fem dat sg.  form of ὁ (fem: ἡ; neut: τό).  Lemma: ἡ; see [Archimedes][Perseus] [TLG/LSJ]  " to be displayed in the footnote area.  The lexicographical analysis, while complete, cannot possibly say all that there is to be said concerning the word in question, and so links are provided from the analysis to three very important online lexica : The Archimedes Project, at Harvard; the Perseus Project, at Tufts; and the Liddell-Scott-Jones Greek-English Lexicon hosted by Thesaurus Linguae Graecae at the University of California, Irvine.  If any of these links is followed, it does not  open a new browser window or new browser tab, nor does it overwrite the text and the lexicographical note; instead, it displays the relevant information in the space normally occupied by the MS facsimile.  This has many benefits : it leaves the text and the lexicographical analysis visible at the same time as the contents of the external link, and the reader can (should he/she so choose) alternate between the off-site content and the MS facsimile simply by clicking on the lexicon link.  It is not necessary to switch windows or tabs, nor even to use the browser's "forward" and "backward" buttons :  the text remains in place, the lexicographical analysis likewise, and the user can view either MS facsimile or external text as he/she chooses.  The MS facsimile can be restored by clicking on the "View MS " button at the top of the MS pane.

Apparatus criticus & apparatus fontium

If, instead of the transcription, the edition is selected in the text pane, then even more functionality becomes available.  The simultaneous highlighting of words in the text and image functions as before, each word is still linked to a lexicographical analysis and so on, but in addition a number of scholarly apparatus are now offered. Some words in the edition, for example, will be picked out in green, indicating that they are accompanied by a note in the apparatus criticus.  These highlight either a peculiarity in the manuscript, typically a correction or insertion made by the author, or a textual emendation made by the editors.  If the mouse cursor hovers over any one of these words a "speech bubble" will pop up, containing details of the manuscript feature or editorial intervention.  For example, hovering over "ἐμφανεστάτῃ" in f. 1r (Edition) will display the note "corr.: ἐμφανέστατῃ cod." in a speech bubble pointing to the word in question (the transcription contains "ἐμφανέστατῃ" at this point, of course, since it faithfully reflects the exact orthography of the author).  Quotations and citations are identified by notes in the apparatus fontium cum referentium, triggered from footnote marks.  For example, on f. 4r (Edition), this takes the form of the superscripted number [1] in square brackets following the italicised text "μῆλον ὑπερφυὲς μεγέθει".  If this number is clicked, the text "[1] Plutarch: Life of Artaxerxes IV:5" (indicating the work to which the author is referring) appears in the footnote area. Clicking on the raised [1] a second time will dismiss the footnote text. This functionality is also present in the translation with an identical effect.

Special features of the translation : simultaneous highlighting and the apparatus scholia

Turning finally to the translation, there is again a linkage between translation and facsimile image, but in this case the linkage is not (and cannot be) on a word-by-word basis.  Instead, the translation has been carefully prepared so as to echo the macro structure of the MS text, and the linkage between translation and image is therefore on the basis of a short stretch of text (a phrase, clause, sentence, whatever) rather than on the basis of a single word.  Hovering over any word in either text or image will cause an entire stretch of text to be highlit in red, and the corresponding stretch of text in the opposite pane will also be highlit.  Furthermore, in addition to the apparatus criticus and apparatus fontium already mentioned, the translation also contains instances of apparatus scholia, the first of which may be seen in f. 9r (Translation).  Here, following the text "and subdued the impregnable city of Boulogne and triumphantly overcame the ranks of many enemies. " a superscripted [a] can be seen.  Clicking on the [a] will disclose a fairly long note in the footnote area commencing "[a] Henry launched a major invasion of France in alliance with the Emperor Charles V in summer 1544 ", and this note provides a historical background to the MS text at that point.

Using the navigation aids

There are several different ways of moving between folia : simplest, and probably the most convenient, is to move forwards or backwards by one folio by clicking on the [« Prev] or [Next »] buttons as desired; alternatively, any folio in the codex can be selected by using the [Folio] drop-down menu and clicking on the folio of interest or by entering the desired folio number in the [Folio] text box.  Over the text pane, the Edition, Transcription or Translation can be selected using the [Text] drop-down, and when the Edition is selected line-reflow can be modified using the [Reflow] drop-down :  the possible values are "None" (in which case the line turns in the Edition are in 1:1 correspondence with those in the MS), "Normal" (in which case the text is re-flowed but solidi ("|") are introduced to indicate the position of the line-turns in the MS), and "Full" (which is similar to "Normal" but without the introduction of solidi).

If an error is spotted in the text (or indeed, if the user simply wishes to comment on it), feedback can be sent to the team by using the mouse to highlight the stretch of text in question and then clicking on the [Feedback] button; this will pre-populate a web form with the URL of the current page (including details of the selected folio, text and reflow options) and the user will then be invited to supply his/her contact details, offer feedback on the passage of interest, and finally submit the form.

If help is needed on using the Electronic Edition, this Help text can be brought up at any time by clicking on the [Help] button above the text pane.  This will display the Help text as an overlay to the MS facsimile, and the facsimile can be restored either by clicking on the [Help] button a second time or by clicking on the [View MS] button above the MS pane.  The [View MS] button is also used to dismiss the display of the online lexica that are linked from the lexicographical analyses.

Finally the [Home] button returns the browser to the landing page for the project whilst the [Debug] button will cause additional diagnostic information to be written to the console log file which may help the development team identify the cause of any problems reported (whilst the code has been tested in a number of current mainstream browsers, there is always the possibility that something unforeseen may occur, or that the user may have elected to use a browser that behaves differently from those in which testing took place).

Implementation Details

Much of the underlying implementation functions in exactly the same way as a "normal" web page, and no attempt is made to document here those aspects that are not innovative in some way.  We concentrate instead on those aspects of the implementation that are, we believe, both innovative and interesting, and these are presented in (a) the order in which they take place (i.e., as the page is loaded), and then (b) the order in which it is anticipated that most users will exploit them.

  1. The static code

    1. Syntax errors

      • Any syntax error detected by the JavaScript (hereinafter "JS") interpreter will result in a pop-up alert; the user is referred to the error console for additional diagnostic information.

    2. Global declarations, naming and other conventions

      • In order to minimise the risk of an inadvertent reference to a global variable (e.g., because of a missing local declaration in a function), a single global object called "Global" is declared; all other global variables, no matter whether simple or structured, are declared as members of this single global object.

      • Both constants and load-time variables are initialised at the point of declaration, and no naming convention is adopted to differentiate between the two, nor is the so-called "Hungarian notation" (oGlobal, strFolio, . . .) used, for philosophical reasons that we do not seek to justify here.

      • Multi-word identifiers use case differentiation with a leading capital to identify word boundaries (ApparatusCriticus, LexicographicNotes, . . .).

      • Local variables are normally all lower-case unless (a) they are abbreviations (XHR, URL) or (b) are multi-word (see above).

      • The short form of array declarations (var linkage = [ ]) is used rather than the long (var linkage = new Array () ).

      • ALL redundant semi-colons are intentionally omitted.

      • Braces (and other paired delimiters) either occur on the same line or are vertically aligned; we do not pair an open-brace (or other delimiter) at the end of one line with the corresponding close brace at the start of another.

      • In general, the code is written in a procedural manner; the use of object-oriented code is normally restricted to references to library objects.

      • try {} catch {} is used where errors are anticipated; it is by no means impossible that errors may occur elsewhere and further try {} catch {} clauses may be introduced in later revisions of the code.

    3. Browser differences

      • As far as possible, all code is written to perform identically in the two main browser families (Gecko-based, IE-based) — in other words, code is written at the level of the highest common factor; where differences are known to exist and the HCF approach is untenable, variant code is used to handle these differences.  For example, the [Go ! ] button exists solely because IE does not recognise <return> as indicating "confirm data entry" for a text field in a form element).

      • A null replacement is provided for "console.log ()" which will (for example) result in no console logging in IE unless the console log feature is enabled (via F12) before the page is loaded.

  2. Load-time initialisation

    1. The syntax-error handler is nominated.

    2. The global object is declared, and its members declared and initialised.

    3. A null replacement is provided for "console.log ()" if the latter does not exist.

    4. A number of external files are loaded (apparatus criticus, apparatus fontium cum referentium, betacode, lexicon, dictionarium) and global arrays are populated with the contents of these.  Such files are loaded using XMLHttpRequest ().

    5. A null mouse handler is established, and hooks created that will allow this to be replaced with the real mouse handler once all necessary initialisation is complete.

    6. A replacement is provided for "window.getComputedStyle ()", which is missing in early instances of IE.

    7. The suite of JS modules associated with Sheldon McKay's popup balloon utilities is loaded; the reader is referred to the documentation associated therewith for details of their load-time behaviour (the code has been slightly modified in order to make it location-invariant).

    8. At this point, load-time (static) initialisation is complete.

  3. Run-time initialisation

    1. When the document has finished loading, the event handler associated with the "onLoad" attribute of the document's <BODY> element will be invoked.  This is specified in the document's HTML as the function "OnLoad ()", the behaviour of which is as follows :

      1. The navigation aids are dimmed to indicate that a page transition is in process.

      2. Any parameters associated with the URL are retrieved and their values (or their default values) stored in the global object — these are passed as a structured query string, the syntax of which may be easily deduced from the following example :

        • ?folio=f001v;text=Transcription;reflow=None;debug=False

      3. Using the values retrieved or defaulted from these parameters, the desired folio, text and reflow are selected; as a side-effect of selecting these, the associated map (q.v.) is retrieved and analysed and the associated mask (also q.v.) selected.

      4. Handlers for all anticipated mouse events are prepared and stored in the global object.

      5. In a single monolithic operation (so as to avoid any possibility of a race hazard), all passive (dummy) mouse handlers are replaced by their active counterparts.

      6. The navigation aids are restored to their former brightness to indicate that the page transition is complete.

      At this point, all initialisation is complete, and all further behaviour results directly from user interaction; however, a great deal of background work was carried out during run-time initialisation (particularly under ii., above) and it is necessary to explain this in far greater detail before the behaviour resulting from user interaction can be properly understood.

    2. Under ii, above, it was stated that "the desired folio, text and reflow are selected [using the values retrieved or defaulted from the parameters]; as a side-effect of selecting these, the associated map (q.v.) is retrieved and analysed and the associated masks (also q.v.) selected".  This, it turns out, is a very superficial analysis of what takes place, and the actual steps involved are both manifold and complex :  they will therefore be covered in considerable detail.

      1. Selecting the desired folio

        1. from the "folio=f001v"-type information present or defaulted in the URL parameter string, and from a number of intrinsic and/or computed constants, the code is able to infer that the required folio image is "Royal_MS_16_C_X_ f001v.jpg" and that this is to be retrieved from a directory the location of which can be computed from the URL of the current document (i.e., the path to the image is a relative URL).

        2. If the image is loaded successfully, an attempt is next made to load the map file associated with the image (such files consist of a large number of <AREA> elements, each of which defines one rectangular sub-region of the folio image :  in an ideal world, there would be exactly one <AREA> element for each word in the manuscript, but life is rarely that simple and in practice words frequently have to be broken down into a number of (possibly overlapping) sub-areas, for reasons that will be explained later).  The map files must be prepared by hand — a vital but labour-intensive task.

          The map file for folio 4r

        3. If the map file is successfully loaded, it must next be analysed.  For each <AREA> element in the file, there are two key attributes : "coords", which specifies the co-ordinates of the (rectangular) region defined by that particular area, and "class", which would normally be used to denote the CSS class(es) with which it is associated and thus the CSS style(s) to be applied to the element; however, as maps are invisible they have no need of styling, and the "class" attribute is here used as a convenient way of passing information to the analyser.  In particular, each "class" attribute will be of the form "class='Rr Ll Ww'", where "R", "L" and "W" are the actual characters but "r", "l" and "w" are integers denoting the region (r), line (l) and word (w) of the word with which the area is associated (e.g., "class='R1 L2 W1'").  It is through this mechanism that it is possible to unambiguously associate multiple areas with one word :  i.e., for all areas associated with a given word, the class values will be identical.  The line and word values will be used to associate a particular word in the folio image with the corresponding word in the text (i.e., in the transcription or the edition), but as the concept of "the corresponding word" is not meaningful for the translation, the mapping there is at a coarser level of granularity which is referred to as a "region", whence the need for an "R"-value in the class.  Since the analysis is time-consuming and is therefore performed only once for each folio for reasons of efficiency, the global object is used store to all of the co-ordinate 4-tuples associated with each region, and with each (attested) combination of line and word.  The maximum number of areas associated with any single word is also recorded; this will later be used to determine how many instances of each mask (q.v.,) will be needed.

          While analysing each <AREA> for co-ordinates and class, the opportunity is taken to associate a unique "id" attribute with each :  the attribute value is formed by interpolating appropriate values into the string "FO-Rr-Ll-Ww-Pp" (for "r", "l" and "w" as previously defined, and where "p" represents the particular part of the word with which this area is associated (i.e., p = 1, 2, 3, . . .) — this unique ID would normally be used to facilitate direct access to the element (using getElementById () ), but here it is primarily used to provide a many:1 mapping between areas of the folio and words in the text.  Just as each area in the folio map has an ID of the form "FO-Rr-Ll-Ww-Pp", so each word in the text has an ID of the form "ED-Rr-Ll-Ww" (for the Edition) or "TC-Rr-Ll-Ww" (for the Transcription) : it is thus very simple to identify which areas in the map correspond with which words in the text, a feature of which considerable use is made.  The opportunity is also taken to bind two event handlers to the area — these will deal with possible 'onmouseover' and 'onmouseout' events, and will in practice result in the simultaneous highlighting of a word (or region) in the folio and the corresponding word (or region) in the text when the mouse is moved over the word (or region) in the folio; detailed discussion of this will be deferred until later.

        4. When analysis of the map is complete, the program next attempts to locate and load the mask associated with the folio image.  Before going into the details of how this is accomplished, an explanation of the nature and rôle of a mask must be given :

          Each folio image is similar to a greyscale scan of one particular folio of the MS, but whereas conventional greyscale images consist of nothing but shades of gray, our "greyscales" consist of shades of sepia; in use, when the mouse is moved over any word in the folio image, that word is highlit by displaying it not in shades of sepia but rather in shades of red.  Whilst it would in theory be possible to carry out real-time image manipulation to achieve this effect, it would be extremely resource-consuming and a decision was therefore taken to pre-process all folio images in the collection.  The set of masks therefore consists of a set of images which are identical to the folio image collection except that every possible shade of sepia in the original is replaced by the corresponding shade of red in the mask.  If the program were displaying the folio image for (say) f001r, and this were suddenly replaced by the mask for f001r, the user would notice no difference other than that it had apparently changed colour from sepia to red.

          The actual mechanics of locating and loading the mask image corresponding to a folio image are trivial, and are accomplished by nothing more complex than simply re-writing a part of the URL for the folio image and then loading the corresponding mask using XMLHttpRequest () specifying the modified URL.  What follows, however, is far more complex and important —

          It was mentioned above that, when analysing a map, a note is made of the maximum number of areas associated with any given word.  This number, referred to in the code as 'Global.MaxParts', is now used to load not one but n instances of the mask, where n = Global.MaxParts.  Because browser implementations are highly optimised, this does not require n fetches of the mask from the server : in practice, not only is the mask cached after the first fetch, but even more beneficially images are embedded not by value but by reference, so in fact only one instance of the mask is fetched and stored.  But logically there are n instances of the mask, and each of these is associated with a different layer — HTML allows a web page to consist of multiple layers which can (if desired) overlap, either partially or fully.  Where two or more layers overlap, only the topmost layer is visible, unless it is transparent, in which case the next layer beneath is visible, and so on.

          So now all of the elements that will be needed to highlight a single word in the folio image are in place :  the image itself; a sufficient number of masks, all identical to the image except for their colour (they are red, the image is sepia); a map that partitions each word into a number of (possibly overlapping) rectangular areas; a record of how many such areas are associated with each word; and the co-ordinates of each.  The highlighting process (which will be returned to in the section devoted to the response to mouse activity) will therefore be as follows :

          The initial state of all mask layers is with visibility: "invisible" and the clipping region set to a zero-area rectangle with co-ordinates (0, 0, 0, 0).  The code iterates through the set of areas associated with the word of interest and with each associates a mask layer.  The co-ordinates of the area are retrieved, and these are then used to define the rectangular clipping region of the associated mask layer.  And finally the visibility of the layer is set to "visible".  Thus a second copy is built up of the word of interest, identical save for its colour, and consisting of a number of layers each of which is clipped to display exactly one rectangular part of the word.  As each of these layers is logically "on top" of the layer containing the sepia folio image, the rectangular region to which each is clipped obscures the corresponding part of the sepia image, and thus what remains visible is a sepia image of the folio with a single word displayed in red.  The technique is generalised when the translation is visible in the text pane, as then a whole stretch of text is highlit rather than a single word, but the underlying methodology and technology are identical.  It may be worth noting in passing that, as the rectangular areas can overlap and only the topmost part of any overlap can be visible, it might be thought that this could result in a part of the word being hidden, if it occurs only in an intermediate layer :  in practice this will never be the case, as the content of all overlapping parts is identical — thus it does not matter if a part of an intermediate layer is obscured, as its content will be replicated in the corresponding part of all higher layers (and also of all lower layers, but this latter fact is irrelevant and is noted only in the interests of precision).  "De-highlighting" a word (which occurs when the mouse leaves its vicinity) is simply the reverse of the above :  the clipping region of each layer is reset to (0, 0, 0, 0) and its visibility reset to 'invisible'.

      2. Selecting the desired text

        1. Using once again XMLHttpRequest () and the code's intrinsic knowledge of how to compute the URL at which the required document is to be found, the text corresponding to the current folio is loaded.  Each text exists in three versions :  transcription (near-diplomatic), edition, and translation, but only one of these is ever loaded at one time.  As considerable work will be carried out on the DOM representation of the text once it has been loaded, a number of global variables are initialised preparatory to this task.  And, as it is possible that the previously displayed text (if any) had been interrogated for data from its apparatus criticus, fontium cum referentium, or scholia, any previously displayed annotations are concealed.  If the text is an edition, then its reflow characteristics (which control how line-endings in the folio are presented in the text) are set to those requested.  Once this has been done, a great deal of behind-the-scenes activity takes place through a mechanism known as "walking the DOM", or (rather more formally) as "DOM traversal".

        2. "Walking the DOM" is web jargon to describe an activity that is pivotal not only to this project but to many others besides.  It is necessary to start by explaining exactly what the DOM is, how it is created, and the rôle that it plays when a web page is rendered.  The DOM ("Document Object Model") is the internal representation of a web page, created when that page is loaded and capable of being subsequently modified (without any impact on the source document) by scripting languages such as JavaScript and even by events such as a mouse gesture or a key press.  Although one tends to think of a web page (i.e., an HTML document) as being rendered, in practice this is no longer the case (and perhaps never was) :  instead, the web page is parsed, a Document Object Model built in the computer's memory, and then that DOM is itself used to generate the rendered image.

        3. In the context of the current project, "Walking the DOM" is used to analyse the content of the text page associated with the current folio.  Such content (for a transcription) will typically be along the lines of the following :
              <P>
          <B class="L1 W1">Τῇ</B>
          <B class="L1 W2">τιμιωτάτῃ</B>
          <B class="L1 W3">κ(αὶ)</B>
          <B class="L1 W4">ἐμφανέστατῃ</B>
          </P>
          Each <P> element contains a single line of the folio, and each <B> element contains a single word of that line.  The " class " attribute is used to indicate explicitly indicate the line and word.  This is near-minimal markup ("near", in the sense that it might have been possible to avoid even the need for the "class" attribute, but these were introduced early in the development cycle and there seemed little point in removing them once the DOM-walking code was in place), and it will be obvious that there are, for example, no event handlers associated with each <B> element.  These, and other essential attributes, will be grafted on to each <B> element as the DOM is walked.

          Because all well-formed HTML documents can be viewed as serialisations of a (mathematical) tree, "walking the DOM" is in fact a recursive process.  Starting at the root element, which for one of the text documents in this project will be a <DIV>, the code ascertains whether or not this element has any child nodes; if it does, then the sub-branch of the DOM rooted at that node is walked, and so on.  Whenever a node is reached that has no descendants, any additional operations that are necessary are performed and then the code returns to whatever it was doing prior to walking that node.  The tree-like nature of the DOM ensures that this process terminates (the same would not be true for a graph).

          As each <B> ("word") node in the DOM is walked, the code retrieves the line and word associated with that node, and from its intrinsic knowledge as to whether the current text is an edition, transcription or translation, a unique ID is then grafted on to each node to facilitate its rapid access using getElementById (). For an Edition, such IDs will be of the form "ED-Ll-Ww", for a Transcription "TC-Ll-Ww", and for a Translation "TL-Rr" (and all will, of course, be unique : it would be both a logical error and a violation of the rules governing the structure of the DOM if any two were the same).

          In addition to grafting on a unique ID, we also graft on a number of event handlers.  The "onclick" event, for example, is bound to a handler that will display the lexicographic information associated with the word that forms the content of that node; as it is possible that two or more words might be visually indistinguishable (i.e., spelled identically) yet actually be different parts of speech, provision is also made to pick up additional metadata from any "content" attribute associated with the node, and this metadata is then used by the event handler to retrieve the exact lexicographic information associated with that particular combination of word and part of speech.  The "onmouseover" and "onmouseout" events are bound to handlers that will highlight the word both in the text and in the folio.

          In addition to <B> elements, which denote words, the texts also contain <SPAN>s; these are used to provide an association between a particular stretch of text and an entry in one of the four classes of apparatus : criticus, fontium, referentium and scholia.  When a <SPAN> element is encountered during the DOM-walk, the value of the "class" attribute (if any) of the element is retrieved, and from this is determined to which of the four possible apparatus the <SPAN> is linked.  Once this is know, an additional "trigger" element may be grafted into the DOM, if the contents of the apparatus are to be displayed only as a result of a mouse-click (the trigger element will typically be rendered as a superscript on which the user can click to disclose the contents of the relevant apparatus entry).  Not all apparatus entries require a click in order to display them, and for those that do not, no additional trigger element will be necessary :  instead, simply hovering over the word or stretch of text in question will be sufficient to reveal the entry, and this will take the form of a "speech bubble" adjacent to the text under the mouse.

          Apart from <B> elements and <SPAN> elements, only one other type of element is afforded special treatment during the walking of the DOM, and that is the <DIV> element.  Its normal role in the texts is to act as a container for the whole page (i.e., the root element, from which DOM traversal will start) but it has an additional role in relation to the apparatus scholia (i.e., a commentary on a particular historical event).  Because of the large number, and generally terse nature, of the entries in the other three apparatus (criticus, fontium, referentium ), they are stored in two external files (one for the apparatus criticus, and one for the apparatus fontium cum referentium.  However, apparatus scholia entries are both few and generally discursive, and it therefore makes more sense to store them in the page from which they are referenced.  Thus when such a page contains one or more apparatus scholia entries, each of these will be contained in a separate <DIV> element, and the DOM walker will extract the content of each of these and store it in the global 2-dimensional array "Global.ApparatusScholia [ ] [ ]" from which it can be retrieved when the user indicates (by a mouse gesture) that it is to be displayed.

      3. Selecting the desired reflow

        As has already been described, whilst the presentation of the transcription and translation are fixed, the style of presentation of the edition is under user control.  As, by definition, an edition can only coincidentally be in 1:1 correspondence with the text from which it is derived, it is necessary to decide how line-turns in the original text will be indicated in the edition.  In the present project, three options are offered, and are under user control :

        1. Reflow: none
          • Line turns in the folio are the same as those in the edition.

        2. Reflow: normal
          • Line turns in the folio are indicated by spaced solidi in the edition.

        3. Reflow: full
          • Line turns in the folio do not appear at all in the edition, and the latter can therefore be read as a stretch of uninterrupted prose.

        The implementation of this is extremely straightforward.  If the desired reflow has been passed as a parameter to the URL, that value is used; if not, the current value of the "Reflow" dropdown is used instead.  Using getDocumentById (), access is made to the internal representation of the Edition and the class of its outermost <DIV> element is set to "Edition, "Reflowed-edition" or "Fully-reflowed-edition" as required; all further transformations, such as the suppression of line turns or the insertion of solidi, are accomplished using CSS.

      Once the document has loaded, all further behaviour will directly result from user interaction with the page.  As there are manifold possible ways in which a user can interact with the page, the following analysis will assume a typical usage scenario.

  4. Page Navigation

    1. Selecting the desired folio

      The desired folio can be selected in several different ways :  by direct text entry of the desired folio into the box labelled "Folio :" followed either by clicking on the [Go !] button or hitting <return>/<enter> (the [Go !] button is required only for Internet Explorer  :  all other browsers tested recognise <return>/<enter> as indicating text entry complete), by using the [« Prev] or [Next »] buttons, or by selecting the desired folio using the drop-down menu.  Regardless of the method used, the underlying behaviour remains very much the same.  Each of the navigation aids will first call "Dim ()", to indicate that a page transition is in progress, and then all but the the drop-down menu will call "GotoFolio ()" (for the direct text entry field) or "GotoAdjacentFolio ()" (for the [« Prev] and [Next »] buttons) which will compute the desired folio and then dynamically change the selected value of the folio drop-down menu.  A change in the selected value of the folio drop-down menu (either as a result of the dynamic change just referred to or as a result of direct user interaction with the menu) will result in a call to "BookmarkCurrentState ()" which lies at the heart of all page navigation and which will therefore be covered next.

      "BookmarkCurrentState ()" was a fairly late addition to the code of the electronic edition.  Initially our design goal was to avoid page changes for efficiency reasons, whence the widespread deployment of "XMLHttpRequest ()" , but as the project neared completion it became ever more obvious that our intended audience would need to be able to refer to, and perhaps bookmark, the state of the current page (i.e., which folio, which text variant, which reflow, and so on).  So, somewhat late in the day, "BookmarkCurrentState ()" was added, which introduced certain unavoidable overheads (most of which are mitigated by browser cacheing) but which offers so many advantages that it is clear with the benefit of hindsight that it could beneficially have been incorporated from the very outset.  Despite its now pivotal rôle in page navigation, "BookmarkCurrentState ()" is extremely simple :  it retrieves the current values of the folio, text and reflow selectors, and then modifies the URL of the page which the browser is currently displaying by replacing the query-part (if any :  the query part consist of a trailing question mark followed by a sequence of keyword:value pairs) with a new query-part containing the following :  "?folio=folio; text=text; reflow=reflow; debug=debug".  As a result, the browser fetches a new copy of the page, which in turn triggers the latter's "OnLoad ()" function, which then (as described in Section 3, above) fetches the desired folio, map, mask and text, adjusts the reflow if the text is an Edition, and finally calls "Brighten ()" to restore the navigation aids to their original intensity, thereby indicating that the page transition is complete.

    2. Selecting the desired text and reflow

      Just as there are navigation aids above the folio pane, so there are navigation aids above the text, and these allow the selection of the desired text and (if the desired text is an Edition), the desired reflow.  The action of these is even simpler than those above the folio pane :  as soon as the user has selected the desired text or reflow, the drop-down menu calls "Dim ()" to indicate that a page transition is in progress, then immediately calls "BookmarkCurrentState ()".  The latter then retrieves the values from the folio and text navigation aids (by definition, one of the latter has just been set) and reloads the page with the new parameters.

    3. Invoking "Help"

      Clicking on the [Help] button will cause the text of the User Guide to be displayed in the space normally occupied by the folio image.  As this same space is also used to display off-site lexicographic information, a single function "OverlayFolio ()" is used to provide both features.  When OverlayFolio () is called from the [Help] button, the URL of the User Guide is passed as an implicit parameter.  OverlayFolio () retrieves this parameter and then checks to see whether a <DIV> element called "Overlay-panel" is currently hidden; if it is, it replaces the contents of this element with an <IFRAME> element the source of which is the URL described above and makes the <DIV> visible.  If, on the other hand, the <DIV> was already visible (because, for example, the[Help] button had already been pressed), then the visibility of the <DIV> is set to "hidden".  Thus the first press of the [Help] button will reveal the User Guide as a textual overlay to the folio image, and a second press will conceal the overlay so that the folio image is once again visible.

    4. Providing feedback

      If someone using the Electronic Edition spots (e.g.,) an infelicity in the translation, or simply wants to seek clarification on some seemingly obscure aspect of the text, a facility is provided whereby he/she can highlight the stretch of text of interest, and then, by clicking on the [Feedback] button, add additional information and then send the whole electronically to the project team.  Highlighting a stretch of text requires no additional support in the code (such functionality is intrinsic in all browsers) but a problem arises when the user then wants to transfer the highlit information into a web form :  the problem is, quite simply, that clicking on a button will immediately clear the highlit text ! Thus the code that implements this feature has to be particularly devious, and it captures the highlit text not when the [Feedback] button is clicked ("too late !") but when the mouse moves over the button.  This text is then saved in Global.SelectedText for possible future use ("possible" because the user may decide not to send feedback at all, or may change his/her mind about the stretch of text of interest before actually clicking the [Feedback] button).  When (if) the button is finally clicked, SendFeedback () is called with Global.SelectedText as parameter.  SendFeedback () creates a new (small) browser window which contains an ASP.NET form, passing as parameters to the form the URL of the page (which will, implicitly or explicitly include information on the folio, text and reflow) and the previously selected text.  The ASP.NET form ("SendMail.aspx") will ensure that the user has provided a syntactically valid e-mail address and will then send all of the information as an e-mail to the project team.  Successful sending of the e-mail will result in a green "Feedback successfully sent" diagnostic and after a delay of a couple of seconds the feedback window will self-dismiss.

    5. Enabling Debug

      In the event of the Electronic Edition misbehaving itself in some way, it may be necessary for the project team to gain additional insights into exactly what the code was doing at the point of failure.  For this reason, a [Debug] button is provided, the sole effect of which is to set Global.Debug to true.  At various critical points in the code, this variable is inspected, and if true additional information is recorded in the console log file.

  5. Interacting with the page

    Everything that has taken place so far is by way of preparation :  static initialisation, dynamic initialisation and page navigation.  With the desired folio, text and reflow selected, the user is at last in a position to interact with the page.  We start by considering interactions with the MS folio image, because the possibilities here are far fewer than those associated with the text.

    1. Interaction with the folio image

      As the mouse is moved over the script of the MS folio image, a part of the script will turn red :  if the text in the text pane is a Transcription or Edition, individual words will be highlit as the mouse moves over them; if the corresponding text is a Translation, then a short stretch of text will be highlit.  At the same time, the corresponding word or phrase in the text pane will also turn red.  When the mouse moves away from the script (e.g., into the space between words or lines, or to the borders, or outside the image pane completely), the red highlighting is removed and the script and text returned to their former colours of sepia and black respectively.  This effect is achieved as follows :

      1. Moving the mouse over a word in the folio image

        Each folio image has associated with it a corresponding mask image; text that is sepia-coloured in the folio image is red in the mask.  Each mask image has associated with it a map file :  an HTML file consisting of a number of <area> elements, such as the example below :

        <area alt="" coords="118,37,158,77" class="R1 L1 W1">
        <area alt="" coords="157,47,168,61" class="R1 L1 W1"> 
        <area alt="" coords="164,56,259,85" class="R1 L1 W2"> 
        <area alt="" coords="222,48,254,63" class="R1 L1 W2"> 
        <area alt="" coords="258,48,283,91" class="R1 L1 W3"> 
        <area alt="" coords="285,50,302,64" class="R1 L1 W4"> 
        <area alt="" coords="336,43,361,63" class="R1 L1 W4"> 
        <area alt="" coords="282,57,392,85" class="R1 L1 W4"> 
        
        <area alt="" coords="131,84,239,121" class="R1 L2 W1"> 
        <area alt="" coords="130,77,150,88" class="R1 L2 W1"> 
        <area alt="" coords="234,100,247,111" class="R1 L2 W1"> 
        <area alt="" coords="246,86,295,120" class="R2 L2 W2">
        <area alt="" coords="300,83,374,123" class="R2 L2 W3">

        Each of these area elements defines a rectangular region which contains a part or the whole of a single word.  No area element ever defines a region that contains parts of two or more words. 

        The mao for folio f0004r

        As the mouse moves over one of these regions, an event handler is triggered.  These event handlers are not a part of the static code; instead, they are added dynamically when the map file is first loaded.  Two event handlers are associated with each <area> element :  "onmouseover" and "onmouseout".  The first is bound to "Mouse.Live.Over.Folio () ", and the second (predictably) to "Mouse.Live.Out.Folio () ".  When these event handlers are called, they are passed as parameter the <area> element from which they were triggered.

        Mouse.Live is itself a pointer to Mouse.Active once the page is fully loaded (prior to that, it was a pointer to Mouse.Passive, to avoid race hazards as described above).  The sequence of actions which result from Mouse.Active.Over.Folio () is now described :

        1. Mouse.Active.Over.Folio () records the event that triggered it in Global.LastEvent and then calls "Disclose ()" and "Highlight ()", passing as parameter to each the <area> element that was passed as parameter to itself.

        2. Disclose () calls "ConcealDisclose ()", passing once again the <area> element but also passing (as second parameter) the string "visible".

        3. ConcealDisclose () starts by temporarily setting Mouse.Live to Mouse.Passive (to inhibit further mouse events until the current one has been fully processed), ascertains the type of the text currently displayed (i.e., edition, transcription or translation) and then retrieves the class of the <area> element.  As can be seen above, the class value consists of a triplet of ordered pairs of the form Rr Ll Ww, where "R" denotes "Region", "L" denotes "Line" and "W" denotes "Word".  These are next separated and the numeric value associated with "R", "L" and "W" retrieved.  From the type of text currently displayed, the required mapping is deduced (word-level for editions and transcriptions, phrase-level for translations) and the code then forks :  one branch for word-level mapping, a separate branch for phrase-level.

          • For word-level mapping, the code next retrieves from the Global.Parts [] [] array the number of discrete parts (areas) required to display the entire word in red (remember that a single word may require multiple parts, as each part must not overlap with any other word), and for each part required the corresponding mask layer is then manipulated :  the clipping region is set to (a transform of) the co-ordinates retrieved from the Global.Coordinates [] [] array and the layer's visibility set to "visible".

          • For phrase-level mapping, the process is similar, but in this case the process carried out for every part required to display the entire phrase in red rather than just a single word, and the clipping region is set to (a transform of) the co-ordinates retrieved from the Global.Regions [] [] array.

          When the entire word (or phrase) has been disclosed in red, Mouse.Live is restored to Mouse.Active, thereby enabling further mouse events.

        4. Next, as described above, "Highlight ()" is called.  HIghlight () calls HighlightRestore () passing as parameters the <area> element with which it was called and the string "Highlight".

        5. HighlightRestore () calls "TextOf ()" to retrieve the text element corresponding to the <area> element, passing as parameter the <area> element with which it was itself called.

        6. TextOf () interrogates the text-selector drop-down to ascertain which type of text is currently loaded (Edition, Transcription or Translation) and using that information then determines the appropriate prefix of "ED-", "TC-" or "TR-" to use in order to access the desired text element.  The ID of the <area> passed as parameter is split at each embedded "-" (the ID will be of the form "FO-Rr-Ll-Ww-Pp") and a new ID formed by contenating the computed prefix with the appropriate subset of the parts derived by splitting.  If the text is a edition, the resultant ID will be of the form "ED-Ll-Ww"; if a transcription, "TC-Ll-Ww", and if a translation, "TL-Rr".  Using the computed ID, the element with that ID is then retrieved.  This element will therefore be the text element that corresponds to the word (or phrase, for translations) in the MS folio image of which the <area> element (over which the mouse moved to trigger this whole train of events, and whose computed ID was "FO-Rr-Ll-Ww-Pp") denoted one rectangular part.  This element is then returned as the result of the function.

        7. Using the text element returned by TextOf (), HighlightRestore () next records that element's current foreground colour in a non-standard attribute of the element called "Colour" (non-standard in the sense that no such attribute exists in the HTML 4.01 specification :  the DOM allows such non-standard attributes to be created and exploited).  Then the foreground colour of the element is set to red.

          And that concludes the description of the sequence of events that is triggered when the user's mouse passes over a word (to be more precise, over an <area> that overlays part or all of a word) in the MS folio image. We now turn our attention to what happens when the mouse leaves that <area>, but in considerably less detail as it is simply the reverse of what was described above.

      2. Moving the mouse outside a word in the folio image

        When the mouse leaves an <area> over which it was previously moved, the following sequences of events takes place :

        1. Mouse.Live.Out.Folio () is called with the <area> element as parameter, which in turn calls Mouse.Active.Out.Folio () with the same parameter.

        2. Mouse.Active.Out.Folio () records the last event (i.e., "Mouse.Out.Folio") in Global.LastEvent and then calls (in turn) Restore () and Conceal (), again passing as parameter the element with which it was called.

        3. Restore () calls HighlightRestore (), passing as parameters the parameter with which it was called and the string "Restore".

        4. HighlightRestore () calls TextOf () to access the text element corresponding to the <area> element with which it was called as parameter.  It then retrieves the former colour of the text element from the latter's non-standard "Colour" attribute and then sets the foreground colour of the element to this colour.

        5. Conceal () calls ConcealDisclose (), passing as parameters the parameter with which it was called and the string "hidden".

        6. ConcealDisclose () goes through much the same sequence of steps as described under the actions resulting from an "onmouseover" event, the only significant differences being that the clip region is set to (0, 0, 0, 0) and the mask visibility is set to "hidden".

          When the red highlighting of the entire word (or phrase) has been concealed, Mouse.Live is restored to Mouse.Active, thereby enabling further mouse events.

          And that concludes the description of the sequence of events that is triggered when the user's mouse leaves an <area> that overlays part or all of a word in the MS folio image.  We will now turn our attention to the sequence of events that occur when the mouse moves over (or away from) a word or phrase in the text pane.

    2. Interaction with the text

      What follows is very much the mirror image of what was described above, at least in so far as mouse movements over words or phrases in the text are concerned.  However, in the text pane, rather more functionality is exposed (the user can click on a word, for example, in order to view the relevant lexicographical note), and various other features are provided through superscripted footnote callouts and "active text" (text that is already highlit in a contrasting colour when the page is loaded, and for which additional information can be displayed simply by moving the mouse over the text).  But we will start with the mirror sequence of actions to those described above.

      As the mouse is moved over words or phrases in the text, the word or phrase will turn red :  if the text is a Transcription or Edition, individual words will be highlit as the mouse moves over them; if the text is a Translation, then a short stretch of text will be highlit.  At the same time, the corresponding word or phrase in the image (manuscript) pane will also turn red.  When the mouse moves away from the text (e.g., into the space between words or lines, or to the borders, or outside the text pane completely), the red highlighting is removed and the text and script return to their former colours of black and sepia respectively.  This effect is achieved as follows :

      1. A number of event handlers are associated with each (word or phrase-containing) element in the text :  of these, only "onmouseover" is relevant here.  This is bound to "Mouse.Live.Over.Text ()".  When this event handler is called, it is passed as parameter the text element from which it was triggered.

        Mouse.Live is itself a pointer to Mouse.Active once the page is fully loaded (prior to that, it was a pointer to Mouse.Passive, to avoid race hazards as described above).  The sequence of actions which result from Mouse.Active.Over.Text () is now described :

        1. Mouse.Active.Over.Text () records the event that triggered it in Global.LastEvent and establishes an "onmouseout" handler for the element :  this handler, when called, will itself record the event that triggered it in Global.LastEvent and then call Conceal () and Restore (), passing as parameter the element with which it is associated.  Mouse.Active.Over.Text () then calls Highlight () and Disclose (), passing as parameter the element with which the triggering event was associated.

        2. Just as under Interaction with the folio image, above, Highlight () calls HighlightRestore () and Disclose () calls ConcealDisclose ()

        3. HighlightRestore () saves the current colour of the text in the "Colour" attribute of the element and then sets the element's foreground colour to red.

        4. ConcealDisclose () starts by temporarily setting Mouse.Live to Mouse.Passive (to inhibit further mouse events until the current one has been fully processed), ascertains the type of the text currently displayed (i.e., edition, transcription or translation) and then retrieves the class of the <area> element. The class value will consist of a triplet of ordered pairs of the form Rr Ll Ww, where "R" denotes "Region", "L" denotes "Line" and "W" denotes "Word".  These are next separated and the numeric value associated with "R", "L" and "W" retrieved.  From the type of text currently displayed, the required mapping is deduced (word-level for editions and transcriptions, phrase-level for translations) and the code then forks :  one branch for word-level mapping, a separate branch for phrase-level.

          • For word-level mapping, the code next retrieves from the Global.Parts [] [] array the number of discrete parts (areas) required to display the entire word in red, and for each part required the corresponding mask is then identified and manipulated :  the clipping region is set to (a transform of) the co-ordinates retrieved from the Global.Coordinates [] [] array and the layer's visibility set to "visible".

          • For phrase-level mapping, the process is similar, but in this case the process carried out for every part required to display the entire phrase in red rather than just a single word, and the clipping region is set to (a transform of) the co-ordinates retrieved from the Global.Coordinates [] [] array.

          When the entire word (or phrase) has been disclosed in red, Mouse.Live is restored to Mouse.Active, thereby enabling further mouse events.

      2. When the mouse leaves the vicinity of the word over which it was positioned, the "onmouseout" event handler that was bound to its containing text element by Mouse.Active.Over.Text () will be triggered; this handler will record the event that triggered it in Global.LastEvent and then call Conceal () and Restore (), passing as parameter the element which triggered the event.  Just as under Interaction with the folio image, above, Highlight () calls HighlightRestore () and Disclose () calls ConcealDisclose (). HighlightRestore () then restores the foreground colour of the text element to the value stored in its "Colour" attribute and ConcealDisclose () sets the clipping region of all currently active mask layers to (0, 0, 0, 0) and their visibility to "hidden".

        That concludes the description of the sequence of events that is triggered when the user's mouse leaves a text element in the Edition, Transcription or Translation.  We now turn our attention to the other interactions that are possible with the texts.

      3. Clicking on a Greek or Latin word in the text

        1. When a Greek or Latin text is loaded (i.e., a transcription or an edition), each word in the text is made active.  Clicking on the word will disclose a lexicographical analysis in the footnote area of the page, and this analysis will itself contain links to a maximum of three external lexica :  Archimedes, Perseus & the TLG ("Thesaurus Linguae Graecae").  Clicking on the word for a second time (or clicking on another word) will dismiss the footnote and (in the case of clicking on another word) bring up its footnote in the place of the former.  No explicit markup is used to add this functionality; instead, the necesssary event handlers are added when the page is loaded, using the DOM traversal technique described above.  The "onclick" event handler associated in this way is LookupLexicographicNote () which is unfortunately one of the more complex parts of the code.  For this reason the exact operation of LookupLexicographicNote () will not be described here :  rather, an overview of its operation is offered, and the interested reader invited to peruse the code for him or herself. 

        2. In summary, LookupLexicographicNote () uses the word itself plus a knowledge of the language of the page that contains the word to retrieve an entry from Global.Lexicographicnotes [] [], indirecting via Global.Languages [] to convert the external name of a language into its internal representation.  The data retrieved from Global.Lexicographicnotes [] [] is itself an array consisting of 10 or 12 individual fields.  There is an additional complication in that the same word may occur in the text with different functions :  for example, in one place it may be plural and another singular; in one place masculine and in another neuter; or in one place a verb and in the other a noun.  Where such complexities arise, additional metadata are associated with the element containing the word, and this metadata is then used as the key into Global.Lexicographicnotes [] [] rather than the word itself.  For example, for a particular instance of ἀθάνατον, the key passed may be "ἀθάνατον (accusative) "; for another instance it may be "ἀθάνατον (nominative) ".  However, the lexicographical analysis itself must start with the word, not with the disambiguating information, and so one of the fields returned by Global.Lexicographicnotes [] [] is the word itself.  Other fields include the lemma (the base form of the word, used directly or indirectly as an index into the offsite lexica), the part of speech, inflexion and so on. 

        3. An additional complication arises from the fact that the major external lexica predate the universal adoption of Unicode by a number of years.  For this reason it is not possible to perform a direct lookup of the lemma in its Unicode encoding (the form in which it is stored and used within the project); rather, it has to be back-translated into Betacode, a simple ASCII-based encoding scheme for polytonic Greek.  Furthermore, just as a word may have more than one rôle within our texts, it may also have two or more entries in some of the external lexica, so further disambiguating information has to be supplied when these are called, and that information too is retrieved from Global.Lexicographicnotes [] [].  Suffice to say that all of these complications make the code of LookupLexicographicNote () so complex that it would be unreasonable to document it fully here :  the interested reader can, of course, always look at the source code.

        4. When LookupLexicographicNote () has finally worked through all its machinations, it then calls LexicographicNote () to display (or conceal, if already displayed), the lexicographical analysis in the footnote area of the page.  In comparison to LookupLexicographicNote (), LexicographicNote () is relatively simple :  it retrieves the invariant portions of the URLs for Archimedes, Perseus and TLG from Global.Prefixes [] [] (indirecting via Global.Languages []), interpolates the appropriate lookup key (after conversion to Betacode and the addition of any necessary additional disambiguating information), and then assembles some raw HTML that will later be dynamically inserted into the contents of the footnote element using the latter's innerHTML property.  This raw HTML takes the form of a sequence of possibly nested <span> elements that lay out the lexicographic information in a consistent manner, and which include event handler specifiers of the form onclick='OverlayFolio (this)'. OverlayFolio () has been described already (in the section entitled "Displaying the HELP text") and its use here is directly analogous to that of the HELP system :  rather than redirecting the browser to an alternative resource or launching a second window or tab, OverlayFolio () causes the (implicitly specified) required resource to be overlayed on the MS folio image.  Thus all three of the text, the lexicographical analysis and the external lexical analysis are displayed concurrently within a single window with the concomitant benefits that such a presentation affords.

        5. The actual mechanism of displaying the lexicographical analysis is slightly complicated by the need to know not only whether a lexicographical analysis is already displayed (in which case it must be concealed) but also (if one is displayed) whether its display was triggered by the same word as has most recently been clicked ("the same word" in this context means the identical element, not just an instance of the word identical in spelling and lexicographical analysis).  If either the previous trigger was not the same as the present trigger, or no lexicographical analysis is currently displayed, then the footnote <div> is made visible, the footnote rule likewise, the trigger element is dynamically underlined, and the previous trigger element (if any) de-underlined.  If neither of these conditions obtain, then the footnote <div> is hidden, the trigger element is de-underlined, and a check is made to see whether any other information (e.g., an entry from the apparatus fontium cum referentium, or from the apparatus scholia) is currently displayed in the footnote area.  If any such information is present, the footnote rule is left visible, otherwise it is hidden.  Any underline of the previous triggered word is also removed.  Finally the most recent trigger element is recorded in Global.LastExternalLink .

      4. Hovering over an active region in the Edition

        1. In preparing the Edition variant of the text, considerable care has been taken to clarify wherever an editorial emendation has been made or where the scribe himself (i.e., George Etheridge) made an alteration to the text.  The first such instance occurs in f. 1r, Edition, at the end of line 1 which reads Τῇ τιμιωτάτῃ καὶ ἐμφανεστάτῃ.  In the Transcription the last words reads ἐμφανέστατῃ, with stress denoted by the oxia on the second ε (i.e., on letter 6, 3rd syllable), whereas in the Edition the stress (and oxia) are relocated to the second α (letter 9, 4th syllable).  To indicate this scholarly emendation, the word ἐμφανεστάτῃ is contrastingly coloured in the Edition (currently green :  this may change in the near future to make the text more accessible to those with red:green colour blindness) and hovering over the word will reveal the corresponding apparatus criticus which reads corr.: ἐμφανέστατῃ cod., displayed in a "speech bubble".  The effect is achieved by adding an extra <span> element around the <B> element that contains the word ἐμφανεστάτῃ so that the markup reads at that point <span class="Apparatus criticus"> <b class="L1 W4">ἐμφανεστάτῃ</b></span>.  Note that it is not necessary to indicate which particular entry in the apparatus criticus is to be displayed : during DOM traversal (q.v.,) a page-local sequence number is assigned to each apparatus criticus callout and this number, in conjunction with the folio number, is sufficient to uniquely identify which entry from the apparatus criticus should be retrieved and displayed.  Note also that, as in earlier analogous examples, there is no explicit event handler specified in the markup :  the event handler is added during DOM traversal of the Edition, and the relevant code reads Node.onmouseover = function (cause) {ProcessApparatusCriticus (this, cause)}.  No explicit onmouseout handler is added :  the onmouseover handler adds the onmouseout handler itself.

        2. ProcessApparatusCriticus () starts by adding an onmouseout handler to the element (CancelApparatusCriticus ()) and then causes a dynamic underline to be added to the triggering element.  It then looks to see if there are any entries in the apparatus criticus for the current folio, and if there are, looks to see if there is an entry for this specific callout.  Provided that both conditions obtain, the relevant entry is retrieved from Global.ApparatusCriticus [] [] and passed as parameter to Sheldon McKay's balloon.showTooltip ().  The latter then causes the "speech bubble" to appear.

        3. CancelApparatusCriticus (), called by the triggering element's onmouseout event, simply removes the underline from the trigger element :  no specific code is required to remove the speech bubble as that functionality is intrinsic to Sheldon's code.

      5. Apparatus fontium, apparatus referentium and apparatus scholia

        All that remains to be described is the mechanism by which entries from the apparatus fontium, apparatus referentium and apparatus scholia are retrieved and displayed.  In practice, the apparatus fontium and apparatus referentium share a single file (referred to elsewhere in this document as the apparatus fontium cum referentium) and a unified mechanism for retrieval and display : they differ only in so far as the callout marker for an entry in the apparatus fontium is a superscript Arabic numeral in square brackets whilst the callout marker for an entry in the apparatus referentium is a superscript Roman numeral in square brackets.  Entries in the apparatus scholia have a superscript lowercase English letter in square brackets as their callout, but as they are both few and discursive they are actually stored in the text that refers to them rather than being stored in an external file.

        1. The markup for all three is very similar, and also similar to that used for the apparatus criticus (see above).  In the first example below, both apparatus fontium and apparatus referentium occur in the same line; in the second example, the apparatus scholia spans two lines.  Below the second example is the text of the apparatus scholia as it appears in the source of the translation to which it applies.

          <B class="R7"><SPAN class="Apparatus fontium">Wide-ruling Agamemnon</SPAN> had once the <SPAN class="Apparatus referentium">heart of a deer,</SPAN></B>

          <SPAN class="Apparatus scholia">
          <B class="R2">having been very well educated in it both in itself</B>
          <B class="R3">and as you are accustomed to engage also in other goods of education</B>;</SPAN>

          <DIV id="Translation" class="Translation f1v-4r">
          <P>
          <B class="R1">both because you do not consider such speech to be foreign</B>, ...
          <B class="R8">so that I should always educate the youths of this University earnestly engaged with the Greek tongue</B>
          </P>
          </DIV>
          <DIV class="Commentary">
          Elizabeth's education had benefited from the skills of a talented circle of humanist scholars centred on St John's College, Cambridge, ...  Ascham was more guarded regarding her spoken Greek, saying that she spoke the language 'frequently, willingly and moderately well'.
          </DIV>


        2. During DOM traversal (q.v.,) additional nodes are grafted into the DOM which contain the trigger elements that act as apparatus callouts; as a result, the <span class="Apparatus ..."> elements are augmented by <sup> elements that contain the required square brackets and sequence number together with an onclick attribute that will cause the associated apparatus entry to be displayed in the footnote area.  Also during DOM traversal the text of the apparatus scholia (i.e., the contents of the <div class="Commentary"> elements) are extracted from the page and entered into Global.ApparatusScholia [] [], indexed by folio and sequence number.

        3. When the user clicks on one of the apparatus callouts, one of two routines is called :  for apparatus fontium and apparatus referentium, ProcessApparatusFontium (), and for apparatus scholia, ProcessApparatusScholia ().  We will discuss each of these in turn.

        4. ProcessApparatusFontium () is a fairly complex piece of code which itself makes use of a number of helper functions :  PopulateFootnoteText (), DisplayApparatusFontium (), ConcealApparatusFontium () and ConcealFootnoteruleIfredundant ().  It has intrinsic knowledge of how apparatus fontium entries should be presented, typographically speaking, and starts by preparing boilerplate that will be inserted as required in the footnote.  It then attempts to retrieve the required entry from Global.ApparatusFontium [] [], and if successful, then formats the entry using PopulateFootnoteText ().  This function parses the apparatus fontium entry, which can be quite complex :

          "Author=Homer; Work=Iliad; Loci=I:69, II:716, V:843, VI:76, VII:221, XII:344, XII:357, XV:282, XXIII:357& Author=Homer; Work=Odyssey; Loci=VIII:123, IX:432, XV:253, XXIV.429"

          and then interpolates each element into the footnote text surrounded by the appropriate boilerplate.

          The footnote number is then prepended to the footnote in the same style as the callout (Arabic for apparatus fontium, Roman for apparatus referentium), and then a check is made to see if there is already a footnote displayed.  If no footnote is displayed, DisplayApparatusFontium () is called to display the footnote; if a footnote is already visible, then a further check is made to see whether it is the same footnote or another.  If it is the same footnote, ConcealApparatusFontium () and ConcealFootnoteruleIfredundant () are called, otherwise ConcealApparatusFontium () and DisplayApparatusFontium () are called instead. Finally the trigger element is recorded in Global.LastAppfontHotspot which is used as the basis for deciding whether a footnote is the same as one already displayed.

        5. ProcessApparatusScholia () is considerably simpler.  It start by attempting to retrieve the required entry from Global.ApparatusScholia [] [] and then prepares the footnote by prepending the footnote number to the entry retrieved.  It then looks to see if an apparatus scholia entry is already displayed.  If it is not, it makes the apparatus scholia <div> visible, does the same to the footnote rule, and then causes the trigger element to be underlined.  If an apparatus scholia entry is already displayed, then it makes the apparatus scholia <div> invisible (i.e., hidden), removes the underlining from the trigger element, and then removes the footnote rule if and only if it is not required by (e.g.,) a visible apparatus fontium.

  6. And that just about wraps it up.  There are, almost certainly, some features still undocumented, such as the mechanism by which clicking on a footnote returns to the point on the page from which the footnote's appearance was triggered, and these will be added in the fullness of time.  Writing this documentation has been an interesting and worthwhile experience, and it has already identified some places where the code could be improved. That, too, will be addressed.  In the meantime, we hope very much that you will enjoy using the Electronic Edition of George Etheridge's Autograph Encomium on Henry VIII, addressed to Elizabeth I; if you have any comments or suggestions to offer, do please make use of the feedback form provided.

Philip Taylor  :  last updated 20-Feb-2013 23:31


  1. It is with considerable regret that we must note that the work is not accessible to all, and in particular it is not accessible to blind and partially sighted users, much as we would have wished it so to be.  The problem arises solely from the nature of the material that we seek to present : a digital facsimile of a 16th-century manuscript, handwritten in polytonic Greek.  The transcription, edition and translation are, of course, intended to be accessible, and we would welcome feedback from any blind or partially sighted users who experience difficulty in accessing these elements of the project, but for what we believe to be obvious and understandable reasons, it is presently beyond our ability to make the manuscript facsimile itself accessible to blind and partially sighted users.  We offer them our sincere apologies and our profound regrets.