home *** CD-ROM | disk | FTP | other *** search
/ Freelog 121 / FreelogMagazineJuilletAout2014-No121.iso / Bureautique / calibre / calibre-1.35.0.msi / file_620 (.txt) < prev    next >
LaTeX Document  |  2013-05-28  |  13KB  |  354 lines

  1. /*************************************************************
  2.  *  MathJax/extensions/TeX/mhchem.js
  3.  *  Implements the \ce command for handling chemical formulas
  4.  *  from the mhchem LaTeX package.
  5.  *  ---------------------------------------------------------------------
  6.  *  Copyright (c) 2011-2012 Design Science, Inc.
  7.  *  Licensed under the Apache License, Version 2.0 (the "License");
  8.  *  you may not use this file except in compliance with the License.
  9.  *  You may obtain a copy of the License at
  10.  *      http://www.apache.org/licenses/LICENSE-2.0
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16. MathJax.Extension["TeX/mhchem"] = {
  17.   version: "2.0"
  18. MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
  19.   var TEX = MathJax.InputJax.TeX,
  20.       MACROS = TEX.Definitions.macros;
  21.    *  This is the main class for handing the \ce and related commands.
  22.    *  Its main method is Parse() which takes the argument to \ce and
  23.    *  returns the corresponding TeX string.
  24.    */
  25.   var CE = MathJax.Object.Subclass({
  26.     string: "",   // the \ce string being parsed
  27.     i: 0,         // the current position in the string
  28.     tex: "",      // the processed TeX result
  29.     atom: false,  // last processed token is an atom
  30.     sup: "",      // pending superscript
  31.     sub: "",      // pending subscript
  32.     //
  33.     //  Store the string when a CE object is created
  34.     //
  35.     Init: function (string) {this.string = string},
  36.     //
  37.     //  These are the special characters and the methods that
  38.     //  handle them.  All others are passed through verbatim.
  39.     //
  40.     ParseTable: {
  41.       '-': "Minus",
  42.       '+': "Plus",
  43.       '(': "Open",
  44.       ')': "Close",
  45.       '[': "Open",
  46.       ']': "Close",
  47.       '<': "Less",
  48.       '^': "Superscript",
  49.       '_': "Subscript",
  50.       '*': "Dot",
  51.       '.': "Dot",
  52.       '=': "Equal",
  53.       '#': "Pound",
  54.       '$': "Math",
  55.       '\\': "Macro",
  56.       ' ': "Space"
  57.     },
  58.     //
  59.     //  Basic arrow names for reactions
  60.     //
  61.     Arrows: {
  62.       '->': "rightarrow",
  63.       '<-': "leftarrow",
  64.       '<->': "leftrightarrow",
  65.       '<=>': "rightleftharpoons",
  66.       '<=>>': "Rightleftharpoons",
  67.       '^': "uparrow",
  68.       'v': "downarrow"
  69.     },
  70.     //
  71.     //  Implementations for the various bonds
  72.     //  (the ~ ones are hacks that don't work well in NativeMML)
  73.     //
  74.     Bonds: {
  75.       '-': "-",
  76.       '=': "=",
  77.       '#': "\\equiv",
  78.       '~': "\\tripledash",
  79.       '~-': "\\begin{CEstack}{}\\tripledash\\\\-\\end{CEstack}",
  80.       '~=': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
  81.       '~--': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
  82.       '-~-': "\\raise2mu{\\begin{CEstack}{}-\\\\\\tripledash\\\\-\\end{CEstack}}",
  83.       '...': "{\\cdot}{\\cdot}{\\cdot}",
  84.       '....': "{\\cdot}{\\cdot}{\\cdot}{\\cdot}",
  85.       '->': "\\rightarrow",
  86.       '<-': "\\leftarrow",
  87.       '??': "\\text{??}"           // unknown bond
  88.     },
  89.     //
  90.     //  This converts the CE string to a TeX string.
  91.     //  It loops through the string and calls the proper
  92.     //  method depending on the ccurrent character.
  93.     //  
  94.     Parse: function () {
  95.       this.tex = ""; this.atom = false;
  96.       while (this.i < this.string.length) {
  97.         var c = this.string.charAt(this.i);
  98.         if (c.match(/[a-z]/i)) {this.ParseLetter()}
  99.         else if (c.match(/[0-9]/)) {this.ParseNumber()}
  100.         else {this["Parse"+(this.ParseTable[c]||"Other")](c)}
  101.       }
  102.       this.FinishAtom();
  103.       return this.tex;
  104.     },
  105.     //
  106.     //  Make an atom name or a down arrow
  107.     //  
  108.     ParseLetter: function () {
  109.       this.FinishAtom();
  110.       if (this.Match(/^v( |$)/)) {
  111.         this.tex += "{\\"+this.Arrows["v"]+"}";
  112.       } else {
  113.         this.tex += "\\text{"+this.Match(/^[a-z]+/i)+"}";
  114.         this.atom = true;
  115.       }
  116.     },
  117.     //
  118.     //  Make a number of fraction preceeding an atom,
  119.     //  or a subscript for an atom.
  120.     //  
  121.     ParseNumber: function () {
  122.       var n = this.Match(/^\d+/);
  123.       if (this.atom && !this.sub) {
  124.         this.sub = n;
  125.       } else {
  126.         this.FinishAtom();
  127.         var match = this.Match(/^\/\d+/);
  128.         if (match) {
  129.           var frac = "\\frac{"+n+"}{"+match.substr(1)+"}";
  130.           this.tex += "\\mathchoice{\\textstyle"+frac+"}{"+frac+"}{"+frac+"}{"+frac+"}";
  131.         } else {
  132.           this.tex += n;
  133.           if (this.i < this.string.length) {this.tex += "\\,"}
  134.         }
  135.       }
  136.     },
  137.     //
  138.     //  Make a superscript minus, or an arrow, or a single bond.
  139.     //
  140.     ParseMinus: function (c) {
  141.       if (this.atom && (this.i === this.string.length-1 || this.string.charAt(this.i+1) === " ")) {
  142.         this.sup += c;
  143.       } else {
  144.         this.FinishAtom();
  145.         if (this.string.substr(this.i,2) === "->") {this.i += 2; this.AddArrow("->"); return}
  146.         else {this.tex += "{-}"}
  147.       }
  148.       this.i++;
  149.     },
  150.     //
  151.     //  Make a superscript plus, or pass it through
  152.     //
  153.     ParsePlus: function (c) {
  154.       if (this.atom) {this.sup += c} else {this.FinishAtom(); this.tex += c}
  155.       this.i++;
  156.     },
  157.     //
  158.     //  Handle dots and double or triple bonds
  159.     //
  160.     ParseDot:   function (c) {this.FinishAtom(); this.tex += "\\cdot "; this.i++},
  161.     ParseEqual: function (c) {this.FinishAtom(); this.tex += "{=}"; this.i++},
  162.     ParsePound: function (c) {this.FinishAtom(); this.tex += "{\\equiv}"; this.i++},
  163.     //
  164.     //  Look for (v) or (^), or pass it through
  165.     //
  166.     ParseOpen: function (c) {
  167.       this.FinishAtom();
  168.       var match = this.Match(/^\([v^]\)/);
  169.       if (match) {this.tex += "{\\"+this.Arrows[match.charAt(1)]+"}"}
  170.         else {this.tex += "{"+c; this.i++}
  171.     },
  172.     //
  173.     //  Allow ) and ] to get super- and subscripts
  174.     //
  175.     ParseClose: function (c) {this.FinishAtom(); this.atom = true; this.tex += c+"}"; this.i++},
  176.     //
  177.     //  Make the proper arrow
  178.     //
  179.     ParseLess: function (c) {
  180.       this.FinishAtom();
  181.       var arrow = this.Match(/^(<->?|<=>>?)/);
  182.       if (!arrow) {this.tex += c; this.i++} else {this.AddArrow(arrow)}
  183.     },
  184.     //
  185.     //  Look for a superscript, or an up arrow
  186.     //  
  187.     ParseSuperscript: function (c) {
  188.       c = this.string.charAt(++this.i);
  189.       if (c === "{") {
  190.         this.i++; var m = this.Find("}");
  191.         if (m === "-.") {this.sup += "{-}{\\cdot}"} else if (m) {this.sup += CE(m).Parse()}
  192.       } else if (c === " " || c === "") {
  193.         this.tex += "{\\"+this.Arrows["^"]+"}"; this.i++;
  194.       } else {
  195.         var n = this.Match(/^(\d+|-\.)/);
  196.         if (n) {this.sup += n}
  197.       }
  198.     },
  199.     //
  200.     //  Look for subscripts
  201.     //
  202.     ParseSubscript: function (c) {
  203.       if (this.string.charAt(++this.i) == "{") {
  204.         this.i++; this.sub += CE(this.Find("}")).Parse();
  205.       } else {
  206.         var n = this.Match(/^\d+/);
  207.         if (n) {this.sub += n}
  208.       }
  209.     },
  210.     //
  211.     //  Look for raw TeX code to include
  212.     //
  213.     ParseMath: function (c) {
  214.       this.FinishAtom();
  215.       this.i++; this.tex += this.Find(c);
  216.     },
  217.     //
  218.     //  Look for specific macros for bonds
  219.     //  and allow \} to have subscripts
  220.     //
  221.     ParseMacro: function (c) {
  222.       this.FinishAtom();
  223.       this.i++; var match = this.Match(/^([a-z]+|.)/i)||" ";
  224.       if (match === "sbond") {this.tex += "{-}"}
  225.       else if (match === "dbond") {this.tex += "{=}"}
  226.       else if (match === "tbond") {this.tex += "{\\equiv}"}
  227.       else if (match === "bond") {
  228.         var bond = (this.Match(/^\{.*?\}/)||"");
  229.         bond = bond.substr(1,bond.length-2);
  230.         this.tex += "{"+(this.Bonds[bond]||"\\text{??}")+"}";
  231.       }
  232.       else if (match === "{") {this.tex += "{\\{"}
  233.       else if (match === "}") {this.tex += "\\}}"; this.atom = true}
  234.       else {this.tex += c+match}
  235.     },
  236.     //
  237.     //  Ignore spaces
  238.     //
  239.     ParseSpace: function (c) {this.FinishAtom(); this.i++},
  240.     //
  241.     //  Pass anything else on verbatim
  242.     //
  243.     ParseOther: function (c) {this.FinishAtom(); this.tex += c; this.i++},
  244.     //
  245.     //  Process an arrow (looking for brackets for above and below)
  246.     //
  247.     AddArrow: function (arrow) {
  248.       var c = this.Match(/^[CT]\[/);
  249.       if (c) {this.i--; c = c.charAt(0)}
  250.       var above = this.GetBracket(c), below = this.GetBracket(c);
  251.       arrow = this.Arrows[arrow];
  252.       if (above || below) {
  253.         if (below) {arrow += "["+below+"]"}
  254.         arrow += "{"+above+"}";
  255.         arrow = "\\mathrel{\\x"+arrow+"}";
  256.       } else {
  257.         arrow = "\\long"+arrow+" ";
  258.       }
  259.       this.tex += arrow;
  260.     },
  261.     //
  262.     //  Handle the super and subscripts for an atom
  263.     //  
  264.     FinishAtom: function () {
  265.       if (this.sup || this.sub) {
  266.         if (this.sup && this.sub && !this.atom) {
  267.           //
  268.           // right-justify super- and subscripts when they are before the atom
  269.           //
  270.           var n = Math.abs(this.sup.length-this.sub.length);
  271.           if (n) {
  272.             var zeros = "0000000000".substr(0,n);
  273.             var script = (this.sup.length > this.sub.length ? "sub" : "sup");
  274.             this[script] = "\\phantom{"+zeros+"}" + this[script];
  275.           }
  276.         }
  277.         if (!this.sup) {this.sup = "\\Space{0pt}{0pt}{.2em}"} // forces subscripts to align properly
  278.         this.tex += "^{"+this.sup+"}_{"+this.sub+"}";
  279.         this.sup = this.sub = "";
  280.       }
  281.       this.atom = false;
  282.     },
  283.     //
  284.     //  Find a bracket group and handle C and T prefixes
  285.     //
  286.     GetBracket: function (c) {
  287.       if (this.string.charAt(this.i) !== "[") {return ""}
  288.       this.i++; var bracket = this.Find("]");
  289.       if (c === "C") {bracket = "\\ce{"+bracket+"}"} else
  290.       if (c === "T") {
  291.         if (!bracket.match(/^\{.*\}$/)) {bracket = "{"+bracket+"}"}
  292.         bracket = "\\text"+bracket;
  293.       };
  294.       return bracket;
  295.     },
  296.     //
  297.     //  Check if the string matches a regular expression
  298.     //    and move past it if so, returning the match
  299.     //
  300.     Match: function (regex) {
  301.       var match = regex.exec(this.string.substr(this.i));
  302.       if (match) {match = match[0]; this.i += match.length}
  303.       return match;
  304.     },
  305.     //
  306.     //  Find a particular character, skipping over braced groups
  307.     //
  308.     Find: function (c) {
  309.       var m = this.string.length, i = this.i, braces = 0;
  310.       while (this.i < m) {
  311.         var C = this.string.charAt(this.i++);
  312.         if (C === c && braces === 0) {return this.string.substr(i,this.i-i-1)}
  313.         if (C === "{") {braces++} else
  314.         if (C === "}") {
  315.           if (braces) {braces--}
  316.             else {TEX.Error("Extra close brace or missing open brace")}
  317.         }
  318.       }
  319.       if (braces) {TEX.Error("Missing close brace")};
  320.       TEX.Error("Can't find closing "+c);
  321.     }
  322.   });
  323.   /***************************************************************************/
  324.   //  Set up the macros for chemistry
  325.   MACROS.ce  = 'CE';
  326.   MACROS.cf  = 'CE';
  327.   MACROS.cee = 'CE';
  328.   //  Include some missing arrows (some are hacks)
  329.   MACROS.xleftrightarrow = ['xArrow',0x2194,6,6];
  330.   MACROS.xrightleftharpoons = ['xArrow',0x21CC,5,7];  // FIXME:  doesn't stretch in HTML-CSS output
  331.   MACROS.xRightleftharpoons = ['xArrow',0x21CC,5,7];  // FIXME:  how should this be handled?
  332.   //  FIXME:  These don't work well in FF NativeMML mode
  333.   MACROS.longrightleftharpoons = ["Macro","\\stackrel{\\textstyle{{-}\\!\\!{\\rightharpoonup}}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"];
  334.   MACROS.longRightleftharpoons = ["Macro","\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\small\\smash\\leftharpoondown}"];
  335.   //  Needed for \bond for the ~ forms
  336.   MACROS.tripledash = ["Macro","\\raise3mu{\\tiny\\text{-}\\kern2mu\\text{-}\\kern2mu\\text{-}}"];
  337.   TEX.Definitions.environment.CEstack = ['Array',null,null,null,'r',null,"0.001em",'T',1]
  338.   //  Add \hyphen used in some mhchem examples
  339.   //  
  340.   MACROS.hyphen = ["Macro","\\text{-}"];
  341.   TEX.Parse.Augment({
  342.     //
  343.     //  Implements \ce and friends
  344.     //
  345.     CE: function (name) {
  346.       var arg = this.GetArgument(name);
  347.       var tex = CE(arg).Parse();
  348.       this.string = tex + this.string.substr(this.i); this.i = 0;
  349.     }
  350.   });
  351.   //  Indicate that the extension is ready
  352.   MathJax.Hub.Startup.signal.Post("TeX mhchem Ready");
  353. MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js");
  354.