Sourcecode Listing of

http://purl.oclc.org/NEUMES/ref/NeumesXML.xsl





Color Key :   [•] XML code      [•] HTML      [•] symbol substitution      [•] XML comment   

Line
0001 <?xml version='1.0' encoding="UTF-8" standalone="no"?>
0002 <!--
0003 *   XML Transformation (XSLT) generated on 6 December 2006.
0004 *   Filename: http://www.scribeserver.com/NEUMES/xml/NeumesXML.xsl
0005 *   Version: 3.1
0006 *   Owner: The NEUMES Project
0007 *   (Neumed and Ecphonetic Universal Manuscript Encoding Standard).
0008 *   For details see, http://purl.oclc.org/SCRIBE/NEUMES/
0009 *   Authors: Louis W. G. Barton, with Clare McInerney and Jeni Tennison.
0010 *   Type: XML XSLT
0011 -->
0012 
0013 <!--   NeumesXML visualization XSLT
0014    Output: HTML 'beta-test' visualization for NeumesXML Schema version 2.3
0015    Instance documents. This is an XSLT (XML Stylesheet Language Transformations)
0016    for NeumesXML. NeumesXML is an XML application for describing medieval chant
0017    manuscript sources and transcribing their content to data in NEUMES format.
0018 
0019    Protected by law under one or more of the following copyrights:
0020    Copyright 2005-2006, The University of Oxford.
0021    Copyright 2003-2005, Louis W. G. Barton.
0022    Copyright 2002-2003, The President and Fellows of Harvard College;</span>
0023    contains software or other intellectual property licensed from
0024    Louis W. G. Barton, copyright 1995-2001 by Louis W. G. Barton.
0025 
0026    The copyright holders grant royalty-free license to transmit, display,
0027    perform and/or distribute without modification the NeumeXML version 2
0028    Schema and its accompanying documentation for non-commercial
0029    educational, cultural, and charitable uses, provided that the above
0030    copyright notice and this paragraph appear in all copies. The copyright
0031    holders make no representation about the suitability of the Schema and
0032    its accompanying documentation for any purpose. It is provided "as is"
0033    without expressed or implied warranty.
0034 -->
0035 
0036 <!DOCTYPE xsl:stylesheet SYSTEM "http://www.scribeserver.com/NEUMES/xml/NeumesXML_xsl.dtd" [
0037 <!-- *** NeumesXML_xsl.dtd includes NEUMES codepoint declarations. *** -->
0038 <!-- ****** Visualization Entities Particular to this Transformation: ****** -->
0039 <!ENTITY version_this   "3.1"> class="CommentColor"><!--version number of this XSLT -->
0040 <!--standard images path:-->
0041 <!ENTITY std_img_path   "http://www.scribeserver.com/NEUMES/xml/images">
0042 <!--standard scripts path:-->
0043 <!ENTITY std_scripts_path   "http://www.scribeserver.com/NEUMES/scripts">
0044 <!--standard XML files path:-->
0045 <!ENTITY std_xml_path   "http://www.scribeserver.com/NEUMES/xml">
0046 <!ENTITY red_subpath   "red/"> class="CommentColor"><!--subpath expression for red glyphs-->
0047 <!ENTITY file_parm_name   "filepath"> class="CommentColor"><!-- NOTE: synchronize with NeumesXSLTServlet.java -->
0048 <!ENTITY verdana      "Verdana,Geneva,Arial,Helvetica,sans-serif"> class="CommentColor"><!--font face-->
0049 <!ENTITY start_neume   "&#091;"> class="CommentColor"><!--start neume (left square bracket)-->
0050 <!ENTITY start_rubric   "&#091;"> class="CommentColor"><!--start rubric (left square bracket)-->
0051 <!-- SUB-space enlarges row uniformly for comment or CFs: -->
0052 <!ENTITY end_neume   "&lt;SUB> &lt;/SUB>&#093;"> class="CommentColor"><!--end neume (right square bracket)-->
0053 <!ENTITY end_rubric   "&lt;SUB> &lt;/SUB>&#093;"> class="CommentColor"><!--end rubric (right square bracket)-->
0054 <!ENTITY vowel_spacer   "3"> class="CommentColor"><!--approximate Displacement of vowel from syllable (3px)-->
0055 <!ENTITY cm         "&lt;SUB>*&lt;/SUB>"> class="CommentColor"><!--hypercomment (hash mark 035)-->
0056 <!ENTITY cf         "&lt;SUP>&#037;&lt;/SUP>"> class="CommentColor"><!--certainty factor (percent sign)-->
0057 <!ENTITY no_tone_mark   " &nbsp;"> class="CommentColor"><!--neumatic glyph has no tonal quality-->
0058 <!ENTITY no_preced_tone   " 0"> class="CommentColor"><!--no preceding tonal movement-->
0059 <!ENTITY mv_unk      " ?"> class="CommentColor"><!--tonal movement unknown (question mark)-->
0060 <!ENTITY mv_eq      " ="> class="CommentColor"><!--tonal movement equal (space, equals sign)-->
0061 <!ENTITY mv_up      " +"> class="CommentColor"><!--tonal movement up (plus sign)-->
0062 <!ENTITY mv_dn      " -"> class="CommentColor"><!--tonal movement down (space, minus sign)-->
0063 <!ENTITY ligation      "^"> class="CommentColor"><!--ligated to next tone (circumflex)-->
0064 <!-- Tonal Movement background color: -->
0065 <!ENTITY tonal_bg      "background-color:rgb(255,255,186);">
0066 ]>
0067 
0068 <!-- Root Element: -->
0069 <xsl:stylesheet version="1.0"
0070    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
0071    xmlns:nxm="http://www.scribeserver.com/NEUMES/xml/NeumesXML"
0072 >
0073 
0074 <xsl:include href="&std_xml_path;/NeumesXSLT_utils.xsl"/>
0075 
0076 <!--[end, Root Element]-->
0077 
0078 <xsl:output method="html"/>
0079 
0080 
0081 <!--   PROGRAMMER'S NOTES:
0082 * Dependencies:
0083 * - Reading of external Glyphs Manifest XML file can be done only after loading
0084     sarissa.js and sarissa_ieemu_xpath.js. XMLHttpRequest(), DOMParser(), and
0085     Sarissa.setXpathNamespaces are defined in sarissa.js. Some functionality for
0086     this of Internet Explorer is emulated for Mozilla by sarissa_ieemu_xpath.js.
0087 * If notation is unheighted, then the 'baseline' numbers are ignored, and all glyphs
0088   get aligned at the bottom.
0089 * Definition: "Offset" is a metric of the vertical position of a glyph image (or an
0090   adjunct text particle) in visualization, above or below the global baseline for glyph
0091   image rendering.
0092 * Definition: "Displacement" is a metric of the horizontal position of a glyph image
0093   (or a text particle) in visualization, to the right of the preceding glyph or text.
0094 * Rem: Cf, INTONED TEXT Row
0095 * To do: allow suppress of linebreaks.
0096 * To do: change default imgBasePath to dothead.
0097 * To do: divide glyph and qualifier tests by east/west.
0098 * Utilities moved to file NeumesXSLT_utils.xsl.
0099 * Remark: for 'if' tests, JS uses '==' for comparator relation;</span> XSLT uses '='.
0100 * The stylesheet gets validated every time it is run. Most XSLT processors, however,
0101   do not validate a stylesheet against the DTD given in the DOCTYPE declaration;</span> the
0102   rules for XSLT are too complicated to be summed up in a DTD.
0103 * Future: if we do a transformation on the NeumesXML Schema, we would need the 'obd'
0104   namespace to be declared so that we could process the documentation in the schemas;</span>
0105   in this case, we would also need the 'xsd' namespace declaration since we would be
0106   processing XSD Elements.
0107 * The <xsl:output> method specifies serialization of the results of this transformation
0108   as HTML. This transformation is creating HTML Elements in no namespace (because there
0109   is no default namespace declaration). By rule in XSLT, HTML Elements created in no
0110   namespace are serialized as HTML.
0111   One could add the default namespace declaration,
0112    xmlns="http://www.w3.org/1999/xhtml"
0113   in which case, the output would be like XML (e.g., you'd get <br/> instead of <br>);</span>
0114   <xsl:output method="html"/> would then be essential to ensure the output is written
0115   as HTML. Selective output in XML form can be done by the 'HTML' prefix and the
0116   declaration,
0117      xmlns:HTML="http://www.w3.org/Profiles/XHTML-transitional"
0118 * W3C Visual Formatting Model (Inline Formatting Context): "When several inline boxes
0119   cannot fit horizontally within a single line box, they are distributed among two or
0120   more vertically-stacked line boxes. ... When the total width of the inline boxes on
0121   a line is less than the width of the line box containing them, their horizontal
0122   distribution within the line box is determined by the 'text-align' property."
0123 * Table layout for visualization
0124    Row 1: neumatic symbols
0125    Row 2: chant text
0126    Row 3: pitches
0127    Row 4: tonal movement
0128 * DO NOT break a line of JavaScript, except a literal followed by '+'.
0129 
0130 Strategy:
0131 BOGUS - revise (up from bottom of containing box to bottom of IMG]
0132 1/ Tonal movement (leadingMvmt and internalMvmt) is calculated up/down in
0133 *steps* (or, 'tones'). Example: currently, dn_m3 and dn_M3 both evaluate to
0134 tonal movement of "-3".
0135 2/ Utilities Template 'GetTonalMvmtBounds' calculates the tonal range of the
0136 whole chant above/below the intial glyph.
0137 3/ transcriptionBaseline is in pixels (positive) up from bottom of glyphs Row.
0138 4/ The first glyph in a transcription is at the transcriptionBaseline, and
0139 gets positioned as (-glyphRowHeight + transcriptionBaseline) down from top.
0140 5/ In Image layout, JS fn drawGlyph() uses position-relative, with top equal
0141 to the number of pixels down from top of containing box to top of Image.
0142 6/ In staffed notation, staff is displayed as a background image, and
0143 vertical position is measured up from bottom of containing box.
0144 7/ During display of glyphs, the tonal movement just be scaled by multiplying
0145 it by the heightingFactor to produce the pixels down from top of containing box.
0146 
0147 [End, Programmer's Notes]-->
0148 
0149 
0150 <!--   XSLT GLOBAL VARIABLES: -->
0151 <xsl:variable name="discipline" select="//nxm:encoding_declaration/@discipline"/>
0152 <xsl:variable name="notation_family" select="//nxm:notation_x/@family"/>
0153 <!-- Temp conditional: -->
0154 <xsl:variable name="heighted">  <!--whether heighted notation-->
0155    <xsl:choose>
0156       <xsl:when test="//nxm:notation_x[@heighted]">
0157          <xsl:choose>
0158             <xsl:when test="//nxm:notation_x/@heighted='false'">false</xsl:when>
0159             <xsl:otherwise>true</xsl:otherwise>
0160          </xsl:choose>
0161       </xsl:when>
0162       <xsl:otherwise>true</xsl:otherwise>
0163    </xsl:choose>
0164 </xsl:variable>
0165 <xsl:variable name="pitched">  <!--whether pitched notation-->
0166    <xsl:choose>
0167       <xsl:when test="//nxm:notation_x[@pitched]">
0168          <xsl:choose>
0169             <xsl:when test="//nxm:notation_x/@pitched='true'">true</xsl:when>
0170             <xsl:otherwise>false</xsl:otherwise>
0171          </xsl:choose>
0172       </xsl:when>
0173       <xsl:otherwise>true</xsl:otherwise>
0174    </xsl:choose>
0175 </xsl:variable>
0176 
0177 <!--   **************************
0178    **  Root Node Template  **
0179 -->
0180 <xsl:template match="//nxm:NeumesXML">
0181 
0182 <!-- ****** Begin HTML: ****** -->
0183 <!--
0184 Q: How do we get,
0185 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
0186 <html>
0187 <head>
0188 It currently says:
0189 <html xmlns:nxm="http://www.scribeserver.com/NEUMES/xml/NeumesXML">
0190 <head>
0191 -->
0192    <html>
0193    <head>
0194    <title>NEUMES: <xsl:value-of select="//nxm:transcription_title/@content"
0195      disable-output-escaping="yes"/></title>
0196 
0197 
0198 <!-- ****** CSS [client-side]: ****** -->
0199    <LINK HRef="&std_scripts_path;/NeumesXML_xsl.css" Type="text/css" Rel="stylesheet" />
0200 
0201 <!-- ***** JavaScript [client-side execution] ***** -->
0202 
0203    <!--   *************************
0204       * STAND-ALONE INCLUDES: *
0205    -->
0206    <SCRIPT type="text/javascript"
0207       SRC="&std_scripts_path;/imageprotect.js"></SCRIPT>
0208    <!-- For importation of a Glyphs Manifest XML file: -->
0209    <SCRIPT type="text/javascript"
0210       SRC="&std_scripts_path;/sarissa.js"></SCRIPT>
0211    <!-- For importation of a Glyphs Manifest XML file (Mozilla compatibility): -->
0212    <SCRIPT type="text/javascript"
0213       SRC="&std_scripts_path;/sarissa_ieemu_xpath.js"></SCRIPT>
0214 
0215 <!-- Begin, JavaScript in HTML Head -->
0216 <SCRIPT type="text/javascript">
0217 
0218    <!--   **************************
0219       * INDEPENDENT FUNCTIONS: *
0220 
0221       The following functions have no dependencies.
0222    -->
0223 
0224 
0225    <!--   FN: CONSTRUCTOR FOR GlyphObject
0226       Create an object for one glyph image from the Glpyhs Manifest XML file.
0227       Dependencies: none.
0228    -->
0229    function glyphObject(description, tones, mnemonic_code, substitute_style, filename,
0230      imgWidth, imgHeight, baseline) {
0231       this.description=description;
0232       this.tones=tones;
0233       this.mnemonic_code=mnemonic_code;
0234       this.substitute_style=substitute_style;
0235       this.filename=filename;
0236       this.imgWidth=imgWidth;
0237       this.imgHeight=imgHeight;
0238       this.baseline=baseline;
0239    }  <!--[end, glyphObject constructor]-->
0240 
0241 
0242    <!--   ********************************
0243       * JavaScript GLOBAL VARIABLES: *
0244    -->
0245    <!-- These vars depend on XSLT: -->
0246    var heighted=<xsl:value-of select="$heighted"/>; <!--whether symbols have Offsets-->
0247    var pitched=<xsl:value-of select="$pitched"/>; <!--whether symbols have pitches-->
0248    <!-- for pulldown(): -->
0249    var plus_img='&std_img_path;/plus_sm.gif';  <!-- plus sign -->
0250    var minus_img='&std_img_path;/minus_sm.gif';  <!-- minus sign -->
0251    <!--[end, dependency]-->
0252 
0253    var filepathValue=''; <!--CONST complete filepath of this NeumesXML file-->
0254    var globalColorPath=''; <!-- CONST global, append Color subpath if not color==black -->
0255    var imgColorPath=''; <!-- VAR temp, append Color subpath if not color==black -->
0256    var heightingFactor=2; <!--CONST multiplicative scaling factor for heights, was 2-->
0257    <!--baseline in px of the initial glyph (a positive number),
0258      measured up from top of containing box:-->
0259    var transcriptionBaseline=0;  <!-- start position of transcription -->
0260    var glyphRowHeight=0;
0261    var heightSum=0; <!--VAR cumulative Tonal Movement to current position-->
0262    var current_notation=''; <!--String, name of currently-used notation family-->
0263    var current_lines=0; <!--VAR integer, number of staff lines to show-->
0264    var native_lines=0; <!--staff lines, as coming from transcription-->
0265    var staffOffset=0; <!--placement of staff lines image-->
0266    var imgs_not_found=''; <!--VAR String, glyph image names not found-->
0267    var imagesLoaded=false; <!--VAR flag, browser done trying to load all images-->
0268    var scrWidth=800;  <!--default screen width; adjusted in loadfn()-->
0269    var scrHeight=600;  <!--default screen height; adjusted in loadfn()-->
0270    <!-- From Calling URL: -->
0271    var urlParams=null;
0272    var zoomIndex=0;
0273    var notationIndex=0;
0274    var notationValue=''; <!--user-specified notation family, or 'native'-->
0275    var bgIndex=0;
0276    var pitchtone_mvmtIndex=0;
0277    var metadataIndex=0;
0278    var lmarginIndex=0;
0279    var rmarginIndex=0;
0280    var userImgPathIndex=0;
0281    <!--[end, from Calling URL]-->
0282    <!-- Open Wait Window: -->
0283    var waitFile='http://www.scribeserver.com/NEUMES/wait_visualization.htm';
0284    var centerH=Math.round((screen.width/2)- 45);
0285    var centerV=Math.round((screen.height/2) - 20);
0286    var waitWindow=window.open(waitFile, '', 'toolbar=no,location=no,directories=no,' +
0287      'status=no,menubar=no,scrollbars=no,resizable=no,left=' + centerH +
0288      ',top=' + centerV + ', width=123, height=103');
0289    <!--[end, open Wait Window]-->
0290    <!--   for randID(): -->
0291    var today=new Date();
0292    var seed=today.getTime();
0293    <!--Array of glyphObjects for JS local-storage of data from a Glyphs Manifest file:-->
0294    var glyphObjects=new Array();
0295    <!-- Warning: check return code from getGlyphObject() before using this Index: -->
0296    var currentIndexGO=0;  <!--VAR, index of the current glyph in glyphObjects array-->
0297    <!--VAR flag, true if Glyphs Manifest has been read-in for this glyph image set:-->
0298    var glyphsManifest=false;
0299    var glyphsManifestImgFilepath=''; <!--Image filepath in current Glyphs Manifest file-->
0300    var greatestDescender=888;  <!-- greatest descender in Glyphs Manifest; 888==UNK -->
0301    var greatestAscender=888;  <!-- greatest ascender in Glyphs Manifest; 888==UNK -->
0302 
0303 
0304    <!--   ************************
0305       * DEPENDENT FUNCTIONS: *
0306 
0307       These functions depend on global variables or functions declared above.
0308    -->
0309 
0310    <!--   FN: LOAD GLYPHS MANIFEST
0311       Load an external Glyphs Manifest XML file;</span> populate the glyphObjects JS array
0312       with a glyphObject for each glyph image.
0313 
0314       Post conditions:
0315       Returns 'true' if loading of Glyphs Manifest XML file was successful:
0316          glyphsManifest==true;</span>
0317          glyphObjects==array of glyphObject's from GlyphsManifest;</span>
0318          currentIndexGO==0;</span>
0319          glyphsManifestImgFilepath==URL path of glyph image set;</span>
0320          greatestDescender==greatest descender (pixels) in Glyphs Manifest
0321            (a positive int).
0322          greatestAscender==greatest ascender (pixels) in Glyphs Manifest
0323            (a positive int).
0324       Returns 'false' if loading generated an error, or glyphObjects is now empty:
0325          glyphsManifest==false;</span>
0326          glyphObjects==null;</span>
0327          currentIndexGO==0;</span>
0328          glyphsManifestImgFilepath=='';</span>
0329          greatestDescender==888.
0330          greatestAscender==888.
0331 
0332       Dependencies:
0333         Depends on sarissa.js and sarissa_ieemu_xpath.js, and should follow
0334           their declarations. [The '@' operators are of sarissa, not of XSLT.]
0335         Depends on global vars listed below, and should follow their declarations.
0336         Depends on Element names and optionality declared in the glyphs_manifest.xsd.
0337         Note: if migrating to external JS file, change the 'lt' Entity.
0338       HTTP error codes: xmlhttp.status code to see whether it was successful.
0339         Anything in the 200s means the file has been found, whereas 404 is the most
0340         common (not found) error.
0341    -->
0342    function loadGlyphsManifest(manifestURL) {
0343       <!-- Clear the glyphObjects array, and reset currentIndexGO to 0:
0344          [Setting the array length to 0 would leave the previous contents of the
0345          array somewhere in memory;</span> it will be garbage-collected if set to null.]
0346       -->
0347       <!-- global vars: -->
0348       glyphObjects=null;  <!-- mark old glyphsObject array for garbage-collection -->
0349       glyphsManifest=false;  <!-- flag: no Glyphs Manifest loaded, global -->
0350       glyphObjects=new Array();  <!-- JS array of glyphObject's from GlyphsManifest -->
0351       currentIndexGO=0;  <!-- defensive to avoid out-of-bounds reference, global -->
0352       glyphsManifestImgFilepath='';  <!-- declared globally -->
0353       greatestDescender=888;  <!-- greatest descender in Glyphs Manifest; 888==UNK -->
0354       greatestAscender=888;  <!-- greatest ascender in Glyphs Manifest; 888==UNK -->
0355 
0356       <!-- local utility vars: -->
0357       var xmlhttp;
0358       var manifest;
0359       var glyphs;
0360       var glyph;
0361       var description;
0362       var tones;
0363       var mnemonic_code;
0364       var substitute_style;
0365       var filename;
0366       var width;
0367       var height;
0368       var baseline;
0369       var oGlyph;
0370       var i;  <!-- local temp index -->
0371       var j;  <!-- local temp index -->
0372       var k;  <!-- local temp value holder -->
0373 
0374       <!-- sarissa.js setup: -->
0375       try {
0376          xmlhttp=new XMLHttpRequest();  <!-- from sarissa.js ... -->
0377          xmlhttp.open('GET', manifestURL, false);
0378          xmlhttp.send('');
0379          manifest=(new DOMParser()).parseFromString(xmlhttp.responseText,
0380            'text/xml');
0381          manifest.setProperty('SelectionLanguage', 'XPath');
0382          <!-- Set Xpath namespace: -->
0383          Sarissa.setXpathNamespaces(manifest,
0384            'xmlns:gm="http://www.scribeserver.com/NEUMES/xml/glyphs_manifest"');
0385          <!-- glyphs is an array of DOM nodes, one for each glyph: -->
0386          glyphs=manifest.selectNodes('/gm:glyphs_manifest/gm:glyph');
0387          <!-- Get glyph image filepath specified in the Glyphs Manifest: -->
0388          glyphsManifestImgFilepath=manifest.selectNodes(
0389            '/gm:glyphs_manifest/gm:glyphSetProperties/@virtual_path'); 
0390       } catch (e) {
0391          return false;  <!-- failure -->
0392       }  <!--end, try/catch sarissa-->
0393       for (i=0; i &lt; glyphs.length; i++) {
0394          glyph=glyphs[i];
0395          <!-- no dependency on XSLT: -->
0396          description=glyph.selectSingleNode('@description').nodeValue;
0397          tones=glyph.selectSingleNode('@tones').nodeValue;
0398          mnemonic_code=glyph.selectSingleNode('@mnemonic_code').nodeValue;
0399          <!-- Remark: substitute style is optional in Glyphs Manifest: -->
0400          try {
0401             substitute_style=glyph.selectSingleNode('@substitute_style').nodeValue;
0402          } catch (e) {
0403             substitute_style='';
0404          }  <!--[end, try/catch substitute style]-->
0405          filename=glyph.selectSingleNode('@filename').nodeValue;
0406          width=glyph.selectSingleNode('@width').nodeValue;
0407          height=glyph.selectSingleNode('@height').nodeValue;
0408          baseline=glyph.selectSingleNode('@baseline').nodeValue;
0409          oGlyph=new glyphObject(description, tones, mnemonic_code,
0410            substitute_style, filename, width, height, baseline);
0411          <!-- Index is required: -->
0412          glyphObjects[i]=oGlyph;
0413       }  <!--[end, for i]-->
0414       <!-- Assume that no Glyphs Manifest has only one glyph: -->
0415       if (i > 0) {
0416          glyphsManifest=true;  <!-- flag: Glyphs Manifest loaded -->
0417          greatestDescender=0;  <!-- init -->
0418          for (j=0; j &lt; glyphObjects.length; j++) {
0419             k=parseInt(glyphObjects[j].baseline);
0420             if (k > greatestDescender) {
0421                greatestDescender=k;
0422             }  <!--[end, if k]-->
0423          }  <!--[end, for j]-->
0424          greatestAscender=0;  <!-- init -->
0425          for (j=0; j &lt; glyphObjects.length; j++) {
0426             k=parseInt(glyphObjects[j].imgHeight) -
0427               parseInt(glyphObjects[j].baseline);
0428             if (k > greatestAscender) {
0429                greatestAscender=k;
0430             }  <!--[end, if k]-->
0431          }  <!--[end, for j]-->
0432          return true;  <!-- success -->
0433       } else {
0434          return false;  <!-- failure -->
0435       }  <!--[end, if/else]-->
0436    }  <!--[end, loadGlyphsManifest()]-->
0437 
0438 
0439    <!--   FN: GET GLYPH OBJECT By FILENAME From GLYPHS MANIFEST
0440       Searches the glyphObjects array for passed image filename.
0441       If found, sets the currentIndexGO index of the glyphObjects for this glyph, and
0442         returns 'true' (==found).
0443       If not found, currentIndexGO is unchanged, and returns 'false' (==not found).
0444 
0445       Dependencies: Depends on the global vars glyphObjects and currentIndexGO.
0446    -->
0447    function getGlyphObject(filename) {
0448       for (i=0; i &lt; glyphObjects.length; i++) {
0449          if (glyphObjects[i].filename == filename) {
0450             currentIndexGO=i;
0451             return true;  <!-- found -->
0452          }  //end, if
0453       }  //end, for
0454       return false;  <!-- not found -->
0455    }  <!--[end, getGlyphObject()]-->
0456 
0457 
0458    <!--   FN: OPEN GLYPH ROW
0459       Opens a Table Row;</span> sets Height according to glyphRowHeight;</span>
0460       displays background image according to number of staff lines required.
0461       NOTICE: CSS counts Height and Vertical Offset from *TOP* of the containing box
0462       to TOP of the offset box.
0463       First line of 4-line staff is down 30px from top of image;</span> lines are 8px apart.
0464       TR.lines4, background-position-y MUST be *bottom*.
0465       TD.neume height of 72 is the height of 4-line staff image [min-height doesn't
0466         work]. Add *offsetFloor*.
0467    -->
0468    function openGlyphRow() {
0469 <!--xxx Testing: border="1" bordercolor="red" [no effect] -->
0470       document.write('&lt;TR class="glyphRow" style=\"height:' +
0471         glyphRowHeight + 'px; ');
0472       if (current_lines == 4) {
0473          <!-- background-position-y is measured from TOP of containing box
0474              (glyphs positions are specified up from bottom) -->
0475          document.write('background-image:' +
0476            'url(\'&std_img_path;/shared/staff_4_line.gif\'); ');
0477          document.write('background-attachment:fixed; background-repeat:repeat-x; ');
0478          document.write('background-position-y:' + staffOffset + 'px;');
0479       }
0480       document.writeln('\">');  <!--end, <TR>-->
0481    } <!--[end, openGlyphRow()]-->
0482 
0483 
0484 <!--xxx Testing
0485 var firstTime=0;</span>
0486  -->
0487    <!--   FN: DRAW GLYPH
0488       glyph heighting;</span> eliminate Substitute Style if not Native Notation.
0489       leadingOffset is vertical distance from previous glyph.
0490       internalOffset is internal movement for multi-tone glyphs.
0491       Height scaling factor is multiplied *only* when computing height of
0492         this glyph (carried-forward values are in terms of tonal movement).
0493       Returned leadingOffset of 888 means UNK: reset heightSum to 0 + offsetFloor.
0494 
0495       If CharToShow is a clef, then the leading movement==the line number on the
0496       staff (1 through 6) of the clef's position;</span> if no position was specified,
0497       then the line number is 0.
0498    -->
0499    function drawGlyph(CharToShow, imgName, leadingMvmt, internalMvmt, certaintyFactor) {
0500 
0501 <!--xxx Testing:
0502 if (firstTime == 0) {
0503    document.write('<span class="SymbolColor">&lt;</span>IMG SRC=\"' + imgColorPath + 'punctum_1.gif' +
0504      '\" HSpace="<span class="SymbolColor">&vowel_spacer;</span>" Border="0"');</span>
0505    tempStr=' style=\"position:relative;</span> top:' + 0 + 'px !important;</span>\"';</span>
0506    document.write(tempStr);</span>
0507    document.write(' onError=\"imgErr(\'' + imgName + '\');</span>\" alt="">Z');</span>
0508 
0509    document.write('<span class="SymbolColor">&lt;</span>IMG SRC=\"' + imgColorPath + 'punctum_1.gif' +
0510      '\" HSpace="<span class="SymbolColor">&vowel_spacer;</span>" Border="0"');</span>
0511    tempStr=' style=\"position:relative;</span> top:-' + glyphRowHeight + 'px !important;</span>\"';</span>
0512    document.write(tempStr);</span>
0513    document.write(' onError=\"imgErr(\'' + imgName + '\');</span>\" alt="">H');</span>
0514 
0515    document.write('<span class="SymbolColor">&lt;</span>IMG SRC=\"' + imgColorPath + 'blueline.gif' +
0516      '\" HSpace="<span class="SymbolColor">&vowel_spacer;</span>" Border="0"');</span>
0517    tempStr=' style=\"position:relative;</span> top:-' + glyphRowHeight + 'px !important;</span>\"';</span>
0518    document.write(tempStr);</span>
0519    document.write(' onError=\"imgErr(\'' + imgName + '\');</span>\" alt="">H');</span>
0520 
0521    firstTime=1;</span>
0522 }  //end, Testing
0523 -->
0524       var tempStr='';
0525       var thisOffset=0;
0526       var tempFound=false;  <!-- if image found in Glyphs Manifest -->
0527       var tempGlyphBaseline=0;  <!-- baseline of image from Glyphs Manifest -->
0528       var tempGlyphHeight=0;  <!-- Y-dimension of image from Glyphs Manifest -->
0529       var cfMsg=''; <!--CF message-->
0530       <!-- The following two Math operations ARE NECESSARY: -->
0531       var leadingMvmtNum=Math.round(leadingMvmt);
0532       var internalMvmtNum=Math.round(internalMvmt);
0533       if (leadingMvmtNum == 888) { <!--UNK height-->
0534          leadingMvmtNum=0;
0535          heightSum=0; <!--reset-->
0536       }
0537 
0538       <!--Ignore Substitute Style image if not using Native Notation:-->
0539       if ('native' != notationValue) {
0540          var imgNameArr=imgName.split('.');
0541          var i=imgNameArr[0].lastIndexOf('_');
0542          if (i != -1) {
0543             imgNameArr[0]=imgNameArr[0].substring(0, i);
0544             imgNameArr[0]=imgNameArr[0] + '_1';
0545          }
0546          imgName=imgNameArr.join('.');
0547       }
0548 
0549       <!-- Display CF hypercomment if non-10 CF (conditional display): -->
0550 <!-- Testing: height of cf? -->
0551       if ( ('yes' == pitchtone_mvmtValue) &amp;&amp; (10 != certaintyFactor) ) {
0552          cfMsg='Certainty factor = ' + certaintyFactor + '.';
0553          document.write('&lt;A HRef="CF" class="rubric" ' +
0554            'onClick=\"noop=pop(\'' + cfMsg + '\'); return false;\">');
0555       } <!--[end, conditional display]-->
0556 
0557       <!--  NB: this paragraph might be bogus!
0558           Calculate descent (counted down from TOP), and DISPLAY:
0559          CSS counts Vertical Offset from *TOP* of the containing box,
0560          to *TOP* of the image box. 
0561       -->
0562       if (('&doh_clef;' == CharToShow) || ('&fah_clef;' == CharToShow)
0563         || ('fah_clef_1.gif' == imgName) || ('fah_clef_2.gif' == imgName) ) {
0564          <!-- First line of 4-line staff is down 30px from top of image; lines are
0565             8px apart;</span> baseline of clefs is 8 pixels down from top of clef image.
0566 Testing:
0567          thisOffset= -(staffOffset - ((current_lines - leadingMvmtNum) * 8) +4);</span>
0568          -->
0569          thisOffset= (transcriptionBaseline + staffOffset) * heightingFactor + 4;
0570       } else {
0571          thisOffset= transcriptionBaseline + ((heightSum + leadingMvmtNum) *
0572            heightingFactor);
0573          <!-- BOGUS? Count down from top of containing box: -->
0574          var tempGlyphYPos = glyphRowHeight - thisOffset;
0575          <!-- Push BOTTOM of Img up (neg number) from bottom of containing box: -->
0576          var tempGlyphYPos = -thisOffset;
0577          <!--Seek filename; currentIndexGO is index of correct image, if found:-->
0578          tempFound=getGlyphObject(imgName);
0579          if (tempFound) {
0580             tempGlyphBaseline=parseInt(glyphObjects[currentIndexGO].baseline);
0581             tempGlyphHeight=parseInt(glyphObjects[currentIndexGO].imgHeight);
0582             <!-- pull IMG down to baseline of glyph: -->
0583             tempGlyphYPos=tempGlyphYPos + tempGlyphBaseline;
0584          }  <!--[end, if image found]-->
0585       }
0586       document.write('&lt;IMG SRC=\"' + imgColorPath + imgName +
0587         '\" HSpace="&vowel_spacer;" Border="0"');
0588       tempStr=' style=\"position:relative; top:' + tempGlyphYPos + 'px !important;\" ';
0589       document.write(tempStr);
0590 <!-- TO DO: use name from glyphs manifest instead of imgName: -->
0591       document.write('onError=\"imgErr(\'' + imgName + '\');\" alt="' +
0592         imgName + '">');
0593 
0594       <!-- Close CF link if open: -->
0595       if ( (pitchtone_mvmtValue == 'yes') &amp;&amp; (certaintyFactor != 10) ) {
0596          document.write('&lt;span style=\"display:inline; vertical-align:' +
0597            thisOffset + ';\">&cf;&lt;/span>&lt;/A>');
0598       }
0599       <!-- Don't add to cumulative height if Special Char: -->
0600       if ( ('&custos;' == CharToShow) || ('&ut_supra;' == CharToShow) ||
0601         ('&doh_clef;' == CharToShow) || ('&fah_clef;' == CharToShow) ) {
0602          // noop
0603       } else {
0604          heightSum=(heightSum + leadingMvmtNum + internalMvmtNum);
0605       }
0606    } <!--[end, drawGlyph()]-->
0607 
0608 
0609    <!--   FN: SET STAFF LINES
0610       Set current_lines and calculate staffOffset.
0611       staffOffset is measured from TOP.
0612       Assume glyphRowHeight is set correctly.
0613       Preconditions:
0614         glyphRowHeight and transcriptionBaseline must already have been calculated.
0615    -->
0616    function setStaffLines() {
0617       var staffMiddleDepth=0; <!--distance from TOP of staff image to middle space-->
0618 
0619       if (notationValue == 'native') { <!--use staff lines coming from transcription-->
0620          current_lines=native_lines; <!--initially 0-->
0621       <!-- User is forcing to different notation: -->
0622       } else if (current_notation == 'Aquitanian') {
0623          current_lines=0;
0624       } else if (current_notation == 'Middle_Byzantine') {
0625          current_lines=0;
0626       } else if (current_notation == 'Post_Byzantine') {
0627          current_lines=0;
0628       } else if (current_notation == 'Sarum') {
0629          current_lines=4;
0630       } else if (current_notation == 'square') {
0631          current_lines=4;
0632       } else if (current_notation == 'St_Gall') {
0633          current_lines=0;
0634       } else { <!-- default: -->
0635          current_lines=5; <!--for dothead notation-->
0636       }
0637       <!--   Calculate Staff Position: -->
0638       if (current_lines == 4) {
0639          staffMiddleDepth=(30 + 12); <!--dist from 4-line staff img TOP to
0640            middle space. Staff is 72px high;</span> this number is correct-->
0641       }
0642 <!--xxx Testing:
0643 staffMiddleDepth=(30 + 12);</span>
0644       staffOffset=(-glyphRowHeight + transcriptionBaseline + staffMiddleDepth -3);</span>
0645 -->
0646       staffOffset=(-glyphRowHeight + transcriptionBaseline + staffMiddleDepth +18 +3);
0647    }
0648    <!--[end, setStaffLines()]-->
0649 
0650 
0651    <!--   FN: ONLOAD
0652    -->
0653    function loadfn() {
0654       <xsl:if test="$discipline != 'Western'">
0655          document.redisplayForm.notation_family.disable;
0656          document.redisplayForm.notation_family.style.backgroundColor="gray";
0657 <!--   <INPUT type="HIDDEN" name="notation_family" value="native"> -->
0658       </xsl:if>
0659       waitWindow.close();
0660       <!-- Try to set window to full-screen: -->
0661       try {
0662          scrWidth=self.screen.width;
0663          scrHeight=self.screen.availHeight;
0664          self.resizeTo(scrWidth, scrHeight);
0665          self.moveTo(0,0);
0666       } catch (e) {
0667          // noop
0668       }
0669       // Gain focus:
0670       if (window.focus) {
0671          self.focus();
0672       }
0673       <!-- Timer: -->
0674 //      var endTime=new Date();
0675 //      var elapsed=endTime - startTime;
0676 //      alert('Loading time = ' + elapsed);
0677    } <!--[end, loadfn()]-->
0678 
0679 
0680 
0681    <!--   ***************************
0682       * JavaScript INLINE CODE: *
0683 
0684       Remark: local vars are declared inline, as needed.
0685    -->
0686    if (window.focus) {
0687       waitWindow.focus();  <!-- focus on small Wait window -->
0688    }
0689    <!-- Timer: -->
0690 //   var startTime=new Date();
0691 
0692    <!--   HANDLE PARAMETERS IN CALLING URL:
0693    -->
0694    <!--   Normalise and decompose the calling URL: -->
0695    var newWindowValue='no'; <!--re: Redraw in a new window-->
0696    var callingURL=window.location.href;
0697    if (callingURL.indexOf('?') == -1) {
0698       callingURL=callingURL + '?';
0699    }
0700    var urlQuery=callingURL.split('?');
0701    <!-- Add 'zoom' parameter if absent in URL: -->
0702    if (urlQuery[1].indexOf('&amp;zoom=') == -1) {
0703       urlQuery[1]=urlQuery[1] + '&amp;zoom=100';
0704    }
0705    <!-- Add 'notation' param if absent in URL, set it to 'native': -->
0706    if (urlQuery[1].indexOf('&amp;notation=') == -1) {
0707       urlQuery[1]=urlQuery[1] + '&amp;notation=native';
0708    }
0709    <!-- Add 'bg' param if absent in URL: -->
0710    if (urlQuery[1].indexOf('&amp;bg=') == -1) {
0711       urlQuery[1]=urlQuery[1] + '&amp;bg=parch';
0712    }
0713    <!-- Add 'pitchtone_mvmt' param if absent in URL: -->
0714    if (urlQuery[1].indexOf('&amp;pitchtone_mvmt=') == -1) {
0715       urlQuery[1]=urlQuery[1] + '&amp;pitchtone_mvmt=yes';
0716    }
0717    <!-- Add 'metadata' param if absent in URL: -->
0718    if (urlQuery[1].indexOf('&amp;metadata=') == -1) {
0719       urlQuery[1]=urlQuery[1] + '&amp;metadata=yes';
0720    }
0721    <!-- Add 'lmargin' param if absent in URL: -->
0722    if (urlQuery[1].indexOf('&amp;lmargin=') == -1) {
0723       urlQuery[1]=urlQuery[1] + '&amp;lmargin=6';
0724    }
0725    <!-- Add 'rmargin' param if absent in URL: -->
0726    if (urlQuery[1].indexOf('&amp;rmargin=') == -1) {
0727       urlQuery[1]=urlQuery[1] + '&amp;rmargin=6';
0728    }
0729    <!-- Add 'imgpath' param if absent in URL: -->
0730    if (urlQuery[1].indexOf('&amp;imgpath=') == -1) {
0731       urlQuery[1]=urlQuery[1] + '&amp;imgpath=';
0732    }
0733 
0734    <!-- vars declared in this section record just the Redisplay Options: -->
0735    urlParams = urlQuery[1].split('&amp;'); <!--global-->
0736    <!-- Isolate the source filepath parameter value: -->
0737    for (i in urlParams) {
0738       if (urlParams[i].indexOf('&file_parm_name;=') != -1) {
0739          filepathValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0740            urlParams[i].length);
0741       }
0742    }
0743    <!-- Isolate the 'zoom' param index and value: -->
0744    zoomIndex=0; <!--global-->
0745    var zoomValue='';
0746    for (i in urlParams) {
0747       if (urlParams[i].indexOf('zoom=') != -1) {
0748          zoomIndex=i;
0749          zoomValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0750            urlParams[i].length);
0751       }
0752    }
0753    <!-- Isolate the 'notation' param index and value: -->
0754    notationIndex=0; <!--global-->
0755    notationValue=''; <!--global-->
0756    for (i in urlParams) {
0757       <!-- User override, or 'native' if not overridden: -->
0758       if (urlParams[i].indexOf('notation=') != -1) {
0759          notationIndex=i;
0760          notationValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0761            urlParams[i].length);
0762       }
0763    }
0764 
0765    <!--   *** SET CURRENT NOTATION: ***   -->
0766 
0767    if('native' == notationValue) {
0768       current_notation='<xsl:value-of select="$notation_family"/>';
0769    } else {
0770       current_notation=notationValue; <!--user override-->
0771    }
0772    <!-- Isolate the 'bg' param index and value: -->
0773    bgIndex=0; <!--global-->
0774    var bgValue='';
0775    for (i in urlParams) {
0776       if (urlParams[i].indexOf('bg=') != -1) {
0777          bgIndex=i;
0778         bgValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,urlParams[i].length);
0779       }
0780    }
0781    <!-- Isolate the 'pitchtone_mvmt' param index and value: -->
0782    pitchtone_mvmtIndex=0; <!--global-->
0783    var pitchtone_mvmtValue='';  <!--whether user wants display of Pitch & Mvmt rows-->
0784    for (i in urlParams) {
0785       if (urlParams[i].indexOf('pitchtone_mvmt=') != -1) {
0786          pitchtone_mvmtIndex=i;
0787          pitchtone_mvmtValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0788            urlParams[i].length);
0789       }
0790    }
0791    <!-- Isolate the 'metadata' param index and value: -->
0792    metadataIndex=0; <!--global-->
0793    var metadataValue='';
0794    for (i in urlParams) {
0795       if (urlParams[i].indexOf('metadata=') != -1) {
0796          metadataIndex=i;
0797          metadataValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0798            urlParams[i].length);
0799       }
0800    }
0801    <!-- Isolate the 'lmargin' param index and value: -->
0802    lmarginIndex=0; <!--global-->
0803    var lmarginValue='';
0804    for (i in urlParams) {
0805       if (urlParams[i].indexOf('lmargin=') != -1) {
0806          lmarginIndex=i;
0807          lmarginValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0808            urlParams[i].length);
0809       }
0810    }
0811    <!-- Isolate the 'rmargin' param index and value: -->
0812    rmarginIndex=0; <!--global-->
0813    var rmarginValue='';
0814    for (i in urlParams) {
0815       if (urlParams[i].indexOf('rmargin=') != -1) {
0816          rmarginIndex=i;
0817          rmarginValue=urlParams[i].substring(urlParams[i].indexOf('=')+1,
0818            urlParams[i].length);
0819       }
0820    }
0821    <!-- Isolate the 'imgpath' param index and value: -->
0822    userImgPathIndex=0; <!--global-->
0823    var userImgPathValue=null;
0824    for (i in urlParams) {
0825       if (urlParams[i].indexOf('imgpath=') != -1) {
0826          userImgPathIndex=i;
0827          <!-- "unescape" normalizes the URL to plaintext: -->
0828          userImgPathValue=
0829            unescape(urlParams[i].substring(urlParams[i].indexOf('=')+1,
0830            urlParams[i].length));
0831       }
0832    }
0833    <!--[end, Handle Parameters in Calling URL]-->
0834 
0835 
0836    <!--   *** SET BASE PATH FOR GLYPHS: ***
0837 
0838       Note: this section must follow "Handle Parameters in Calling URL".
0839       Precedence: user-specified;</span> transcription-specified;</span> standard path.
0840       "imgBasePath" is temporary and local to this block only.
0841       If user-specified then userImgPathValue will be non-empty.
0842    -->
0843    var imgBasePath=''; <!--LOCAL/TEMP basepath of glyphs (not of navigation icons)-->
0844    <xsl:if test="//nxm:glyphs_resource[@glyph_path]">
0845       imgBasePath='<xsl:value-of select="//nxm:glyphs_resource/@glyph_path"/>';
0846    </xsl:if>
0847    <!-- Case 1: User override: -->
0848    if ('' != userImgPathValue) {
0849       <!-- TO DO, Temporary solution (need to allow user-supplied manifest): -->
0850       document.write('&lt;BASE HRef=\"' + userImgPathValue + '\">');
0851    }
0852 <!--xxx To do: Change in NeumesXML Schema, URL of Glyphs Manifest specified, not img path. -->
0853    <!-- Case 2: filepath specified in the NeumesXML file: -->
0854    else if ('' != imgBasePath) {
0855       <!-- TO DO, Temporary solution (need to provide for a manifest): -->
0856       document.write('&lt;BASE HRef=\"' + imgBasePath + '\">');
0857    }
0858    <!-- Case 3: use standard image paths: -->
0859    else {
0860       if (current_notation == 'Aquitanian') {
0861          glyphsManifest=loadGlyphsManifest('&std_img_path;' +
0862            '/aquitanian/aquitanian_manifest.xml');
0863          if (glyphsManifest) {  <!-- TO DO: get img path from Glyphs Manifest -->
0864             imgBasePath='&std_img_path;/aquitanian/';
0865          } else {
0866             imgBasePath='&std_img_path;/aquitanian/';
0867          }  <!--[end, if/else glyphsManifest]-->
0868       } else if (current_notation == 'Middle_Byzantine') {
0869          glyphsManifest=false;  <!-- no Manifest -->
0870          imgBasePath='&std_img_path;/middle_byzantine/';
0871       } else if (current_notation == 'Post_Byzantine') {
0872          glyphsManifest=false;  <!-- no Manifest -->
0873          imgBasePath='&std_img_path;/post_byzantine/';
0874       } else if (current_notation == 'Sarum') {
0875          glyphsManifest=loadGlyphsManifest('&std_img_path;' +
0876            '/sarum/sarum_manifest.xml');
0877          imgBasePath='&std_img_path;/sarum/';
0878       } else if (current_notation == 'square') {
0879          glyphsManifest=loadGlyphsManifest('&std_img_path;' +
0880            '/square/square_manifest.xml');
0881          imgBasePath='&std_img_path;/square/';
0882       } else if (current_notation == 'St_Gall') {
0883          glyphsManifest=loadGlyphsManifest('&std_img_path;' +
0884            '/st_gall/st_gall_manifest.xml');
0885          imgBasePath='&std_img_path;/st_gall/';
0886       } else { <!-- Default: -->
0887          glyphsManifest=loadGlyphsManifest('&std_img_path;' +
0888            '/square/square_manifest.xml');
0889          imgBasePath='&std_img_path;/square/'; <!-- TO DO Change to dothead -->
0890       }  <!--[end, if/else current_notation]-->
0891       <!-- WRITE imgBasePath to HTML as the document BASE: -->
0892       document.write('&lt;BASE HRef=\"' + imgBasePath + '\">');
0893    } <!--[end, Case 3]-->
0894    <!--[end, Set BASE Path for Glyphs]-->
0895 
0896 
0897    <!--   CALCULATE LOWEST AND HIGHEST TONAL MOVEMENT FROM FIRST GLYPH:
0898       [Temporary code]
0899       Set the baseline offset (in pixels) for glyphs according to Tonal Movement bounds.
0900       Note: this section must follow "Set BASE Path for Glyphs" for glyph dimensions,
0901       and call to loadGlyphsManifest() for value of greatestDescender and
0902       greatestAscender.
0903    -->
0904    var tempMaxDescender=56; <!--Hack: in absence of a Glyphs Manifest-->
0905    if (greatestDescender &lt; 888) {
0906       tempMaxDescender=greatestDescender;
0907    }
0908    var tempMaxAscender=56; <!--Hack: in absence of a Glyphs Manifest-->
0909    if (greatestAscender &lt; 888) {
0910       tempMaxAscender=greatestAscender;
0911    }
0912    var offsetFloor=0; <!-- greatest px offset below transcriptionBaseline -->
0913    var offsetCeiling=0; <!--greatest px offset above transcriptionBaseline-->
0914    <xsl:if test="$heighted='true'">
0915       <xsl:variable name="multiVal"> <!--a multi-valued string is generated-->
0916          <xsl:call-template name="GetTonalMvmtBounds"/>
0917       </xsl:variable>
0918       <!-- unpack *multiVal* (comma-delimited string); set global vars: -->
0919       <xsl:variable name="movementFloor" select="substring-before($multiVal, ',')"/>
0920       <xsl:variable name="movementCeiling" select="substring-after($multiVal, ',')"/>
0921       <!-- Value of maximumTonesDown is a negative number: -->
0922       var maximumTonesDown=<xsl:value-of select="$movementFloor"/>;
0923       if (maximumTonesDown >= 0) {
0924          offsetFloor=tempMaxDescender;
0925       } else {
0926          <!-- Reverse polarity of maximumTonesDown: -->
0927          offsetFloor= -(maximumTonesDown * heightingFactor) +
0928            tempMaxDescender;
0929       }
0930       var maximumTonesUp=<xsl:value-of select="$movementCeiling"/>;
0931       if (0 >= maximumTonesUp) {
0932          offsetCeiling=tempMaxAscender;
0933       } else {
0934          offsetCeiling=(maximumTonesUp * heightingFactor) +
0935            tempMaxAscender;
0936       }
0937    </xsl:if>
0938 
0939    glyphRowHeight=offsetFloor + offsetCeiling; <!--all global-->
0940    transcriptionBaseline=offsetFloor;  <!-- Number of pixels down -->
0941 
0942    <!-- Call must follow assignment of notationValue and current_notation, and
0943       calculation of glyphRowHeight and transcriptionBaseline: -->
0944    setStaffLines(); <!--calculate staffOffset-->
0945 
0946 </SCRIPT><!--[end, JavaScript in HTML Head]-->
0947 
0948    <!--   ***********************
0949       * DEPENDENT INCLUDES: *
0950       Dependencies on foregoing inline code.
0951       Defensive coding: since JS is an interpreted language, forward references ought
0952       not be used;</span> i.e., a function or variable must be defined at the time it is
0953       referenced. In principle, JS allows forward references to *inline* functions
0954       because it scans the code for all function definitions before it executes the
0955       code. You can't, however, have a forward reference from one 'imported' SCRIPT
0956       element to another. 
0957    -->
0958    <SCRIPT type="text/javascript"
0959       SRC="&std_scripts_path;/NeumesXML_xsl.js"></SCRIPT>
0960 
0961    </head>
0962 
0963    <!--   **************
0964       * HTML BODY: *
0965    -->
0966    <SCRIPT type="text/javascript">
0967    document.write('&lt;BODY onLoad="loadfn();" ');
0968    if ('white' == bgValue) {
0969       document.write('BGColor="#FCFCFC">');
0970    } else {
0971       document.write('BGColor="#E6E3A0" Background="&std_img_path;/parch3.jpg">');
0972    }
0973    </SCRIPT>
0974 
0975    <!-- Warn non-JavaScript browsers [DO NOT break these lines]: -->
0976    <SCRIPT type="text/javascript">
0977    <xsl:text disable-output-escaping="yes">
0978    &lt;!-- --> &lt;TABLE CellPadding="3" CellSpacing="0" Border="1" BGColor="#E0E0E0" BorderColor="#7A0805">&lt;TR>&lt;TD>
0979    &lt;!-- --> &lt;IMG Width="34" Height="31" SRC="&std_img_path;/exclamation.gif" HSpace="5" Align="absmiddle" alt="" />
0980    &lt;!-- --> &lt;FONT Color="#7A0805" Size="1">&lt;B>JavaScript is &lt;U>REQUIRED&lt;/U> for this visualization.&lt;BR />
0981    &lt;!-- --> &nbsp;Please enable JavaScript, or upgrade your browser if necessary.&nbsp;&lt;/B>&lt;/FONT>
0982    &lt;!-- --> &lt;/TD>&lt;/TR>&lt;/TABLE>&lt;BR />
0983    </xsl:text>
0984    </SCRIPT>
0985    <NOSCRIPT>
0986    <TABLE CellPadding="3" CellSpacing="0" Border="1" BGColor="#E0E0E0"
0987       BorderColor="#7A0805"><TR><TD>
0988    <IMG Width="34" Height="31" SRC="&std_img_path;/exclamation.gif" HSpace="5"
0989      style="vertical-align:middle;" alt="" />
0990    <FONT Color="#7A0805"><B>JavaScript is <U>REQUIRED</U> for this visualization.<BR />
0991       &nbsp;Please enable JavaScript, or upgrade your browser if necessary.&nbsp;
0992       </B></FONT>
0993    </TD></TR></TABLE><BR />
0994    </NOSCRIPT>
0995    <!--[end, non-JavaScript browser]-->
0996 
0997    <DIV style="text-align:center;">
0998    <!--  Disclaimer (conditional display): -->
0999    <SCRIPT type="text/javascript">
1000    if ('yes' == metadataValue) {
1001       document.write('&lt;H3 Align="center">&lt;FONT Face="&verdana;" Color="green" ' +
1002         'Size="-1">');
1003       document.write('&lt;I>&lt;B>&lt;U>&lt;FONT Color="maroon">' +
1004         'Please note&lt;/U>:&lt;/B>&lt;/FONT>');
1005       document.write(' This &lt;/I>beta-test&lt;I> visualization of the transcription' +
1006         ' is used for testing the underlying software.&lt;BR>' +
1007         'Improved visualization programs will follow.&lt;/I>');
1008       document.write('&lt;/FONT>&lt;/H3>');
1009    }
1010    </SCRIPT>
1011 
1012    <!--   *****************************
1013       *** BEGIN META-DATA BLOCK ***
1014    -->
1015    <!--  META-DATA BLOCK (conditional display): -->
1016 <!--Make this an overridable template call: -->
1017    <SCRIPT type="text/javascript">
1018    document.write('&lt;TABLE CellPadding="7" CellSpacing="1" Border="5" ' +
1019      'BGColor="#CFCFCF" BorderColorLight="#909000" BorderColorDark="#E6EA33" ');
1020    if ('yes' == metadataValue) {
1021       document.write('style="margin:auto;">');
1022    } else {
1023       document.write('style="display:none; margin:auto;">');
1024    }
1025    </SCRIPT>
1026    <TR>
1027    <TD Colspan="2" Align="center">
1028       <TABLE Width="100%" CellSpacing="0" CellPadding="3"><TR VAlign="top">
1029       <TD Width="100" style="color:maroon;
1030         font-size:smaller;"><B>Visualization<BR /><I>version</I>&nbsp;
1031       <SCRIPT type="text/javascript">
1032       document.write('&version_this;');
1033       </SCRIPT>
1034       </B></TD>
1035       <!-- Generate random Window ID, modulo 999: -->
1036       <TD style="text-align:center; font-size:larger;">|= NeumesXML document
1037          description =|</TD>
1038       <TD Width="100" style="text-align:right; color:maroon; font-size:smaller;
1039          font-weight:bold;">Window ID:
1040          <SCRIPT type="text/javascript">document.write(randID(999));</SCRIPT><BR />
1041          <IMG Width="36" Height="14" SRC="&std_img_path;/xml_std.gif" Align="right"
1042            HSpace="6" alt="" />
1043       </TD>
1044       </TR></TABLE>
1045 <!--End, make this an overridable template call. -->
1046    <FONT Color="blue"><H3>
1047    <xsl:value-of select="//nxm:transcription_title/@content"
1048       disable-output-escaping="yes"/></H3></FONT>
1049    </TD>
1050    </TR>
1051 
1052    <!-- Identity: -->
1053    <TR VAlign="top">
1054    <TD Width="37%">
1055    <FONT Size="-1">
1056    <CENTER><FONT FACE="&verdana;" Color="green">
1057    <B>Source Identity</B></FONT>
1058    </CENTER>
1059    <HR Width="86%" />
1060    <B>Title:</B>&nbsp;<xsl:value-of select="//nxm:transcription_title/@content"
1061       disable-output-escaping="yes"/><BR />
1062    <CENTER><FONT Color="green"><B>- Attribution -</B></FONT>&nbsp;&nbsp;</CENTER>
1063    <B>Discipline:</B>&nbsp;<xsl:value-of select="$discipline"/><BR />
1064    <B>Language of chant text:</B>&nbsp;<xsl:value-of
1065       select="//nxm:language_x/@content"/><BR />
1066    <B>Notation family:</B>&nbsp;<xsl:value-of select="$notation_family"/><BR />
1067    <xsl:if test="//nxm:notation_x[@species]">
1068       <B>Notation species:</B>&nbsp;<xsl:value-of
1069       select="//nxm:notation_x/@species"/><BR />
1070    </xsl:if>
1071    <B>Date range:</B>&nbsp;
1072    <xsl:choose>
1073       <xsl:when test="//nxm:attribution[nxm:date_range]">
1074          <xsl:value-of select="//nxm:attribution/nxm:date_range/@content"/>
1075       </xsl:when>
1076       <xsl:otherwise>
1077          [unavailable]
1078       </xsl:otherwise>
1079    </xsl:choose>
1080    <BR />
1081    <xsl:if test="//nxm:accession_x[nxm:rite]">
1082       <B>Rite:</B>&nbsp;<xsl:value-of select="//nxm:rite/@group"/><BR />
1083    </xsl:if>
1084    <xsl:if test="//nxm:accession_x[nxm:rite_x]">
1085       <B>Rite:</B>&nbsp;<xsl:value-of select="//nxm:rite_x/@group"/>
1086       <xsl:if test="//nxm:rite_x[@subgroup]">
1087          &nbsp;&nbsp;&nbsp;<xsl:value-of select="//nxm:rite_x/@subgroup"/>
1088       </xsl:if>
1089       <BR />
1090    </xsl:if>
1091    <xsl:if test="//nxm:accession_x[nxm:service]">
1092       <B>Service:</B>&nbsp;<xsl:value-of select="//nxm:service/@group"/><BR />
1093    </xsl:if>
1094    <xsl:if test="//nxm:accession_x[nxm:service_x]">
1095       <B>Service:</B>&nbsp;<xsl:value-of select="//nxm:service_x/@group"/>
1096       <xsl:if test="//nxm:service_x[@subgroup]">
1097          &nbsp;&nbsp;&nbsp;<xsl:value-of select="//nxm:service_x/@subgroup"/>
1098       </xsl:if>
1099       <BR />
1100    </xsl:if>
1101    <xsl:if test="//nxm:accession_x[nxm:genre_x]">
1102       <B>Genre:</B>&nbsp;<xsl:value-of select="//nxm:genre_x/@group"/>&nbsp;
1103          &nbsp;&nbsp;&nbsp;
1104       <xsl:if test="//nxm:genre_x[@subgroup]">
1105          <B>Subtype:</B>&nbsp;<xsl:value-of select="//nxm:genre_x/@subgroup"/>
1106       </xsl:if>
1107       <BR />
1108    </xsl:if>
1109    <xsl:if test="//nxm:accession_x[nxm:occasion]">
1110       <B>Occasion:</B>&nbsp;<xsl:value-of select="//nxm:occasion/@celebration"/><BR />
1111    </xsl:if>
1112 
1113    <CENTER><FONT Color="green"><B>- Accession -</B></FONT>&nbsp;&nbsp;</CENTER>
1114    <B>Incipit:</B>&nbsp;<xsl:value-of select="//nxm:incipit/@content"
1115       disable-output-escaping="yes"/><BR />
1116    <xsl:if test="//nxm:accession_x[nxm:siglum]">
1117       <B>Siglum:</B>&nbsp;<xsl:value-of select="//nxm:siglum/@content"/><BR />
1118    </xsl:if>
1119    <xsl:if test="//nxm:accession_x[nxm:location]">
1120       <B>Location:</B>&nbsp;<xsl:value-of select="//nxm:location/@content"/><BR />
1121    </xsl:if>
1122    <xsl:if test="//nxm:accession_x[nxm:cao]">
1123       <B>CAO:</B>&nbsp;<xsl:value-of select="//nxm:cao/@content"/>&nbsp;
1124          &nbsp;&nbsp;&nbsp;<BR />
1125    </xsl:if>
1126    <xsl:if test="//nxm:accession_x[nxm:concordance]">
1127       <B>Concordance:</B>&nbsp;<xsl:value-of select="//nxm:concordance/@content"/><BR />
1128    </xsl:if>
1129 
1130    <CENTER><FONT Color="green"><B>- Physical Description -</B></FONT>&nbsp;</CENTER>
1131    <B>Dimensions of manuscript:</B><BR />
1132    <xsl:choose>
1133       <xsl:when test="//nxm:physical_description[nxm:dimensions]">
1134          Height = <xsl:value-of
1135             select="//nxm:physical_description/nxm:dimensions/@height"/>
1136          &nbsp;<xsl:value-of
1137             select="//nxm:physical_description/nxm:dimensions/@unit_of_measure"/>
1138          .&nbsp;Width = <xsl:value-of
1139             select="//nxm:physical_description/nxm:dimensions/@width"/>
1140          &nbsp;<xsl:value-of
1141             select="//nxm:physical_description/nxm:dimensions/@unit_of_measure"/>
1142       </xsl:when>
1143       <xsl:otherwise>
1144          Height = [unavailable].&nbsp;Width = [unavailable]
1145       </xsl:otherwise>
1146    </xsl:choose>
1147    <BR />
1148 
1149    <xsl:if test="//nxm:physical_description[nxm:layout]">
1150       <B>Layout:</B>&nbsp;
1151       <xsl:value-of
1152          select="//nxm:physical_description/nxm:layout/@description"
1153          disable-output-escaping="yes"/>
1154       <BR />
1155    </xsl:if>
1156 
1157    <xsl:if test="//nxm:attribution[nxm:provenance]">
1158       <CENTER><FONT Color="green"><B>- Manuscript Provenance -</B></FONT>&nbsp;&nbsp;</CENTER>
1159       <xsl:for-each select="//nxm:attribution/nxm:provenance">
1160          <IMG Width="0" Height="19" SRC="&std_img_path;/spacer1.gif"
1161            style="vertical-align:bottom;" alt="" />&bullet;
1162          <xsl:value-of select="self::node()/@content"
1163          disable-output-escaping="yes"/><BR />
1164       </xsl:for-each>
1165    </xsl:if>
1166 
1167    <xsl:if test="//nxm:attribution[nxm:cultural_context]">
1168       <CENTER><FONT Color="green"><B>- Cultural Context -</B></FONT>&nbsp;&nbsp;</CENTER>
1169       <xsl:value-of select="//nxm:attribution/nxm:cultural_context/@content"/><BR />
1170    </xsl:if>
1171 
1172    <xsl:if test="//nxm:description_part[nxm:bibliographic_reference]">
1173       <CENTER><FONT Color="green"><B>- Bibliographic References -</B></FONT>&nbsp;&nbsp;</CENTER>
1174       <xsl:for-each select="//nxm:description_part/nxm:bibliographic_reference">
1175          <IMG Width="0" Height="19" SRC="&std_img_path;/spacer1.gif"
1176            style="vertical-align:bottom;" alt="" />&bullet;
1177          <xsl:value-of select="self::node()/@description"
1178          disable-output-escaping="yes"/><BR />
1179       </xsl:for-each>
1180    </xsl:if>
1181 
1182    <xsl:if test="//nxm:description_part[nxm:content_link]">
1183       <CENTER><FONT Color="green"><B>- Content Hyperlinks -</B></FONT>&nbsp;&nbsp;</CENTER>
1184       <xsl:for-each select="//nxm:description_part/nxm:content_link">
1185          <A class="norm" HRef="{self::node()/@link}" Target="link_page">
1186          <xsl:value-of select="self::node()/@content"/></A><BR />
1187       </xsl:for-each>
1188    </xsl:if>
1189 
1190    </FONT>
1191    </TD>
1192 
1193    <!-- Transcription Chronicle: -->
1194    <TD>
1195    <FONT Size="-1">
1196    <CENTER><FONT FACE="&verdana;" Color="green">
1197    <B>Transcription Chronicle</B></FONT></CENTER>
1198    <HR Width="86%" />
1199    <B>Meta-data encoding:</B>&nbsp;
1200    <xsl:value-of select="//nxm:encoding_declaration/@description"/>,&nbsp; version&nbsp;
1201    <xsl:value-of select="//nxm:encoding_declaration/@version"/><BR />
1202    <B>Transcription-data encoding:</B> NEUMES, version 2.2.b (<i>beta</i>-test)<BR />
1203    <HR Width="87%" />
1204    <xsl:for-each select="//nxm:transcription_log">
1205       <B>Project:</B>&nbsp;
1206       <xsl:value-of select="self::node()/nxm:project/@project_name"
1207       disable-output-escaping="yes"/><BR />
1208 
1209       <xsl:if test="self::node()/nxm:project[@project_description]">
1210          <xsl:value-of
1211             select="self::node()/nxm:project/@project_description"
1212             disable-output-escaping="yes"/><BR />
1213       </xsl:if>
1214       <xsl:if test="self::node()[nxm:editorial_procedures]">
1215          <B>Editorial Procedures:</B>&nbsp;
1216          <A class="norm"><xsl:attribute name="href">javascript:var y=confirm
1217          ("<xsl:value-of
1218             select="self::node()/nxm:editorial_procedures/@description"
1219             disable-output-escaping="yes"/>")</xsl:attribute>view</A><BR />
1220       </xsl:if>
1221       <xsl:for-each select="self::node()/nxm:transcription_statement">
1222          <IMG Width="0" Height="20" SRC="&std_img_path;/spacer1.gif"
1223            style="vertical-align:bottom;" alt="" />&bullet;
1224          <xsl:if test="self::node()/nxm:version_identifier[@nr]">
1225             <B>Transcription Version:</B>&nbsp;
1226             <xsl:value-of
1227               select="self::node()/nxm:version_identifier/@nr"/>
1228             &nbsp;&nbsp;&nbsp;&nbsp; 
1229          </xsl:if>
1230          <B>Date:</B>&nbsp;
1231          <xsl:value-of select="self::node()/nxm:transcription_date/@content"/><BR />
1232          <B>Transcriber:</B>&nbsp;
1233          <xsl:value-of select="self::node()/nxm:transcriber/@content"
1234             disable-output-escaping="yes"/><BR />
1235          <xsl:if test="self::node()/nxm:version_identifier[@description]">
1236             <B>Description:</B>&nbsp;
1237             <xsl:value-of
1238                select="self::node()/nxm:version_identifier/@description"/>
1239             <BR />
1240          </xsl:if>
1241          <xsl:if test="self::node()[nxm:edition_comments]">
1242             <B>Edition comments:</B>&nbsp;
1243             <A class="norm"><xsl:attribute name="href">javascript:var y=confirm
1244             ("<xsl:value-of select="self::node()/nxm:edition_comments/@content"
1245             disable-output-escaping="yes"/>")</xsl:attribute>view</A><BR />
1246          </xsl:if>
1247          <!-- Copyright notice (separate copyrights OK for different versions): -->
1248          <xsl:if test="self::node()[nxm:copyright_statement]">
1249             <B>Copyright notice:</B>&nbsp;<FONT Color="green">
1250             <xsl:value-of select="self::node()/nxm:copyright_statement/@content"
1251             disable-output-escaping="yes"/></FONT><BR />
1252          </xsl:if>
1253       </xsl:for-each>
1254       <HR Width="42%" />
1255    </xsl:for-each>
1256    </FONT>
1257    </TD>
1258    </TR>
1259    <xsl:if test="//nxm:transcription_part[nxm:edited_text]">
1260       <TR>
1261       <TD Colspan="2">
1262         &nbsp;<B>Edited chant text:</B><br />
1263         &nbsp;<xsl:value-of select="//nxm:edited_text/@content"/>
1264       </TD>
1265       </TR>
1266    </xsl:if>
1267 
1268    <SCRIPT type="text/javascript">
1269       document.write('&lt;/TABLE>');
1270    </SCRIPT>
1271    <BR clear="left" />
1272    </DIV>
1273 
1274    <!--   ***********************************
1275       *** BEGIN DISPLAY OPTIONS BLOCK ***
1276    -->
1277    <DIV style="text-align:center;">
1278    <!--  DISPLAY OPTIONS BLOCK (conditional display): -->
1279    <SCRIPT type="text/javascript">
1280    document.write('&lt;TABLE Width="100%" CellPadding="6" CellSpacing="1" Border="5" ' +
1281      'BGColor="#CFCFCF" BorderColorLight="#909000" BorderColorDark="#E6EA33" ');
1282    if ('yes' == metadataValue) {
1283       document.write('style="margin:auto;">');
1284    } else {
1285       document.write('style="display:none; margin:auto;">');
1286    }
1287    </SCRIPT>
1288    <TR VAlign="top">
1289    <TD Align="center">
1290       <TABLE Width="100%" CellPadding="0" CellSpacing="0">
1291       <colgroup><col width="78" /><col width="*" /><col width="78" /></colgroup>
1292       <tbody>
1293       <TR valign="middle">
1294       <TD Background="&std_img_path;/blueshade_bg.gif"><IMG Width="52" Height="40"
1295         SRC="&std_img_path;/neumes_logo.gif" HSpace="3" VSpace="2" alt="" /></TD>
1296       <TD Align="center" Background="&std_img_path;/blueshade_bg.gif"><span
1297         class="times lg myblue">|= <b>NEUMES&nbsp;</b>transcription =|</TD>
1298 <!-- BOGUS: next TD style, vertical-align:top; ... also anchor style="" -->
1299       <TD style="background-image:url('&std_img_path;/blueshade_bg.gif');
1300         text-align:right;"><span class="verdana sm red">Legend:<a href="#"
1301         onClick="javascript:noop=pulldown('Legend'); if(blur) this.blur();
1302         return false;"><IMG ID="Legend-control" Width="14" Height="14"
1303         SRC="&std_img_path;/plus_sm.gif" HSpace="5" VSpace="2" border="0"
1304         style="vertical-align:middle;" alt="open/close" /></a><br
1305         clear="right" />Options:<a style="" href="#"
1306         onClick="javascript:noop=pulldown('Options'); if(blur) this.blur();
1307         return false;"><IMG ID="Options-control" Width="14" Height="14" HSpace="4"
1308         SRC="&std_img_path;/plus_sm.gif" border="0" style="vertical-align:middle;"
1309         alt="open/close" /></a></TD>
1310       </TR></tbody></TABLE>
1311    </TD></TR>
1312    <TR ID="Legend" style="display:none;"><TD>
1313       <table style="text-align:left;" Width="100%" cellSpacing="0" cellPadding="0">
1314       <colgroup><col width="140" /><col width="*" /></colgroup>
1315       <tbody><tr><td>
1316          <!-- Line Guide: -->
1317          <TABLE cellSpacing="0" cellPadding="2" border="1"
1318            style="display:inline; margin-left:5px; margin-right:15px;">
1319          <CAPTION VAlign="top" Align="left">
1320          <span class="verdana med blue bold">&nbsp;Line Guide:
1321          </CAPTION>
1322          <TBODY>
1323          <TR>
1324          <TD Background="&std_img_path;/parch3.jpg"><span
1325            class="verdana sm black bold">&nbsp;Neumatic glyphs&nbsp;
1326          </TD>
1327          </TR>
1328          <TR>
1329          <TD Background="&std_img_path;/parch3.jpg"><span
1330            class="verdana sm black bold">&nbsp;Chant text&nbsp;
1331          </TD>
1332          </TR>
1333          <TR>
1334          <TD Background="&std_img_path;/parch3.jpg"><span
1335            class="verdana sm maroon"><b>&nbsp;Pitches </b>(optional)&nbsp;
1336          </TD>
1337          </TR>
1338          <TR>
1339          <TD style="&tonal_bg;"><span
1340            class="verdana sm blue bold">&nbsp;Tonal movement&nbsp;
1341          </TD>
1342          </TR>
1343          </TBODY>
1344          </TABLE>
1345       </td><td>
1346          <!-- Key: -->
1347          <TABLE cellSpacing="0" cellPadding="1" border="0"
1348            style="display:inline; margin-left:0px; margin-right:11px;">
1349          <CAPTION VAlign="top" Align="left">
1350          <span class="verdana med blue bold">Legend: <span
1351            class="black">Tonal Movement
1352          </CAPTION>
1353          <colgroup>
1354            <col width="34"
1355              style="&tonal_bg; margin-left:0px; margin-right:10px;" />
1356            <col width="*" />
1357          </colgroup>
1358          <TBODY>
1359          <TR>
1360          <TD class="verdana sm maroon bold center">?</TD>
1361          <TD class="verdana sm black left">&nbsp;denotes that the tonal movement
1362            from previous glyph is unknown.</TD>
1363          </TR>
1364          <TR>
1365          <TD class="verdana sm navy bold center">=</TD>
1366          <TD class="verdana sm black left">&nbsp;denotes tonal movement staying on
1367            the same tone.</TD>
1368          </TR>
1369          <TR>
1370          <TD class="verdana sm navy bold center">-m3</TD>
1371          <TD class="verdana sm black left">&nbsp;denotes tonal movement down a minor
1372            third; and so on.</TD>
1373          </TR>
1374          <TR>
1375          <TD class="verdana sm navy bold center">+(2)</TD>
1376          <TD class="verdana sm black left">&nbsp;denotes tonal movement up an
1377            undifferentiated second; and so on.</TD>
1378          </TR>
1379          <TR>
1380          <TD class="verdana sm navy bold center">^</TD>
1381          <TD class="verdana sm black left">&nbsp;denotes ligation.</TD>
1382          </TR>
1383          <TR>
1384          <TD class="verdana sm green center"><b>[</b> <span
1385            class="black">... <b>]</b></TD>
1386          <TD class="verdana sm black left">&nbsp;denotes the beginning and end
1387            of a neume.</TD>
1388          </TR>
1389          <TR>
1390          <TD class="verdana sm maroon center"><b>[</b> <span
1391            class="black">... <b>]</b></TD>
1392          <TD class="verdana sm black left">&nbsp;denotes the beginning and end
1393            of a rubric or special symbol.</TD>
1394          </TR>
1395          <TR>
1396          <TD class="verdana sm red bold center">[?]</TD>
1397          <TD class="verdana sm black left">&nbsp;denotes an unrecognized character
1398            in the transcription.</TD>
1399          </TR>
1400          </TBODY>
1401          </TABLE>
1402       </td></tr></tbody></table>
1403    </TD>
1404    </TR>
1405 
1406    <!-- REDISPLAY OPTIONS: -->
1407    <TR ID="Options" style="display:none;">
1408    <TD>
1409    <FORM name="redisplayForm">
1410       <TABLE CellSpacing="3" CellPadding="0" Border="0" Width="100%"
1411         style="font-size:10px; font-family:&verdana;;">
1412       <TR VAlign="top">
1413       <!-- Column #1. zoom; margins; BG: -->
1414       <TD Align="center"><SPAN style="visibility:hidden;"><IMG Width="29" Height="29"
1415         SRC="&std_img_path;/zoom.gif" HSpace="2" style="vertical-align:middle;"
1416         alt="" /><span class="verdana med blue"><B>To rescale the visualization,<br />
1417         enter an integer percentage<br />
1418         in range of [50 - 200] %</B>&nbsp;
1419         <SCRIPT type="text/javascript">
1420         document.write('&lt;INPUT TYPE="text" NAME="magnification" ' +
1421           'style="vertical-align:middle;" SIZE="3" MAXLENGTH="3" VALUE="' +
1422           zoomValue + '" onkeypress="return noEnter()">');
1423         </SCRIPT></SPAN>
1424 
1425         <DIV style="position:relative; bottom: -11px;">
1426 <!-- NOBR is non-compliant with standard: -->
1427         <NOBR><span class="verdana med maroon">
1428         <IMG Width="16" Height="16" SRC="&std_img_path;/margins_sm.gif"
1429           HSpace="1" style="vertical-align:middle;" alt="" /><B>Margins</B>&nbsp;
1430         <SCRIPT type="text/javascript">
1431         document.write('&lt;INPUT TYPE="text" NAME="lmargin" ' +
1432           'style="vertical-align:middle;" SIZE="3" MAXLENGTH="3" VALUE="' +
1433           lmarginValue + '" onkeypress="return noEnter()">');
1434         </SCRIPT>
1435         &nbsp;Left&nbsp;
1436         <SCRIPT type="text/javascript">
1437         document.write('&lt;INPUT TYPE="text" NAME="rmargin" ' +
1438           'style="vertical-align:middle;" SIZE="3" MAXLENGTH="3" VALUE="' +
1439           rmarginValue + '" onkeypress="return noEnter()">');
1440         </SCRIPT>&nbsp;RIGHT&nbsp;</NOBR>
1441 <!--[end, NOBR]-->
1442         <BR />
1443         <span class="verdana med teal"><B>Background</B>
1444         <SCRIPT type="text/javascript">
1445         <!--  Nested single-quotes are escaped '\' to disambiguate the nesting.
1446            Also, _see_ implementation note in the redrawDisplay() definition.
1447         -->
1448         document.write('&lt;INPUT type="RADIO" name="background" value="white" ' +
1449           'style="vertical-align:middle;" onclick="bgValue=\'white\';" ');
1450         if ('white' == bgValue) {
1451          document.write('CHECKED="true"');
1452         }
1453         document.write('>');
1454         document.write('&lt;SPAN ' +
1455           'style="background-color:#FFFFFF; color:inherit;">White&lt;/SPAN>&nbsp;');
1456 
1457         document.write('&lt;INPUT type="RADIO" name="background" VALUE="parch" ' +
1458           'style="vertical-align:middle;" onclick="bgValue=\'parch\';" ');
1459         if ('parch' == bgValue) {
1460          document.write('CHECKED="true"');
1461         }
1462         document.write('>');
1463         document.write('&lt;SPAN ' +
1464           'style="background-color:#E6E3A0; color:inherit;">Parchment&lt;/SPAN>');
1465         </SCRIPT>
1466         </DIV>
1467       </TD>
1468 
1469       <!-- Column #2. title; notation-family selector: -->
1470       <TD Height="100%" Align="center">
1471          <TABLE CellPadding="0" CellSpacing="0" Width="100%">
1472          <TR VAlign="center">
1473          <TD BGColor="#E1DA52"><IMG Width="30" Height="30"
1474            SRC="&std_img_path;/display_options.gif" HSpace="10" VSpace="1"
1475            alt="" /></TD>
1476          <TD BGColor="#E1DA52" Align="left"><span class="verdana lg black"><B>Display
1477            Options</B></TD>
1478          </TR>
1479          </TABLE>
1480         <DIV style="position:relative; bottom: -9px;">
1481          <TABLE CellPadding="0" CellSpacing="0" Align="center">
1482          <TR VAlign="bottom">
1483          <TD Width="61"><IMG Width="53" Height="25"
1484            SRC="&std_img_path;/chg_notation.jpg" HSpace="4" alt="" /></TD>
1485          <TD Align="left"><span class="verdana med green"><B>To view source in<br />
1486            different notation:&nbsp;</B></TD>
1487          </TR>
1488          <TR>
1489          <TD ColSpan="2" Align="center">
1490            <SELECT class="small" Name="notation_family" Size="3" Multiple="true">
1491            <xsl:if test="$discipline='Western'">
1492 <!--TO DO: put the following code into an iteration of an array? Maybe not, because the
1493  capability to display in different notation can vary among notations types.  -->
1494             <SCRIPT type="text/javascript">
1495             document.write('&lt;option value="native" ');
1496             if ('native' == notationValue) {
1497                document.write('SELECTED="true"');
1498             }
1499             document.write('>Native notation of the source&lt;/option>');
1500 
1501             document.write('&lt;option value="Aquitanian" ');
1502             if ('Aquitanian' == notationValue) {
1503                document.write('SELECTED="true"');
1504             }
1505             document.write('>Aquitanian&lt;/option>');
1506 
1507             document.write('&lt;option value="Sarum" ');
1508             if ('Sarum' == notationValue) {
1509                document.write('SELECTED="true"');
1510             }
1511             document.write('>Sarum&lt;/option>');
1512 
1513             document.write('&lt;option value="square" ');
1514             if ('square' == notationValue) {
1515                document.write('SELECTED="true"');
1516             }
1517             document.write('>Square-neume&lt;/option>');
1518 
1519             document.write('&lt;option value="St_Gall" ');
1520             if ('St_Gall' == notationValue) {
1521                document.write('SELECTED="true"');
1522             }
1523             document.write('>St. Gall&lt;/option>');
1524             </SCRIPT>
1525            </xsl:if>
1526            <xsl:if test="$discipline='Eastern'">
1527             <SCRIPT type="text/javascript">
1528             document.write('&lt;option value="native" ');
1529             if ('native' == notationValue) {
1530                document.write('SELECTED="true"');
1531             }
1532             document.write('>Native notation of the source&lt;/option>');
1533 
1534             document.write('&lt;option value="Middle_Byzantine" ');
1535             if ('Middle_Byzantine' == notationValue) {
1536                document.write('SELECTED="true"');
1537             }
1538             document.write('>Middle Byzantine&lt;/option>');
1539 
1540             document.write('&lt;option value="Post_Byzantine" ');
1541             if ('Post_Byzantine' == notationValue) {
1542                document.write('SELECTED="true"');
1543             }
1544             document.write('>Post Byzantine&lt;/option>');
1545             </SCRIPT>
1546            </xsl:if>
1547            </SELECT>
1548          </TD>
1549          </TR>
1550          </TABLE>
1551         </DIV>
1552       </TD>
1553 
1554       <!-- Column #3. radio buttons; checkboxes; Redraw button: -->
1555       <TD Align="center">
1556         <DIV Align="left"> <!-- align checkboxes -->
1557 
1558         <!-- META-DATA: -->
1559         <SCRIPT type="text/javascript">
1560         <!--  Nested single-quotes are escaped '\' to disambiguate the nesting.
1561            Also, _see_ implementation note in the redrawDisplay() definition.
1562         -->
1563         document.write('&lt;INPUT type="CHECKBOX" name="metadata" ' +
1564           'value="no" onclick="readCheckBoxes();" ');
1565         if ('yes' == metadataValue) {
1566          document.write('CHECKED');
1567         }
1568         document.write('>');
1569         </SCRIPT>
1570         <span class="verdana med brown">
1571         <B><U>&nbsp;Suppress meta-data</U></B>&nbsp;
1572         <IMG Width="36" Height="14" SRC="&std_img_path;/no_xml.gif"
1573           style="vertical-align:middle;" alt="" /><BR />
1574 
1575         <!-- PITCH/TONAL MOVEMENT: -->
1576         <SCRIPT type="text/javascript">
1577         <!--  Nested single-quotes are escaped '\' to disambiguate the nesting.
1578            Also, see implementation note in the redrawDisplay() definition.
1579         -->
1580         document.write('&lt;INPUT type="CHECKBOX" name="pitchtone_mvmt" ' +
1581           'value="no" onclick="readCheckBoxes();" ');
1582         if ('no' == pitchtone_mvmtValue) {
1583          document.write('CHECKED="true"');
1584         }
1585         document.write('>');
1586         </SCRIPT>
1587         <span class="verdana med purple">
1588         <B><U>&nbsp;Suppress pitch/tone</U></B>&nbsp;
1589         <IMG Width="36" Height="14" SRC="&std_img_path;/no_pitch.gif"
1590           style="vertical-align:middle;" alt="" /><BR />
1591 
1592         <!-- NEW WINDOW: -->
1593 <!-- NOBR is non-compliant with standard: -->
1594         <NOBR><INPUT type="CHECKBOX" name="newWindow" value="yes"
1595           onclick="readCheckBoxes();" />
1596         <span class="verdana med navy">
1597         <B><U>&nbsp;Open in new window</U></B>&nbsp;
1598         <IMG Width="32" Height="31" SRC="&std_img_path;/new_window.gif"
1599           style="vertical-align:middle;" alt="" /></NOBR><BR clear="left" />
1600 <!--[end, NOBR]-->
1601         </DIV>
1602         <DIV style="position:relative; bottom: -10px;">
1603          <TABLE CellPadding="0" CellSpacing="0">
1604          <TR VAlign="middle"><TD RowSpan="2"><IMG Width="27" Height="27"
1605            SRC="&std_img_path;/redisplay.gif" alt="" /></TD>
1606          <TD Width="6" RowSpan="2"><IMG Width="6" Height="0"
1607            SRC="&std_img_path;/spacer1.gif" alt="" /></TD>
1608 <!-- NOBR is non-compliant with standard: -->
1609          <TD Align="center"><NOBR><span class="verdana med maroon"><B>Click button
1610            to redraw:</B></NOBR>
1611 <!--[end, NOBR]-->
1612          </TD>
1613          </TR>
1614          <TR>
1615          <TD><INPUT TYPE="BUTTON" VALUE="Redraw visualization"
1616            onclick="redrawDisplay(
1617              document.redisplayForm.magnification.value,
1618              document.redisplayForm.notation_family.value,
1619              document.redisplayForm.lmargin.value,
1620              document.redisplayForm.rmargin.value,
1621              document.redisplayForm.userURL.value);" /></TD>
1622          </TR>
1623          </TABLE>
1624         </DIV>
1625       </TD>
1626       </TR>
1627 
1628       <!-- Row 2. user-specified IMG filepath: -->
1629       <TR Align="bottom">
1630       <TD ColSpan="3" Align="center"><BR />
1631          <TABLE CellSpacing="0" CellPadding="0" style="font-size:10px;
1632            font-family:&verdana;;">
1633          <TR VAlign="center">
1634          <TD><IMG Width="30" Height="31"
1635            SRC="&std_img_path;/load_glyphs.gif" alt="" /></TD>
1636          <TD Width="3"><IMG Width="3" Height="0"
1637            SRC="&std_img_path;/spacer1.gif" alt="" /></TD>
1638          <TD><B>To use custom glyph set, enter the image path&nbsp;<BR />
1639            <I>http://<FONT Color="red">...</FONT>/images/</I><FONT Color="green">
1640            OR&nbsp; </FONT><I>file:///<FONT Color="red">drive
1641            letter</FONT>:/<FONT Color="red">...</FONT>/</I></B>
1642          </TD>
1643          <TD><SCRIPT type="text/javascript">
1644            document.write('&lt;INPUT TYPE="text" NAME="userURL" SIZE="60" ' +
1645              'MAXLENGTH="80" VALUE=\"' + userImgPathValue +
1646              '\" onkeypress="return noEnter()">');
1647            </SCRIPT></TD>
1648          </TR>
1649          </TABLE>
1650       </TD>
1651       </TR>
1652       </TABLE>
1653       </FORM>
1654    </TD>
1655    </TR>
1656    <!--[end, REDISPLAY OPTIONS]-->
1657 
1658    <SCRIPT type="text/javascript">
1659    document.write('&lt;/TABLE>');
1660    </SCRIPT>
1661    <BR clear="left" />
1662    </DIV>
1663 
1664    <!--  DIFFERENT NOTATION NOTICE (conditional display): -->
1665    <SCRIPT type="text/javascript">
1666    if ('yes' == metadataValue) {
1667       if ('native' != notationValue) {
1668          document.write('&lt;span class="verdana sm maroon bold">[Translation to ' +
1669            current_notation + ' notation]&lt;/span>&lt;br>&lt;br>');
1670       }
1671    }
1672    </SCRIPT>
1673 
1674 
1675    <!--   ***************************
1676       *** BEGIN TRANSCRIPTION ***
1677    -->
1678    <!-- OUTER TABLE: -->
1679    <SCRIPT type="text/javascript">
1680    openTranscriptionTable();
1681    </SCRIPT>
1682    <TR style="vertical-align:baseline;">
1683    <TD style="vertical-align:baseline;">
1684 
1685    <xsl:apply-templates select="//nxm:transcription"/>
1686 
1687    <!-- Close OUTER TABLE: -->
1688    </TD>
1689    </TR>
1690    <SCRIPT type="text/javascript">
1691    document.write('&lt;/TABLE>');
1692    </SCRIPT>
1693    <BR clear="left" />
1694    <!--[end, Transcription]-->
1695 
1696    <!-- Vertical retainer at end: -->
1697    <IMG Width="0" Height="24" SRC="&std_img_path;/spacer1.gif" alt="" />
1698    <!-- Closing: -->
1699    <BR clear="left" />
1700 
1701    <!-- Footer (conditional display): -->
1702    <SCRIPT type="text/javascript">
1703    if ('yes' == metadataValue) {
1704       document.write('&lt;CENTER>&lt;HR Width="87%">');
1705       document.write('&lt;FONT Size="4" Color="blue">&lt;B>= End, NEUMES ' +
1706         'Transcription =&lt;/B>&lt;/FONT>&lt;BR>&lt;BR>');
1707       document.write('&lt;IMG Width="32" Height="32" SRC="&std_img_path;/help.gif" ' +
1708         'HSpace="4" style="vertical-align:middle;" alt="Help">');
1709       document.write('&lt;INPUT TYPE="BUTTON" VALUE="Help" onclick="showHelpFile()">');
1710       document.write('&nbsp;&nbsp;&nbsp;&nbsp;');
1711       document.write('&lt;IMG Width="34" Height="31" HSpace="4" ' +
1712         'SRC="&std_img_path;/show_errors.gif" style="vertical-align:middle;" ' +
1713         'alt="Show errors">');
1714       document.write('&lt;INPUT TYPE="BUTTON" VALUE="List errors in visualization" ' +
1715         'style="width:172px;" onclick="showErrList()">');
1716       document.write('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
1717       document.write('&lt;IMG Width="27" Height="32" HSpace="5" Border="1" ' +
1718         'SRC="&std_img_path;/sourcecode.gif" style="vertical-align:middle;" ' +
1719         'alt="Show sourcecode">');
1720       document.write('&lt;INPUT TYPE="BUTTON" VALUE="Show source code" ' +
1721         'style="width:132px;" onclick="showSourceCode(\'' + filepathValue + '\')">');
1722       document.write('&nbsp;&nbsp;&nbsp;&nbsp;');
1723       document.write('&lt;IMG Width="34" Height="26" HSpace="3" ' +
1724         'SRC="&std_img_path;/neumes_icon.gif" style="vertical-align:middle;" ' +
1725         'alt="NEUMES Project homepage">');
1726       document.write('&lt;INPUT TYPE="BUTTON" VALUE="NEUMES homepage" ' +
1727         'style="width:143px;" onclick="showHomepage()">');
1728       document.write('&lt;/CENTER>&lt;BR>');
1729    }
1730    document.write('&lt;/BODY>');
1731    </SCRIPT>
1732    </html>
1733 </xsl:template>
1734 <!--[end, Root Node template]-->
1735 
1736 
1737 <!--   ******************************
1738    **  GLOBAL LAYOUT Template  **
1739 
1740 Gets the number of staff lines from *global_layout* and sets JavaScript variables.
1741 [In document-order, this is the first element in *transcription_Type*.]
1742 -->
1743 <xsl:template match="//nxm:global_layout">
1744 
1745    <xsl:variable name="neumesSequence" select="text()"/>
1746 
1747    <!-- Staff Lines: -->
1748    <xsl:choose>
1749    <xsl:when test="contains($neumesSequence, '&staff_lines_6;')">
1750       <SCRIPT type="text/javascript">native_lines = 6;</SCRIPT>
1751    </xsl:when>
1752    <xsl:when test="contains($neumesSequence, '&staff_lines_5;')">
1753       <SCRIPT type="text/javascript">native_lines = 5;</SCRIPT>
1754    </xsl:when>
1755    <xsl:when test="contains($neumesSequence, '&staff_lines_4;')">
1756       <SCRIPT type="text/javascript">native_lines = 4;</SCRIPT>
1757    </xsl:when>
1758    <xsl:when test="contains($neumesSequence, '&staff_lines_3;')">
1759       <SCRIPT type="text/javascript">native_lines = 3;</SCRIPT>
1760    </xsl:when>
1761    <xsl:when test="contains($neumesSequence, '&staff_lines_2;')">
1762       <SCRIPT type="text/javascript">native_lines = 2;</SCRIPT>
1763    </xsl:when>
1764    <xsl:when test="contains($neumesSequence, '&staff_lines_1;')">
1765       <SCRIPT type="text/javascript">native_lines = 1;</SCRIPT>
1766    </xsl:when>
1767    <xsl:otherwise>
1768       <SCRIPT type="text/javascript">native_lines = 0;</SCRIPT>
1769    </xsl:otherwise>
1770    </xsl:choose>
1771    <SCRIPT type="text/javascript">setStaffLines();</SCRIPT>
1772 
1773    <!-- CONST Global Glyph Color: -->
1774    <xsl:choose>
1775    <xsl:when test="contains($neumesSequence, '&glyphs_color_red;')">
1776       <SCRIPT type="text/javascript">globalColorPath = '&red_subpath;';</SCRIPT>
1777    </xsl:when>
1778    <!-- Default = black: -->
1779    <xsl:otherwise>
1780       <SCRIPT type="text/javascript">globalColorPath = '';</SCRIPT>
1781    </xsl:otherwise>
1782    </xsl:choose>
1783    <!-- VAR Local Glyph Color: -->
1784    <SCRIPT type="text/javascript">imgColorPath=globalColorPath;</SCRIPT>
1785 
1786 </xsl:template>
1787 <!--[end, global_layout template]-->
1788 
1789 
1790 <!--   **********************************
1791    **  PHYSICAL BOUNDARY Template  **
1792 -->
1793 <xsl:template match="//nxm:physical_boundary">
1794    <xsl:variable name="neumesSequence" select="text()"/>
1795 
1796    <!-- Begin physical_boundary: -->
1797    <xsl:variable name="description"
1798       select="self::node()/@description"/>
1799 
1800    <xsl:choose>
1801    <xsl:when test="$description='line_boundary'">
1802       <SCRIPT type="text/javascript">
1803       if (pitchtone_mvmtValue == "yes") {
1804          <!-- Close OUTER TABLE: -->
1805          document.write('&lt;/TD>&lt;/TR>&lt;/TABLE>&lt;BR clear="left">');
1806          <!-- Put linebreak in separate TABLE, and close: -->
1807          openTranscriptionTable();
1808          document.write('&lt;TD class="commentary">');
1809          document.write('&lt;FONT Color="navy">[line&nbsp;break]&lt;/FONT>');
1810          document.write('&lt;/TD>&lt;/TR>&lt;/TABLE>');
1811          document.write('&lt;BR clear="left">');
1812          openTranscriptionTable(); <!--Reopen OUTER TABLE-->
1813          document.write('&lt;TR>&lt;TD style="vertical-align:baseline">&nbsp;');
1814       }
1815       </SCRIPT>
1816    </xsl:when>
1817    <xsl:when test="$description='page_boundary'">
1818       <SCRIPT type="text/javascript">
1819       if (pitchtone_mvmtValue == "yes") {
1820          <!-- Close OUTER TABLE: -->
1821          document.write('&lt;/TD>&lt;/TR>&lt;/TABLE>&lt;BR clear="left">');
1822          <!-- Put pagebreak in separate TABLE, and close: -->
1823          openTranscriptionTable();
1824          document.write('&lt;TD class="commentary">');
1825          document.write('&lt;FONT Color="navy">[page&nbsp;break]&lt;/FONT>');
1826          document.write('&lt;/TD>&lt;/TR>&lt;/TABLE>');
1827          document.write('&lt;BR clear="left">');
1828          openTranscriptionTable(); <!--Reopen OUTER TABLE-->
1829          document.write('&lt;TR>&lt;TD style="vertical-align:baseline">&nbsp;');
1830       }
1831       </SCRIPT>
1832    </xsl:when>
1833    <xsl:otherwise>
1834       <FONT Color="red"><B>[?]</B></FONT>
1835    </xsl:otherwise>
1836    </xsl:choose>
1837 </xsl:template>
1838 <!--[end, physical_boundary template]-->
1839 
1840 
1841 <!--   ***********************
1842    **  RUBRIC Template  **
1843 
1844 Template is for meta-data-delineated rubrics, sometimes appearing on the MS
1845 inline with the chant text, but also including a few rubrics that appear with
1846 the neumatic glyphs. Rubric tag has a "description" attribute.
1847 Rubric commentary line is all one color.
1848 -->
1849 <xsl:template match="//nxm:rubric">
1850    <xsl:variable name="neumesSequence" select="text()"/>
1851 
1852    <TABLE class="neume" BORDER="0">
1853 
1854    <!-- GLYPHS Row: -->
1855    <SCRIPT type="text/javascript">
1856    openGlyphRow();
1857    </SCRIPT>
1858    <!-- Displays only glyphs inline with notation: -->
1859    <xsl:call-template name="ParseGlyphs">
1860       <xsl:with-param name="SequenceToParse" select="$neumesSequence"/>
1861    </xsl:call-template>
1862    <SCRIPT type="text/javascript">document.write('&lt;/TR>');</SCRIPT>
1863 
1864    <!-- INTONED TEXT Row: -->
1865    <TR>
1866    <!-- Display only rubric text plus glyphs that go inline w/chant text: -->
1867    <TD class="intone">
1868    <xsl:call-template name="ParseRubric">
1869       <xsl:with-param name="SequenceToParse" select="$neumesSequence"/>
1870       <xsl:with-param name="insideTag" select="'no'"/> <!--if Other tag is embedded-->
1871    </xsl:call-template>
1872    &nbsp;</TD> <!--retainer in case empty-->
1873    </TR>
1874 
1875    <!-- PITCH Row (empty): -->
1876    <SCRIPT type="text/javascript">
1877    if ('no' == pitchtone_mvmtValue) {
1878       document.write('&lt;TR style="display:none;">');
1879    } else {
1880       document.write('&lt;TR class="pitches">');
1881    }
1882    </SCRIPT>
1883    <TD class="pitches">&nbsp;</TD>  <!-- spacer necessary to prevent collapse of row -->
1884    <SCRIPT type="text/javascript">
1885    document.write('&lt;/TR>');
1886    </SCRIPT>
1887 
1888    <!-- TONAL MOVEMENT Row: -->
1889    <SCRIPT type="text/javascript">
1890    if ('no' == pitchtone_mvmtValue) {
1891       document.write('&lt;TR style="display:none;">');
1892    } else {
1893       document.write('&lt;TR class="commentary">');
1894    }
1895    </SCRIPT>
1896    <TD class="commentary"><FONT color="maroon">
1897 <!-- NOBR is non-compliant with standard: -->
1898    <xsl:text disable-output-escaping="yes">&lt;NOBR>&start_rubric;</xsl:text>
1899    <xsl:if test="self::node()[@description]">
1900       <!-- Escape double-quotes and apostrophes: -->
1901       <xsl:variable name="userComment" select="self::node()/@description"/>
1902       <xsl:variable name="noQuot">
1903          <xsl:call-template name="EscQuot">
1904             <xsl:with-param name="passString" select="$userComment"/>
1905          </xsl:call-template>
1906       </xsl:variable>
1907       <xsl:variable name="noAposQuot">
1908          <xsl:call-template name="EscApos">
1909             <xsl:with-param name="passString" select="$noQuot"/>
1910          </xsl:call-template>
1911       </xsl:variable>
1912       <xsl:text disable-output-escaping="yes">&lt;A HRef="" class="rubric"
1913          onClick="noop=pop('</xsl:text>
1914       <xsl:value-of select="$noAposQuot"/>
1915       <xsl:text disable-output-escaping="yes">'); return false;">&cm;</xsl:text>
1916    </xsl:if>
1917    <!-- Commentary: -->
1918    <xsl:choose>
1919       <!-- Western sources: -->
1920       <xsl:when test="contains($neumesSequence, '&doh_clef;')"> doh clef</xsl:when>
1921       <xsl:when test="contains($neumesSequence, '&fah_clef;')"> fah clef</xsl:when>
1922       <xsl:when test="contains($neumesSequence, '&custos;')"> custos</xsl:when>
1923       <xsl:when test="contains($neumesSequence, '&equaliter;')"> equaliter</xsl:when>
1924       <xsl:when test="contains($neumesSequence, '&ut_supra;')"> ut supra</xsl:when>
1925       <xsl:when test="contains($neumesSequence, '&antiphon;')"> antiphon</xsl:when>
1926       <xsl:when test="contains($neumesSequence, '&verse;')"> verse</xsl:when>
1927       <xsl:when test="contains($neumesSequence, '&response;')"> response</xsl:when>
1928       <xsl:when test="contains($neumesSequence, '&ij;')"> ij.</xsl:when>
1929       <xsl:when test="contains($neumesSequence, '&iij;')"> iij.</xsl:when>
1930       <!-- Eastern sources: -->
1931       <xsl:when
1932         test="contains($neumesSequence, '&martyria_deuteros;')"> martyr</xsl:when>
1933       <xsl:when
1934         test="contains($neumesSequence, '&martyria_plagios_deuteros;')">
1935         martyr</xsl:when>
1936       <xsl:when
1937         test="contains($neumesSequence, '&fanerosis_tetrafonias;')"> martyr</xsl:when>
1938 <!-- $$ continue ... -->
1939       <!-- Generic Rubric: -->
1940       <xsl:otherwise>rubric</xsl:otherwise>
1941    </xsl:choose>
1942    <!-- End comment if open: -->
1943    <xsl:if test="self::node()[@description]">
1944       <xsl:text disable-output-escaping="yes">&lt;/A></xsl:text>
1945    </xsl:if>
1946    <xsl:text disable-output-escaping="yes">&lt;/NOBR>&end_rubric;</xsl:text></FONT></TD>
1947 <!--[end, NOBR]-->
1948    <SCRIPT type="text/javascript">
1949    document.write('&lt;/TR>');
1950    </SCRIPT>
1951    </TABLE>
1952 </xsl:template>
1953 <!--[end, rubric template]-->
1954 
1955 
1956 <!--   ********************
1957    **  PARSE RUBRIC  **
1958 
1959 Recursive template parses a rubric character-by-character;</span> outputs any (non-PUA) text
1960 plus images that belong inline w/chant text. Skips any tags that are embedded within Rubric.
1961 -->
1962 <xsl:template name="ParseRubric">
1963    <xsl:param name="SequenceToParse"/>
1964    <xsl:param name="insideTag"/>
1965 
1966    <xsl:variable name="FirstChar" select="substring($SequenceToParse, 1, 1)"/>
1967 
1968    <xsl:choose>
1969    <xsl:when test="$FirstChar=''"/> <!--Base case, stop recursion.-->
1970    <xsl:when test="$FirstChar='&lt;'"> <!--Entering an Other tag-->
1971       <xsl:call-template name="ParseRubric">
1972          <xsl:with-param name="SequenceToParse"
1973             select="substring($SequenceToParse, 2)"/>
1974          <xsl:with-param name="insideTag" select="'yes'"/>
1975       </xsl:call-template>
1976    </xsl:when>
1977    <xsl:when test="$FirstChar='>'"> <!--Exiting an Other tag-->
1978       <xsl:call-template name="ParseRubric">
1979          <xsl:with-param name="SequenceToParse"
1980             select="substring($SequenceToParse, 2)"/>
1981          <xsl:with-param name="insideTag" select="'no'"/>
1982       </xsl:call-template>
1983    </xsl:when>
1984    <xsl:otherwise>
1985       <xsl:choose>
1986       <xsl:when test="$insideTag='yes'"/> <!--Inside an Other tag: skip-->
1987       <xsl:when test="$FirstChar='&STA;'"/>
1988       <xsl:when test="$FirstChar='&END;'"/>
1989       <!-- Clef signs, skip: -->
1990       <xsl:when test="contains('&ClefSigns;', $FirstChar)"/>
1991       <xsl:when test="contains('&ClefPositions;', $FirstChar)"/>
1992       <!-- Cases of particular glyphs that are not inline w/chant text, skip: -->
1993       <xsl:when test="$FirstChar='&custos;'"/>
1994       <xsl:when test="$FirstChar='&equaliter;'"/>
1995       <xsl:when test="$FirstChar='&ut_supra;'"/>
1996       <!-- $$ skip Martyriai [text in martyria?]: -->
1997       <xsl:when test="contains('&Martyriai;', $FirstChar)"/>
1998       <!-- SubstituteStyle, LocalColor, Pitch, TonalMovement, or CF in Rubric: -->
1999       <xsl:when test="contains('&SubstituteStyles;', $FirstChar)"/>
2000       <xsl:when test="contains('&LocalInkColors;', $FirstChar)"/>
2001       <xsl:when test="contains('&Pitches;', $FirstChar)"/>
2002       <xsl:when test="contains('&TonalMovements;', $FirstChar)"/>
2003       <xsl:when test="contains('&CertaintyFactors;', $FirstChar)"/>
2004       <xsl:when test="$FirstChar='&verse;'">
2005          <IMG SRC="&std_img_path;/shared/verse_1.gif"
2006            style="vertical-align:baseline;" onError="imgErr('verse_1.gif');"
2007            alt="Verse" />
2008       </xsl:when>
2009 <!-- Other Rubric Glyphs go here. -->
2010       <xsl:otherwise>
2011          <!-- Check for out-of-range char: -->
2012          <SCRIPT type="text/javascript">
2013          if ('<xsl:value-of select="$FirstChar"/>' >= '&PUA_floor;') {
2014             document.write('&lt;span class="verdana med red">&lt;B>[?]&lt;/B>&lt;/span>');
2015          } else {
2016             document.write('<xsl:value-of select="$FirstChar"/>');
2017          }
2018          </SCRIPT>         
2019       </xsl:otherwise>
2020       </xsl:choose>
2021       <xsl:call-template name="ParseRubric"> <!--Recurse-->
2022          <xsl:with-param name="SequenceToParse"
2023             select="substring($SequenceToParse, 2)"/>
2024          <xsl:with-param name="insideTag" select="$insideTag"/>
2025       </xsl:call-template>
2026    </xsl:otherwise>
2027    </xsl:choose>
2028 </xsl:template>
2029 <!--[end, Parse Rubric]-->
2030 
2031 
2032 <!--   ********************************
2033    **  NEUMED_SYLLABLE Template  **
2034 
2035 Template dispatches the creation of one table for each Neume.
2036 It assembles the chant text with a neumatic symbol for the first table.
2037 -->
2038 <xsl:template match="//nxm:neumed_syllable">
2039    <xsl:variable name="included_text" select="child::nxm:syllable[1]/text()"/>
2040    <xsl:for-each select="child::nxm:neume[1]">
2041       <xsl:call-template name="neume_table">
2042          <xsl:with-param name="intoned_text" select="$included_text"/>
2043       </xsl:call-template>
2044    </xsl:for-each>
2045    <xsl:for-each select="child::nxm:neume[position()>1]">
2046       <xsl:call-template name="neume_table">
2047          <xsl:with-param name="intoned_text"></xsl:with-param> <!--no param-->
2048       </xsl:call-template>
2049    </xsl:for-each>
2050 </xsl:template>
2051 
2052 
2053 <!--   *******************
2054    **  NEUME TABLE  **
2055 
2056 Template controls the placement of items in rows of a table for one Neume.
2057 "intoned_text" contains chant text on first neume;</span> it is empty in subsequent
2058 calls.
2059 -->
2060 <xsl:template name="neume_table">
2061    <xsl:param name="intoned_text"/>
2062 <!--xxx Testing: BORDER="1" bordercolor="#CDCDCD" -->
2063    <xsl:variable name="neumesSequence" select="text()"/>
2064    <TABLE class="neume">
2065    <!-- GLYPHS Row: -->
2066    <SCRIPT type="text/javascript">openGlyphRow();</SCRIPT>
2067    <xsl:call-template name="ParseGlyphs">
2068       <xsl:with-param name="SequenceToParse" select="$neumesSequence"/>
2069    </xsl:call-template>
2070    <SCRIPT type="text/javascript">document.write('&lt;/TR>');</SCRIPT>
2071 
2072    <!-- INTONED TEXT Row: -->
2073    <TR>
2074    <!-- Retainer in case empty: -->
2075    <TD class="intone"><xsl:value-of select="$intoned_text"/>&nbsp;</TD>
2076    </TR>
2077 
2078    <!-- PITCH Row: -->
2079    <SCRIPT type="text/javascript">
2080    if ('no' == pitchtone_mvmtValue) {
2081       document.write('&lt;TR style="display:none;">');
2082    } else {
2083       document.write('&lt;TR class="pitches">');
2084    }
2085    </SCRIPT>
2086    <xsl:if test="$pitched='true'">
2087       <!-- (No need to pre-open TD) -->
2088       <xsl:call-template name="ParsePitches">
2089          <xsl:with-param name="SequenceToParse"
2090             select="substring($neumesSequence, 1)"/>
2091       </xsl:call-template>
2092    </xsl:if>
2093    <SCRIPT type="text/javascript">document.write('&lt;/TR>');</SCRIPT>
2094 
2095    <!-- TONAL MOVEMENT Row: -->
2096    <SCRIPT type="text/javascript">
2097    if ('no' == pitchtone_mvmtValue) {
2098       document.write('&lt;TR style="display:none;">');
2099    } else {
2100       document.write('&lt;TR class="commentary">');
2101    }
2102    </SCRIPT>
2103    <TD class="commentary">
2104    <FONT Color="green"><xsl:text
2105       disable-output-escaping="yes">&lt;NOBR>&start_neume;</xsl:text>
2106    <!-- Allow one comment in this position: -->
2107    <xsl:for-each select="child::nxm:comment[1]">
2108       <xsl:text disable-output-escaping="yes">&lt;A HRef=""
2109          onClick="noop=pop('</xsl:text>
2110       <xsl:value-of select="self::node()/@content"/>
2111       <xsl:text disable-output-escaping="yes">'); return false;">&cm;</xsl:text>
2112    </xsl:for-each>
2113    </FONT><SPAN style="color:navy;">
2114    <xsl:call-template name="ParseTonalMovement"> <!--write the Tonal Movements-->
2115       <xsl:with-param name="SequenceToParse" select="substring($neumesSequence, 1)"/>
2116       <!-- Notify template that TD is open: -->
2117       <xsl:with-param name="TD_opened" select="'yes'"/>
2118    </xsl:call-template>
2119    </SPAN>
2120    <!-- End comment if open: -->
2121    <xsl:for-each select="child::nxm:comment[1]">
2122       <xsl:text disable-output-escaping="yes">&lt;/A></xsl:text>
2123    </xsl:for-each>
2124    <!-- Close TD [no space]: -->
2125    <FONT Color="green"><xsl:text
2126       disable-output-escaping="yes">&end_neume;&lt;/NOBR></xsl:text></FONT></TD>
2127    <SCRIPT type="text/javascript">document.write('&lt;/TR>');</SCRIPT>
2128    </TABLE>
2129 </xsl:template>
2130 
2131 
2132 <!--   ********************
2133    **  PARSE GLYPHS  **
2134 
2135 Displays only glyphs (rubric or neume) that are inline with the chant notation.
2136 For each pair of characters "<span class="SymbolColor">&STA;</span>" "<span class="SymbolColor">&END;</span>" (which delimit one neumatic symbol,
2137 be it simple or compound), instantiate a new <td> Element in this table row.
2138 Recursive template parses a string character-by-character for NEUMES characters.
2139 The glyphs are displayed in the TOP ROW. First caller does not open or close TD.
2140 -->
2141 <xsl:template name="ParseGlyphs">
2142    <xsl:param name="SequenceToParse"/>
2143 
2144    <xsl:variable name="FirstChar" select="substring($SequenceToParse, 1, 1)"/>
2145    <xsl:variable name="LineLessOne" select="substring($SequenceToParse, 2)"/>
2146 
2147    <xsl:if test="$FirstChar != ''"> <!--Stop recursion at end-of-string-->
2148       <!-- Only the first xsl:when that tests true is instantiated -->
2149       <xsl:choose>
2150       <!-- Neumatic Symbol Delimeters: -->
2151       <xsl:when test="$FirstChar='&STA;'">
2152          <xsl:text disable-output-escaping="yes">
2153 <!--xxx Testing
2154 In NeumesXML_xsl.css: bottom works, glyph offset measured from bottom [top puts
2155  ALL glyphs at top line]. vertical-align: bottom;</span>
2156   border=1 bordercolor="red"
2157 -->
2158             &lt;TD class="glyph" Align="left">
2159          </xsl:text>
2160       </xsl:when>
2161       <xsl:when test="$FirstChar='&END;'">
2162          <xsl:text disable-output-escaping="yes">&lt;/TD></xsl:text>
2163       </xsl:when>
2164       <!-- Compound Neume Forms Layout: -->
2165       <xsl:when test="$FirstChar='&STA_compose;'">
2166          <xsl:text disable-output-escaping="yes">
2167            &lt;TABLE class="compositeNeume" CellSpacing="0"
2168            CellPadding="0">&lt;TR>&lt;TD class="stackedGlyph">
2169          </xsl:text>
2170       </xsl:when>
2171       <xsl:when test="$FirstChar='&subordinate;'">
2172          <xsl:text disable-output-escaping="yes">
2173            &lt;/TD>&lt;/TR>&lt;TR>&lt;TD class="stackedGlyph">
2174          </xsl:text>
2175       </xsl:when>
2176       <xsl:when test="$FirstChar='&END_compose;'">
2177          <xsl:text disable-output-escaping="yes">
2178            &lt;/TD>&lt;/TR>&lt;/TABLE>
2179          </xsl:text>
2180       </xsl:when>
2181       <!-- Displayable Western glyphs: -->
2182       <xsl:when test="$discipline='Western'">
2183          <!-- Enumerated in probable-frequency order -->
2184          <xsl:choose>
2185          <xsl:when test="contains('&NeumaticSymbolsWest;', $FirstChar)
2186             or contains('&CompatibilityCharsWest;', $FirstChar)
2187             or contains('&NeumeAdjunctSymbolsWest;', $FirstChar)
2188             or contains('&NeumeRubricsHeightedWest;', $FirstChar)
2189             or contains('&NeumeRubricsUnheightedWest;', $FirstChar)
2190             or contains('&ClefSigns;', $FirstChar)">
2191                <xsl:call-template name="VisualizeGlyph">
2192                   <xsl:with-param name="CharToShow" select="$FirstChar"/>
2193                   <xsl:with-param name="LineRemainder"
2194                     select="$LineLessOne"/>
2195                </xsl:call-template>
2196          </xsl:when>
2197          <!-- noop -->
2198          </xsl:choose>
2199       </xsl:when>
2200       <!-- Displayable Eastern glyphs: -->
2201       <xsl:when test="$discipline='Eastern'">
2202          <!-- Enumerated in probable-frequency order -->
2203          <xsl:choose>
2204          <xsl:when test="contains('&NeumaticSymbolsEast;', $FirstChar)
2205             or contains('&QualifierGlyphsEast;', $FirstChar)
2206             or contains('&CompatibilityCharsEast;', $FirstChar)
2207             or contains('&GreatSigns;', $FirstChar)
2208             or contains('&Martyriai;', $FirstChar)">
2209                <xsl:call-template name="VisualizeGlyph">
2210                   <xsl:with-param name="CharToShow" select="$FirstChar"/>
2211                   <xsl:with-param name="LineRemainder"
2212                     select="$LineLessOne"/>
2213                </xsl:call-template>
2214          </xsl:when>
2215          <!-- noop otherwise -->
2216          </xsl:choose>
2217       </xsl:when>
2218       </xsl:choose>
2219       <!-- Skip all other characters. Recurse in any case: -->
2220       <xsl:call-template name="ParseGlyphs"> <!--Recurse-->
2221          <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2222       </xsl:call-template>
2223    </xsl:if> <!--end, if not end-of-string; stop recursion -->
2224 </xsl:template>
2225 <!--[end, Parse Glyphs]-->
2226 
2227 
2228 <!--   *********************
2229    **  PARSE PITCHES  **
2230 
2231 Recursive template parses a NEUMES sequence character-by-character.
2232 First caller does not open or close TD.
2233 -->
2234 <xsl:template name="ParsePitches">
2235    <xsl:param name="SequenceToParse"/>
2236 
2237    <xsl:variable name="FirstChar" select="substring($SequenceToParse, 1, 1)"/>
2238    <xsl:variable name="SecondChar" select="substring($SequenceToParse, 2, 1)"/>
2239    <xsl:variable name="LineLessOne" select="substring($SequenceToParse, 2)"/>
2240 
2241    <xsl:if test="$FirstChar != ''"> <!--Stop recursion if end-of-string-->
2242       <xsl:choose>
2243       <xsl:when test="$FirstChar='&STA;'">
2244          <xsl:text disable-output-escaping="yes">
2245             &lt;TD class="pitches">&lt;SPAN style="color:maroon;">&lt;SUB>
2246                &lt;/SUB>
2247          </xsl:text>
2248       </xsl:when>
2249       <xsl:when test="$FirstChar='&END;'">
2250          <xsl:text disable-output-escaping="yes">&lt;/SPAN>&lt;SUB>
2251             &lt;/SUB>&lt;/TD></xsl:text>
2252       </xsl:when>
2253       <xsl:when test="$FirstChar='&ton_ut;'">ut </xsl:when>
2254       <xsl:when test="$FirstChar='&ton_re;'">re </xsl:when>
2255       <xsl:when test="$FirstChar='&ton_mi;'">mi </xsl:when>
2256       <xsl:when test="$FirstChar='&ton_fa;'">fa </xsl:when>
2257       <xsl:when test="$FirstChar='&ton_sol;'">sol </xsl:when>
2258       <xsl:when test="$FirstChar='&ton_la;'">la </xsl:when>
2259       <xsl:when test="$FirstChar='&ton_si;'">si </xsl:when>
2260 
2261       <xsl:when test="$FirstChar='&ton_GG;'">GG </xsl:when>
2262       <xsl:when test="$FirstChar='&ton_A;'">A </xsl:when>
2263       <xsl:when test="$FirstChar='&ton_B;'">B </xsl:when>
2264       <xsl:when test="$FirstChar='&ton_H;'">H </xsl:when>
2265       <xsl:when test="$FirstChar='&ton_C;'">C </xsl:when>
2266       <xsl:when test="$FirstChar='&ton_D;'">D </xsl:when>
2267       <xsl:when test="$FirstChar='&ton_E;'">E </xsl:when>
2268       <xsl:when test="$FirstChar='&ton_F;'">F </xsl:when>
2269       <xsl:when test="$FirstChar='&ton_G;'">G </xsl:when>
2270       <xsl:when test="$FirstChar='&ton_a;'">a </xsl:when>
2271       <xsl:when test="$FirstChar='&ton_b;'">b </xsl:when>
2272       <xsl:when test="$FirstChar='&ton_h;'">h </xsl:when>
2273       <xsl:when test="$FirstChar='&ton_c;'">c </xsl:when>
2274       <xsl:when test="$FirstChar='&ton_d;'">d </xsl:when>
2275       <xsl:when test="$FirstChar='&ton_e;'">e </xsl:when>
2276       <xsl:when test="$FirstChar='&ton_f;'">f </xsl:when>
2277       <xsl:when test="$FirstChar='&ton_g;'">g </xsl:when>
2278       <xsl:when test="$FirstChar='&ton_aa;'">aa </xsl:when>
2279       <xsl:when test="$FirstChar='&ton_bb;'">bb </xsl:when>
2280       <xsl:when test="$FirstChar='&ton_hh;'">hh </xsl:when>
2281       <xsl:when test="$FirstChar='&ton_cc;'">cc </xsl:when>
2282       <xsl:when test="$FirstChar='&ton_dd;'">dd </xsl:when>
2283       <xsl:when test="$FirstChar='&ton_ee;'">ee </xsl:when>
2284       <xsl:when test="$FirstChar='&ton_ff;'">ff </xsl:when>
2285       <xsl:when test="$FirstChar='&ton_gg;'">gg </xsl:when>
2286       </xsl:choose>
2287       <xsl:call-template name="ParsePitches"> <!--Recurse-->
2288          <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2289       </xsl:call-template>
2290    </xsl:if>
2291 </xsl:template>
2292 
2293 
2294 <!--   ****************************
2295    **  PARSE TONAL MOVEMENT  **
2296 
2297 Recursive template parses a NEUMES sequence character-by-character and outputs
2298 Tonal Movement line of display.
2299 First caller opens and closes TD.
2300 -->
2301 <xsl:template name="ParseTonalMovement">
2302    <xsl:param name="SequenceToParse"/>
2303    <xsl:param name="TD_opened"/>
2304 
2305    <xsl:variable name="FirstChar" select="substring($SequenceToParse, 1, 1)"/>
2306    <xsl:variable name="SecondChar" select="substring($SequenceToParse, 2, 1)"/>
2307    <xsl:variable name="LineLessOne" select="substring($SequenceToParse, 2)"/>
2308    <xsl:choose>
2309       <xsl:when test="$FirstChar=''"/> <!--Stop recursion if end-of-string-->
2310       <xsl:when test="$FirstChar='&STA;'">
2311          <xsl:if test="$TD_opened='no'">
2312             <!-- NO SPACE: -->
2313             <xsl:text disable-output-escaping="yes">&lt;TD
2314               class="commentary">&lt;SPAN style="color:navy;"></xsl:text>
2315          </xsl:if>
2316          <xsl:call-template name="ParseTonalMovement">
2317             <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2318             <xsl:with-param name="TD_opened" select="'yes'"/>
2319          </xsl:call-template>
2320       </xsl:when>
2321       <xsl:when test="$FirstChar='&END;'">
2322          <xsl:choose>
2323          <!-- First caller will close TD if this is end of neume: -->
2324          <xsl:when test="$SecondChar=''">
2325             <xsl:call-template name="ParseTonalMovement">
2326                <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2327                <xsl:with-param name="TD_opened" select="'yes'"/>
2328             </xsl:call-template>
2329          </xsl:when>
2330          <xsl:otherwise>
2331             <xsl:text
2332                disable-output-escaping="yes">&lt;/SPAN>&lt;/TD></xsl:text>
2333             <xsl:call-template name="ParseTonalMovement">
2334                <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2335                <xsl:with-param name="TD_opened" select="'no'"/>
2336             </xsl:call-template>
2337          </xsl:otherwise>
2338          </xsl:choose>
2339       </xsl:when>
2340       <xsl:otherwise>
2341          <xsl:choose>
2342          <xsl:when test="$FirstChar='&LIG;'">&ligation;</xsl:when>
2343          <xsl:when test="$FirstChar='&no_tone;'">&no_tone_mark;</xsl:when>
2344          <xsl:when test="$FirstChar='&no_preced;'">&no_preced_tone;</xsl:when>
2345          <xsl:when test="$FirstChar='&UNK;'">&mv_unk;</xsl:when>
2346          <xsl:when test="$FirstChar='&EQ;'">&mv_eq;</xsl:when>
2347          <!-- Up: -->
2348          <xsl:when test="$FirstChar='&up;'">&mv_up;</xsl:when>
2349          <xsl:when test="$FirstChar='&up_little;'">&mv_up;lit</xsl:when>
2350          <xsl:when test="$FirstChar='&up_lot;'">&mv_up;lot</xsl:when>
2351          <xsl:when test="$FirstChar='&up_undiff2;'">&mv_up;(2)</xsl:when>
2352          <xsl:when test="$FirstChar='&up_m2;'">&mv_up;m2</xsl:when>
2353          <xsl:when test="$FirstChar='&up_M2;'">&mv_up;M2</xsl:when>
2354          <xsl:when test="$FirstChar='&up_undiff3;'">&mv_up;(3)</xsl:when>
2355          <xsl:when test="$FirstChar='&up_m3;'">&mv_up;m3</xsl:when>
2356          <xsl:when test="$FirstChar='&up_M3;'">&mv_up;M3</xsl:when>
2357          <xsl:when test="$FirstChar='&up_4;'">&mv_up;4</xsl:when>
2358          <xsl:when test="$FirstChar='&up_aug4;'">&mv_up;aug4</xsl:when>
2359          <xsl:when test="$FirstChar='&up_dim5;'">&mv_up;dim5</xsl:when>
2360          <xsl:when test="$FirstChar='&up_5;'">&mv_up;5</xsl:when>
2361          <xsl:when test="$FirstChar='&up_undiff6;'">&mv_up;(6)</xsl:when>
2362          <xsl:when test="$FirstChar='&up_m6;'">&mv_up;m6</xsl:when>
2363          <xsl:when test="$FirstChar='&up_M6;'">&mv_up;M6</xsl:when>
2364          <xsl:when test="$FirstChar='&up_undiff7;'">&mv_up;(7)</xsl:when>
2365          <xsl:when test="$FirstChar='&up_m7;'">&mv_up;m7</xsl:when>
2366          <xsl:when test="$FirstChar='&up_M7;'">&mv_up;M7</xsl:when>
2367          <xsl:when test="$FirstChar='&up_8;'">&mv_up;8</xsl:when>
2368          <xsl:when test="$FirstChar='&up_undiff9;'">&mv_up;(9)</xsl:when>
2369          <!-- Down: -->
2370          <xsl:when test="$FirstChar='&dn;'">&mv_dn;</xsl:when>
2371          <xsl:when test="$FirstChar='&dn_little;'">&mv_dn;lit</xsl:when>
2372          <xsl:when test="$FirstChar='&dn_lot;'">&mv_dn;lot</xsl:when>
2373          <xsl:when test="$FirstChar='&dn_undiff2;'">&mv_dn;(2)</xsl:when>
2374          <xsl:when test="$FirstChar='&dn_m2;'">&mv_dn;m2</xsl:when>
2375          <xsl:when test="$FirstChar='&dn_M2;'">&mv_dn;M2</xsl:when>
2376          <xsl:when test="$FirstChar='&dn_undiff3;'">&mv_dn;(3)</xsl:when>
2377          <xsl:when test="$FirstChar='&dn_m3;'">&mv_dn;m3</xsl:when>
2378          <xsl:when test="$FirstChar='&dn_M3;'">&mv_dn;M3</xsl:when>
2379          <xsl:when test="$FirstChar='&dn_4;'">&mv_dn;4</xsl:when>
2380          <xsl:when test="$FirstChar='&dn_aug4;'">&mv_dn;aug4</xsl:when>
2381          <xsl:when test="$FirstChar='&dn_dim5;'">&mv_dn;dim5</xsl:when>
2382          <xsl:when test="$FirstChar='&dn_5;'">&mv_dn;5</xsl:when>
2383          <xsl:when test="$FirstChar='&dn_undiff6;'">&mv_dn;(6)</xsl:when>
2384          <xsl:when test="$FirstChar='&dn_m6;'">&mv_dn;m6</xsl:when>
2385          <xsl:when test="$FirstChar='&dn_M6;'">&mv_dn;M6</xsl:when>
2386          <xsl:when test="$FirstChar='&dn_undiff7;'">&mv_dn;(7)</xsl:when>
2387          <xsl:when test="$FirstChar='&dn_m7;'">&mv_dn;m7</xsl:when>
2388          <xsl:when test="$FirstChar='&dn_M7;'">&mv_dn;M7</xsl:when>
2389          <xsl:when test="$FirstChar='&dn_8;'">&mv_dn;8</xsl:when>
2390          <xsl:when test="$FirstChar='&dn_undiff9;'">&mv_dn;9</xsl:when>
2391          </xsl:choose>
2392          <xsl:call-template name="ParseTonalMovement"> <!--Recurse-->
2393             <xsl:with-param name="SequenceToParse" select="$LineLessOne"/>
2394             <xsl:with-param name="TD_opened" select="$TD_opened"/>
2395          </xsl:call-template>
2396       </xsl:otherwise>
2397    </xsl:choose>
2398 </xsl:template>
2399 <!--[end, Parse Tonal Mvmt]-->
2400 
2401 
2402 <!--   ***********************
2403    **  VISUALIZE GLYPH  **
2404 
2405 Should be called only when *CharToShow* is a rubrical glyph or a neumatic
2406 glyph. Template calls MapGlyphImage() to get the standard .gif filename
2407 for this NEUMES character, then dispatches display by calling Glyph().
2408 Also sets the color path temporarily for this glyph.
2409 
2410 The first three characters after this character are examined for Substitute
2411 Style or Qualifier in order to pass SubStyle parameter to MapGlyphImage().
2412 (Some Qualifiers, such as '<span class="SymbolColor">&quilisma;</span>', affect the choice of glyph image;</span>
2413 there is no harm in passing Qualifier, because MapGlyphImage() defaults
2414 to the standard .gif filename.)
2415 
2416 Sequence of Characters in a neumatic glyph:
2417    glyph character
2418    optional CF
2419    optional Substitute Style
2420    optional Local Color
2421    one-or-more optional Qualifiers, plus CFs
2422 Followed by Neume a descriptor list:
2423    optional pitch, plus CF
2424    tonal movement, plus CF
2425    optional LIGation
2426 The Position specifier of a clef is considered as a Qualifier of the clef.
2427 Errors: Display inline red a '?' if unrecognized PUA char, or char as-is if non-PUA.
2428 -->
2429 <xsl:template name="VisualizeGlyph">
2430    <xsl:param name="CharToShow"/>
2431    <xsl:param name="LineRemainder"/>
2432 
2433    <xsl:variable name="SecondChar" select="substring($LineRemainder, 1, 1)"/>
2434    <xsl:variable name="ThirdChar" select="substring($LineRemainder, 2, 1)"/>
2435    <xsl:variable name="FourthChar" select="substring($LineRemainder, 3, 1)"/>
2436 
2437    <xsl:variable name="CF">
2438       <xsl:choose>
2439          <xsl:when test="contains('&CertaintyFactors;', $SecondChar)">
2440             <xsl:value-of select="$SecondChar"/>
2441          </xsl:when>
2442          <xsl:otherwise>
2443             <xsl:value-of select="'&objReplace;'"/>
2444          </xsl:otherwise>
2445          </xsl:choose>
2446    </xsl:variable>
2447 
2448    <xsl:variable name="SubStyle">
2449       <!-- ordered choose, preferring SubstituteStyles over Qualifiers: -->
2450       <xsl:choose>
2451       <xsl:when test="contains('&SubstituteStyles;', $SecondChar)
2452         or contains('&QualifiersWest;', $SecondChar)
2453         or contains('&QualifierGlyphsEast;', $SecondChar)">
2454          <xsl:value-of select="$SecondChar"/>
2455       </xsl:when>
2456       <xsl:when test="contains('&SubstituteStyles;', $ThirdChar)
2457         or contains('&QualifiersWest;', $ThirdChar)
2458         or contains('&QualifierGlyphsEast;', $ThirdChar)">
2459          <xsl:value-of select="$ThirdChar"/>
2460       </xsl:when>
2461       <xsl:when test="contains('&SubstituteStyles;', $FourthChar)
2462         or contains('&QualifiersWest;', $FourthChar)
2463         or contains('&QualifierGlyphsEast;', $FourthChar)">
2464          <xsl:value-of select="$FourthChar"/>
2465       </xsl:when>
2466       <xsl:otherwise>
2467          <xsl:value-of select="'&objReplace;'"/>
2468       </xsl:otherwise>
2469       </xsl:choose>
2470    </xsl:variable>
2471 
2472    <xsl:variable name="LocalColor">
2473       <xsl:choose>
2474       <xsl:when test="contains('&LocalInkColors;', $SecondChar)">
2475          <xsl:value-of select="$SecondChar"/>
2476       </xsl:when>
2477       <xsl:when test="contains('&LocalInkColors;', $ThirdChar)">
2478          <xsl:value-of select="$ThirdChar"/>
2479       </xsl:when>
2480 <!-- XXX buggy, composed symbols
2481       <xsl:when test="contains('<span class="SymbolColor">&CertaintyFactors;</span>', $SecondChar)
2482         and contains('<span class="SymbolColor">&LocalInkColors;</span>', $FourthChar))">
2483          <xsl:value-of select="$FourthChar"/>
2484       </xsl:when>
2485 -->
2486       <xsl:otherwise>
2487          <xsl:value-of select="'&objReplace;'"/>
2488       </xsl:otherwise>
2489       </xsl:choose>
2490    </xsl:variable>
2491 
2492    <xsl:variable name="ImgName">
2493       <xsl:call-template name="MapGlyphImage">
2494          <xsl:with-param name="CharToShow" select="$CharToShow"/>
2495          <xsl:with-param name="SubStyle" select="$SubStyle"/>
2496       </xsl:call-template>
2497    </xsl:variable>
2498 
2499    <xsl:choose>
2500    <!-- IF ERROR, HANDLE IT: -->
2501    <xsl:when test="$ImgName='&objReplace;'">
2502       <SCRIPT type="text/javascript">
2503       var CharToShow = '<xsl:value-of select="$CharToShow"/>';
2504       </SCRIPT>
2505       <xsl:text disable-output-escaping="yes">
2506       &lt;SCRIPT type="text/javascript">
2507       document.write('&lt;FONT Color="red">&lt;B>[');
2508       <!-- Error if char is in Private Use Area but no image known: -->
2509       if ((CharToShow >= '&NEUMES_floor;') &amp;&amp;
2510          (CharToShow &lt;= '&NEUMES_ceiling;')) {
2511          document.write('?');
2512       } else {
2513          <!-- Non-PUA case should never happen:  -->
2514          document.write(CharToShow);
2515       }
2516       document.write(']&lt;/B>&lt;/FONT>');
2517       &lt;/SCRIPT>
2518       </xsl:text>
2519    </xsl:when>
2520    <!-- OTHERWISE DISPATCH: -->
2521    <xsl:otherwise>
2522       <!-- Change local color before dispatch: -->
2523       <xsl:choose>
2524       <xsl:when test="contains($LocalColor, '&local_color_red;')">
2525          <SCRIPT type="text/javascript">imgColorPath= '&red_subpath;';</SCRIPT>
2526       </xsl:when>
2527       <xsl:when test="contains($LocalColor, '&local_color_black;')">
2528          <SCRIPT type="text/javascript">imgColorPath= '';</SCRIPT>
2529       </xsl:when>
2530       </xsl:choose>
2531       <!-- Dispatch: -->
2532        <xsl:call-template name="Glyph">
2533          <xsl:with-param name="CharToShow" select="$CharToShow"/>
2534          <xsl:with-param name="Output" select="$ImgName"/>
2535          <xsl:with-param name="LineRemainder" select="$LineRemainder"/>
2536          <xsl:with-param name="CF" select="$CF"/>
2537       </xsl:call-template>
2538       <!-- Restore, local color <- global color iff changed [economize JavaScript]: -->
2539       <xsl:if test="$LocalColor != '&objReplace;'">
2540          <SCRIPT type="text/javascript">imgColorPath=globalColorPath;</SCRIPT>
2541       </xsl:if>
2542    </xsl:otherwise>
2543    </xsl:choose>
2544 </xsl:template>
2545 <!--[end, Visualize Glyph]-->
2546 
2547 
2548 <!--   *************
2549    **  GLYPH  **
2550 
2551 Template computes glyph Height based on Tonal Movement.
2552 Each tone in a multi-tonal glyph has a Tonal Movement specifier.
2553 The JavaScript function 'drawGlyph' is called to draw the image.
2554 Parameters passed to that function are: glyph image name;</span> leading
2555 movement from the previous glyph;</span> total internal movement of the
2556 glyph;</span> and the CF.
2557 If CharToShow is a clef, then the leading movement = the line
2558 number (1 through 6) of the clef position;</span> if no position was
2559 specified, then the line number is 0.
2560 -->
2561 <xsl:template name="Glyph">
2562    <xsl:param name="CharToShow"/>
2563    <xsl:param name="Output"/>
2564    <xsl:param name="LineRemainder"/>
2565    <xsl:param name="CF"/>
2566 
2567    <!-- Set CF: -->
2568    <xsl:variable name="cf">
2569       <xsl:choose>
2570       <xsl:when test="$CF != '&objReplace;'">
2571          <xsl:call-template name="LookupCF">
2572             <xsl:with-param name="CF" select="$CF"/>
2573          </xsl:call-template>
2574       </xsl:when>
2575       <xsl:otherwise>
2576          <xsl:value-of select="10"/>
2577       </xsl:otherwise>
2578       </xsl:choose>
2579    </xsl:variable>
2580 
2581    <xsl:choose>
2582       <!-- Clef sign: -->
2583       <xsl:when test="contains('&ClefSigns;', $CharToShow)">
2584          <xsl:variable name="SecondChar" select="substring($LineRemainder, 1, 1)"/>
2585          <xsl:variable name="ThirdChar" select="substring($LineRemainder, 2, 1)"/>
2586          <xsl:variable name="FourthChar" select="substring($LineRemainder, 3, 1)"/>
2587          <xsl:variable name="ClefPosition">
2588             <xsl:choose>
2589             <xsl:when test="contains('&ClefPositions;', $SecondChar)">
2590                <xsl:value-of select="$SecondChar"/>
2591             </xsl:when>
2592             <xsl:when test="contains('&ClefPositions;', $ThirdChar)">
2593                <xsl:value-of select="$ThirdChar"/>
2594             </xsl:when>
2595             <xsl:when test="contains('&ClefPositions;', $FourthChar)">
2596                <xsl:value-of select="$FourthChar"/>
2597             </xsl:when>
2598             <xsl:otherwise>
2599                <xsl:value-of select="'&objReplace;'"/>
2600             </xsl:otherwise>
2601             </xsl:choose>
2602          </xsl:variable>
2603          <xsl:variable name="LineNumber">
2604             <xsl:choose>
2605             <xsl:when test="$ClefPosition='&line1;'">1</xsl:when>
2606             <xsl:when test="$ClefPosition='&line2;'">2</xsl:when>
2607             <xsl:when test="$ClefPosition='&line3;'">3</xsl:when>
2608             <xsl:when test="$ClefPosition='&line4;'">4</xsl:when>
2609             <xsl:when test="$ClefPosition='&line5;'">5</xsl:when>
2610             <xsl:when test="$ClefPosition='&line6;'">6</xsl:when>
2611             <xsl:otherwise>0</xsl:otherwise>
2612             </xsl:choose>
2613          </xsl:variable>
2614          <SCRIPT type="text/javascript">
2615          drawGlyph('<xsl:value-of select="$CharToShow"/>',
2616            '<xsl:value-of select="$Output"/>',
2617            '<xsl:value-of select="$LineNumber"/>',
2618            '0',
2619            '<xsl:value-of select="$cf"/>');
2620          </SCRIPT>
2621 
2622       </xsl:when>
2623 
2624       <!-- Unheighted: -->
2625       <xsl:when test="$heighted='false'">
2626          <SCRIPT type="text/javascript">
2627          drawGlyph('<xsl:value-of select="$CharToShow"/>',
2628            '<xsl:value-of select="$Output"/>',
2629            '0',
2630            '0',
2631            '<xsl:value-of select="$cf"/>');
2632          </SCRIPT>
2633       </xsl:when>
2634 
2635       <!-- Glyphs having Tonal Movement: -->
2636       <xsl:otherwise>
2637          <!--Set Heighting:-->
2638          <xsl:variable name="returnValues">
2639             <xsl:call-template name="ComputeHeight">
2640                <xsl:with-param name="sequenceToParse" select="$LineRemainder"/>
2641             </xsl:call-template>
2642          </xsl:variable>
2643          <xsl:variable name="leadingMvmt"
2644             select="substring-before($returnValues, ',')"/>
2645          <xsl:variable name="internalMvmt"
2646             select="substring-after($returnValues, ',')"/>
2647          <!-- Returned leadingMvmt of 888 means UNK -->
2648          <SCRIPT type="text/javascript">
2649          drawGlyph('<xsl:value-of select="$CharToShow"/>',
2650             '<xsl:value-of select="$Output"/>',
2651             '<xsl:value-of select="$leadingMvmt"/>',
2652             '<xsl:value-of select="$internalMvmt"/>',
2653             '<xsl:value-of select="$cf"/>');
2654          </SCRIPT>
2655       </xsl:otherwise>
2656    </xsl:choose>
2657 
2658 </xsl:template>
2659 
2660 </xsl:stylesheet>
2661 <!--[end, NeumesXML.xsl]-->
= END LISTING =