--- loncom/html/adm/jsMath/plugins/autoload.js 2005/12/07 18:57:49 1.1 +++ loncom/html/adm/jsMath/plugins/autoload.js 2006/05/17 22:19:38 1.3 @@ -12,17 +12,30 @@ * jsMath.Autoload.findMathElements * jsMath.Autoload.findTeXstrings * jsMath.Autoload.findLaTeXstrings + * jsMath.Autoload.findCustomStrings + * jsMath.Autoload.findCustomSettings * * which control whether to look for SPAN and DIV elements of class * "math", TeX strings that will be converted by jsMath.ConvertTeX(), or * LaTeX strings that will be converted by jsMath.ConvertLaTeX(). By - * default, the first is true and the last two are false. + * default, the first is true and the second and third are false. The + * findCustomStrings can be used to specify your own delimiters for + * in-line and display mathematics, e.g + * + * jsMath.Autoload.findCustomStrings = [ + * '[math],'[/math]', // start and end in-line math + * '[display]','[/display]' // start and end display math + * ]; + * + * Finally, findCustomSettings can be set to an object reference whose + * name:value pairs control the individual search settings for tex2math. + * (See the plugins/tex2math.js file for more details). * * If any math strings are found, jsMath.js will be loaded automatically, - * but not loaded otherwise. If any of the last two are true and TeX math + * but not loaded otherwise. If any of the last four are set and TeX math * strings are found, then plugins/tex2ath.js will be loaded * automatically. jsMath.Autoload.needsJsMath will be set to true or - * false depending on whether jsMath needs to be loaded. + * false depending on whether jsMath needed to be loaded. * * The value of jsMath.Autoload.element controls the element to be * searched by the autoload plug-in. If unset, the complete document will @@ -41,21 +54,31 @@ * will be run. Relative URL's are loaded based from the URL containing * jsMath.js. * - * --------------------------------------------------------------------- + * The autoload plugin can be loaded in the document HEAD or in the BODY. + * If it is loaded in the HEAD, you will need to call jsMath.Autoload.Check() + * at the end of the BODY (say in the window.onload handler) in order to + * get it to check the page for math that needs to be tagged, otherwise load + * the file at the bottom of the BODY and it will run the check automatically. * - * jsMath is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * jsMath is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * You can call jsMath.Autoload.Run() after the check has been performed + * in order to call the appropriate tex2math routines for the given Autoload + * settings. You can call jsMath.Autoload.Run() even when jsMath isn't loaded. + * + * --------------------------------------------------------------------- * - * You should have received a copy of the GNU General Public License - * along with jsMath; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Copyright 2004-2006 by Davide P. Cervone + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************/ @@ -63,146 +86,278 @@ /* * Make sure jsMath.Autoload is available */ -if (jsMath == null) {var jsMath = {}} +if (!window.jsMath) {window.jsMath = {}} if (jsMath.Autoload == null) {jsMath.Autoload = {}} +jsMath.Add = function (dst,src) {for (var id in src) {dst[id] = src[id]}}, +jsMath.document = document; // tex2math needs this -/* - * Look to see if there are SPAN or DIV elements of class "math". - */ -jsMath.Autoload.areMathElements = function (obj) { - if (!obj) {obj = document} - if (typeof(obj) == 'string') {obj = document.getElementById(obj)} - if (!obj.getElementsByTagName) {return false} - var math = obj.getElementsByTagName('DIV'); - for (var k = 0; k < math.length; k++) - {if (math[k].className == 'math') {return true}} - math = obj.getElementsByTagName('SPAN'); - for (var k = 0; k < math.length; k++) - {if (math[k].className == 'math') {return true}} - return false; -}; +jsMath.Add(jsMath.Autoload,{ + + Script: { + + iframe: null, // the hidden iframe + + /* + * Load an external JavaScript file asynchronously + */ + Load: function (url) { + this.iframe = document.createElement('iframe'); + this.iframe.style.visibility = 'hidden'; + this.iframe.style.position = 'absolute'; + this.iframe.style.width = '0px'; + this.iframe.style.height = '0px'; + if (document.body.firstChild) { + document.body.insertBefore(this.iframe,document.body.firstChild); + } else { + document.body.appendChild(this.iframe); + } + this.url = url; setTimeout('jsMath.Autoload.Script.setURL()',100); + }, + endLoad: function () {setTimeout('jsMath.Autoload.Script.AfterLoad()',1)}, + + /* + * Use location.replace() to avoid browsers placing the file in + * the history (and messing up the BACK button action). Not + * completely effective in Firefox 1.0.x. Safari won't handle + * replace() if the document is local (not sure if that's really + * the issue, but that's the only time I see it). + */ + setURL: function () { + var url = jsMath.Autoload.root+"jsMath-autoload.html"; + var doc = this.iframe.contentDocument; + if (!doc && this.iframe.contentWindow) {doc = this.iframe.contentWindow.document} + if (navigator.vendor == "Apple Computer, Inc." && + document.location.protocol == 'file:') {doc = null} + if (doc) {doc.location.replace(url)} else {this.iframe.src = url} + }, + + /* + * Queue items that need to be postponed until jsMath has run + */ + queue: [], + Push: function (name,data) {this.queue[this.queue.length] = [name,data]}, + RunStack: function () { + if (this.tex2math) {jsMath.Autoload.Check2(); return} + for (var i = 0; i < this.queue.length; i++) { + var name = this.queue[i][0]; + var data = this.queue[i][1]; + if (data.length == 1) {jsMath[name](data[0])} + else {jsMath[name](data[0],data[1],data[2],data[3])} + } + }, + + AfterLoad: function () {jsMath.Autoload.Script.RunStack()}, + + /* + * Look up the jsMath root directory, if it is not already supplied + */ + Root: function () { + if (jsMath.Autoload.root) return; + var script = document.getElementsByTagName('script'); + if (script) { + for (var i = 0; i < script.length; i++) { + var src = script[i].src; + if (src && src.match('(^|/)plugins/autoload.js$')) { + jsMath.Autoload.root = src.replace(/plugins\/autoload.js$/,''); + break; + } + } + } + } -/* - * The patterns used for searching for TeX and LaTeX math strings - * (taken from plugins/tex2math.js). - */ -jsMath.Autoload.pattern = { - tex: /((^|[^\\])(\\[^\[\(])*)(\\\((([^\\]|\\[^\)])*)\\\)|\\\[(([^\\]|\\[^\]])*)\\\]|(\$\$?)(([^$\\]|\\.)*)\9)/, - latex: /((^|[^\\])(\\[^\[\(])*)(\\\((([^\\]|\\[^\)])*)\\\)|\\\[(([^\\]|\\[^\]])*)\\\])/ -}; + }, + + /**************************************************************/ + + /* + * Load tex2math first (so we can call its search functions + * to look to see if anything needs to be turned into math) + * if it is needed, otherwise go on to the second check. + */ + Check: function () { + if (this.checked) return; this.checked = 1; + if (this.findTeXstrings || this.findLaTeXstrings || + this.findCustomStrings || this.findCustomSettings) { + this.Script.tex2math = 1; + this.Script.Load('plugins/tex2math.js'); + } else { + if (!jsMath.tex2math) {jsMath.tex2math = {}} + this.Check2(); + } + }, -/* - * Recursively search for text elements, and check them for - * TeX or LaTeX strings that would be recognized by tex2math. - */ -jsMath.Autoload.FindPattern = function (method,element,recurse) { - if (!element) { - if (recurse) {return false}; - element = document.body; - } - if (typeof(element) == 'string') {element = document.getElementById(element)} - - var pattern = jsMath.Autoload.pattern[method]; - while (element) { - if (element.nodeName == '#text') { - if (pattern.exec(element.nodeValue.replace(/\n/g,' '))) {return true} - } else if (!element.tagName || - !element.tagName.match(/^(SCRIPT|NOSCRIPT|STYLE|TEXTAREA|PRE)$/i)) { - if (this.FindPattern(method,element.firstChild,1)) {return true}; + /* + * Once tex2math is loaded, use it to check for math that + * needs to be tagged for jsMath, and load jsMath if it is needed + */ + Check2: function () { + this.Script.tex2math = 0; + this.needsJsMath = 0; if (this.checkElement == null) {this.checkElement = null} + if (this.findMathElements) { + this.needsJsMath = this.areMathElements(this.checkElement); } - element = element.nextSibling; - } - return false; -}; + jsMath.tex2math.callback = this.tex2mathCallback; + if (this.findTeXstrings && !this.needsJsMath) { + jsMath.tex2math.ConvertTeX(this.checkElement); + } + if (this.findLaTeXstrings && !this.needsJsMath) { + jsMath.tex2math.ConvertLaTeX(this.checkElement); + } + if (this.findCustomSettings && !this.needsJsMath) { + jsMath.tex2math.Convert(this.checkElement,this.findCustomSettings); + } + if (this.findCustomStrings && !this.needsJsMath) { + var s = this.findCustomStrings; + jsMath.tex2math.CustomSearch(s[0],s[1],s[2],s[3]); + jsMath.tex2math.ConvertCustom(this.checkElement); + } + jsMath.tex2math.callback = null; -jsMath.Autoload.areTeXstrings = function (obj) {return this.FindPattern('tex',obj,0)} -jsMath.Autoload.areLaTeXstrings = function (obj) {return this.FindPattern('latex',obj,0)} + if (this.needsJsMath) { + this.LoadJsMath(); + } else { + jsMath.Autoload.Script = null; + jsMath.Process = function () {}; + jsMath.ProcessBeforeShowing = function () {}; + jsMath.Synchronize = function () {}; + jsMath.ConvertTeX = function () {}; + jsMath.ConvertTeX2 = function () {}; + jsMath.ConvertLaTeX = function () {}; + jsMath.ConvertCustom = function () {}; + jsMath.CustomSearch = function () {}; + jsMath.Macro = function () {}; + jsMath.Autoload.Run = function () {}; + } + }, -/* - * When math tags are found, load the jsMath.js file. If we looked - * for TeX and LaTeX strings, load the tex2math as well. - */ -jsMath.Autoload.LoadJsMath = function () { - if (!jsMath.Autoload.root) { - var script = document.getElementsByTagName('SCRIPT'); - if (script) { - for (var i = 0; i < script.length; i++) { - var src = script[i].src; - if (src && src.match('(^|/)plugins/autoload.js$')) { - jsMath.Autoload.root = src.replace(/plugins\/autoload.js$/,''); - break; - } - } + /* + * A callback used in the tex2math searches to signal that + * some math has been found. + */ + tex2mathCallback: function () { + jsMath.Autoload.needsJsMath = 1; + return false; + }, + + /* + * jsMath.Autoload.Run() can be called to perform the + * tex2math calls given by the Autoload parameters. + */ + Run: function (data) {this.Script.Push('Autorun',[data])}, + + Autorun: function () { + if (this.findTeXstrings) {jsMath.ConvertTeX(this.checkElement)} + if (this.findLaTeXstrings) {jsMath.ConvertLaTeX(this.checkElement)} + if (this.findCustomSettings) { + jsMath.Synchronize(function () { + jsMath.tex2math.Convert(jsMath.Autoload.checkElement, + jsMath.Autoload.findCustomSettings); + }); } - } - if (jsMath.Autoload.root) { - document.write('