mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
0.8.66
This commit is contained in:
commit
0e23e6ec19
11
COPYRIGHT
11
COPYRIGHT
@ -41,6 +41,12 @@ License: Apache 2.0
|
|||||||
The full text of the Apache 2.0 license is available at:
|
The full text of the Apache 2.0 license is available at:
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Files: resources/viewer/mathjax/*
|
||||||
|
Copyright: Unknown
|
||||||
|
License: Apache 2.0
|
||||||
|
The full text of the Apache 2.0 license is available at:
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Files: /src/cherrypy/*
|
Files: /src/cherrypy/*
|
||||||
Copyright: Copyright (c) 2004-2007, CherryPy Team (team@cherrypy.org)
|
Copyright: Copyright (c) 2004-2007, CherryPy Team (team@cherrypy.org)
|
||||||
Copyright: Copyright (C) 2005, Tiago Cogumbreiro <cogumbreiro@users.sf.net>
|
Copyright: Copyright (C) 2005, Tiago Cogumbreiro <cogumbreiro@users.sf.net>
|
||||||
@ -396,8 +402,9 @@ License: other
|
|||||||
|
|
||||||
Liberation Fonts
|
Liberation Fonts
|
||||||
-----------------
|
-----------------
|
||||||
calibre includes a copy of the liberation fonts, available from
|
calibre includes a copy of the liberation fonts in TTF format, licensed under
|
||||||
https://calibre-ebook.com/downloads/liberation-fonts
|
the SIL Open Font License, Version 1.1, and available from
|
||||||
|
https://fedorahosted.org/liberation-fonts/
|
||||||
|
|
||||||
BSD License (for all the BSD licensed code indicated above)
|
BSD License (for all the BSD licensed code indicated above)
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
@ -19,6 +19,89 @@
|
|||||||
# new recipes:
|
# new recipes:
|
||||||
# - title:
|
# - title:
|
||||||
|
|
||||||
|
- version: 0.8.66
|
||||||
|
date: 2012-08-24
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "E-book viewer: Support the display of mathematics in e-books. Supports both embedded TeX and MathML"
|
||||||
|
description: "The calibre ebook viewer can now display embedded mathematics (symbols, equations, fractions, matrices, etc.) in EPUB and HTML ebooks. For details, see: http://manual.calibre-ebook.com/typesetting_math.html"
|
||||||
|
type: major
|
||||||
|
|
||||||
|
- title: "Drivers for SONY PRS-T2, Freelander PD10 and Coolreader Tablet"
|
||||||
|
tickets: [1039103]
|
||||||
|
|
||||||
|
- title: "Wireless device connections: Use a streamed mode for improved networking performance leading to much less time spent sending metadata to/from the device. Also make it easier to specify a fixed port directly in the dialog used to start the connection."
|
||||||
|
|
||||||
|
- title: "Get books: Add ebooksgratuitis.com"
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "PDF Output: Handle input epub documents with filenames starting with a dot. Also do not hang if there is an unhandled error."
|
||||||
|
tickets: [1040603]
|
||||||
|
|
||||||
|
- title: "Get Books: Update B&N plugin to handle changes to the B&N website"
|
||||||
|
|
||||||
|
- title: "Content server: Fix regression that caused the port being advertised via BonJour to be incorrect if the user changed the port for the server."
|
||||||
|
tickets: [1037912]
|
||||||
|
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Variety
|
||||||
|
- The Times UK
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: Le Monde subscription version
|
||||||
|
author: Remi Vanicat
|
||||||
|
|
||||||
|
- title: Brecha Digital
|
||||||
|
author: Darko Miletic
|
||||||
|
|
||||||
|
- version: 0.8.65
|
||||||
|
date: 2012-08-17
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "A new wireless device driver. This allows connecting wirelessly to a device running a 'smart' calibre client"
|
||||||
|
description: "The wireless connection functions just as if the device was plugged into the computer by USB cable. Currently, Android devices are supported. See https://play.google.com/store/apps/details?id=com.multipie.calibreandroid"
|
||||||
|
type: major
|
||||||
|
|
||||||
|
- title: "MOBI Output: Add an option to control the type of MOBI file produced, to the MOBI Output conversion options. You can now generate an old MOBI6, a new KF8 or a joint MOBI6/KF8 file. By default, MOBI6 files are generated. This replaces the previous use of a tweak."
|
||||||
|
|
||||||
|
- title: "E-book viewer: Make paged mode the default. You can go back to the old flow mode by clicking the button with the yellow scroll in the top right corner of the viewer."
|
||||||
|
|
||||||
|
- title: "Driver for COBY kYROS MID7042 and Samsung Galaxy Ace S5839i"
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "Update version of poppler bundled with calibre to fix reading covers from some PDF files"
|
||||||
|
|
||||||
|
- title: "Get Books: Fix clicking of results from Diesel books when there is only a single result not working"
|
||||||
|
|
||||||
|
- title: "Improve detection of system language on first run of calibre"
|
||||||
|
tickets: [1036354]
|
||||||
|
|
||||||
|
- title: "When finding the next series index and the last series index is a fractional number, use the next largest integer, instead of just adding 1"
|
||||||
|
|
||||||
|
- title: "Fix exception when saving a search/replace when no saved search/replace had been opened previously in the bulk search/replace dialog"
|
||||||
|
tickets: [1036464]
|
||||||
|
|
||||||
|
- title: "Fix restore database not restoring entries for the original_* formats"
|
||||||
|
|
||||||
|
- title: "Fix first run wizard not allowing empty email sending settings"
|
||||||
|
tickets: [1036358]
|
||||||
|
|
||||||
|
- title: "Do not error out when setting the cover for a book that has no folders in the library."
|
||||||
|
tickets: [1035935]
|
||||||
|
|
||||||
|
- title: "Conversion pipeline: Ignore unparseable values in the color attribute of font tags, instead of erroring out on them."
|
||||||
|
tickets: [1035633]
|
||||||
|
|
||||||
|
- title: "Catalogs: Fix regression that broke creation of catalogs while a device is connected"
|
||||||
|
|
||||||
|
- title: "Fix --with-library=/whatever not working for calibredb list"
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Slashdot
|
||||||
|
- Various Canadian newspapers
|
||||||
|
- Business Spectator
|
||||||
|
|
||||||
- version: 0.8.64
|
- version: 0.8.64
|
||||||
date: 2012-08-09
|
date: 2012-08-09
|
||||||
|
|
||||||
|
@ -182,6 +182,10 @@ The plugin API
|
|||||||
As you may have noticed above, a plugin in |app| is a class. There are different classes for the different types of plugins in |app|.
|
As you may have noticed above, a plugin in |app| is a class. There are different classes for the different types of plugins in |app|.
|
||||||
Details on each class, including the base class of all plugins can be found in :ref:`plugins`.
|
Details on each class, including the base class of all plugins can be found in :ref:`plugins`.
|
||||||
|
|
||||||
|
Your plugin is almost certainly going to use code from |app|. To learn
|
||||||
|
how to find various bits of functionality in the
|
||||||
|
|app| code base, read the section on the |app| :ref:`code_layout`.
|
||||||
|
|
||||||
Debugging plugins
|
Debugging plugins
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ a device driver plugin. You can browse the
|
|||||||
for new conversion formats involves writing input/output format plugins. Another example of the modular design is the :ref:`recipe system <news>` for
|
for new conversion formats involves writing input/output format plugins. Another example of the modular design is the :ref:`recipe system <news>` for
|
||||||
fetching news. For more examples of plugins designed to add features to |app|, see the `plugin index <http://www.mobileread.com/forums/showthread.php?p=1362767#post1362767>`_.
|
fetching news. For more examples of plugins designed to add features to |app|, see the `plugin index <http://www.mobileread.com/forums/showthread.php?p=1362767#post1362767>`_.
|
||||||
|
|
||||||
|
.. _code_layout:
|
||||||
|
|
||||||
Code layout
|
Code layout
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -548,7 +548,7 @@ Calibre has several keyboard shortcuts to save you time and mouse movement. Thes
|
|||||||
- Toggle jobs list
|
- Toggle jobs list
|
||||||
* - :kbd:`Alt+Shift+B`
|
* - :kbd:`Alt+Shift+B`
|
||||||
- Toggle Cover Browser
|
- Toggle Cover Browser
|
||||||
* - :kbd:`Alt+Shift+B`
|
* - :kbd:`Alt+Shift+D`
|
||||||
- Toggle Book Details panel
|
- Toggle Book Details panel
|
||||||
* - :kbd:`Alt+Shift+T`
|
* - :kbd:`Alt+Shift+T`
|
||||||
- Toggle Tag Browser
|
- Toggle Tag Browser
|
||||||
|
BIN
manual/images/lorentz.png
Normal file
BIN
manual/images/lorentz.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
102
manual/mathjax.html
Normal file
102
manual/mathjax.html
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<!-- Copyright (c) 2012 Design Science, Inc. -->
|
||||||
|
<head>
|
||||||
|
<title>Math Test Page</title>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||||
|
|
||||||
|
<!-- This script tag is needed to make calibre's ebook-viewer recpgnize that this file needs math typesetting -->
|
||||||
|
<script type="text/x-mathjax-config">
|
||||||
|
// This line adds numbers to all equations automatically, unless explicitly suppressed.
|
||||||
|
MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "all"} } });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
h1 {text-align:center}
|
||||||
|
h2 {
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #DDDDDD;
|
||||||
|
padding: .2em .5em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
border-top: 3px solid #666666;
|
||||||
|
border-bottom: 2px solid #999999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Sample Equations</h1>
|
||||||
|
|
||||||
|
<h2>The Lorenz Equations</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
\begin{align}
|
||||||
|
\dot{x} & = \sigma(y-x) \label{lorenz}\\
|
||||||
|
\dot{y} & = \rho x - y - xz \\
|
||||||
|
\dot{z} & = -\beta z + xy
|
||||||
|
\end{align}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>The Cauchy-Schwarz Inequality</h2>
|
||||||
|
|
||||||
|
<p>\[
|
||||||
|
\left( \sum_{k=1}^n a_k b_k \right)^{\!\!2} \leq
|
||||||
|
\left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
|
||||||
|
\]</p>
|
||||||
|
|
||||||
|
<h2>A Cross Product Formula</h2>
|
||||||
|
|
||||||
|
<p>\[
|
||||||
|
\mathbf{V}_1 \times \mathbf{V}_2 =
|
||||||
|
\begin{vmatrix}
|
||||||
|
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
|
||||||
|
\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\
|
||||||
|
\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\
|
||||||
|
\end{vmatrix}
|
||||||
|
\]</p>
|
||||||
|
|
||||||
|
<h2>The probability of getting \(k\) heads when flipping \(n\) coins is:</h2>
|
||||||
|
|
||||||
|
<p>\[P(E) = {n \choose k} p^k (1-p)^{ n-k} \]</p>
|
||||||
|
|
||||||
|
<h2>An Identity of Ramanujan</h2>
|
||||||
|
|
||||||
|
<p>\[
|
||||||
|
\frac{1}{(\sqrt{\phi \sqrt{5}}-\phi) e^{\frac25 \pi}} =
|
||||||
|
1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
|
||||||
|
{1+\frac{e^{-8\pi}} {1+\ldots} } } }
|
||||||
|
\]</p>
|
||||||
|
|
||||||
|
<h2>A Rogers-Ramanujan Identity</h2>
|
||||||
|
|
||||||
|
<p>\[
|
||||||
|
1 + \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots =
|
||||||
|
\prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})},
|
||||||
|
\quad\quad \text{for $|q|<1$}.
|
||||||
|
\]</p>
|
||||||
|
|
||||||
|
<h2>Maxwell's Equations</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
\begin{align}
|
||||||
|
\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\
|
||||||
|
\nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
|
||||||
|
\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
|
||||||
|
\nabla \cdot \vec{\mathbf{B}} & = 0
|
||||||
|
\end{align}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>In-line Mathematics</h2>
|
||||||
|
|
||||||
|
<p>While display equations look good for a page of samples, the
|
||||||
|
ability to mix math and text in a paragraph is also important. This
|
||||||
|
expression \(\sqrt{3x-1}+(1+x)^2\) is an example of an inline equation. As
|
||||||
|
you see, equations can be used this way as well, without unduly
|
||||||
|
disturbing the spacing between lines.</p>
|
||||||
|
|
||||||
|
<h2>References to equations</h2>
|
||||||
|
|
||||||
|
<p>Here is a reference to the Lorenz Equations (\ref{lorenz}). Clicking on the equation number will take you back to the equation.</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
manual/resources/mathjax.epub
Normal file
BIN
manual/resources/mathjax.epub
Normal file
Binary file not shown.
@ -18,4 +18,5 @@ Here you will find tutorials to get you started using |app|'s more advanced feat
|
|||||||
regexp
|
regexp
|
||||||
server
|
server
|
||||||
creating_plugins
|
creating_plugins
|
||||||
|
typesetting_math
|
||||||
|
|
||||||
|
70
manual/typesetting_math.rst
Normal file
70
manual/typesetting_math.rst
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
.. include:: global.rst
|
||||||
|
|
||||||
|
.. _typesetting_math:
|
||||||
|
|
||||||
|
|
||||||
|
Typesetting Math in ebooks
|
||||||
|
============================
|
||||||
|
|
||||||
|
The |app| ebook viewer has the ability to display math embedded in ebooks (ePub
|
||||||
|
and HTML files). You can typeset the math directly with TeX or MathML or
|
||||||
|
AsciiMath. The |app| viewer uses the excellent `MathJax
|
||||||
|
<http://www.mathjax.org>`_ library to do this. This is a brief tutorial on
|
||||||
|
creating ebooks with math in them that work well with the |app| viewer.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This only applies to calibre version 0.8.66 and newer
|
||||||
|
|
||||||
|
A simple HTML file with mathematics
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
You can write mathematics inline inside a simple HTML file and the |app| viewer
|
||||||
|
will render it into properly typeset mathematics. In the example below, we use
|
||||||
|
TeX notation for mathematics. You will see that you can use normal TeX
|
||||||
|
commands, with the small caveat that ampersands and less than and greater than
|
||||||
|
signs have to be written as & < and > respectively.
|
||||||
|
|
||||||
|
The first step is to tell |app| that this will contains maths. You do this by
|
||||||
|
adding the following snippet of code to the <head> section of the HTML file::
|
||||||
|
|
||||||
|
<script type="text/x-mathjax-config"></script>
|
||||||
|
|
||||||
|
That's it, now you can type mathematics just as you would in a .tex file. For
|
||||||
|
example, here are Lorentz's equations::
|
||||||
|
|
||||||
|
<h2>The Lorenz Equations</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
\begin{align}
|
||||||
|
\dot{x} & = \sigma(y-x) \\
|
||||||
|
\dot{y} & = \rho x - y - xz \\
|
||||||
|
\dot{z} & = -\beta z + xy
|
||||||
|
\end{align}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
This snippet looks like the following screen shot in the |app| viewer.
|
||||||
|
|
||||||
|
.. figure:: images/lorentz.png
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
:guilabel:`The Lorenz Equations`
|
||||||
|
|
||||||
|
The complete HTML file, with more equations and inline mathematics is
|
||||||
|
reproduced below. You can convert this HTML file to EPUB in |app| to end up
|
||||||
|
with an ebook you can distribute easily to other people.
|
||||||
|
|
||||||
|
.. only:: online
|
||||||
|
|
||||||
|
Here is the generated EPUB file: `mathjax.epub <_static/mathjax.epub>`_.
|
||||||
|
|
||||||
|
.. literalinclude:: mathjax.html
|
||||||
|
:language: html
|
||||||
|
|
||||||
|
More information
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Since the |app| viewer uses the MathJax library to render mathematics, the best
|
||||||
|
place to find out more about math in ebooks and get help is the `MathJax
|
||||||
|
website <http://www.mathjax.org>`_.
|
||||||
|
|
35
recipes/arcadia.recipe
Normal file
35
recipes/arcadia.recipe
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# -*- coding: utf8 -*-
|
||||||
|
|
||||||
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Arcadia_BBS(BasicNewsRecipe):
|
||||||
|
title = u'Arcadia'
|
||||||
|
__author__ = 'Masahiro Hasegawa'
|
||||||
|
language = 'ja'
|
||||||
|
encoding = 'utf8'
|
||||||
|
filter_regexps = [r'ad\.jp\.ap\.valuecommerce.com',]
|
||||||
|
timefmt = '[%Y/%m/%d]'
|
||||||
|
remove_tags_before = dict(name='a', attrs={'name':'kiji'})
|
||||||
|
|
||||||
|
sid_list = [] #some sotory id
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
result = []
|
||||||
|
for sid in self.sid_list:
|
||||||
|
s_result = []
|
||||||
|
soup = self.index_to_soup(
|
||||||
|
'http://www.mai-net.net/bbs/sst/sst.php?act=dump&all=%d'
|
||||||
|
% sid)
|
||||||
|
sec = soup.findAll('a', attrs={'href':re.compile(r'.*?kiji')})
|
||||||
|
for s in sec[:-2]:
|
||||||
|
s_result.append(dict(title=s.string,
|
||||||
|
url="http://www.mai-net.net" + s['href'],
|
||||||
|
date=s.parent.parent.parent.findAll('td')[3].string[:-6],
|
||||||
|
description='', content=''))
|
||||||
|
result.append((s_result[0]['title'], s_result))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ class TheAtlantic(BasicNewsRecipe):
|
|||||||
|
|
||||||
cover = soup.find('img', src=True, attrs={'class':'cover'})
|
cover = soup.find('img', src=True, attrs={'class':'cover'})
|
||||||
if cover is not None:
|
if cover is not None:
|
||||||
self.cover_url = cover['src']
|
self.cover_url = cover['src'].replace(' ', '%20')
|
||||||
|
|
||||||
feeds = []
|
feeds = []
|
||||||
seen_titles = set([])
|
seen_titles = set([])
|
||||||
|
82
recipes/brecha.recipe
Normal file
82
recipes/brecha.recipe
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
www.brecha.com.uy
|
||||||
|
'''
|
||||||
|
|
||||||
|
import urllib
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Brecha(BasicNewsRecipe):
|
||||||
|
title = 'Brecha Digital'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'Brecha , Cultura ,Sociales , Separatas, Lupas, Vueltas de Montevideo y toda la infomacion que caracteriza a este semanario'
|
||||||
|
publisher = 'Brecha'
|
||||||
|
category = 'brecha, digital, prensa, uruguay, semanario, sociedad, politica, cultura'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 200
|
||||||
|
no_stylesheets = True
|
||||||
|
encoding = 'utf8'
|
||||||
|
use_embedded_content = False
|
||||||
|
language = 'es_UY'
|
||||||
|
remove_empty_feeds = True
|
||||||
|
publication_type = 'magazine'
|
||||||
|
auto_cleanup = True
|
||||||
|
needs_subscription = 'optional'
|
||||||
|
masthead_url = 'http://www.brecha.com.uy/templates/ja_nex/themes/orange/images/logo.png'
|
||||||
|
extra_css = """
|
||||||
|
body{font-family: Arial,Helvetica,sans-serif }
|
||||||
|
img{margin-bottom: 0.4em; display:block}
|
||||||
|
"""
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_browser(self):
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
br.open('http://www.brecha.com.uy/index.php/acceder-miembros')
|
||||||
|
if self.username is not None and self.password is not None:
|
||||||
|
data = urllib.urlencode({ 'task':'login'
|
||||||
|
,'view':'register'
|
||||||
|
,'username':self.username
|
||||||
|
,'password':self.password
|
||||||
|
})
|
||||||
|
br.open('http://www.brecha.com.uy/index.php/index.php?option=com_osemsc&controller=register',data)
|
||||||
|
return br
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name=['meta','link']),
|
||||||
|
dict(name='div', attrs={'id':'js_ja'}),
|
||||||
|
dict(name='ul', attrs={'class':'actions'})
|
||||||
|
]
|
||||||
|
remove_attributes=['lang', 'border']
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Politica' , u'http://www.brecha.com.uy/index.php/politica-uruguaya?format=feed&type=rss'),
|
||||||
|
(u'Mundo' , u'http://www.brecha.com.uy/index.php/mundo?format=feed&type=rss'),
|
||||||
|
(u'Mapamundi', u'http://www.brecha.com.uy/index.php/mundo/mapamundi?format=feed&type=rss'),
|
||||||
|
(u'Cultura' , u'http://www.brecha.com.uy/index.php/cultura?format=feed&type=rss'),
|
||||||
|
(u'Vueltas de Montevideo', u'http://www.brecha.com.uy/index.php/cultura/vueltas-de-montevideo?format=feed&type=rss'),
|
||||||
|
(u'Secos y Mojados', u'http://www.brecha.com.uy/index.php/cultura/secos-y-mojados?format=feed&type=rss'),
|
||||||
|
(u'Literarias', u'http://www.brecha.com.uy/index.php/cultura/literarias?format=feed&type=rss'),
|
||||||
|
(u'Sociedad', u'http://www.brecha.com.uy/index.php/sociedad?format=feed&type=rss'),
|
||||||
|
(u'Especiales', u'http://www.brecha.com.uy/index.php/especiales?format=feed&type=rss'),
|
||||||
|
(u'Contratapa', u'http://www.brecha.com.uy/index.php/contratapa?format=feed&type=rss')
|
||||||
|
]
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url + '?tmpl=component&print=1&layout=default&page='
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
soup = self.index_to_soup('http://www.brecha.com.uy/index.php')
|
||||||
|
for image in soup.findAll('img', alt=True):
|
||||||
|
if image['alt'].startswith('Tapa '):
|
||||||
|
return 'http://www.brecha.com.uy' + urllib.quote(image['src'])
|
||||||
|
return None
|
70
recipes/bwmagazine2.recipe
Normal file
70
recipes/bwmagazine2.recipe
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
class BusinessWeekMagazine(BasicNewsRecipe):
|
||||||
|
|
||||||
|
title = 'Business Week Magazine'
|
||||||
|
__author__ = 'Rick Shang'
|
||||||
|
|
||||||
|
description = 'A renowned business publication. Business news, trends and profiles of successful businesspeople.'
|
||||||
|
language = 'en'
|
||||||
|
category = 'news'
|
||||||
|
encoding = 'UTF-8'
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'id':'article_body_container'}),
|
||||||
|
]
|
||||||
|
remove_tags = [dict(name='ui'),dict(name='li')]
|
||||||
|
no_javascript = True
|
||||||
|
no_stylesheets = True
|
||||||
|
|
||||||
|
cover_url = 'http://images.businessweek.com/mz/covers/current_120x160.jpg'
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
|
||||||
|
#Go to the issue
|
||||||
|
soup = self.index_to_soup('http://www.businessweek.com/magazine/news/articles/business_news.htm')
|
||||||
|
|
||||||
|
#Find date
|
||||||
|
mag=soup.find('h2',text='Magazine')
|
||||||
|
dates=self.tag_to_string(mag.findNext('h3'))
|
||||||
|
self.timefmt = u' [%s]'%dates
|
||||||
|
|
||||||
|
#Go to the main body
|
||||||
|
div0 = soup.find ('div', attrs={'class':'column left'})
|
||||||
|
section_title = ''
|
||||||
|
feeds = OrderedDict()
|
||||||
|
articles = []
|
||||||
|
for div in div0.findAll('a'):
|
||||||
|
section_title = self.tag_to_string(div.findPrevious('h3')).strip()
|
||||||
|
self.log('Processing section:', section_title)
|
||||||
|
title=self.tag_to_string(div).strip()
|
||||||
|
url=div['href']
|
||||||
|
soup0 = self.index_to_soup(url)
|
||||||
|
urlprint=soup0.find('li', attrs={'class':'print'}).a['href']
|
||||||
|
articles.append({'title':title, 'url':urlprint, 'description':'', 'date':''})
|
||||||
|
|
||||||
|
|
||||||
|
if articles:
|
||||||
|
if section_title not in feeds:
|
||||||
|
feeds[section_title] = []
|
||||||
|
feeds[section_title] += articles
|
||||||
|
div1 = soup.find ('div', attrs={'class':'column center'})
|
||||||
|
section_title = ''
|
||||||
|
articles = []
|
||||||
|
for div in div1.findAll('a'):
|
||||||
|
desc=self.tag_to_string(div.findNext('p')).strip()
|
||||||
|
section_title = self.tag_to_string(div.findPrevious('h3')).strip()
|
||||||
|
self.log('Processing section:', section_title)
|
||||||
|
title=self.tag_to_string(div).strip()
|
||||||
|
url=div['href']
|
||||||
|
soup0 = self.index_to_soup(url)
|
||||||
|
urlprint=soup0.find('li', attrs={'class':'print'}).a['href']
|
||||||
|
articles.append({'title':title, 'url':urlprint, 'description':desc, 'date':''})
|
||||||
|
|
||||||
|
if articles:
|
||||||
|
if section_title not in feeds:
|
||||||
|
feeds[section_title] = []
|
||||||
|
feeds[section_title] += articles
|
||||||
|
ans = [(key, val) for key, val in feeds.iteritems()]
|
||||||
|
return ans
|
||||||
|
|
@ -1,35 +1,314 @@
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
class CalgaryHerald(BasicNewsRecipe):
|
__license__ = 'GPL v3'
|
||||||
title = u'Calgary Herald'
|
|
||||||
oldest_article = 3
|
'''
|
||||||
max_articles_per_feed = 100
|
www.canada.com
|
||||||
|
'''
|
||||||
feeds = [
|
import re
|
||||||
(u'News', u'http://rss.canada.com/get/?F233'),
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
(u'Calgary', u'http://www.calgaryherald.com/scripts/sp6query.aspx?catalog=cahr&tags=keyword|calgary&output=rss?link=http%3a%2f%2fwww.calgaryherald'),
|
from calibre.ebooks.BeautifulSoup import Tag, BeautifulStoneSoup
|
||||||
(u'Alberta', u'http://www.calgaryherald.com/scripts/Sp6Query.aspx?catalog=CAHR&tags=Keyword|Alberta&output=rss?link=http%3A%2F%2Fwww.calgaryherald.com%2Fnews%2Falberta%2Findex.html'),
|
|
||||||
(u'Politics', u'http://rss.canada.com/get/?F7551'),
|
|
||||||
(u'National', u'http://rss.canada.com/get/?F7552'),
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
(u'World', u'http://rss.canada.com/get/?F7553'),
|
|
||||||
]
|
postmedia_index_pages = [
|
||||||
__author__ = 'rty'
|
(u'Headlines',u'/index.html'),
|
||||||
pubisher = 'Calgary Herald'
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
description = 'Calgary, Alberta, Canada'
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
category = 'News, Calgary, Alberta, Canada'
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
remove_javascript = True
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
use_embedded_content = False
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
no_stylesheets = True
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
language = 'en_CA'
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
encoding = 'utf-8'
|
(u'National',u'/news/national/index.html'),
|
||||||
conversion_options = {'linearize_tables':True}
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
##masthead_url = 'http://www.calgaryherald.com/index.html'
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
keep_only_tags = [
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
dict(name='div', attrs={'id':'storyheader'}),
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
dict(name='div', attrs={'id':'storycontent'})
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
]
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
remove_tags_after = {'class':"story_tool_hr"}
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
|
## title = u'Vancouver Province'
|
||||||
|
## url_prefix = 'http://www.theprovince.com'
|
||||||
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
## logo_url = 'vplogo.jpg'
|
||||||
|
## fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
|
## title = u'Vancouver Sun'
|
||||||
|
## url_prefix = 'http://www.vancouversun.com'
|
||||||
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
## logo_url = 'vslogo.jpg'
|
||||||
|
## fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Calgary Herald
|
||||||
|
title = u'Calgary Herald'
|
||||||
|
url_prefix = 'http://www.calgaryherald.com'
|
||||||
|
description = u'News from Calgary, AB'
|
||||||
|
std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
logo_url = 'chlogo.jpg'
|
||||||
|
fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
|
## title = u'Edmonton Journal'
|
||||||
|
## url_prefix = 'http://www.edmontonjournal.com'
|
||||||
|
## description = u'News from Edmonton, AB'
|
||||||
|
## std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
## logo_url = 'ejlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
|
## title = u'Ottawa Citizen'
|
||||||
|
## url_prefix = 'http://www.ottawacitizen.com'
|
||||||
|
## description = u'News from Ottawa, ON'
|
||||||
|
## std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
## logo_url = 'oclogo.jpg'
|
||||||
|
## fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
|
## title = u'Montreal Gazette'
|
||||||
|
## url_prefix = 'http://www.montrealgazette.com'
|
||||||
|
## description = u'News from Montreal, QC'
|
||||||
|
## std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
|
## logo_url = 'mglogo.jpg'
|
||||||
|
## fp_tag = 'CAN_MG'
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
|
language = 'en_CA'
|
||||||
|
__author__ = 'Nick Redding'
|
||||||
|
no_stylesheets = True
|
||||||
|
timefmt = ' [%b %d]'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
extra_css = '''
|
||||||
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
|
#storyheader { font-size: medium; }
|
||||||
|
#storyheader h1 { font-size: x-large; }
|
||||||
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
|
.byline { font-size:xx-small; }
|
||||||
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
|
remove_tags = [{'class':'comments'},
|
||||||
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
from datetime import timedelta, date
|
||||||
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
daysback=1
|
||||||
|
try:
|
||||||
|
br.open(cover)
|
||||||
|
except:
|
||||||
|
while daysback<7:
|
||||||
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str((date.today() - timedelta(days=daysback)).day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
try:
|
||||||
|
br.open(cover)
|
||||||
|
except:
|
||||||
|
daysback = daysback+1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
if daysback==7:
|
||||||
|
self.log("\nCover unavailable")
|
||||||
|
cover = None
|
||||||
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
|
def fixChars(self,string):
|
||||||
|
# Replace lsquo (\x91)
|
||||||
|
fixed = re.sub("\x91","‘",string)
|
||||||
|
# Replace rsquo (\x92)
|
||||||
|
fixed = re.sub("\x92","’",fixed)
|
||||||
|
# Replace ldquo (\x93)
|
||||||
|
fixed = re.sub("\x93","“",fixed)
|
||||||
|
# Replace rdquo (\x94)
|
||||||
|
fixed = re.sub("\x94","”",fixed)
|
||||||
|
# Replace ndash (\x96)
|
||||||
|
fixed = re.sub("\x96","–",fixed)
|
||||||
|
# Replace mdash (\x97)
|
||||||
|
fixed = re.sub("\x97","—",fixed)
|
||||||
|
fixed = re.sub("’","’",fixed)
|
||||||
|
return fixed
|
||||||
|
|
||||||
|
def massageNCXText(self, description):
|
||||||
|
# Kindle TOC descriptions won't render certain characters
|
||||||
|
if description:
|
||||||
|
massaged = unicode(BeautifulStoneSoup(description, convertEntities=BeautifulStoneSoup.HTML_ENTITIES))
|
||||||
|
# Replace '&' with '&'
|
||||||
|
massaged = re.sub("&","&", massaged)
|
||||||
|
return self.fixChars(massaged)
|
||||||
|
else:
|
||||||
|
return description
|
||||||
|
|
||||||
|
def populate_article_metadata(self, article, soup, first):
|
||||||
|
if first:
|
||||||
|
picdiv = soup.find('body').find('img')
|
||||||
|
if picdiv is not None:
|
||||||
|
self.add_toc_thumbnail(article,re.sub(r'links\\link\d+\\','',picdiv['src']))
|
||||||
|
xtitle = article.text_summary.strip()
|
||||||
|
if len(xtitle) == 0:
|
||||||
|
desc = soup.find('meta',attrs={'property':'og:description'})
|
||||||
|
if desc is not None:
|
||||||
|
article.summary = article.text_summary = desc['content']
|
||||||
|
|
||||||
|
def strip_anchors(self,soup):
|
||||||
|
paras = soup.findAll(True)
|
||||||
|
for para in paras:
|
||||||
|
aTags = para.findAll('a')
|
||||||
|
for a in aTags:
|
||||||
|
if a.img is None:
|
||||||
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
|
return soup
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
|
if divtags:
|
||||||
|
for div in divtags:
|
||||||
|
del(div['id'])
|
||||||
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
|
||||||
|
articles = {}
|
||||||
|
ans = []
|
||||||
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
|
return ans
|
||||||
|
|
||||||
|
79
recipes/chronicle_higher_ed.recipe
Normal file
79
recipes/chronicle_higher_ed.recipe
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
class Chronicle(BasicNewsRecipe):
|
||||||
|
|
||||||
|
title = 'The Chronicle of Higher Education'
|
||||||
|
__author__ = 'Rick Shang'
|
||||||
|
|
||||||
|
description = 'Weekly news and job-information source for college and university faculty members, administrators, and students.'
|
||||||
|
language = 'en'
|
||||||
|
category = 'news'
|
||||||
|
encoding = 'UTF-8'
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'article'}),
|
||||||
|
]
|
||||||
|
remove_tags = [dict(name='div',attrs={'class':'related module1'})]
|
||||||
|
no_javascript = True
|
||||||
|
no_stylesheets = True
|
||||||
|
|
||||||
|
|
||||||
|
needs_subscription = True
|
||||||
|
|
||||||
|
def get_browser(self):
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
if self.username is not None and self.password is not None:
|
||||||
|
br.open('http://chronicle.com/myaccount/login')
|
||||||
|
br.select_form(nr=1)
|
||||||
|
br['username'] = self.username
|
||||||
|
br['password'] = self.password
|
||||||
|
br.submit()
|
||||||
|
return br
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
|
||||||
|
#Go to the issue
|
||||||
|
soup0 = self.index_to_soup('http://chronicle.com/section/Archives/39/')
|
||||||
|
issue = soup0.find('ul',attrs={'class':'feature-promo-list'}).li
|
||||||
|
issueurl = "http://chronicle.com"+issue.a['href']
|
||||||
|
|
||||||
|
#Find date
|
||||||
|
dates = self.tag_to_string(issue.a).split(': ')[-1]
|
||||||
|
self.timefmt = u' [%s]'%dates
|
||||||
|
|
||||||
|
#Find cover
|
||||||
|
cover=soup0.find('div',attrs={'class':'promo'}).findNext('div')
|
||||||
|
self.cover_url="http://chronicle.com"+cover.find('img')['src']
|
||||||
|
|
||||||
|
#Go to the main body
|
||||||
|
soup = self.index_to_soup(issueurl)
|
||||||
|
div0 = soup.find ('div', attrs={'id':'article-body'})
|
||||||
|
|
||||||
|
feeds = OrderedDict()
|
||||||
|
for div in div0.findAll('div',attrs={'class':'module1'}):
|
||||||
|
section_title = self.tag_to_string(div.find('h3'))
|
||||||
|
for post in div.findAll('li',attrs={'class':'sub-promo'}):
|
||||||
|
articles = []
|
||||||
|
a=post.find('a', href=True)
|
||||||
|
title=self.tag_to_string(a)
|
||||||
|
url="http://chronicle.com"+a['href'].strip()
|
||||||
|
desc=self.tag_to_string(post.find('p'))
|
||||||
|
articles.append({'title':title, 'url':url, 'description':desc, 'date':''})
|
||||||
|
|
||||||
|
if articles:
|
||||||
|
if section_title not in feeds:
|
||||||
|
feeds[section_title] = []
|
||||||
|
feeds[section_title] += articles
|
||||||
|
ans = [(key, val) for key, val in feeds.iteritems()]
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#process all the images
|
||||||
|
for div in soup.findAll('div', attrs={'class':'tableauPlaceholder'}):
|
||||||
|
|
||||||
|
noscripts=div.find('noscript').a
|
||||||
|
div.replaceWith(noscripts)
|
||||||
|
for div0 in soup.findAll('div',text='Powered by Tableau'):
|
||||||
|
div0.extract()
|
||||||
|
return soup
|
||||||
|
|
58
recipes/ciperchile.recipe
Normal file
58
recipes/ciperchile.recipe
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
ciperchile.cl
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class CiperChile(BasicNewsRecipe):
|
||||||
|
title = 'CIPER Chile'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'El Centro de Investigacion e Informacion Periodistica (CIPER) es una institucion independiente que desarrolla reportajes de investigacion de acuerdo a principios de maxima calidad e integridad profesional. Para lograr dicho objetivo, los profesionales de CIPER incorporan a las tecnicas propias del reporteo el uso sistematico de las leyes chilenas que norman el libre acceso a la informacion, de manera que los documentos que se obtengan por esta via esten puestos a disposicion del publico sin restricciones.'
|
||||||
|
publisher = 'CIPER'
|
||||||
|
category = 'news, politics, Chile'
|
||||||
|
oldest_article = 15
|
||||||
|
max_articles_per_feed = 200
|
||||||
|
no_stylesheets = True
|
||||||
|
encoding = 'utf8'
|
||||||
|
use_embedded_content = False
|
||||||
|
language = 'es_CL'
|
||||||
|
auto_cleanup = False
|
||||||
|
remove_empty_feeds = True
|
||||||
|
publication_type = 'blog'
|
||||||
|
masthead_url = 'http://ciperchile.cl/wp-content/themes/cipertheme/css/ui/ciper-logo.png'
|
||||||
|
extra_css = """
|
||||||
|
body{font-family: Arial,sans-serif}
|
||||||
|
.excerpt{font-family: Georgia,"Times New Roman",Times,serif; font-style: italic; font-size: 1.25em}
|
||||||
|
.author{font-family: Georgia,"Times New Roman",Times,serif; font-style: italic; font-size: small}
|
||||||
|
.date{font-family: Georgia,"Times New Roman",Times,serif; font-size: small; color: grey}
|
||||||
|
.epigrafe{font-size: small; color: grey}
|
||||||
|
img{margin-bottom: 0.4em; display:block}
|
||||||
|
"""
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name=['meta','link']),
|
||||||
|
dict(attrs={'class':['articleSharingTools','articleNav']})
|
||||||
|
]
|
||||||
|
remove_attributes=['lang']
|
||||||
|
remove_tags_before=dict(name='p', attrs={'class':'epigrafe'})
|
||||||
|
remove_tags_after=dict(name='div', attrs={'class':'articleBody'})
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'class':'articleElements'})]
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Opinion del lector', u'http://ciperchile.cl/category/opinion-del-lector/feed/')
|
||||||
|
,(u'Reportajes de investigacion', u'http://ciperchile.cl/category/reportajes-de-investigacion/feed/')
|
||||||
|
,(u'Actualidad y Entrevistas', u'http://ciperchile.cl/category/actualidad-y-entrevistas/feed/')
|
||||||
|
,(u'Opinion', u'http://ciperchile.cl/category/opinion/feed/')
|
||||||
|
,(u'Accesso a la informacion', u'http://ciperchile.cl/category/acceso-a-la-informacion/feed/')
|
||||||
|
,(u'Libros', u'http://ciperchile.cl/category/libros/feed/')
|
||||||
|
,(u'Blog', u'http://ciperchile.cl/category/blog/feed/')
|
||||||
|
]
|
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.codinghorror.com/blog/
|
www.codinghorror.com/blog/
|
||||||
'''
|
'''
|
||||||
@ -14,28 +12,25 @@ class CodingHorror(BasicNewsRecipe):
|
|||||||
description = 'programming and human factors - Jeff Atwood'
|
description = 'programming and human factors - Jeff Atwood'
|
||||||
category = 'blog, programming'
|
category = 'blog, programming'
|
||||||
publisher = 'Jeff Atwood'
|
publisher = 'Jeff Atwood'
|
||||||
language = 'en'
|
language = 'en'
|
||||||
|
|
||||||
author = 'Jeff Atwood'
|
|
||||||
oldest_article = 30
|
oldest_article = 30
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = True
|
use_embedded_content = True
|
||||||
encoding = 'cp1252'
|
encoding = 'utf8'
|
||||||
|
auto_cleanup = True
|
||||||
|
|
||||||
html2lrf_options = [
|
conversion_options = {
|
||||||
'--comment' , description
|
'comment' : description
|
||||||
, '--category' , category
|
, 'tags' : category
|
||||||
, '--publisher', publisher
|
, 'publisher': publisher
|
||||||
, '--author' , author
|
, 'language' : language
|
||||||
]
|
, 'authors' : publisher
|
||||||
|
}
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nauthors="' + author + '"'
|
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name=['object','link'])
|
dict(name=['object','link'])
|
||||||
,dict(name='div',attrs={'class':'feedflare'})
|
,dict(name='div',attrs={'class':'feedflare'})
|
||||||
]
|
]
|
||||||
|
|
||||||
feeds = [(u'Articles', u'http://feeds2.feedburner.com/codinghorror' )]
|
feeds = [(u'Articles', u'http://feeds2.feedburner.com/codinghorror' )]
|
||||||
|
|
59
recipes/cumhuriyet.recipe
Normal file
59
recipes/cumhuriyet.recipe
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# based on a recipe by Darko Miletic
|
||||||
|
#
|
||||||
|
# Cumhuriyet Gazetesi'nin köşe yazıları okuyuculara cumhuriyet.com.tr
|
||||||
|
# adresi üzerinden ücretsiz olarak sunulmaktadır.
|
||||||
|
# Calibre yazılımıyla kullanılabilen bu reçete Cumhuriyet Gazetesi'nin
|
||||||
|
# günlük köşe yazılarını hızlıca derleyip e-okuyucunuzda kolayca okunabilir
|
||||||
|
# hale getirir. Yazıların yayınlanma saati sabah olduğu için reçeteyi
|
||||||
|
# 7:00-24:00 arasında çizelgelemeniz gerekmektedir.
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2012, Sethi Eksi <sethi.eksi at gmail.com>'
|
||||||
|
'''
|
||||||
|
cumhuriyet.com.tr
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Cumhuriyet_tr(BasicNewsRecipe):
|
||||||
|
title = 'Cumhuriyet - Yazarlar'
|
||||||
|
__author__ = 'Cumhuriyet Gazetesi Yazarları'
|
||||||
|
description = 'Günlük Cumhuriyet Gazetesi Köşe Yazıları'
|
||||||
|
publisher = 'Cumhuriyet'
|
||||||
|
category = 'news, politics, Turkey'
|
||||||
|
oldest_article = 1
|
||||||
|
max_articles_per_feed = 150
|
||||||
|
no_stylesheets = True
|
||||||
|
encoding = 'cp1254'
|
||||||
|
use_embedded_content = False
|
||||||
|
masthead_url = 'http://www.cumhuriyet.com.tr/home/cumhuriyet/sablon2000/img/cumlogobeyaz1.gif'
|
||||||
|
language = 'tr'
|
||||||
|
extra_css = """ @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||||
|
.article_description,body{font-family: Arial,Verdana,Helvetica,sans1,sans-serif}
|
||||||
|
"""
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_tags = [dict(name=['embed','iframe','object','link','base'])]
|
||||||
|
remove_tags_before = dict(attrs={'class':'c565'})
|
||||||
|
remove_tags_after = dict(attrs={'class':'c565'})
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Yazarlar' , u'http://www.cumhuriyet.com.tr/?kn=5&xl=rss')
|
||||||
|
]
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
articleid = url.rpartition('hn=')[2]
|
||||||
|
return 'http://www.cumhuriyet.com.tr/?hn=' + articleid
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
return self.adeify_images(soup)
|
||||||
|
|
@ -1,105 +1,136 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
www.canada.com
|
www.canada.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup
|
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
class CanWestPaper(BasicNewsRecipe):
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
|
|
||||||
# un-comment the following four lines for the Victoria Times Colonist
|
postmedia_index_pages = [
|
||||||
## title = u'Victoria Times Colonist'
|
(u'Headlines',u'/index.html'),
|
||||||
## url_prefix = 'http://www.timescolonist.com'
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
## description = u'News from Victoria, BC'
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
## fp_tag = 'CAN_TC'
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
|
(u'National',u'/news/national/index.html'),
|
||||||
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Province
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
## title = u'Vancouver Province'
|
## title = u'Vancouver Province'
|
||||||
## url_prefix = 'http://www.theprovince.com'
|
## url_prefix = 'http://www.theprovince.com'
|
||||||
## description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
## fp_tag = 'CAN_VP'
|
## std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
## logo_url = 'vplogo.jpg'
|
||||||
|
## fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Sun
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
## title = u'Vancouver Sun'
|
## title = u'Vancouver Sun'
|
||||||
## url_prefix = 'http://www.vancouversun.com'
|
## url_prefix = 'http://www.vancouversun.com'
|
||||||
## description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
## logo_url = 'vslogo.jpg'
|
||||||
## fp_tag = 'CAN_VS'
|
## fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
# un-comment the following four lines for the Edmonton Journal
|
# un-comment the following six lines for the Calgary Herald
|
||||||
title = u'Edmonton Journal'
|
|
||||||
url_prefix = 'http://www.edmontonjournal.com'
|
|
||||||
description = u'News from Edmonton, AB'
|
|
||||||
fp_tag = 'CAN_EJ'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Calgary Herald
|
|
||||||
## title = u'Calgary Herald'
|
## title = u'Calgary Herald'
|
||||||
## url_prefix = 'http://www.calgaryherald.com'
|
## url_prefix = 'http://www.calgaryherald.com'
|
||||||
## description = u'News from Calgary, AB'
|
## description = u'News from Calgary, AB'
|
||||||
|
## std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
## logo_url = 'chlogo.jpg'
|
||||||
## fp_tag = 'CAN_CH'
|
## fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
# un-comment the following four lines for the Regina Leader-Post
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
## title = u'Regina Leader-Post'
|
title = u'Edmonton Journal'
|
||||||
## url_prefix = 'http://www.leaderpost.com'
|
url_prefix = 'http://www.edmontonjournal.com'
|
||||||
## description = u'News from Regina, SK'
|
description = u'News from Edmonton, AB'
|
||||||
## fp_tag = ''
|
std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
logo_url = 'ejlogo.jpg'
|
||||||
|
fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
# un-comment the following four lines for the Saskatoon Star-Phoenix
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
## title = u'Saskatoon Star-Phoenix'
|
|
||||||
## url_prefix = 'http://www.thestarphoenix.com'
|
|
||||||
## description = u'News from Saskatoon, SK'
|
|
||||||
## fp_tag = ''
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Windsor Star
|
|
||||||
## title = u'Windsor Star'
|
|
||||||
## url_prefix = 'http://www.windsorstar.com'
|
|
||||||
## description = u'News from Windsor, ON'
|
|
||||||
## fp_tag = 'CAN_'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Ottawa Citizen
|
|
||||||
## title = u'Ottawa Citizen'
|
## title = u'Ottawa Citizen'
|
||||||
## url_prefix = 'http://www.ottawacitizen.com'
|
## url_prefix = 'http://www.ottawacitizen.com'
|
||||||
## description = u'News from Ottawa, ON'
|
## description = u'News from Ottawa, ON'
|
||||||
|
## std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
## logo_url = 'oclogo.jpg'
|
||||||
## fp_tag = 'CAN_OC'
|
## fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
# un-comment the following four lines for the Montreal Gazette
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
## title = u'Montreal Gazette'
|
## title = u'Montreal Gazette'
|
||||||
## url_prefix = 'http://www.montrealgazette.com'
|
## url_prefix = 'http://www.montrealgazette.com'
|
||||||
## description = u'News from Montreal, QC'
|
## description = u'News from Montreal, QC'
|
||||||
|
## std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
|
## logo_url = 'mglogo.jpg'
|
||||||
## fp_tag = 'CAN_MG'
|
## fp_tag = 'CAN_MG'
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
language = 'en_CA'
|
language = 'en_CA'
|
||||||
__author__ = 'Nick Redding'
|
__author__ = 'Nick Redding'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
timefmt = ' [%b %d]'
|
timefmt = ' [%b %d]'
|
||||||
|
encoding = 'utf-8'
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
.timestamp { font-size:xx-small; display: block; }
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
#storyheader { font-size: medium; }
|
#storyheader { font-size: medium; }
|
||||||
#storyheader h1 { font-size: x-large; }
|
#storyheader h1 { font-size: x-large; }
|
||||||
#storyheader h2 { font-size: large; font-style: italic; }
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
.byline { font-size:xx-small; }
|
.byline { font-size:xx-small; }
|
||||||
#photocaption { font-size: small; font-style: italic }
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
#photocredit { font-size: xx-small; }'''
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'})]
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
remove_tags = [{'class':'comments'},
|
remove_tags = [{'class':'comments'},
|
||||||
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
def get_cover_url(self):
|
def get_cover_url(self):
|
||||||
from datetime import timedelta, date
|
from datetime import timedelta, date
|
||||||
if self.fp_tag=='':
|
|
||||||
return None
|
|
||||||
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
daysback=1
|
daysback=1
|
||||||
@ -120,6 +151,18 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
cover = None
|
cover = None
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
def fixChars(self,string):
|
def fixChars(self,string):
|
||||||
# Replace lsquo (\x91)
|
# Replace lsquo (\x91)
|
||||||
fixed = re.sub("\x91","‘",string)
|
fixed = re.sub("\x91","‘",string)
|
||||||
@ -166,55 +209,106 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
|
if divtags:
|
||||||
|
for div in divtags:
|
||||||
|
del(div['id'])
|
||||||
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
return self.strip_anchors(soup)
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
soup = self.index_to_soup(self.url_prefix+'/news/todays-paper/index.html')
|
|
||||||
|
|
||||||
articles = {}
|
articles = {}
|
||||||
key = 'News'
|
ans = []
|
||||||
ans = ['News']
|
|
||||||
|
|
||||||
# Find each instance of class="sectiontitle", class="featurecontent"
|
|
||||||
for divtag in soup.findAll('div',attrs={'class' : ["section_title02","featurecontent"]}):
|
|
||||||
#self.log(" div class = %s" % divtag['class'])
|
|
||||||
if divtag['class'].startswith('section_title'):
|
|
||||||
# div contains section title
|
|
||||||
if not divtag.h3:
|
|
||||||
continue
|
|
||||||
key = self.tag_to_string(divtag.h3,False)
|
|
||||||
ans.append(key)
|
|
||||||
self.log("Section name %s" % key)
|
|
||||||
continue
|
|
||||||
# div contains article data
|
|
||||||
h1tag = divtag.find('h1')
|
|
||||||
if not h1tag:
|
|
||||||
continue
|
|
||||||
atag = h1tag.find('a',href=True)
|
|
||||||
if not atag:
|
|
||||||
continue
|
|
||||||
url = self.url_prefix+'/news/todays-paper/'+atag['href']
|
|
||||||
#self.log("Section %s" % key)
|
|
||||||
#self.log("url %s" % url)
|
|
||||||
title = self.tag_to_string(atag,False)
|
|
||||||
#self.log("title %s" % title)
|
|
||||||
pubdate = ''
|
|
||||||
description = ''
|
|
||||||
ptag = divtag.find('p');
|
|
||||||
if ptag:
|
|
||||||
description = self.tag_to_string(ptag,False)
|
|
||||||
#self.log("description %s" % description)
|
|
||||||
author = ''
|
|
||||||
autag = divtag.find('h4')
|
|
||||||
if autag:
|
|
||||||
author = self.tag_to_string(autag,False)
|
|
||||||
#self.log("author %s" % author)
|
|
||||||
if not articles.has_key(key):
|
|
||||||
articles[key] = []
|
|
||||||
articles[key].append(dict(title=title,url=url,date=pubdate,description=description,author=author,content=''))
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
BIN
recipes/icons/ciperchile.png
Normal file
BIN
recipes/icons/ciperchile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -9,7 +9,7 @@ from calibre.web.feeds.recipes import BasicNewsRecipe
|
|||||||
class LeMonde(BasicNewsRecipe):
|
class LeMonde(BasicNewsRecipe):
|
||||||
title = 'Le Monde'
|
title = 'Le Monde'
|
||||||
__author__ = 'veezh'
|
__author__ = 'veezh'
|
||||||
description = 'Actualités'
|
description = u'Actualités'
|
||||||
oldest_article = 1
|
oldest_article = 1
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
132
recipes/le_monde_sub.recipe
Normal file
132
recipes/le_monde_sub.recipe
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2012, Rémi Vanicat <vanicat at debian.org>'
|
||||||
|
'''
|
||||||
|
Lemonde.fr: Version abonnée
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
import os, zipfile, re, time
|
||||||
|
|
||||||
|
from calibre import strftime
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
|
|
||||||
|
class LeMondeAbonne(BasicNewsRecipe):
|
||||||
|
|
||||||
|
title = u'Le Monde: Édition abonnés'
|
||||||
|
__author__ = u'Rémi Vanicat'
|
||||||
|
description = u'Actualités'
|
||||||
|
category = u'Actualités, France, Monde'
|
||||||
|
language = 'fr'
|
||||||
|
needs_subscription = True
|
||||||
|
|
||||||
|
no_stylesheets = True
|
||||||
|
|
||||||
|
extra_css = u'''
|
||||||
|
h1{font-size:130%;}
|
||||||
|
.ariane{font-size:xx-small;}
|
||||||
|
.source{font-size:xx-small;}
|
||||||
|
.href{font-size:xx-small;}
|
||||||
|
.LM_caption{color:#666666; font-size:x-small;}
|
||||||
|
.main-article-info{font-family:Arial,Helvetica,sans-serif;}
|
||||||
|
#full-contents{font-size:small; font-family:Arial,Helvetica,sans-serif;font-weight:normal;}
|
||||||
|
#match-stats-summary{font-size:small; font-family:Arial,Helvetica,sans-serif;font-weight:normal;}
|
||||||
|
'''
|
||||||
|
|
||||||
|
zipurl_format = 'http://medias.lemonde.fr/abonnes/editionelectronique/%Y%m%d/html/%y%m%d.zip'
|
||||||
|
coverurl_format = '/img/%y%m%d01.jpg'
|
||||||
|
path_format = "%y%m%d"
|
||||||
|
login_url = 'http://www.lemonde.fr/web/journal_electronique/identification/1,56-0,45-0,0.html'
|
||||||
|
|
||||||
|
keep_only_tags = [ dict(name="div", attrs={ 'class': 'po-prti' }), dict(name=['h1']), dict(name='div', attrs={ 'class': 'photo' }), dict(name='div', attrs={ 'class': 'po-ti2' }), dict(name='div', attrs={ 'class': 'ar-txt' }), dict(name='div', attrs={ 'class': 'po_rtcol' }) ]
|
||||||
|
|
||||||
|
article_id_pattern = re.compile("[0-9]+\\.html")
|
||||||
|
article_url_format = 'http://www.lemonde.fr/journalelectronique/donnees/protege/%Y%m%d/html/'
|
||||||
|
|
||||||
|
def get_browser(self):
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
if self.username is not None and self.password is not None:
|
||||||
|
br.open(self.login_url)
|
||||||
|
br.select_form(nr=0)
|
||||||
|
br['login'] = self.username
|
||||||
|
br['password'] = self.password
|
||||||
|
br.submit()
|
||||||
|
return br
|
||||||
|
|
||||||
|
decalage = 24 * 60 * 60 # today Monde has tomorow date
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
url = time.strftime(self.coverurl_format, self.ltime)
|
||||||
|
return self.articles_path + url
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
browser = self.get_browser()
|
||||||
|
|
||||||
|
second = time.time()
|
||||||
|
second += self.decalage
|
||||||
|
ltime = self.ltime = time.gmtime(second)
|
||||||
|
url = time.strftime(self.zipurl_format, ltime)
|
||||||
|
|
||||||
|
self.timefmt=strftime(" %A %d %B %Y", ltime)
|
||||||
|
|
||||||
|
response = browser.open(url)
|
||||||
|
|
||||||
|
tmp = PersistentTemporaryFile(suffix='.zip')
|
||||||
|
self.report_progress(0.1,_('downloading zip file'))
|
||||||
|
tmp.write(response.read())
|
||||||
|
tmp.close()
|
||||||
|
|
||||||
|
zfile = zipfile.ZipFile(tmp.name, 'r')
|
||||||
|
self.report_progress(0.1,_('extracting zip file'))
|
||||||
|
|
||||||
|
zfile.extractall(self.output_dir)
|
||||||
|
zfile.close()
|
||||||
|
|
||||||
|
path = os.path.join(self.output_dir, time.strftime(self.path_format, ltime), "data")
|
||||||
|
|
||||||
|
self.articles_path = path
|
||||||
|
|
||||||
|
files = os.listdir(path)
|
||||||
|
|
||||||
|
nb_index_files = len([ name for name in files if re.match("frame_gauche_[0-9]+.html", name) ])
|
||||||
|
|
||||||
|
flux = []
|
||||||
|
|
||||||
|
article_url = time.strftime(self.article_url_format, ltime)
|
||||||
|
|
||||||
|
for i in range(nb_index_files):
|
||||||
|
filename = os.path.join(path, "selection_%d.html" % (i + 1))
|
||||||
|
tmp = open(filename,'r')
|
||||||
|
soup=BeautifulSoup(tmp)
|
||||||
|
title=soup.find('span').contents[0]
|
||||||
|
tmp.close()
|
||||||
|
|
||||||
|
filename = os.path.join(path, "frame_gauche_%d.html" % (i + 1))
|
||||||
|
tmp = open(filename,'r')
|
||||||
|
soup = BeautifulSoup(tmp)
|
||||||
|
articles = []
|
||||||
|
for link in soup.findAll("a"):
|
||||||
|
article_file = link['href']
|
||||||
|
article_id=self.article_id_pattern.search(article_file).group()
|
||||||
|
article = {
|
||||||
|
'title': link.contents[0],
|
||||||
|
'url': article_url + article_id,
|
||||||
|
'descripion': '',
|
||||||
|
'content': ''
|
||||||
|
}
|
||||||
|
articles.append(article)
|
||||||
|
tmp.close()
|
||||||
|
|
||||||
|
flux.append((title, articles))
|
||||||
|
|
||||||
|
return flux
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: python
|
||||||
|
# End:
|
||||||
|
|
@ -1,48 +1,314 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
www.canada.com
|
www.canada.com
|
||||||
'''
|
'''
|
||||||
|
import re
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
class CanWestPaper(BasicNewsRecipe):
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
|
|
||||||
# un-comment the following three lines for the Montreal Gazette
|
postmedia_index_pages = [
|
||||||
|
(u'Headlines',u'/index.html'),
|
||||||
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
|
(u'National',u'/news/national/index.html'),
|
||||||
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
|
## title = u'Vancouver Province'
|
||||||
|
## url_prefix = 'http://www.theprovince.com'
|
||||||
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
## logo_url = 'vplogo.jpg'
|
||||||
|
## fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
|
## title = u'Vancouver Sun'
|
||||||
|
## url_prefix = 'http://www.vancouversun.com'
|
||||||
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
## logo_url = 'vslogo.jpg'
|
||||||
|
## fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Calgary Herald
|
||||||
|
## title = u'Calgary Herald'
|
||||||
|
## url_prefix = 'http://www.calgaryherald.com'
|
||||||
|
## description = u'News from Calgary, AB'
|
||||||
|
## std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
## logo_url = 'chlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
|
## title = u'Edmonton Journal'
|
||||||
|
## url_prefix = 'http://www.edmontonjournal.com'
|
||||||
|
## description = u'News from Edmonton, AB'
|
||||||
|
## std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
## logo_url = 'ejlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
|
## title = u'Ottawa Citizen'
|
||||||
|
## url_prefix = 'http://www.ottawacitizen.com'
|
||||||
|
## description = u'News from Ottawa, ON'
|
||||||
|
## std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
## logo_url = 'oclogo.jpg'
|
||||||
|
## fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
title = u'Montreal Gazette'
|
title = u'Montreal Gazette'
|
||||||
|
url_prefix = 'http://www.montrealgazette.com'
|
||||||
description = u'News from Montreal, QC'
|
description = u'News from Montreal, QC'
|
||||||
|
std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
|
logo_url = 'mglogo.jpg'
|
||||||
|
fp_tag = 'CAN_MG'
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
language = 'en_CA'
|
language = 'en_CA'
|
||||||
__author__ = 'Nick Redding'
|
__author__ = 'Nick Redding'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
auto_cleanup = True
|
timefmt = ' [%b %d]'
|
||||||
auto_cleanup_keep = '//*[@id="imageBox"]'
|
encoding = 'utf-8'
|
||||||
timefmt = ' [%b %d]'
|
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
.timestamp { font-size:xx-small; display: block; }
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
#storyheader { font-size: medium; }
|
#storyheader { font-size: medium; }
|
||||||
#storyheader h1 { font-size: x-large; }
|
#storyheader h1 { font-size: x-large; }
|
||||||
#storyheader h2 { font-size: large; font-style: italic; }
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
.byline { font-size:xx-small; }
|
.byline { font-size:xx-small; }
|
||||||
#photocaption { font-size: small; font-style: italic }
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
#photocredit { font-size: xx-small; }'''
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
|
remove_tags = [{'class':'comments'},
|
||||||
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
feeds = [
|
def get_cover_url(self):
|
||||||
('News',
|
from datetime import timedelta, date
|
||||||
'http://rss.canada.com/get/?F297'),
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
('Sports',
|
br = BasicNewsRecipe.get_browser()
|
||||||
'http://rss.canada.com/get/?F299'),
|
daysback=1
|
||||||
('Entertainment',
|
try:
|
||||||
'http://rss.canada.com/get/?F7366'),
|
br.open(cover)
|
||||||
('Business',
|
except:
|
||||||
'http://rss.canada.com/get/?F6939'),
|
while daysback<7:
|
||||||
]
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str((date.today() - timedelta(days=daysback)).day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
try:
|
||||||
|
br.open(cover)
|
||||||
|
except:
|
||||||
|
daysback = daysback+1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
if daysback==7:
|
||||||
|
self.log("\nCover unavailable")
|
||||||
|
cover = None
|
||||||
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
|
def fixChars(self,string):
|
||||||
|
# Replace lsquo (\x91)
|
||||||
|
fixed = re.sub("\x91","‘",string)
|
||||||
|
# Replace rsquo (\x92)
|
||||||
|
fixed = re.sub("\x92","’",fixed)
|
||||||
|
# Replace ldquo (\x93)
|
||||||
|
fixed = re.sub("\x93","“",fixed)
|
||||||
|
# Replace rdquo (\x94)
|
||||||
|
fixed = re.sub("\x94","”",fixed)
|
||||||
|
# Replace ndash (\x96)
|
||||||
|
fixed = re.sub("\x96","–",fixed)
|
||||||
|
# Replace mdash (\x97)
|
||||||
|
fixed = re.sub("\x97","—",fixed)
|
||||||
|
fixed = re.sub("’","’",fixed)
|
||||||
|
return fixed
|
||||||
|
|
||||||
|
def massageNCXText(self, description):
|
||||||
|
# Kindle TOC descriptions won't render certain characters
|
||||||
|
if description:
|
||||||
|
massaged = unicode(BeautifulStoneSoup(description, convertEntities=BeautifulStoneSoup.HTML_ENTITIES))
|
||||||
|
# Replace '&' with '&'
|
||||||
|
massaged = re.sub("&","&", massaged)
|
||||||
|
return self.fixChars(massaged)
|
||||||
|
else:
|
||||||
|
return description
|
||||||
|
|
||||||
|
def populate_article_metadata(self, article, soup, first):
|
||||||
|
if first:
|
||||||
|
picdiv = soup.find('body').find('img')
|
||||||
|
if picdiv is not None:
|
||||||
|
self.add_toc_thumbnail(article,re.sub(r'links\\link\d+\\','',picdiv['src']))
|
||||||
|
xtitle = article.text_summary.strip()
|
||||||
|
if len(xtitle) == 0:
|
||||||
|
desc = soup.find('meta',attrs={'property':'og:description'})
|
||||||
|
if desc is not None:
|
||||||
|
article.summary = article.text_summary = desc['content']
|
||||||
|
|
||||||
|
def strip_anchors(self,soup):
|
||||||
|
paras = soup.findAll(True)
|
||||||
|
for para in paras:
|
||||||
|
aTags = para.findAll('a')
|
||||||
|
for a in aTags:
|
||||||
|
if a.img is None:
|
||||||
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
|
return soup
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
|
if divtags:
|
||||||
|
for div in divtags:
|
||||||
|
del(div['id'])
|
||||||
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
|
||||||
|
articles = {}
|
||||||
|
ans = []
|
||||||
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
|
return ans
|
||||||
|
|
||||||
|
@ -1,105 +1,136 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
www.canada.com
|
www.canada.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup
|
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
class CanWestPaper(BasicNewsRecipe):
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
|
|
||||||
# un-comment the following four lines for the Victoria Times Colonist
|
postmedia_index_pages = [
|
||||||
## title = u'Victoria Times Colonist'
|
(u'Headlines',u'/index.html'),
|
||||||
## url_prefix = 'http://www.timescolonist.com'
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
## description = u'News from Victoria, BC'
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
## fp_tag = 'CAN_TC'
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
|
(u'National',u'/news/national/index.html'),
|
||||||
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Province
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
## title = u'Vancouver Province'
|
## title = u'Vancouver Province'
|
||||||
## url_prefix = 'http://www.theprovince.com'
|
## url_prefix = 'http://www.theprovince.com'
|
||||||
## description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
## fp_tag = 'CAN_VP'
|
## std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
## logo_url = 'vplogo.jpg'
|
||||||
|
## fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Sun
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
## title = u'Vancouver Sun'
|
## title = u'Vancouver Sun'
|
||||||
## url_prefix = 'http://www.vancouversun.com'
|
## url_prefix = 'http://www.vancouversun.com'
|
||||||
## description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
## logo_url = 'vslogo.jpg'
|
||||||
## fp_tag = 'CAN_VS'
|
## fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
# un-comment the following four lines for the Edmonton Journal
|
# un-comment the following six lines for the Calgary Herald
|
||||||
## title = u'Edmonton Journal'
|
|
||||||
## url_prefix = 'http://www.edmontonjournal.com'
|
|
||||||
## description = u'News from Edmonton, AB'
|
|
||||||
## fp_tag = 'CAN_EJ'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Calgary Herald
|
|
||||||
## title = u'Calgary Herald'
|
## title = u'Calgary Herald'
|
||||||
## url_prefix = 'http://www.calgaryherald.com'
|
## url_prefix = 'http://www.calgaryherald.com'
|
||||||
## description = u'News from Calgary, AB'
|
## description = u'News from Calgary, AB'
|
||||||
|
## std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
## logo_url = 'chlogo.jpg'
|
||||||
## fp_tag = 'CAN_CH'
|
## fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
# un-comment the following four lines for the Regina Leader-Post
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
## title = u'Regina Leader-Post'
|
## title = u'Edmonton Journal'
|
||||||
## url_prefix = 'http://www.leaderpost.com'
|
## url_prefix = 'http://www.edmontonjournal.com'
|
||||||
## description = u'News from Regina, SK'
|
## description = u'News from Edmonton, AB'
|
||||||
## fp_tag = ''
|
## std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
## logo_url = 'ejlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
# un-comment the following four lines for the Saskatoon Star-Phoenix
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
## title = u'Saskatoon Star-Phoenix'
|
|
||||||
## url_prefix = 'http://www.thestarphoenix.com'
|
|
||||||
## description = u'News from Saskatoon, SK'
|
|
||||||
## fp_tag = ''
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Windsor Star
|
|
||||||
## title = u'Windsor Star'
|
|
||||||
## url_prefix = 'http://www.windsorstar.com'
|
|
||||||
## description = u'News from Windsor, ON'
|
|
||||||
## fp_tag = 'CAN_'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Ottawa Citizen
|
|
||||||
title = u'Ottawa Citizen'
|
title = u'Ottawa Citizen'
|
||||||
url_prefix = 'http://www.ottawacitizen.com'
|
url_prefix = 'http://www.ottawacitizen.com'
|
||||||
description = u'News from Ottawa, ON'
|
description = u'News from Ottawa, ON'
|
||||||
|
std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
logo_url = 'oclogo.jpg'
|
||||||
fp_tag = 'CAN_OC'
|
fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
# un-comment the following four lines for the Montreal Gazette
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
## title = u'Montreal Gazette'
|
## title = u'Montreal Gazette'
|
||||||
## url_prefix = 'http://www.montrealgazette.com'
|
## url_prefix = 'http://www.montrealgazette.com'
|
||||||
## description = u'News from Montreal, QC'
|
## description = u'News from Montreal, QC'
|
||||||
|
## std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
|
## logo_url = 'mglogo.jpg'
|
||||||
## fp_tag = 'CAN_MG'
|
## fp_tag = 'CAN_MG'
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
language = 'en_CA'
|
language = 'en_CA'
|
||||||
__author__ = 'Nick Redding'
|
__author__ = 'Nick Redding'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
timefmt = ' [%b %d]'
|
timefmt = ' [%b %d]'
|
||||||
|
encoding = 'utf-8'
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
.timestamp { font-size:xx-small; display: block; }
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
#storyheader { font-size: medium; }
|
#storyheader { font-size: medium; }
|
||||||
#storyheader h1 { font-size: x-large; }
|
#storyheader h1 { font-size: x-large; }
|
||||||
#storyheader h2 { font-size: large; font-style: italic; }
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
.byline { font-size:xx-small; }
|
.byline { font-size:xx-small; }
|
||||||
#photocaption { font-size: small; font-style: italic }
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
#photocredit { font-size: xx-small; }'''
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'})]
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
remove_tags = [{'class':'comments'},
|
remove_tags = [{'class':'comments'},
|
||||||
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
def get_cover_url(self):
|
def get_cover_url(self):
|
||||||
from datetime import timedelta, date
|
from datetime import timedelta, date
|
||||||
if self.fp_tag=='':
|
|
||||||
return None
|
|
||||||
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
daysback=1
|
daysback=1
|
||||||
@ -120,6 +151,18 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
cover = None
|
cover = None
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
def fixChars(self,string):
|
def fixChars(self,string):
|
||||||
# Replace lsquo (\x91)
|
# Replace lsquo (\x91)
|
||||||
fixed = re.sub("\x91","‘",string)
|
fixed = re.sub("\x91","‘",string)
|
||||||
@ -166,55 +209,106 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
|
if divtags:
|
||||||
|
for div in divtags:
|
||||||
|
del(div['id'])
|
||||||
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
return self.strip_anchors(soup)
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
soup = self.index_to_soup(self.url_prefix+'/news/todays-paper/index.html')
|
|
||||||
|
|
||||||
articles = {}
|
articles = {}
|
||||||
key = 'News'
|
ans = []
|
||||||
ans = ['News']
|
|
||||||
|
|
||||||
# Find each instance of class="sectiontitle", class="featurecontent"
|
|
||||||
for divtag in soup.findAll('div',attrs={'class' : ["section_title02","featurecontent"]}):
|
|
||||||
#self.log(" div class = %s" % divtag['class'])
|
|
||||||
if divtag['class'].startswith('section_title'):
|
|
||||||
# div contains section title
|
|
||||||
if not divtag.h3:
|
|
||||||
continue
|
|
||||||
key = self.tag_to_string(divtag.h3,False)
|
|
||||||
ans.append(key)
|
|
||||||
self.log("Section name %s" % key)
|
|
||||||
continue
|
|
||||||
# div contains article data
|
|
||||||
h1tag = divtag.find('h1')
|
|
||||||
if not h1tag:
|
|
||||||
continue
|
|
||||||
atag = h1tag.find('a',href=True)
|
|
||||||
if not atag:
|
|
||||||
continue
|
|
||||||
url = self.url_prefix+'/news/todays-paper/'+atag['href']
|
|
||||||
#self.log("Section %s" % key)
|
|
||||||
#self.log("url %s" % url)
|
|
||||||
title = self.tag_to_string(atag,False)
|
|
||||||
#self.log("title %s" % title)
|
|
||||||
pubdate = ''
|
|
||||||
description = ''
|
|
||||||
ptag = divtag.find('p');
|
|
||||||
if ptag:
|
|
||||||
description = self.tag_to_string(ptag,False)
|
|
||||||
#self.log("description %s" % description)
|
|
||||||
author = ''
|
|
||||||
autag = divtag.find('h4')
|
|
||||||
if autag:
|
|
||||||
author = self.tag_to_string(autag,False)
|
|
||||||
#self.log("author %s" % author)
|
|
||||||
if not articles.has_key(key):
|
|
||||||
articles[key] = []
|
|
||||||
articles[key].append(dict(title=title,url=url,date=pubdate,description=description,author=author,content=''))
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
@ -19,23 +19,12 @@ class Slashdot(BasicNewsRecipe):
|
|||||||
|
|
||||||
__author__ = 'floweros edited by Huan T'
|
__author__ = 'floweros edited by Huan T'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(name='div',attrs={'id':'article'}),
|
dict(name='div',attrs={'class':'story'}),
|
||||||
dict(name='div',attrs={'class':['postBody' 'details']}),
|
dict(name='div',attrs={'class':'body'}),
|
||||||
dict(name='footer',attrs={'class':['clearfix meta article-foot']}),
|
dict(name='ul',attrs={'id':'commentlisting'}),
|
||||||
dict(name='article',attrs={'class':['fhitem fhitem-story article usermode thumbs grid_24']}),
|
]
|
||||||
dict(name='dl',attrs={'class':'relatedPosts'}),
|
|
||||||
dict(name='h2',attrs={'class':'story'}),
|
|
||||||
dict(name='span',attrs={'class':'comments'}),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
remove_tags = [
|
|
||||||
dict(name='aside',attrs={'id':'slashboxes'}),
|
|
||||||
dict(name='div',attrs={'class':'paginate'}),
|
|
||||||
dict(name='section',attrs={'id':'comments'}),
|
|
||||||
dict(name='span',attrs={'class':'topic'}),
|
|
||||||
]
|
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Slashdot',
|
(u'Slashdot',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.thesundaytimes.co.uk
|
www.thesundaytimes.co.uk
|
||||||
'''
|
'''
|
||||||
@ -43,13 +43,14 @@ class TimesOnline(BasicNewsRecipe):
|
|||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
br.open('http://www.timesplus.co.uk/tto/news/?login=false&url=http://www.thesundaytimes.co.uk/sto/')
|
br.open('http://www.thesundaytimes.co.uk/sto/')
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and self.password is not None:
|
||||||
data = urllib.urlencode({ 'userName':self.username
|
data = urllib.urlencode({
|
||||||
|
'gotoUrl' :self.INDEX
|
||||||
|
,'username':self.username
|
||||||
,'password':self.password
|
,'password':self.password
|
||||||
,'keepMeLoggedIn':'false'
|
|
||||||
})
|
})
|
||||||
br.open('https://www.timesplus.co.uk/iam/app/authenticate',data)
|
br.open('https://acs.thetimes.co.uk/user/login',data)
|
||||||
return br
|
return br
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
time.com
|
time.com
|
||||||
'''
|
'''
|
||||||
@ -11,28 +12,23 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
from lxml import html
|
from lxml import html
|
||||||
|
|
||||||
class Time(BasicNewsRecipe):
|
class Time(BasicNewsRecipe):
|
||||||
#recipe_disabled = ('This recipe has been disabled as TIME no longer'
|
|
||||||
# ' publish complete articles on the web.')
|
|
||||||
title = u'Time'
|
title = u'Time'
|
||||||
__author__ = 'Kovid Goyal'
|
__author__ = 'Kovid Goyal, Rick Shang'
|
||||||
description = ('Weekly US magazine.')
|
description = ('Weekly US magazine.')
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
language = 'en'
|
language = 'en'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
#needs_subscription = 'optional'
|
needs_subscription = True
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
{
|
{
|
||||||
'class':['artHd', 'articleContent',
|
'class':['tout1', 'entry-content', 'external-gallery-img', 'image-meta']
|
||||||
'entry-title','entry-meta', 'entry-content', 'thumbnail']
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
{'class':['content-tools', 'quigo', 'see',
|
{'class':['thumbnail', 'button']},
|
||||||
'first-tier-social-tools', 'navigation', 'enlarge lightbox']},
|
|
||||||
{'id':['share-tools']},
|
|
||||||
{'rel':'lightbox'},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
recursions = 10
|
recursions = 10
|
||||||
@ -43,17 +39,25 @@ class Time(BasicNewsRecipe):
|
|||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser(self)
|
br = BasicNewsRecipe.get_browser(self)
|
||||||
if False and self.username and self.password:
|
# This site uses javascript in its login process
|
||||||
# This site uses javascript in its login process
|
if self.username is not None and self.password is not None:
|
||||||
res = br.open('http://www.time.com/time/magazine')
|
br.open('http://www.time.com/time/magazine')
|
||||||
br.select_form(nr=1)
|
br.select_form(predicate=lambda f: 'action' in f.attrs and f.attrs['action'] == 'https://auth.time.com/login.php')
|
||||||
br['username'] = self.username
|
br['username'] = self.username
|
||||||
br['password'] = self.password
|
br['password'] = self.password
|
||||||
res = br.submit()
|
br['magcode'] = ['TD']
|
||||||
raw = res.read()
|
br.find_control('turl').readonly = False
|
||||||
if '>Log Out<' not in raw:
|
br['turl'] = 'http://www.time.com/time/magazine'
|
||||||
|
br.find_control('rurl').readonly = False
|
||||||
|
br['rurl'] = 'http://www.time.com/time/magazine'
|
||||||
|
br['remember'] = False
|
||||||
|
raw = br.submit().read()
|
||||||
|
if False and '>Log Out<' not in raw:
|
||||||
|
# This check is disabled as it does not work (there is probably
|
||||||
|
# some cookie missing) however, the login is "sufficient" for
|
||||||
|
# the actual article downloads to work.
|
||||||
raise ValueError('Failed to login to time.com, check'
|
raise ValueError('Failed to login to time.com, check'
|
||||||
' your username and password')
|
' your username and password')
|
||||||
return br
|
return br
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
@ -70,6 +74,9 @@ class Time(BasicNewsRecipe):
|
|||||||
except:
|
except:
|
||||||
self.log.exception('Failed to fetch cover')
|
self.log.exception('Failed to fetch cover')
|
||||||
|
|
||||||
|
dates = ''.join(root.xpath('//time[@class="updated"]/text()'))
|
||||||
|
if dates:
|
||||||
|
self.timefmt = ' [%s]'%dates
|
||||||
|
|
||||||
feeds = []
|
feeds = []
|
||||||
parent = root.xpath('//div[@class="content-main-aside"]')[0]
|
parent = root.xpath('//div[@class="content-main-aside"]')[0]
|
||||||
@ -96,7 +103,8 @@ class Time(BasicNewsRecipe):
|
|||||||
title = html.tostring(a[0], encoding=unicode,
|
title = html.tostring(a[0], encoding=unicode,
|
||||||
method='text').strip()
|
method='text').strip()
|
||||||
if not title: continue
|
if not title: continue
|
||||||
url = a[0].get('href')
|
url = a[0].get('href')
|
||||||
|
url = re.sub('/magazine/article/0,9171','/subscriber/printout/0,8816', url)
|
||||||
if url.startswith('/'):
|
if url.startswith('/'):
|
||||||
url = 'http://www.time.com'+url
|
url = 'http://www.time.com'+url
|
||||||
desc = ''
|
desc = ''
|
||||||
@ -111,9 +119,3 @@ class Time(BasicNewsRecipe):
|
|||||||
'date' : '',
|
'date' : '',
|
||||||
'description' : desc
|
'description' : desc
|
||||||
}
|
}
|
||||||
|
|
||||||
def postprocess_html(self,soup,first):
|
|
||||||
for tag in soup.findAll(attrs ={'class':['artPag','pagination']}):
|
|
||||||
tag.extract()
|
|
||||||
return soup
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.thetimes.co.uk
|
www.thetimes.co.uk
|
||||||
'''
|
'''
|
||||||
@ -21,6 +21,7 @@ class TimesOnline(BasicNewsRecipe):
|
|||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
delay = 1
|
delay = 1
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
|
auto_cleanup = False
|
||||||
publication_type = 'newspaper'
|
publication_type = 'newspaper'
|
||||||
masthead_url = 'http://www.thetimes.co.uk/tto/public/img/the_times_460.gif'
|
masthead_url = 'http://www.thetimes.co.uk/tto/public/img/the_times_460.gif'
|
||||||
INDEX = 'http://www.thetimes.co.uk'
|
INDEX = 'http://www.thetimes.co.uk'
|
||||||
@ -41,13 +42,14 @@ class TimesOnline(BasicNewsRecipe):
|
|||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
br.open('http://www.timesplus.co.uk/tto/news/?login=false&url=http://www.thetimes.co.uk/tto/news/?lightbox=false')
|
br.open('http://www.thetimes.co.uk/tto/news/')
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and self.password is not None:
|
||||||
data = urllib.urlencode({ 'userName':self.username
|
data = urllib.urlencode({
|
||||||
|
'gotoUrl' :self.INDEX
|
||||||
|
,'username':self.username
|
||||||
,'password':self.password
|
,'password':self.password
|
||||||
,'keepMeLoggedIn':'false'
|
|
||||||
})
|
})
|
||||||
br.open('https://www.timesplus.co.uk/iam/app/authenticate',data)
|
br.open('https://acs.thetimes.co.uk/user/login',data)
|
||||||
return br
|
return br
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
@ -58,6 +60,7 @@ class TimesOnline(BasicNewsRecipe):
|
|||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(attrs={'class':'heading' })
|
dict(attrs={'class':'heading' })
|
||||||
,dict(attrs={'class':'f-author'})
|
,dict(attrs={'class':'f-author'})
|
||||||
|
,dict(attrs={'class':['media','byline-timestamp']})
|
||||||
,dict(attrs={'id':'bodycopy'})
|
,dict(attrs={'id':'bodycopy'})
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -79,11 +82,6 @@ class TimesOnline(BasicNewsRecipe):
|
|||||||
,(u'Arts' , PREFIX + u'arts/?view=list' )
|
,(u'Arts' , PREFIX + u'arts/?view=list' )
|
||||||
]
|
]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
|
||||||
for item in soup.findAll(style=True):
|
|
||||||
del item['style']
|
|
||||||
return self.adeify_images(soup)
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
totalfeeds = []
|
totalfeeds = []
|
||||||
lfeeds = self.get_feeds()
|
lfeeds = self.get_feeds()
|
||||||
|
@ -1,136 +1,314 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
www.canada.com
|
www.canada.com
|
||||||
'''
|
'''
|
||||||
|
import re
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
class CanWestPaper(BasicNewsRecipe):
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
|
|
||||||
# un-comment the following three lines for the Vancouver Province
|
postmedia_index_pages = [
|
||||||
|
(u'Headlines',u'/index.html'),
|
||||||
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
|
(u'National',u'/news/national/index.html'),
|
||||||
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
title = u'Vancouver Province'
|
title = u'Vancouver Province'
|
||||||
url_prefix = 'http://www.theprovince.com'
|
url_prefix = 'http://www.theprovince.com'
|
||||||
description = u'News from Vancouver, BC'
|
description = u'News from Vancouver, BC'
|
||||||
|
std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
logo_url = 'vplogo.jpg'
|
||||||
|
fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
# un-comment the following three lines for the Vancouver Sun
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
#title = u'Vancouver Sun'
|
## title = u'Vancouver Sun'
|
||||||
#url_prefix = 'http://www.vancouversun.com'
|
## url_prefix = 'http://www.vancouversun.com'
|
||||||
#description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
|
## std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
## logo_url = 'vslogo.jpg'
|
||||||
|
## fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
# un-comment the following three lines for the Edmonton Journal
|
# un-comment the following six lines for the Calgary Herald
|
||||||
#title = u'Edmonton Journal'
|
## title = u'Calgary Herald'
|
||||||
#url_prefix = 'http://www.edmontonjournal.com'
|
## url_prefix = 'http://www.calgaryherald.com'
|
||||||
#description = u'News from Edmonton, AB'
|
## description = u'News from Calgary, AB'
|
||||||
|
## std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
## logo_url = 'chlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
# un-comment the following three lines for the Calgary Herald
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
#title = u'Calgary Herald'
|
## title = u'Edmonton Journal'
|
||||||
#url_prefix = 'http://www.calgaryherald.com'
|
## url_prefix = 'http://www.edmontonjournal.com'
|
||||||
#description = u'News from Calgary, AB'
|
## description = u'News from Edmonton, AB'
|
||||||
|
## std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
## logo_url = 'ejlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
# un-comment the following three lines for the Regina Leader-Post
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
#title = u'Regina Leader-Post'
|
## title = u'Ottawa Citizen'
|
||||||
#url_prefix = 'http://www.leaderpost.com'
|
## url_prefix = 'http://www.ottawacitizen.com'
|
||||||
#description = u'News from Regina, SK'
|
## description = u'News from Ottawa, ON'
|
||||||
|
## std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
## logo_url = 'oclogo.jpg'
|
||||||
|
## fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
# un-comment the following three lines for the Saskatoon Star-Phoenix
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
#title = u'Saskatoon Star-Phoenix'
|
## title = u'Montreal Gazette'
|
||||||
#url_prefix = 'http://www.thestarphoenix.com'
|
## url_prefix = 'http://www.montrealgazette.com'
|
||||||
#description = u'News from Saskatoon, SK'
|
## description = u'News from Montreal, QC'
|
||||||
|
## std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
# un-comment the following three lines for the Windsor Star
|
## logo_url = 'mglogo.jpg'
|
||||||
#title = u'Windsor Star'
|
## fp_tag = 'CAN_MG'
|
||||||
#url_prefix = 'http://www.windsorstar.com'
|
|
||||||
#description = u'News from Windsor, ON'
|
|
||||||
|
|
||||||
# un-comment the following three lines for the Ottawa Citizen
|
|
||||||
#title = u'Ottawa Citizen'
|
|
||||||
#url_prefix = 'http://www.ottawacitizen.com'
|
|
||||||
#description = u'News from Ottawa, ON'
|
|
||||||
|
|
||||||
# un-comment the following three lines for the Montreal Gazette
|
|
||||||
#title = u'Montreal Gazette'
|
|
||||||
#url_prefix = 'http://www.montrealgazette.com'
|
|
||||||
#description = u'News from Montreal, QC'
|
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
language = 'en_CA'
|
language = 'en_CA'
|
||||||
__author__ = 'Nick Redding'
|
__author__ = 'Nick Redding'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
timefmt = ' [%b %d]'
|
timefmt = ' [%b %d]'
|
||||||
|
encoding = 'utf-8'
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
.timestamp { font-size:xx-small; display: block; }
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
#storyheader { font-size: medium; }
|
#storyheader { font-size: medium; }
|
||||||
#storyheader h1 { font-size: x-large; }
|
#storyheader h1 { font-size: x-large; }
|
||||||
#storyheader h2 { font-size: large; font-style: italic; }
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
.byline { font-size:xx-small; }
|
.byline { font-size:xx-small; }
|
||||||
#photocaption { font-size: small; font-style: italic }
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
#photocredit { font-size: xx-small; }'''
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'})]
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
remove_tags = [{'class':'comments'},
|
remove_tags = [{'class':'comments'},
|
||||||
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
from datetime import timedelta, date
|
||||||
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
daysback=1
|
||||||
|
try:
|
||||||
|
br.open(cover)
|
||||||
|
except:
|
||||||
|
while daysback<7:
|
||||||
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str((date.today() - timedelta(days=daysback)).day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
try:
|
||||||
|
br.open(cover)
|
||||||
|
except:
|
||||||
|
daysback = daysback+1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
if daysback==7:
|
||||||
|
self.log("\nCover unavailable")
|
||||||
|
cover = None
|
||||||
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
|
def fixChars(self,string):
|
||||||
|
# Replace lsquo (\x91)
|
||||||
|
fixed = re.sub("\x91","‘",string)
|
||||||
|
# Replace rsquo (\x92)
|
||||||
|
fixed = re.sub("\x92","’",fixed)
|
||||||
|
# Replace ldquo (\x93)
|
||||||
|
fixed = re.sub("\x93","“",fixed)
|
||||||
|
# Replace rdquo (\x94)
|
||||||
|
fixed = re.sub("\x94","”",fixed)
|
||||||
|
# Replace ndash (\x96)
|
||||||
|
fixed = re.sub("\x96","–",fixed)
|
||||||
|
# Replace mdash (\x97)
|
||||||
|
fixed = re.sub("\x97","—",fixed)
|
||||||
|
fixed = re.sub("’","’",fixed)
|
||||||
|
return fixed
|
||||||
|
|
||||||
|
def massageNCXText(self, description):
|
||||||
|
# Kindle TOC descriptions won't render certain characters
|
||||||
|
if description:
|
||||||
|
massaged = unicode(BeautifulStoneSoup(description, convertEntities=BeautifulStoneSoup.HTML_ENTITIES))
|
||||||
|
# Replace '&' with '&'
|
||||||
|
massaged = re.sub("&","&", massaged)
|
||||||
|
return self.fixChars(massaged)
|
||||||
|
else:
|
||||||
|
return description
|
||||||
|
|
||||||
|
def populate_article_metadata(self, article, soup, first):
|
||||||
|
if first:
|
||||||
|
picdiv = soup.find('body').find('img')
|
||||||
|
if picdiv is not None:
|
||||||
|
self.add_toc_thumbnail(article,re.sub(r'links\\link\d+\\','',picdiv['src']))
|
||||||
|
xtitle = article.text_summary.strip()
|
||||||
|
if len(xtitle) == 0:
|
||||||
|
desc = soup.find('meta',attrs={'property':'og:description'})
|
||||||
|
if desc is not None:
|
||||||
|
article.summary = article.text_summary = desc['content']
|
||||||
|
|
||||||
|
def strip_anchors(self,soup):
|
||||||
|
paras = soup.findAll(True)
|
||||||
|
for para in paras:
|
||||||
|
aTags = para.findAll('a')
|
||||||
|
for a in aTags:
|
||||||
|
if a.img is None:
|
||||||
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
|
return soup
|
||||||
|
|
||||||
|
|
||||||
def preprocess_html(self,soup):
|
def preprocess_html(self,soup):
|
||||||
#delete iempty id attributes--they screw up the TOC for unknow reasons
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
divtags = soup.findAll('div',attrs={'id':''})
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
if divtags:
|
if divtags:
|
||||||
for div in divtags:
|
for div in divtags:
|
||||||
del(div['id'])
|
del(div['id'])
|
||||||
return soup
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
soup = self.index_to_soup(self.url_prefix+'/news/todays-paper/index.html')
|
|
||||||
|
|
||||||
articles = {}
|
articles = {}
|
||||||
key = 'News'
|
ans = []
|
||||||
ans = ['News']
|
|
||||||
|
|
||||||
# Find each instance of class="sectiontitle", class="featurecontent"
|
|
||||||
for divtag in soup.findAll('div',attrs={'class' : ["section_title02","featurecontent"]}):
|
|
||||||
#self.log(" div class = %s" % divtag['class'])
|
|
||||||
if divtag['class'].startswith('section_title'):
|
|
||||||
# div contains section title
|
|
||||||
if not divtag.h3:
|
|
||||||
continue
|
|
||||||
key = self.tag_to_string(divtag.h3,False)
|
|
||||||
ans.append(key)
|
|
||||||
self.log("Section name %s" % key)
|
|
||||||
continue
|
|
||||||
# div contains article data
|
|
||||||
h1tag = divtag.find('h1')
|
|
||||||
if not h1tag:
|
|
||||||
continue
|
|
||||||
atag = h1tag.find('a',href=True)
|
|
||||||
if not atag:
|
|
||||||
continue
|
|
||||||
url = self.url_prefix+'/news/todays-paper/'+atag['href']
|
|
||||||
#self.log("Section %s" % key)
|
|
||||||
#self.log("url %s" % url)
|
|
||||||
title = self.tag_to_string(atag,False)
|
|
||||||
#self.log("title %s" % title)
|
|
||||||
pubdate = ''
|
|
||||||
description = ''
|
|
||||||
ptag = divtag.find('p');
|
|
||||||
if ptag:
|
|
||||||
description = self.tag_to_string(ptag,False)
|
|
||||||
#self.log("description %s" % description)
|
|
||||||
author = ''
|
|
||||||
autag = divtag.find('h4')
|
|
||||||
if autag:
|
|
||||||
author = self.tag_to_string(autag,False)
|
|
||||||
#self.log("author %s" % author)
|
|
||||||
if not articles.has_key(key):
|
|
||||||
articles[key] = []
|
|
||||||
articles[key].append(dict(title=title,url=url,date=pubdate,description=description,author=author,content=''))
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
@ -1,105 +1,136 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
www.canada.com
|
www.canada.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup
|
from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
class CanWestPaper(BasicNewsRecipe):
|
class CanWestPaper(BasicNewsRecipe):
|
||||||
|
|
||||||
# un-comment the following four lines for the Victoria Times Colonist
|
postmedia_index_pages = [
|
||||||
## title = u'Victoria Times Colonist'
|
(u'Headlines',u'/index.html'),
|
||||||
## url_prefix = 'http://www.timescolonist.com'
|
(u'Ottawa & Area',u'/news/ottawa/index.html'),
|
||||||
## description = u'News from Victoria, BC'
|
(u'Vancouver',u'/news/vancouver/index.html'),
|
||||||
## fp_tag = 'CAN_TC'
|
(u'Calgary',u'/news/calgary/index.html'),
|
||||||
|
(u'Edmonton',u'/news/edmonton/index.html'),
|
||||||
|
(u'Montreal',u'/news/montreal/index.html'),
|
||||||
|
(u'Fraser Valley',u'/news/fraser-valley/index.html'),
|
||||||
|
(u'British Columbia',u'/news/bc/index.html'),
|
||||||
|
(u'Alberta',u'/news/alberta/index.html'),
|
||||||
|
(u'Canada',u'/news/canada/index.html'),
|
||||||
|
(u'National',u'/news/national/index.html'),
|
||||||
|
(u'Politics',u'/news/politics/index.html'),
|
||||||
|
(u'Insight',u'/news/insight/index.html'),
|
||||||
|
(u'Special Reports',u'/news/specialreports/index.html'),
|
||||||
|
(u'Gangs',u'/news/gangs/index.html'),
|
||||||
|
(u'Education',u'/news/education/index.html'),
|
||||||
|
(u'Health',u'/news/health/index.html'),
|
||||||
|
(u'Environment',u'/news/environment/index.html'),
|
||||||
|
(u'World',u'/news/world/index.html'),
|
||||||
|
(u'Police Blotter',u'/news/crime-and-justice/index.html'),
|
||||||
|
(u'Crime',u'/news/blotter/index.html'),
|
||||||
|
(u'Around Town',u'/news/topic.html?t=keyword&q=Around+Town'),
|
||||||
|
(u'Diplomatica',u'/news/diplomatica/index.html'),
|
||||||
|
(u'Opinion',u'/opinion/index.html'),
|
||||||
|
(u'Columnists',u'/columnists/index.html'),
|
||||||
|
(u'Editorials',u'/opinion/editorials/index.html'),
|
||||||
|
(u'Letters',u'/opinion/letters/index.html'),
|
||||||
|
(u'Business',u'/business/index.html'),
|
||||||
|
(u'Sports',u'/sports/index.html'),
|
||||||
|
(u'Arts',u'/entertainment/index.html'),
|
||||||
|
(u'Life',u'/life/index.html'),
|
||||||
|
(u'Technology',u'/technology/index.html'),
|
||||||
|
(u'Travel',u'/travel/index.html'),
|
||||||
|
(u'Health',u'/health/index.html')
|
||||||
|
]
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Province
|
|
||||||
|
# un-comment the following six lines for the Vancouver Province
|
||||||
## title = u'Vancouver Province'
|
## title = u'Vancouver Province'
|
||||||
## url_prefix = 'http://www.theprovince.com'
|
## url_prefix = 'http://www.theprovince.com'
|
||||||
## description = u'News from Vancouver, BC'
|
## description = u'News from Vancouver, BC'
|
||||||
## fp_tag = 'CAN_VP'
|
## std_logo_url = 'http://www.theprovince.com/images/logo_theprovince.jpg'
|
||||||
|
## logo_url = 'vplogo.jpg'
|
||||||
|
## fp_tag = 'CAN_TP'
|
||||||
|
|
||||||
# un-comment the following four lines for the Vancouver Sun
|
# un-comment the following six lines for the Vancouver Sun
|
||||||
title = u'Vancouver Sun'
|
title = u'Vancouver Sun'
|
||||||
url_prefix = 'http://www.vancouversun.com'
|
url_prefix = 'http://www.vancouversun.com'
|
||||||
description = u'News from Vancouver, BC'
|
description = u'News from Vancouver, BC'
|
||||||
|
std_logo_url = 'http://www.vancouversun.com/images/logo_vancouversun.jpg'
|
||||||
|
logo_url = 'vslogo.jpg'
|
||||||
fp_tag = 'CAN_VS'
|
fp_tag = 'CAN_VS'
|
||||||
|
|
||||||
# un-comment the following four lines for the Edmonton Journal
|
# un-comment the following six lines for the Calgary Herald
|
||||||
## title = u'Edmonton Journal'
|
|
||||||
## url_prefix = 'http://www.edmontonjournal.com'
|
|
||||||
## description = u'News from Edmonton, AB'
|
|
||||||
## fp_tag = 'CAN_EJ'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Calgary Herald
|
|
||||||
## title = u'Calgary Herald'
|
## title = u'Calgary Herald'
|
||||||
## url_prefix = 'http://www.calgaryherald.com'
|
## url_prefix = 'http://www.calgaryherald.com'
|
||||||
## description = u'News from Calgary, AB'
|
## description = u'News from Calgary, AB'
|
||||||
|
## std_logo_url = 'http://www.calgaryherald.com/images/logo_calgaryherald.jpg'
|
||||||
|
## logo_url = 'chlogo.jpg'
|
||||||
## fp_tag = 'CAN_CH'
|
## fp_tag = 'CAN_CH'
|
||||||
|
|
||||||
# un-comment the following four lines for the Regina Leader-Post
|
# un-comment the following six lines for the Edmonton Journal
|
||||||
## title = u'Regina Leader-Post'
|
## title = u'Edmonton Journal'
|
||||||
## url_prefix = 'http://www.leaderpost.com'
|
## url_prefix = 'http://www.edmontonjournal.com'
|
||||||
## description = u'News from Regina, SK'
|
## description = u'News from Edmonton, AB'
|
||||||
## fp_tag = ''
|
## std_logo_url = 'http://www.edmontonjournal.com/images/logo_edmontonjournal.jpg'
|
||||||
|
## logo_url = 'ejlogo.jpg'
|
||||||
|
## fp_tag = 'CAN_EJ'
|
||||||
|
|
||||||
# un-comment the following four lines for the Saskatoon Star-Phoenix
|
# un-comment the following six lines for the Ottawa Citizen
|
||||||
## title = u'Saskatoon Star-Phoenix'
|
|
||||||
## url_prefix = 'http://www.thestarphoenix.com'
|
|
||||||
## description = u'News from Saskatoon, SK'
|
|
||||||
## fp_tag = ''
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Windsor Star
|
|
||||||
## title = u'Windsor Star'
|
|
||||||
## url_prefix = 'http://www.windsorstar.com'
|
|
||||||
## description = u'News from Windsor, ON'
|
|
||||||
## fp_tag = 'CAN_'
|
|
||||||
|
|
||||||
# un-comment the following four lines for the Ottawa Citizen
|
|
||||||
## title = u'Ottawa Citizen'
|
## title = u'Ottawa Citizen'
|
||||||
## url_prefix = 'http://www.ottawacitizen.com'
|
## url_prefix = 'http://www.ottawacitizen.com'
|
||||||
## description = u'News from Ottawa, ON'
|
## description = u'News from Ottawa, ON'
|
||||||
|
## std_logo_url = 'http://www.ottawacitizen.com/images/logo_ottawacitizen.jpg'
|
||||||
|
## logo_url = 'oclogo.jpg'
|
||||||
## fp_tag = 'CAN_OC'
|
## fp_tag = 'CAN_OC'
|
||||||
|
|
||||||
# un-comment the following four lines for the Montreal Gazette
|
# un-comment the following six lines for the Montreal Gazette
|
||||||
## title = u'Montreal Gazette'
|
## title = u'Montreal Gazette'
|
||||||
## url_prefix = 'http://www.montrealgazette.com'
|
## url_prefix = 'http://www.montrealgazette.com'
|
||||||
## description = u'News from Montreal, QC'
|
## description = u'News from Montreal, QC'
|
||||||
|
## std_logo_url = 'http://www.montrealgazette.com/images/logo_montrealgazette.jpg'
|
||||||
|
## logo_url = 'mglogo.jpg'
|
||||||
## fp_tag = 'CAN_MG'
|
## fp_tag = 'CAN_MG'
|
||||||
|
|
||||||
|
Kindle_Fire=False
|
||||||
|
masthead_url = std_logo_url
|
||||||
|
|
||||||
|
url_list = []
|
||||||
language = 'en_CA'
|
language = 'en_CA'
|
||||||
__author__ = 'Nick Redding'
|
__author__ = 'Nick Redding'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
timefmt = ' [%b %d]'
|
timefmt = ' [%b %d]'
|
||||||
|
encoding = 'utf-8'
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
.timestamp { font-size:xx-small; display: block; }
|
.timestamp { font-size:xx-small; display: block; }
|
||||||
#storyheader { font-size: medium; }
|
#storyheader { font-size: medium; }
|
||||||
#storyheader h1 { font-size: x-large; }
|
#storyheader h1 { font-size: x-large; }
|
||||||
#storyheader h2 { font-size: large; font-style: italic; }
|
#storyheader h2 { font-size: small; font-style: italic; }
|
||||||
.byline { font-size:xx-small; }
|
.byline { font-size:xx-small; }
|
||||||
#photocaption { font-size: small; font-style: italic }
|
#photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
#photocredit { font-size: xx-small; }'''
|
.photocaption { font-size: xx-small; font-style: italic; font-weight: normal; }
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'})]
|
#photocredit { font-size: xx-small; font-weight: normal; }'''
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'storyheader'}),dict(name='div', attrs={'id':'storycontent'}),dict(name='div', attrs={'id':'storyphoto'})]
|
||||||
|
|
||||||
remove_tags = [{'class':'comments'},
|
remove_tags = [{'class':'comments'},
|
||||||
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
dict(name='div', attrs={'class':'navbar'}),dict(name='div', attrs={'class':'morelinks'}),
|
||||||
|
dict(name='h2', attrs={'id':'photocredit'}),
|
||||||
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
dict(name='div', attrs={'class':'viewmore'}),dict(name='li', attrs={'class':'email'}),
|
||||||
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
dict(name='div', attrs={'class':'story_tool_hr'}),dict(name='div', attrs={'class':'clear'}),
|
||||||
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
dict(name='div', attrs={'class':'story_tool'}),dict(name='div', attrs={'class':'copyright'}),
|
||||||
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
dict(name='div', attrs={'class':'rule_grey_solid'}),
|
||||||
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
dict(name='li', attrs={'class':'print'}),dict(name='li', attrs={'class':'share'}),dict(name='ul', attrs={'class':'bullet'})]
|
||||||
|
|
||||||
|
|
||||||
def get_cover_url(self):
|
def get_cover_url(self):
|
||||||
from datetime import timedelta, date
|
from datetime import timedelta, date
|
||||||
if self.fp_tag=='':
|
|
||||||
return None
|
|
||||||
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
cover = 'http://webmedia.newseum.org/newseum-multimedia/dfp/jpg'+str(date.today().day)+'/lg/'+self.fp_tag+'.jpg'
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
daysback=1
|
daysback=1
|
||||||
@ -120,6 +151,18 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
cover = None
|
cover = None
|
||||||
return cover
|
return cover
|
||||||
|
|
||||||
|
def prepare_masthead_image(self, path_to_image, out_path):
|
||||||
|
if self.Kindle_Fire:
|
||||||
|
from calibre.utils.magick import Image, create_canvas
|
||||||
|
img = Image()
|
||||||
|
img.open(path_to_image)
|
||||||
|
width, height = img.size
|
||||||
|
img2 = create_canvas(width, height)
|
||||||
|
img2.compose(img)
|
||||||
|
img2.save(out_path)
|
||||||
|
else:
|
||||||
|
BasicNewsRecipe.prepare_masthead_image(self, path_to_image, out_path)
|
||||||
|
|
||||||
def fixChars(self,string):
|
def fixChars(self,string):
|
||||||
# Replace lsquo (\x91)
|
# Replace lsquo (\x91)
|
||||||
fixed = re.sub("\x91","‘",string)
|
fixed = re.sub("\x91","‘",string)
|
||||||
@ -166,55 +209,106 @@ class CanWestPaper(BasicNewsRecipe):
|
|||||||
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
a.replaceWith(a.renderContents().decode('cp1252','replace'))
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
|
||||||
|
def preprocess_html(self,soup):
|
||||||
|
#delete empty id attributes--they screw up the TOC for unknown reasons
|
||||||
|
divtags = soup.findAll('div',attrs={'id':''})
|
||||||
|
if divtags:
|
||||||
|
for div in divtags:
|
||||||
|
del(div['id'])
|
||||||
|
|
||||||
|
pgall = soup.find('div',attrs={'id':'storyphoto'})
|
||||||
|
if pgall is not None: # photo gallery perhaps
|
||||||
|
if (soup.find('div',attrs={'id':'storycontent'}) is None):
|
||||||
|
allpics = Tag(soup,'div')
|
||||||
|
first_img = pgall.find('div','storyimage')
|
||||||
|
if first_img is not None:
|
||||||
|
first_img.extract()
|
||||||
|
tlist = pgall.find('div',attrs={'id':'relatedthumbs'})
|
||||||
|
if tlist is not None:
|
||||||
|
for atag in tlist.findAll('a'):
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
srcpre, sep, srcpost = atag.img['src'].partition('?')
|
||||||
|
img['src'] = srcpre
|
||||||
|
pdesc = Tag(soup,'p')
|
||||||
|
pdesc.insert(0,atag.img['alt'])
|
||||||
|
pdesc['class']='photocaption'
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div.insert(0,pdesc)
|
||||||
|
div.insert(0,img)
|
||||||
|
allpics.append(div)
|
||||||
|
pgall.replaceWith(allpics)
|
||||||
|
|
||||||
|
for pg in soup.findAll('div',attrs={'id':'storyphoto'}):
|
||||||
|
pg.extract()
|
||||||
return self.strip_anchors(soup)
|
return self.strip_anchors(soup)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
soup = self.index_to_soup(self.url_prefix+'/news/todays-paper/index.html')
|
|
||||||
|
|
||||||
articles = {}
|
articles = {}
|
||||||
key = 'News'
|
ans = []
|
||||||
ans = ['News']
|
|
||||||
|
|
||||||
# Find each instance of class="sectiontitle", class="featurecontent"
|
|
||||||
for divtag in soup.findAll('div',attrs={'class' : ["section_title02","featurecontent"]}):
|
|
||||||
#self.log(" div class = %s" % divtag['class'])
|
|
||||||
if divtag['class'].startswith('section_title'):
|
|
||||||
# div contains section title
|
|
||||||
if not divtag.h3:
|
|
||||||
continue
|
|
||||||
key = self.tag_to_string(divtag.h3,False)
|
|
||||||
ans.append(key)
|
|
||||||
self.log("Section name %s" % key)
|
|
||||||
continue
|
|
||||||
# div contains article data
|
|
||||||
h1tag = divtag.find('h1')
|
|
||||||
if not h1tag:
|
|
||||||
continue
|
|
||||||
atag = h1tag.find('a',href=True)
|
|
||||||
if not atag:
|
|
||||||
continue
|
|
||||||
url = self.url_prefix+'/news/todays-paper/'+atag['href']
|
|
||||||
#self.log("Section %s" % key)
|
|
||||||
#self.log("url %s" % url)
|
|
||||||
title = self.tag_to_string(atag,False)
|
|
||||||
#self.log("title %s" % title)
|
|
||||||
pubdate = ''
|
|
||||||
description = ''
|
|
||||||
ptag = divtag.find('p');
|
|
||||||
if ptag:
|
|
||||||
description = self.tag_to_string(ptag,False)
|
|
||||||
#self.log("description %s" % description)
|
|
||||||
author = ''
|
|
||||||
autag = divtag.find('h4')
|
|
||||||
if autag:
|
|
||||||
author = self.tag_to_string(autag,False)
|
|
||||||
#self.log("author %s" % author)
|
|
||||||
if not articles.has_key(key):
|
|
||||||
articles[key] = []
|
|
||||||
articles[key].append(dict(title=title,url=url,date=pubdate,description=description,author=author,content=''))
|
|
||||||
|
|
||||||
|
def handle_article(adiv,key):
|
||||||
|
h1tag = adiv.h1
|
||||||
|
if h1tag is not None:
|
||||||
|
atag = h1tag.a
|
||||||
|
if atag is not None:
|
||||||
|
url = atag['href']
|
||||||
|
if atag['href'].startswith('http'):
|
||||||
|
return
|
||||||
|
elif atag['href'].startswith('/'):
|
||||||
|
url = self.url_prefix+atag['href']
|
||||||
|
else:
|
||||||
|
url = self.url_prefix+'/'+atag['href']
|
||||||
|
if url in self.url_list:
|
||||||
|
return
|
||||||
|
self.url_list.append(url)
|
||||||
|
title = self.tag_to_string(atag,False)
|
||||||
|
if 'VIDEO' in title.upper():
|
||||||
|
return
|
||||||
|
if 'GALLERY' in title.upper():
|
||||||
|
return
|
||||||
|
if 'PHOTOS' in title.upper():
|
||||||
|
return
|
||||||
|
dtag = adiv.find('div','content')
|
||||||
|
description=''
|
||||||
|
print("URL "+url)
|
||||||
|
print("TITLE "+title)
|
||||||
|
if dtag is not None:
|
||||||
|
stag = dtag.span
|
||||||
|
if stag is not None:
|
||||||
|
if stag['class'] != 'timestamp':
|
||||||
|
description = self.tag_to_string(stag,False)
|
||||||
|
else:
|
||||||
|
description = self.tag_to_string(dtag,False)
|
||||||
|
print("DESCRIPTION: "+description)
|
||||||
|
if not articles.has_key(key):
|
||||||
|
articles[key] = []
|
||||||
|
articles[key].append(dict(title=title,url=url,date='',description=description,author='',content=''))
|
||||||
|
|
||||||
|
def parse_web_index(key, keyurl):
|
||||||
|
try:
|
||||||
|
soup = self.index_to_soup(self.url_prefix+keyurl)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
ans.append(key)
|
||||||
|
mainsoup = soup.find('div','bodywrapper')
|
||||||
|
footer = mainsoup.find(attrs={'id':'footerfeature'})
|
||||||
|
if footer is not None:
|
||||||
|
footer.extract()
|
||||||
|
print("Section: "+key)
|
||||||
|
for wdiv in mainsoup.findAll('div',attrs={'id':re.compile('^HorizontalFeatureSlider_1_Story')}):
|
||||||
|
handle_article(wdiv,key)
|
||||||
|
wdiv.extract()
|
||||||
|
for wdiv in mainsoup.findAll(attrs={'id':['featurewidget','textfeature','textlinks_timestamp']}):
|
||||||
|
for adiv in wdiv.findAll('div','featurecontent'):
|
||||||
|
handle_article(adiv,key)
|
||||||
|
|
||||||
|
for (k,url) in self.postmedia_index_pages:
|
||||||
|
parse_web_index(k,url)
|
||||||
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
ans = [(key, articles[key]) for key in ans if articles.has_key(key)]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
@ -19,7 +19,13 @@ class Variety(BasicNewsRecipe):
|
|||||||
category = 'Entertainment Industry News, Daily Variety, Movie Reviews, TV, Awards, Oscars, Cannes, Box Office, Hollywood'
|
category = 'Entertainment Industry News, Daily Variety, Movie Reviews, TV, Awards, Oscars, Cannes, Box Office, Hollywood'
|
||||||
language = 'en'
|
language = 'en'
|
||||||
masthead_url = 'http://images1.variety.com/graphics/variety/Variety_logo_green_tm.gif'
|
masthead_url = 'http://images1.variety.com/graphics/variety/Variety_logo_green_tm.gif'
|
||||||
extra_css = ' body{font-family: Georgia,"Times New Roman",Times,Courier,serif } img{margin-bottom: 1em} '
|
extra_css = """
|
||||||
|
body{font-family: Arial,Helvetica,sans-serif; font-size: 1.275em}
|
||||||
|
.date{font-size: small; border: 1px dotted rgb(204, 204, 204); font-style: italic; color: rgb(102, 102, 102); margin: 5px 0px; padding: 0.5em;}
|
||||||
|
.author{margin: 5px 0px 5px 20px; padding: 0.5em; background: none repeat scroll 0% 0% rgb(247, 247, 247);}
|
||||||
|
.art h2{color: rgb(153, 0, 0); font-size: 1.275em; font-weight: bold;}
|
||||||
|
img{margin-bottom: 1em}
|
||||||
|
"""
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comments' : description
|
'comments' : description
|
||||||
@ -29,7 +35,7 @@ class Variety(BasicNewsRecipe):
|
|||||||
}
|
}
|
||||||
|
|
||||||
remove_tags = [dict(name=['object','link','map'])]
|
remove_tags = [dict(name=['object','link','map'])]
|
||||||
|
remove_attributes=['lang','vspace','hspace','xmlns:ms','xmlns:dt']
|
||||||
keep_only_tags = [dict(name='div', attrs={'class':'art control'})]
|
keep_only_tags = [dict(name='div', attrs={'class':'art control'})]
|
||||||
|
|
||||||
feeds = [(u'News & Articles', u'http://feeds.feedburner.com/variety/headlines' )]
|
feeds = [(u'News & Articles', u'http://feeds.feedburner.com/variety/headlines' )]
|
||||||
@ -37,3 +43,29 @@ class Variety(BasicNewsRecipe):
|
|||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
rpt = url.rpartition('.html')[0]
|
rpt = url.rpartition('.html')[0]
|
||||||
return rpt + '?printerfriendly=true'
|
return rpt + '?printerfriendly=true'
|
||||||
|
|
||||||
|
def preprocess_raw_html(self, raw, url):
|
||||||
|
return '<html><head>'+raw[raw.find('</head>'):]
|
||||||
|
|
||||||
|
def get_article_url(self, article):
|
||||||
|
url = BasicNewsRecipe.get_article_url(self, article)
|
||||||
|
return url.rpartition('?')[0]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
for item in soup.findAll('a'):
|
||||||
|
limg = item.find('img')
|
||||||
|
if item.string is not None:
|
||||||
|
str = item.string
|
||||||
|
item.replaceWith(str)
|
||||||
|
else:
|
||||||
|
if limg:
|
||||||
|
item.name = 'div'
|
||||||
|
item.attrs = []
|
||||||
|
else:
|
||||||
|
str = self.tag_to_string(item)
|
||||||
|
item.replaceWith(str)
|
||||||
|
for item in soup.findAll('img'):
|
||||||
|
if not item.has_key('alt'):
|
||||||
|
item['alt'] = 'image'
|
||||||
|
return soup
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -822,7 +822,6 @@ application/x-lzh lzh
|
|||||||
application/x-lzx lzx
|
application/x-lzx lzx
|
||||||
application/x-maker book fb fbdoc fm frame frm maker
|
application/x-maker book fb fbdoc fm frame frm maker
|
||||||
application/x-mif mif
|
application/x-mif mif
|
||||||
application/x-mobipocket-ebook mobi prc
|
|
||||||
application/x-ms-application application
|
application/x-ms-application application
|
||||||
application/x-ms-wmd wmd
|
application/x-ms-wmd wmd
|
||||||
application/x-ms-wmz wmz
|
application/x-ms-wmz wmz
|
||||||
@ -1371,11 +1370,11 @@ application/x-sony-bbeb lrf lrx
|
|||||||
application/adobe-page-template+xml xpgt
|
application/adobe-page-template+xml xpgt
|
||||||
application/x-font-opentype otf
|
application/x-font-opentype otf
|
||||||
application/x-font-truetype ttf
|
application/x-font-truetype ttf
|
||||||
application/x-mobipocket-ebook mobi prc azw
|
application/x-mobipocket-ebook mobi prc
|
||||||
|
application/vnd.amazon.ebook azw3 azw azw2 azw4
|
||||||
application/x-cbz cbz
|
application/x-cbz cbz
|
||||||
application/x-cbr cbr
|
application/x-cbr cbr
|
||||||
application/x-cb7 cb7
|
application/x-cb7 cb7
|
||||||
application/x-koboreader-ebook kobo
|
application/x-koboreader-ebook kobo
|
||||||
image/wmf wmf
|
image/wmf wmf
|
||||||
application/ereader pdb
|
application/ereader pdb
|
||||||
|
|
||||||
|
@ -402,7 +402,3 @@ img, object, svg|svg {
|
|||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These are needed because ADE renders anchors the same as links */
|
|
||||||
|
|
||||||
a { text-decoration: inherit; color: inherit; cursor: inherit }
|
|
||||||
a[href] { text-decoration: underline; color: blue; cursor: pointer }
|
|
||||||
|
2436
resources/viewer/mathjax/MathJax.js
Normal file
2436
resources/viewer/mathjax/MathJax.js
Normal file
File diff suppressed because it is too large
Load Diff
286
resources/viewer/mathjax/extensions/FontWarnings.js
Normal file
286
resources/viewer/mathjax/extensions/FontWarnings.js
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/FontWarnings.js
|
||||||
|
*
|
||||||
|
* Implements a font warning message window that appears when
|
||||||
|
* the image fonts, no fonts, or web fonts are used, informing
|
||||||
|
* the user where to download the fonts, or to update to a more
|
||||||
|
* modern browser. The window will fade out automatically after
|
||||||
|
* a time, and the user can dismiss it by a close box.
|
||||||
|
*
|
||||||
|
* To include font warning messages, add "FontWarnings.js" to the
|
||||||
|
* extensions array in your MathJax configuration.
|
||||||
|
*
|
||||||
|
* You can customize the warning messages in a number of ways. Use the
|
||||||
|
* FontWarnings section of the configuration to specify any of the items
|
||||||
|
* shown in the CONFIG variable below. These include
|
||||||
|
*
|
||||||
|
* messageStyle the style to apply to the warning box that is
|
||||||
|
* displayed when MathJax uses one of its fallback
|
||||||
|
* methods.
|
||||||
|
*
|
||||||
|
* removeAfter the amount of time to show the warning message (in ms)
|
||||||
|
* fadeoutTime how long the message should take to fade out
|
||||||
|
* fadeoutSteps how many separate steps to use during the fade out
|
||||||
|
* (set to 0 to use no fadeout and simply remove the window)
|
||||||
|
*
|
||||||
|
* Messages stores the descriptions of the messages to use for the
|
||||||
|
* various warnings (webFonts, imageFonts, and noFonts).
|
||||||
|
* These are arrays of strings to be inserted into the window,
|
||||||
|
* or identifiers within brackets, which refer to the HTML
|
||||||
|
* snippets in the HTML section described below. To disable a
|
||||||
|
* specific message, set its value to null (see example below).
|
||||||
|
*
|
||||||
|
* HTML stores snippets of HTML descriptions for various
|
||||||
|
* common parts of the error messages. These include
|
||||||
|
* the closeBox, the message about web fonts being available
|
||||||
|
* in modern browser, and messages about downloadable fonts.
|
||||||
|
* The STIX and TeX font messages are used when only one
|
||||||
|
* of these is in the availableFonts list. The data for these
|
||||||
|
* are arrays of either strings to include or a description of
|
||||||
|
* an HTML item enclosed in square brackets. That description
|
||||||
|
* has (up to) three parts: the name of the tag to be included,
|
||||||
|
* a list (enclosed in braces) of attributes and their values
|
||||||
|
* to be set on the tag (optional), and an array of the contents
|
||||||
|
* of the tag (optional). See the definitions below for examples.
|
||||||
|
*
|
||||||
|
* For example,
|
||||||
|
*
|
||||||
|
* MathJax.Hub.Config({
|
||||||
|
* ...
|
||||||
|
* extensions: ["FontWarnings.js"],
|
||||||
|
* FontWarnings: {
|
||||||
|
* removeAfter: 20*1000, // 20 seconds
|
||||||
|
* messageStyle: {
|
||||||
|
* border: "2px solid black",
|
||||||
|
* padding: "2em"
|
||||||
|
* },
|
||||||
|
* Message: {
|
||||||
|
* webFont: null // no webfont messages (only image and no fonts)
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* would extend the time the message is displayed from 12 seconds to 20,
|
||||||
|
* and changes the border to a solid black one, with 2em of padding
|
||||||
|
* rather than the default of 1em.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (HUB,HTML) {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var CONFIG = HUB.CombineConfig("FontWarnings",{
|
||||||
|
//
|
||||||
|
// The CSS for the message window
|
||||||
|
//
|
||||||
|
messageStyle: {
|
||||||
|
position:"fixed", bottom:"4em", left:"3em", width:"40em",
|
||||||
|
border: "3px solid #880000", "background-color": "#E0E0E0", color: "black",
|
||||||
|
padding: "1em", "font-size":"small", "white-space":"normal",
|
||||||
|
|
||||||
|
"border-radius": ".75em", // Opera 10.5 and IE9
|
||||||
|
"-webkit-border-radius": ".75em", // Safari and Chrome
|
||||||
|
"-moz-border-radius": ".75em", // Firefox
|
||||||
|
"-khtml-border-radius": ".75em", // Konqueror
|
||||||
|
|
||||||
|
"box-shadow": "4px 4px 10px #AAAAAA", // Opera 10.5 and IE9
|
||||||
|
"-webkit-box-shadow": "4px 4px 10px #AAAAAA", // Safari 3 and Chrome
|
||||||
|
"-moz-box-shadow": "4px 4px 10px #AAAAAA", // Forefox 3.5
|
||||||
|
"-khtml-box-shadow": "4px 4px 10px #AAAAAA", // Konqueror
|
||||||
|
filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=3, OffY=3, Color='gray', Positive='true')" // IE
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// The messages for the various situations
|
||||||
|
//
|
||||||
|
Message: {
|
||||||
|
webFont: [
|
||||||
|
["closeBox"],
|
||||||
|
"MathJax is using web-based fonts to display the mathematics ",
|
||||||
|
"on this page. These take time to download, so the page would ",
|
||||||
|
"render faster if you installed math fonts directly in your ",
|
||||||
|
"system's font folder.",
|
||||||
|
["fonts"]
|
||||||
|
],
|
||||||
|
|
||||||
|
imageFonts: [
|
||||||
|
["closeBox"],
|
||||||
|
"MathJax is using its image fonts rather than local or web-based fonts. ",
|
||||||
|
"This will render slower than usual, and the mathematics may not print ",
|
||||||
|
"at the full resolution of your printer.",
|
||||||
|
["fonts"],
|
||||||
|
["webfonts"]
|
||||||
|
],
|
||||||
|
|
||||||
|
noFonts: [
|
||||||
|
["closeBox"],
|
||||||
|
"MathJax is unable to locate a font to use to display ",
|
||||||
|
"its mathematics, and image fonts are not available, so it ",
|
||||||
|
"is falling back on generic unicode characters in hopes that ",
|
||||||
|
"your browser will be able to display them. Some characters ",
|
||||||
|
"may not show up properly, or possibly not at all.",
|
||||||
|
["fonts"],
|
||||||
|
["webfonts"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// HTML objects that can be referred to in the message definitions
|
||||||
|
//
|
||||||
|
HTML: {
|
||||||
|
//
|
||||||
|
// The definition of the close box
|
||||||
|
//
|
||||||
|
closeBox: [[
|
||||||
|
"div",{
|
||||||
|
style: {
|
||||||
|
position:"absolute", overflow:"hidden", top:".1em", right:".1em",
|
||||||
|
border: "1px outset", width:"1em", height:"1em",
|
||||||
|
"text-align": "center", cursor: "pointer",
|
||||||
|
"background-color": "#EEEEEE", color:"#606060",
|
||||||
|
|
||||||
|
"border-radius": ".5em", // Opera 10.5
|
||||||
|
"-webkit-border-radius": ".5em", // Safari and Chrome
|
||||||
|
"-moz-border-radius": ".5em", // Firefox
|
||||||
|
"-khtml-border-radius": ".5em" // Konqueror
|
||||||
|
},
|
||||||
|
onclick: function () {
|
||||||
|
if (DATA.div && DATA.fade === 0)
|
||||||
|
{if (DATA.timer) {clearTimeout(DATA.timer)}; DATA.div.style.display = "none"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[["span",{style:{position:"relative", bottom:".2em"}},["x"]]]
|
||||||
|
]],
|
||||||
|
|
||||||
|
webfonts: [
|
||||||
|
["p"],
|
||||||
|
"Most modern browsers allow for fonts to be downloaded over the web. ",
|
||||||
|
"Updating to a more recent version of your browser (or changing browsers) ",
|
||||||
|
"could improve the quality of the mathematics on this page."
|
||||||
|
],
|
||||||
|
|
||||||
|
fonts: [
|
||||||
|
["p"],
|
||||||
|
"MathJax can use either the ",
|
||||||
|
["a",{href:"http://www.stixfonts.org/",target:"_blank"},"STIX fonts"],
|
||||||
|
" or the ",
|
||||||
|
["a",{href:"http://www.mathjax.org/help-v2/fonts/",target:"_blank"},["MathJax TeX fonts"]],
|
||||||
|
". Download and install either one to improve your MathJax experience."
|
||||||
|
],
|
||||||
|
|
||||||
|
STIXfonts: [
|
||||||
|
["p"],
|
||||||
|
"This page is designed to use the ",
|
||||||
|
["a",{href:"http://www.stixfonts.org/",target:"_blank"},"STIX fonts"],
|
||||||
|
". Download and install those fonts to improve your MathJax experience."
|
||||||
|
],
|
||||||
|
|
||||||
|
TeXfonts: [
|
||||||
|
["p"],
|
||||||
|
"This page is designed to use the ",
|
||||||
|
["a",{href:"http://www.mathjax.org/help-v2/fonts/",target:"_blank"},["MathJax TeX fonts"]],
|
||||||
|
". Download and install those fonts to improve your MathJax experience."
|
||||||
|
]
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
removeAfter: 12*1000, // time to show message (in ms)
|
||||||
|
fadeoutSteps: 10, // fade-out steps
|
||||||
|
fadeoutTime: 1.5*1000 // fadeout over this amount of time (in ms)
|
||||||
|
|
||||||
|
});
|
||||||
|
if (MathJax.Hub.Browser.isIE9 && document.documentMode >= 9)
|
||||||
|
{delete CONFIG.messageStyle.filter}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data for the window
|
||||||
|
//
|
||||||
|
var DATA = {
|
||||||
|
div: null, // the message window, when displayed
|
||||||
|
fade: 0 // number of fade-out steps so far
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the message window and start the fade-out timer
|
||||||
|
//
|
||||||
|
var CREATEMESSAGE = function (data) {
|
||||||
|
if (DATA.div) return;
|
||||||
|
var HTMLCSS = MathJax.OutputJax["HTML-CSS"], frame = document.body;
|
||||||
|
if (HUB.Browser.isMSIE) {
|
||||||
|
if (CONFIG.messageStyle.position === "fixed") {
|
||||||
|
MathJax.Message.Init(); // make sure MathJax_MSIE_frame exists
|
||||||
|
frame = document.getElementById("MathJax_MSIE_Frame");
|
||||||
|
CONFIG.messageStyle.position = "absolute";
|
||||||
|
}
|
||||||
|
} else {delete CONFIG.messageStyle.filter}
|
||||||
|
CONFIG.messageStyle.maxWidth = (document.body.clientWidth-75) + "px";
|
||||||
|
var i = 0; while (i < data.length) {
|
||||||
|
if (data[i] instanceof Array && CONFIG.HTML[data[i][0]])
|
||||||
|
{data.splice.apply(data,[i,1].concat(CONFIG.HTML[data[i][0]]))} else {i++}
|
||||||
|
}
|
||||||
|
DATA.div = HTMLCSS.addElement(frame,"div",{id:"MathJax_FontWarning",style:CONFIG.messageStyle},data);
|
||||||
|
if (CONFIG.removeAfter) {
|
||||||
|
HUB.Register.StartupHook("End",function ()
|
||||||
|
{DATA.timer = setTimeout(FADEOUT,CONFIG.removeAfter)});
|
||||||
|
}
|
||||||
|
HTML.Cookie.Set("fontWarn",{warned:true});
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the opacity based on the number of steps taken so far
|
||||||
|
// and remove the window when it gets to 0
|
||||||
|
//
|
||||||
|
var FADEOUT = function () {
|
||||||
|
DATA.fade++; if (DATA.timer) {delete DATA.timer}
|
||||||
|
if (DATA.fade < CONFIG.fadeoutSteps) {
|
||||||
|
var opacity = 1 - DATA.fade/CONFIG.fadeoutSteps;
|
||||||
|
DATA.div.style.opacity = opacity;
|
||||||
|
DATA.div.style.filter = "alpha(opacity="+Math.floor(100*opacity)+")";
|
||||||
|
setTimeout(FADEOUT,CONFIG.fadeoutTime/CONFIG.fadeoutSteps);
|
||||||
|
} else {
|
||||||
|
DATA.div.style.display = "none";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check that we haven't already issued a warning
|
||||||
|
//
|
||||||
|
if (!HTML.Cookie.Get("fontWarn").warned) {
|
||||||
|
//
|
||||||
|
// Hook into the Startup signal and look for font warning messages.
|
||||||
|
// When one comes, issue the correct message.
|
||||||
|
//
|
||||||
|
HUB.Startup.signal.Interest(function (message) {
|
||||||
|
if (message.match(/HTML-CSS Jax - /) && !DATA.div) {
|
||||||
|
var HTMLCSS = MathJax.OutputJax["HTML-CSS"], FONTS = HTMLCSS.config.availableFonts, MSG;
|
||||||
|
var localFonts = (FONTS && FONTS.length);
|
||||||
|
if (!localFonts) {CONFIG.HTML.fonts = [""]}
|
||||||
|
else if (FONTS.length === 1) {CONFIG.HTML.fonts = CONFIG.HTML[FONTS[0]+"fonts"]}
|
||||||
|
if (HTMLCSS.allowWebFonts) {CONFIG.HTML.webfonts = [""]}
|
||||||
|
if (message.match(/- Web-Font/)) {if (localFonts) {MSG = "webFont"}}
|
||||||
|
else if (message.match(/- using image fonts/)) {MSG = "imageFonts"}
|
||||||
|
else if (message.match(/- no valid font/)) {MSG = "noFonts"}
|
||||||
|
if (MSG && CONFIG.Message[MSG]) {CREATEMESSAGE(CONFIG.Message[MSG])}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})(MathJax.Hub,MathJax.HTML);
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/FontWarnings.js");
|
531
resources/viewer/mathjax/extensions/MathEvents.js
Normal file
531
resources/viewer/mathjax/extensions/MathEvents.js
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/MathEvents.js
|
||||||
|
*
|
||||||
|
* Implements the event handlers needed by the output jax to perform
|
||||||
|
* menu, hover, and other events.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (HUB,HTML,AJAX,CALLBACK,OUTPUT,INPUT) {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var EXTENSION = MathJax.Extension;
|
||||||
|
var ME = EXTENSION.MathEvents = {version: VERSION};
|
||||||
|
|
||||||
|
var SETTINGS = HUB.config.menuSettings;
|
||||||
|
|
||||||
|
var CONFIG = {
|
||||||
|
hover: 500, // time required to be considered a hover
|
||||||
|
frame: {
|
||||||
|
x: 3.5, y: 5, // frame padding and
|
||||||
|
bwidth: 1, // frame border width (in pixels)
|
||||||
|
bcolor: "#A6D", // frame border color
|
||||||
|
hwidth: "15px", // haze width
|
||||||
|
hcolor: "#83A" // haze color
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
x: -4, y: -3, // menu button offsets
|
||||||
|
wx: -2, // button offset for full-width equations
|
||||||
|
src: AJAX.fileURL(OUTPUT.imageDir+"/MenuArrow-15.png") // button image
|
||||||
|
},
|
||||||
|
fadeinInc: .2, // increment for fade-in
|
||||||
|
fadeoutInc: .05, // increment for fade-out
|
||||||
|
fadeDelay: 50, // delay between fade-in or fade-out steps
|
||||||
|
fadeoutStart: 400, // delay before fade-out after mouseout
|
||||||
|
fadeoutDelay: 15*1000, // delay before automatic fade-out
|
||||||
|
|
||||||
|
styles: {
|
||||||
|
".MathJax_Hover_Frame": {
|
||||||
|
"border-radius": ".25em", // Opera 10.5 and IE9
|
||||||
|
"-webkit-border-radius": ".25em", // Safari and Chrome
|
||||||
|
"-moz-border-radius": ".25em", // Firefox
|
||||||
|
"-khtml-border-radius": ".25em", // Konqueror
|
||||||
|
|
||||||
|
"box-shadow": "0px 0px 15px #83A", // Opera 10.5 and IE9
|
||||||
|
"-webkit-box-shadow": "0px 0px 15px #83A", // Safari and Chrome
|
||||||
|
"-moz-box-shadow": "0px 0px 15px #83A", // Forefox
|
||||||
|
"-khtml-box-shadow": "0px 0px 15px #83A", // Konqueror
|
||||||
|
|
||||||
|
border: "1px solid #A6D ! important",
|
||||||
|
display: "inline-block", position:"absolute"
|
||||||
|
},
|
||||||
|
|
||||||
|
".MathJax_Hover_Arrow": {
|
||||||
|
position:"absolute",
|
||||||
|
width:"15px", height:"11px",
|
||||||
|
cursor:"pointer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common event-handling code
|
||||||
|
//
|
||||||
|
var EVENT = ME.Event = {
|
||||||
|
|
||||||
|
LEFTBUTTON: 0, // the event.button value for left button
|
||||||
|
RIGHTBUTTON: 2, // the event.button value for right button
|
||||||
|
MENUKEY: "altKey", // the event value for alternate context menu
|
||||||
|
|
||||||
|
Mousedown: function (event) {return EVENT.Handler(event,"Mousedown",this)},
|
||||||
|
Mouseup: function (event) {return EVENT.Handler(event,"Mouseup",this)},
|
||||||
|
Mousemove: function (event) {return EVENT.Handler(event,"Mousemove",this)},
|
||||||
|
Mouseover: function (event) {return EVENT.Handler(event,"Mouseover",this)},
|
||||||
|
Mouseout: function (event) {return EVENT.Handler(event,"Mouseout",this)},
|
||||||
|
Click: function (event) {return EVENT.Handler(event,"Click",this)},
|
||||||
|
DblClick: function (event) {return EVENT.Handler(event,"DblClick",this)},
|
||||||
|
Menu: function (event) {return EVENT.Handler(event,"ContextMenu",this)},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call the output jax's event handler or the zoom handler
|
||||||
|
//
|
||||||
|
Handler: function (event,type,math) {
|
||||||
|
if (AJAX.loadingMathMenu) {return EVENT.False(event)}
|
||||||
|
var jax = OUTPUT[math.jaxID];
|
||||||
|
if (!event) {event = window.event}
|
||||||
|
event.isContextMenu = (type === "ContextMenu");
|
||||||
|
if (jax[type]) {return jax[type](event,math)}
|
||||||
|
if (EXTENSION.MathZoom) {return EXTENSION.MathZoom.HandleEvent(event,type,math)}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to cancel the event in every way we can
|
||||||
|
//
|
||||||
|
False: function (event) {
|
||||||
|
if (!event) {event = window.event}
|
||||||
|
if (event) {
|
||||||
|
if (event.preventDefault) {event.preventDefault()}
|
||||||
|
if (event.stopPropagation) {event.stopPropagation()}
|
||||||
|
event.cancelBubble = true;
|
||||||
|
event.returnValue = false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load the contextual menu code, if needed, and post the menu
|
||||||
|
//
|
||||||
|
ContextMenu: function (event,math,force) {
|
||||||
|
//
|
||||||
|
// Check if we are showing menus
|
||||||
|
//
|
||||||
|
var JAX = OUTPUT[math.jaxID], jax = JAX.getJaxFromMath(math);
|
||||||
|
var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
|
||||||
|
if (!show || (SETTINGS.context !== "MathJax" && !force)) return;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove selections, remove hover fades
|
||||||
|
//
|
||||||
|
if (ME.msieEventBug) {event = window.event || event}
|
||||||
|
EVENT.ClearSelection(); HOVER.ClearHoverTimer();
|
||||||
|
if (jax.hover) {
|
||||||
|
if (jax.hover.remove) {clearTimeout(jax.hover.remove); delete jax.hover.remove}
|
||||||
|
jax.hover.nofade = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the menu code is loaded, post the menu
|
||||||
|
// Otherwse lad the menu code and try again
|
||||||
|
//
|
||||||
|
var MENU = MathJax.Menu;
|
||||||
|
if (MENU) {
|
||||||
|
MENU.jax = jax;
|
||||||
|
var source = MENU.menu.Find("Show Math As").menu;
|
||||||
|
source.items[1].name = (INPUT[jax.inputJax].sourceMenuTitle||"Original Form");
|
||||||
|
source.items[0].hidden = (jax.inputJax === "Error"); // hide MathML choice for error messages
|
||||||
|
var MathPlayer = MENU.menu.Find("Math Settings","MathPlayer");
|
||||||
|
MathPlayer.hidden = !(jax.outputJax === "NativeMML" && HUB.Browser.hasMathPlayer);
|
||||||
|
return MENU.menu.Post(event);
|
||||||
|
} else {
|
||||||
|
if (!AJAX.loadingMathMenu) {
|
||||||
|
AJAX.loadingMathMenu = true;
|
||||||
|
var ev = {
|
||||||
|
pageX:event.pageX, pageY:event.pageY,
|
||||||
|
clientX:event.clientX, clientY:event.clientY
|
||||||
|
};
|
||||||
|
CALLBACK.Queue(
|
||||||
|
AJAX.Require("[MathJax]/extensions/MathMenu.js"),
|
||||||
|
function () {delete AJAX.loadingMathMenu; if (!MathJax.Menu) {MathJax.Menu = {}}},
|
||||||
|
["ContextMenu",this,ev,math,force] // call this function again
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return EVENT.False(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mousedown handler for alternate means of accessing menu
|
||||||
|
//
|
||||||
|
AltContextMenu: function (event,math) {
|
||||||
|
var JAX = OUTPUT[math.jaxID];
|
||||||
|
var show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
|
||||||
|
if (show) {
|
||||||
|
show = (JAX.config.showMathMenuMSIE != null ? JAX : HUB).config.showMathMenuMSIE;
|
||||||
|
if (SETTINGS.context === "MathJax" && !SETTINGS.mpContext && show) {
|
||||||
|
if (!ME.noContextMenuBug || event.button !== EVENT.RIGHTBUTTON) return;
|
||||||
|
} else {
|
||||||
|
if (!event[EVENT.MENUKEY] || event.button !== EVENT.LEFTBUTTON) return;
|
||||||
|
}
|
||||||
|
return JAX.ContextMenu(event,math,true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ClearSelection: function () {
|
||||||
|
if (ME.safariContextMenuBug) {setTimeout("window.getSelection().empty()",0)}
|
||||||
|
if (document.selection) {setTimeout("document.selection.empty()",0)}
|
||||||
|
},
|
||||||
|
|
||||||
|
getBBox: function (span) {
|
||||||
|
span.appendChild(ME.topImg);
|
||||||
|
var h = ME.topImg.offsetTop, d = span.offsetHeight-h, w = span.offsetWidth;
|
||||||
|
span.removeChild(ME.topImg);
|
||||||
|
return {w:w, h:h, d:d};
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle hover "discoverability"
|
||||||
|
//
|
||||||
|
var HOVER = ME.Hover = {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if we are moving from a non-MathJax element to a MathJax one
|
||||||
|
// and either start fading in again (if it is fading out) or start the
|
||||||
|
// timer for the hover
|
||||||
|
//
|
||||||
|
Mouseover: function (event,math) {
|
||||||
|
if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
|
||||||
|
var from = event.fromElement || event.relatedTarget,
|
||||||
|
to = event.toElement || event.target;
|
||||||
|
if (from && to && (from.isMathJax != to.isMathJax ||
|
||||||
|
HUB.getJaxFor(from) !== HUB.getJaxFor(to))) {
|
||||||
|
var jax = this.getJaxFromMath(math);
|
||||||
|
if (jax.hover) {HOVER.ReHover(jax)} else {HOVER.HoverTimer(jax,math)}
|
||||||
|
return EVENT.False(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Check if we are moving from a MathJax element to a non-MathJax one
|
||||||
|
// and either start fading out, or clear the timer if we haven't
|
||||||
|
// hovered yet
|
||||||
|
//
|
||||||
|
Mouseout: function (event,math) {
|
||||||
|
if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
|
||||||
|
var from = event.fromElement || event.relatedTarget,
|
||||||
|
to = event.toElement || event.target;
|
||||||
|
if (from && to && (from.isMathJax != to.isMathJax ||
|
||||||
|
HUB.getJaxFor(from) !== HUB.getJaxFor(to))) {
|
||||||
|
var jax = this.getJaxFromMath(math);
|
||||||
|
if (jax.hover) {HOVER.UnHover(jax)} else {HOVER.ClearHoverTimer()}
|
||||||
|
return EVENT.False(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Restart hover timer if the mouse moves
|
||||||
|
//
|
||||||
|
Mousemove: function (event,math) {
|
||||||
|
if (SETTINGS.discoverable || SETTINGS.zoom === "Hover") {
|
||||||
|
var jax = this.getJaxFromMath(math); if (jax.hover) return;
|
||||||
|
if (HOVER.lastX == event.clientX && HOVER.lastY == event.clientY) return;
|
||||||
|
HOVER.lastX = event.clientX; HOVER.lastY = event.clientY;
|
||||||
|
HOVER.HoverTimer(jax,math);
|
||||||
|
return EVENT.False(event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear the old timer and start a new one
|
||||||
|
//
|
||||||
|
HoverTimer: function (jax,math) {
|
||||||
|
this.ClearHoverTimer();
|
||||||
|
this.hoverTimer = setTimeout(CALLBACK(["Hover",this,jax,math]),CONFIG.hover);
|
||||||
|
},
|
||||||
|
ClearHoverTimer: function () {
|
||||||
|
if (this.hoverTimer) {clearTimeout(this.hoverTimer); delete this.hoverTimer}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle putting up the hover frame
|
||||||
|
//
|
||||||
|
Hover: function (jax,math) {
|
||||||
|
//
|
||||||
|
// Check if Zoom handles the hover event
|
||||||
|
//
|
||||||
|
if (EXTENSION.MathZoom && EXTENSION.MathZoom.Hover({},math)) return;
|
||||||
|
//
|
||||||
|
// Get the hover data
|
||||||
|
//
|
||||||
|
var JAX = OUTPUT[jax.outputJax],
|
||||||
|
span = JAX.getHoverSpan(jax,math),
|
||||||
|
bbox = JAX.getHoverBBox(jax,span,math),
|
||||||
|
show = (JAX.config.showMathMenu != null ? JAX : HUB).config.showMathMenu;
|
||||||
|
var dx = CONFIG.frame.x, dy = CONFIG.frame.y, dd = CONFIG.frame.bwidth; // frame size
|
||||||
|
if (ME.msieBorderWidthBug) {dd = 0}
|
||||||
|
jax.hover = {opacity:0, id:jax.inputID+"-Hover"};
|
||||||
|
//
|
||||||
|
// The frame and menu button
|
||||||
|
//
|
||||||
|
var frame = HTML.Element("span",{
|
||||||
|
id:jax.hover.id, isMathJax: true,
|
||||||
|
style:{display:"inline-block", width:0, height:0, position:"relative"}
|
||||||
|
},[["span",{
|
||||||
|
className:"MathJax_Hover_Frame", isMathJax: true,
|
||||||
|
style:{
|
||||||
|
display:"inline-block", position:"absolute",
|
||||||
|
top:this.Px(-bbox.h-dy-dd-(bbox.y||0)), left:this.Px(-dx-dd+(bbox.x||0)),
|
||||||
|
width:this.Px(bbox.w+2*dx), height:this.Px(bbox.h+bbox.d+2*dy),
|
||||||
|
opacity:0, filter:"alpha(opacity=0)"
|
||||||
|
}}
|
||||||
|
]]
|
||||||
|
);
|
||||||
|
var button = HTML.Element("span",{
|
||||||
|
isMathJax: true, id:jax.hover.id+"Menu",
|
||||||
|
style:{display:"inline-block", "z-index": 1, width:0, height:0, position:"relative"}
|
||||||
|
},[["img",{
|
||||||
|
className: "MathJax_Hover_Arrow", isMathJax: true, math: math,
|
||||||
|
src: CONFIG.button.src, onclick: this.HoverMenu, jax:JAX.id,
|
||||||
|
style: {
|
||||||
|
left:this.Px(bbox.w+dx+dd+(bbox.x||0)+CONFIG.button.x),
|
||||||
|
top:this.Px(-bbox.h-dy-dd-(bbox.y||0)-CONFIG.button.y),
|
||||||
|
opacity:0, filter:"alpha(opacity=0)"
|
||||||
|
}
|
||||||
|
}]]
|
||||||
|
);
|
||||||
|
if (bbox.width) {
|
||||||
|
frame.style.width = button.style.width = bbox.width;
|
||||||
|
frame.style.marginRight = button.style.marginRight = "-"+bbox.width;
|
||||||
|
frame.firstChild.style.width = bbox.width;
|
||||||
|
button.firstChild.style.left = "";
|
||||||
|
button.firstChild.style.right = this.Px(CONFIG.button.wx);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Add the frame and button
|
||||||
|
//
|
||||||
|
span.parentNode.insertBefore(frame,span);
|
||||||
|
if (show) {span.parentNode.insertBefore(button,span)}
|
||||||
|
if (span.style) {span.style.position = "relative"} // so math is on top of hover frame
|
||||||
|
//
|
||||||
|
// Start the hover fade-in
|
||||||
|
//
|
||||||
|
this.ReHover(jax);
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Restart the hover fade in and fade-out timers
|
||||||
|
//
|
||||||
|
ReHover: function (jax) {
|
||||||
|
if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
|
||||||
|
jax.hover.remove = setTimeout(CALLBACK(["UnHover",this,jax]),CONFIG.fadeoutDelay);
|
||||||
|
this.HoverFadeTimer(jax,CONFIG.fadeinInc);
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Start the fade-out
|
||||||
|
//
|
||||||
|
UnHover: function (jax) {
|
||||||
|
if (!jax.hover.nofade) {this.HoverFadeTimer(jax,-CONFIG.fadeoutInc,CONFIG.fadeoutStart)}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Handle the fade-in and fade-out
|
||||||
|
//
|
||||||
|
HoverFade: function (jax) {
|
||||||
|
delete jax.hover.timer;
|
||||||
|
jax.hover.opacity = Math.max(0,Math.min(1,jax.hover.opacity + jax.hover.inc));
|
||||||
|
jax.hover.opacity = Math.floor(1000*jax.hover.opacity)/1000;
|
||||||
|
var frame = document.getElementById(jax.hover.id),
|
||||||
|
button = document.getElementById(jax.hover.id+"Menu");
|
||||||
|
frame.firstChild.style.opacity = jax.hover.opacity;
|
||||||
|
frame.firstChild.style.filter = "alpha(opacity="+Math.floor(100*jax.hover.opacity)+")";
|
||||||
|
if (button) {
|
||||||
|
button.firstChild.style.opacity = jax.hover.opacity;
|
||||||
|
button.firstChild.style.filter = frame.style.filter;
|
||||||
|
}
|
||||||
|
if (jax.hover.opacity === 1) {return}
|
||||||
|
if (jax.hover.opacity > 0) {this.HoverFadeTimer(jax,jax.hover.inc); return}
|
||||||
|
frame.parentNode.removeChild(frame);
|
||||||
|
if (button) {button.parentNode.removeChild(button)}
|
||||||
|
if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
|
||||||
|
delete jax.hover;
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Set the fade to in or out (via inc) and start the timer, if needed
|
||||||
|
//
|
||||||
|
HoverFadeTimer: function (jax,inc,delay) {
|
||||||
|
jax.hover.inc = inc;
|
||||||
|
if (!jax.hover.timer) {
|
||||||
|
jax.hover.timer = setTimeout(CALLBACK(["HoverFade",this,jax]),(delay||CONFIG.fadeDelay));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle a click on the menu button
|
||||||
|
//
|
||||||
|
HoverMenu: function (event) {
|
||||||
|
if (!event) {event = window.event}
|
||||||
|
return OUTPUT[this.jax].ContextMenu(event,this.math,true);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear all hover timers
|
||||||
|
//
|
||||||
|
ClearHover: function (jax) {
|
||||||
|
if (jax.hover.remove) {clearTimeout(jax.hover.remove)}
|
||||||
|
if (jax.hover.timer) {clearTimeout(jax.hover.timer)}
|
||||||
|
HOVER.ClearHoverTimer();
|
||||||
|
delete jax.hover;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a measurement in pixels
|
||||||
|
//
|
||||||
|
Px: function (m) {
|
||||||
|
if (Math.abs(m) < .006) {return "0px"}
|
||||||
|
return m.toFixed(2).replace(/\.?0+$/,"") + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preload images so they show up with the menu
|
||||||
|
//
|
||||||
|
getImages: function () {
|
||||||
|
var menu = new Image();
|
||||||
|
menu.src = CONFIG.button.src;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle touch events.
|
||||||
|
//
|
||||||
|
// Use double-tap-and-hold as a replacement for context menu event.
|
||||||
|
// Use double-tap as a replacement for double click.
|
||||||
|
//
|
||||||
|
var TOUCH = ME.Touch = {
|
||||||
|
|
||||||
|
last: 0, // time of last tap event
|
||||||
|
delay: 500, // delay time for double-click
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if this is a double-tap, and if so, start the timer
|
||||||
|
// for the double-tap and hold (to trigger the contextual menu)
|
||||||
|
//
|
||||||
|
start: function (event) {
|
||||||
|
var now = new Date().getTime();
|
||||||
|
var dblTap = (now - TOUCH.last < TOUCH.delay);
|
||||||
|
TOUCH.last = now;
|
||||||
|
if (dblTap) {
|
||||||
|
TOUCH.timeout = setTimeout(TOUCH.menu,TOUCH.delay,event,this);
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if there is a timeout pending, i.e., we have a
|
||||||
|
// double-tap and were waiting to see if it is held long
|
||||||
|
// enough for the menu. Since we got the end before the
|
||||||
|
// timeout, it is a double-click, not a double-tap-and-hold.
|
||||||
|
// Prevent the default action and issue a double click.
|
||||||
|
//
|
||||||
|
end: function (event) {
|
||||||
|
if (TOUCH.timeout) {
|
||||||
|
clearTimeout(TOUCH.timeout);
|
||||||
|
delete TOUCH.timeout; TOUCH.last = 0;
|
||||||
|
event.preventDefault();
|
||||||
|
return EVENT.Handler((event.touches[0]||event.touch),"DblClick",this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the timeout passes without an end event, we issue
|
||||||
|
// the contextual menu event.
|
||||||
|
//
|
||||||
|
menu: function (event,math) {
|
||||||
|
delete TOUCH.timeout; TOUCH.last = 0;
|
||||||
|
return EVENT.Handler((event.touches[0]||event.touch),"ContextMenu",math);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mobile screens are small, so use larger version of arrow
|
||||||
|
//
|
||||||
|
if (HUB.Browser.isMobile) {
|
||||||
|
var arrow = CONFIG.styles[".MathJax_Hover_Arrow"];
|
||||||
|
arrow.width = "25px"; arrow.height = "18px";
|
||||||
|
CONFIG.button.x = -6;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up browser-specific values
|
||||||
|
//
|
||||||
|
HUB.Browser.Select({
|
||||||
|
MSIE: function (browser) {
|
||||||
|
var mode = (document.documentMode || 0);
|
||||||
|
var isIE8 = browser.versionAtLeast("8.0");
|
||||||
|
ME.msieBorderWidthBug = (document.compatMode === "BackCompat"); // borders are inside offsetWidth/Height
|
||||||
|
ME.msieEventBug = browser.isIE9; // must get event from window even though event is passed
|
||||||
|
ME.msieAlignBug = (!isIE8 || mode < 8); // inline-block spans don't rest on baseline
|
||||||
|
if (mode < 9) {EVENT.LEFTBUTTON = 1} // IE < 9 has wrong event.button values
|
||||||
|
},
|
||||||
|
Safari: function (browser) {
|
||||||
|
ME.safariContextMenuBug = true; // selection can be started by contextmenu event
|
||||||
|
},
|
||||||
|
Opera: function (browser) {
|
||||||
|
ME.operaPositionBug = true; // position is wrong unless border is used
|
||||||
|
},
|
||||||
|
Konqueror: function (browser) {
|
||||||
|
ME.noContextMenuBug = true; // doesn't produce contextmenu event
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Used in measuring zoom and hover positions
|
||||||
|
//
|
||||||
|
ME.topImg = (ME.msieAlignBug ?
|
||||||
|
HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) :
|
||||||
|
HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}})
|
||||||
|
);
|
||||||
|
if (ME.operaPositionBug) {ME.topImg.style.border="1px solid"}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get configuration from user
|
||||||
|
//
|
||||||
|
ME.config = CONFIG = HUB.CombineConfig("MathEvents",CONFIG);
|
||||||
|
var SETFRAME = function () {
|
||||||
|
var haze = CONFIG.styles[".MathJax_Hover_Frame"];
|
||||||
|
haze.border = CONFIG.frame.bwidth+"px solid "+CONFIG.frame.bcolor+" ! important";
|
||||||
|
haze["box-shadow"] = haze["-webkit-box-shadow"] =
|
||||||
|
haze["-moz-box-shadow"] = haze["-khtml-box-shadow"] =
|
||||||
|
"0px 0px "+CONFIG.frame.hwidth+" "+CONFIG.frame.hcolor;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Queue the events needed for startup
|
||||||
|
//
|
||||||
|
CALLBACK.Queue(
|
||||||
|
HUB.Register.StartupHook("End Config",{}), // wait until config is complete
|
||||||
|
[SETFRAME],
|
||||||
|
["getImages",HOVER],
|
||||||
|
["Styles",AJAX,CONFIG.styles],
|
||||||
|
["Post",HUB.Startup.signal,"MathEvents Ready"],
|
||||||
|
["loadComplete",AJAX,"[MathJax]/extensions/MathEvents.js"]
|
||||||
|
);
|
||||||
|
|
||||||
|
})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.Callback,MathJax.OutputJax,MathJax.InputJax);
|
1025
resources/viewer/mathjax/extensions/MathMenu.js
Normal file
1025
resources/viewer/mathjax/extensions/MathMenu.js
Normal file
File diff suppressed because it is too large
Load Diff
316
resources/viewer/mathjax/extensions/MathZoom.js
Normal file
316
resources/viewer/mathjax/extensions/MathZoom.js
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/MathZoom.js
|
||||||
|
*
|
||||||
|
* Implements the zoom feature for enlarging math expressions. It is
|
||||||
|
* loaded automatically when the Zoom menu selection changes from "None".
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (HUB,HTML,AJAX,HTMLCSS,nMML) {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var CONFIG = HUB.CombineConfig("MathZoom",{
|
||||||
|
styles: {
|
||||||
|
//
|
||||||
|
// The styles for the MathZoom display box
|
||||||
|
//
|
||||||
|
"#MathJax_Zoom": {
|
||||||
|
position:"absolute", "background-color":"#F0F0F0", overflow:"auto",
|
||||||
|
display:"block", "z-index":301, padding:".5em", border:"1px solid black", margin:0,
|
||||||
|
"font-weight":"normal", "font-style":"normal",
|
||||||
|
"text-align":"left", "text-indent":0, "text-transform":"none",
|
||||||
|
"line-height":"normal", "letter-spacing":"normal", "word-spacing":"normal",
|
||||||
|
"word-wrap":"normal", "white-space":"nowrap", "float":"none",
|
||||||
|
"box-shadow":"5px 5px 15px #AAAAAA", // Opera 10.5 and IE9
|
||||||
|
"-webkit-box-shadow":"5px 5px 15px #AAAAAA", // Safari 3 and Chrome
|
||||||
|
"-moz-box-shadow":"5px 5px 15px #AAAAAA", // Forefox 3.5
|
||||||
|
"-khtml-box-shadow":"5px 5px 15px #AAAAAA", // Konqueror
|
||||||
|
filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')" // IE
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// The styles for the hidden overlay (should not need to be adjusted by the page author)
|
||||||
|
//
|
||||||
|
"#MathJax_ZoomOverlay": {
|
||||||
|
position:"absolute", left:0, top:0, "z-index":300, display:"inline-block",
|
||||||
|
width:"100%", height:"100%", border:0, padding:0, margin:0,
|
||||||
|
"background-color":"white", opacity:0, filter:"alpha(opacity=0)"
|
||||||
|
},
|
||||||
|
|
||||||
|
"#MathJax_ZoomEventTrap": {
|
||||||
|
position:"absolute", left:0, top:0, "z-index":302,
|
||||||
|
display:"inline-block", border:0, padding:0, margin:0,
|
||||||
|
"background-color":"white", opacity:0, filter:"alpha(opacity=0)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var FALSE, HOVER, EVENT;
|
||||||
|
MathJax.Hub.Register.StartupHook("MathEvents Ready",function () {
|
||||||
|
EVENT = MathJax.Extension.MathEvents.Event;
|
||||||
|
FALSE = MathJax.Extension.MathEvents.Event.False;
|
||||||
|
HOVER = MathJax.Extension.MathEvents.Hover;
|
||||||
|
});
|
||||||
|
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
var ZOOM = MathJax.Extension.MathZoom = {
|
||||||
|
version: VERSION,
|
||||||
|
settings: HUB.config.menuSettings,
|
||||||
|
scrollSize: 18, // width of scrool bars
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process events passed from output jax
|
||||||
|
//
|
||||||
|
HandleEvent: function (event,type,math) {
|
||||||
|
if (ZOOM.settings.CTRL && !event.ctrlKey) return true;
|
||||||
|
if (ZOOM.settings.ALT && !event.altKey) return true;
|
||||||
|
if (ZOOM.settings.CMD && !event.metaKey) return true;
|
||||||
|
if (ZOOM.settings.Shift && !event.shiftKey) return true;
|
||||||
|
if (!ZOOM[type]) return true;
|
||||||
|
return ZOOM[type](event,math);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Zoom on click
|
||||||
|
//
|
||||||
|
Click: function (event,math) {
|
||||||
|
if (this.settings.zoom === "Click") {return this.Zoom(event,math)}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Zoom on double click
|
||||||
|
//
|
||||||
|
DblClick: function (event,math) {
|
||||||
|
if (this.settings.zoom === "Double-Click") {return this.Zoom(event,math)}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Zoom on hover (called by MathEvents.Hover)
|
||||||
|
//
|
||||||
|
Hover: function (event,math) {
|
||||||
|
if (this.settings.zoom === "Hover") {this.Zoom(event,math); return true}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle the actual zooming
|
||||||
|
//
|
||||||
|
Zoom: function (event,math) {
|
||||||
|
//
|
||||||
|
// Remove any other zoom and clear timers
|
||||||
|
//
|
||||||
|
this.Remove(); HOVER.ClearHoverTimer(); EVENT.ClearSelection();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find the jax
|
||||||
|
//
|
||||||
|
var JAX = MathJax.OutputJax[math.jaxID];
|
||||||
|
var jax = JAX.getJaxFromMath(math);
|
||||||
|
if (jax.hover) {HOVER.UnHover(jax)}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the DOM elements for the zoom box
|
||||||
|
//
|
||||||
|
var Mw = Math.floor(.85*document.body.clientWidth),
|
||||||
|
Mh = Math.floor(.85*Math.max(document.body.clientHeight,document.documentElement.clientHeight));
|
||||||
|
var div = HTML.Element(
|
||||||
|
"span",{
|
||||||
|
style: {position:"relative", display:"inline-block", height:0, width:0},
|
||||||
|
id:"MathJax_ZoomFrame"
|
||||||
|
},[
|
||||||
|
["span",{id:"MathJax_ZoomOverlay", onmousedown:this.Remove}],
|
||||||
|
["span",{
|
||||||
|
id:"MathJax_Zoom", onclick:this.Remove,
|
||||||
|
style:{
|
||||||
|
visibility:"hidden", fontSize:this.settings.zscale,
|
||||||
|
"max-width":Mw+"px", "max-height":Mh+"px"
|
||||||
|
}
|
||||||
|
},[["span",{style:{display:"inline-block", "white-space":"nowrap"}}]]
|
||||||
|
]]
|
||||||
|
);
|
||||||
|
var zoom = div.lastChild, span = zoom.firstChild, overlay = div.firstChild;
|
||||||
|
math.parentNode.insertBefore(div,math);
|
||||||
|
if (span.addEventListener) {span.addEventListener("mousedown",this.Remove,true)}
|
||||||
|
|
||||||
|
if (this.msieTrapEventBug) {
|
||||||
|
var trap = HTML.Element("span",{id:"MathJax_ZoomEventTrap", onmousedown:this.Remove});
|
||||||
|
div.insertBefore(trap,zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Display the zoomed math
|
||||||
|
//
|
||||||
|
if (this.msieZIndexBug) {
|
||||||
|
// MSIE doesn't do z-index properly, so move the div to the document.body,
|
||||||
|
// and use an image as a tracker for the usual position
|
||||||
|
var tracker = HTML.addElement(document.body,"img",{
|
||||||
|
src:"about:blank", id:"MathJax_ZoomTracker", width:0, height:0,
|
||||||
|
style:{width:0, height:0, position:"relative"}
|
||||||
|
});
|
||||||
|
div.style.position = "relative";
|
||||||
|
div.style.zIndex = CONFIG.styles["#MathJax_ZoomOverlay"]["z-index"];
|
||||||
|
div = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bbox = JAX.Zoom(jax,span,math,Mw,Mh);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix up size and position for browsers with bugs (IE)
|
||||||
|
//
|
||||||
|
if (this.msiePositionBug) {
|
||||||
|
if (this.msieSizeBug)
|
||||||
|
{zoom.style.height = bbox.zH+"px"; zoom.style.width = bbox.zW+"px"} // IE8 gets the dimensions completely wrong
|
||||||
|
if (zoom.offsetHeight > Mh) {zoom.style.height = Mh+"px"; zoom.style.width = (bbox.zW+this.scrollSize)+"px"} // IE doesn't do max-height?
|
||||||
|
if (zoom.offsetWidth > Mw) {zoom.style.width = Mw+"px"; zoom.style.height = (bbox.zH+this.scrollSize)+"px"}
|
||||||
|
}
|
||||||
|
if (this.operaPositionBug) {zoom.style.width = Math.min(Mw,bbox.zW)+"px"} // Opera gets width as 0?
|
||||||
|
if (zoom.offsetWidth < Mw && zoom.offsetHeight < Mh) {zoom.style.overflow = "visible"}
|
||||||
|
this.Position(zoom,bbox);
|
||||||
|
if (this.msieTrapEventBug) {
|
||||||
|
trap.style.height = zoom.clientHeight+"px"; trap.style.width = zoom.clientWidth+"px";
|
||||||
|
trap.style.left = (parseFloat(zoom.style.left)+zoom.clientLeft)+"px";
|
||||||
|
trap.style.top = (parseFloat(zoom.style.top)+zoom.clientTop)+"px";
|
||||||
|
}
|
||||||
|
zoom.style.visibility = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add event handlers
|
||||||
|
//
|
||||||
|
if (this.settings.zoom === "Hover") {overlay.onmouseover = this.Remove}
|
||||||
|
if (window.addEventListener) {addEventListener("resize",this.Resize,false)}
|
||||||
|
else if (window.attachEvent) {attachEvent("onresize",this.Resize)}
|
||||||
|
else {this.onresize = window.onresize; window.onresize = this.Resize}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Let others know about the zoomed math
|
||||||
|
//
|
||||||
|
HUB.signal.Post(["math zoomed",jax]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Canel further actions
|
||||||
|
//
|
||||||
|
return FALSE(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the position of the zoom box and overlay
|
||||||
|
//
|
||||||
|
Position: function (zoom,bbox) {
|
||||||
|
var XY = this.Resize(), x = XY.x, y = XY.y, W = bbox.mW;
|
||||||
|
var dx = -Math.floor((zoom.offsetWidth-W)/2), dy = bbox.Y;
|
||||||
|
zoom.style.left = Math.max(dx,10-x)+"px"; zoom.style.top = Math.max(dy,10-y)+"px";
|
||||||
|
if (!ZOOM.msiePositionBug) {ZOOM.SetWH()} // refigure overlay width/height
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle resizing of overlay while zoom is displayed
|
||||||
|
//
|
||||||
|
Resize: function (event) {
|
||||||
|
if (ZOOM.onresize) {ZOOM.onresize(event)}
|
||||||
|
var x = 0, y = 0, obj,
|
||||||
|
div = document.getElementById("MathJax_ZoomFrame"),
|
||||||
|
overlay = document.getElementById("MathJax_ZoomOverlay");
|
||||||
|
obj = div; while (obj.offsetParent) {x += obj.offsetLeft; obj = obj.offsetParent}
|
||||||
|
if (ZOOM.operaPositionBug) {div.style.border = "1px solid"} // to get vertical position right
|
||||||
|
obj = div; while (obj.offsetParent) {y += obj.offsetTop; obj = obj.offsetParent}
|
||||||
|
if (ZOOM.operaPositionBug) {div.style.border = ""}
|
||||||
|
overlay.style.left = (-x)+"px"; overlay.style.top = (-y)+"px";
|
||||||
|
if (ZOOM.msiePositionBug) {setTimeout(ZOOM.SetWH,0)} else {ZOOM.SetWH()}
|
||||||
|
return {x:x, y:y};
|
||||||
|
},
|
||||||
|
SetWH: function () {
|
||||||
|
var overlay = document.getElementById("MathJax_ZoomOverlay");
|
||||||
|
overlay.style.width = overlay.style.height = "1px"; // so scrollWidth/Height will be right below
|
||||||
|
var doc = document.documentElement || document.body;
|
||||||
|
overlay.style.width = doc.scrollWidth + "px";
|
||||||
|
overlay.style.height = Math.max(doc.clientHeight,doc.scrollHeight) + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove zoom display and event handlers
|
||||||
|
//
|
||||||
|
Remove: function (event) {
|
||||||
|
var div = document.getElementById("MathJax_ZoomFrame");
|
||||||
|
if (div) {
|
||||||
|
var JAX = MathJax.OutputJax[div.nextSibling.jaxID];
|
||||||
|
var jax = JAX.getJaxFromMath(div.nextSibling);
|
||||||
|
HUB.signal.Post(["math unzoomed",jax]);
|
||||||
|
div.parentNode.removeChild(div);
|
||||||
|
div = document.getElementById("MathJax_ZoomTracker");
|
||||||
|
if (div) {div.parentNode.removeChild(div)}
|
||||||
|
if (ZOOM.operaRefreshBug) {
|
||||||
|
// force a redisplay of the page
|
||||||
|
// (Opera doesn't refresh properly after the zoom is removed)
|
||||||
|
var overlay = HTML.addElement(document.body,"div",{
|
||||||
|
style:{position:"fixed", left:0, top:0, width:"100%", height:"100%",
|
||||||
|
backgroundColor:"white", opacity:0},
|
||||||
|
id: "MathJax_OperaDiv"
|
||||||
|
});
|
||||||
|
document.body.removeChild(overlay);
|
||||||
|
}
|
||||||
|
if (window.removeEventListener) {removeEventListener("resize",ZOOM.Resize,false)}
|
||||||
|
else if (window.detachEvent) {detachEvent("onresize",ZOOM.Resize)}
|
||||||
|
else {window.onresize = ZOOM.onresize; delete ZOOM.onresize}
|
||||||
|
}
|
||||||
|
return FALSE(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
HUB.Browser.Select({
|
||||||
|
MSIE: function (browser) {
|
||||||
|
var mode = (document.documentMode || 0);
|
||||||
|
var isIE9 = (mode >= 9);
|
||||||
|
ZOOM.msiePositionBug = !isIE9;
|
||||||
|
ZOOM.msieSizeBug = browser.versionAtLeast("7.0") &&
|
||||||
|
(!document.documentMode || mode === 7 || mode === 8);
|
||||||
|
ZOOM.msieZIndexBug = (mode <= 7);
|
||||||
|
ZOOM.msieInlineBlockAlignBug = (mode <= 7);
|
||||||
|
ZOOM.msieTrapEventBug = !window.addEventListener;
|
||||||
|
if (document.compatMode === "BackCompat") {ZOOM.scrollSize = 52} // don't know why this is so far off
|
||||||
|
if (isIE9) {delete CONFIG.styles["#MathJax_Zoom"].filter}
|
||||||
|
},
|
||||||
|
|
||||||
|
Opera: function (browser) {
|
||||||
|
ZOOM.operaPositionBug = true;
|
||||||
|
ZOOM.operaRefreshBug = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ZOOM.topImg = (ZOOM.msieInlineBlockAlignBug ?
|
||||||
|
HTML.Element("img",{style:{width:0,height:0,position:"relative"},src:"about:blank"}) :
|
||||||
|
HTML.Element("span",{style:{width:0,height:0,display:"inline-block"}})
|
||||||
|
);
|
||||||
|
if (ZOOM.operaPositionBug || ZOOM.msieTopBug) {ZOOM.topImg.style.border="1px solid"}
|
||||||
|
|
||||||
|
/*************************************************************/
|
||||||
|
|
||||||
|
MathJax.Callback.Queue(
|
||||||
|
["StartupHook",MathJax.Hub.Register,"Begin Styles",{}],
|
||||||
|
["Styles",AJAX,CONFIG.styles],
|
||||||
|
["Post",HUB.Startup.signal,"MathZoom Ready"],
|
||||||
|
["loadComplete",AJAX,"[MathJax]/extensions/MathZoom.js"]
|
||||||
|
);
|
||||||
|
|
||||||
|
})(MathJax.Hub,MathJax.HTML,MathJax.Ajax,MathJax.OutputJax["HTML-CSS"],MathJax.OutputJax.NativeMML);
|
567
resources/viewer/mathjax/extensions/TeX/AMSmath.js
Normal file
567
resources/viewer/mathjax/extensions/TeX/AMSmath.js
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/AMSmath.js
|
||||||
|
*
|
||||||
|
* Implements AMS math environments and macros.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/AMSmath"] = {
|
||||||
|
version: "2.0",
|
||||||
|
|
||||||
|
number: 0, // current equation number
|
||||||
|
startNumber: 0, // current starting equation number (for when equation is restarted)
|
||||||
|
labels: {}, // the set of labels
|
||||||
|
eqlabels: {}, // labels in the current equation
|
||||||
|
refs: [] // array of jax with unresolved references
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var MML = MathJax.ElementJax.mml,
|
||||||
|
TEX = MathJax.InputJax.TeX,
|
||||||
|
AMS = MathJax.Extension["TeX/AMSmath"];
|
||||||
|
|
||||||
|
var TEXDEF = TEX.Definitions,
|
||||||
|
STACKITEM = TEX.Stack.Item,
|
||||||
|
CONFIG = TEX.config.equationNumbers;
|
||||||
|
|
||||||
|
var COLS = function (W) {return W.join("em ") + "em"};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEXDEF.Add({
|
||||||
|
macros: {
|
||||||
|
mathring: ['Accent','2DA'], // or 0x30A
|
||||||
|
|
||||||
|
nobreakspace: 'Tilde',
|
||||||
|
negmedspace: ['Spacer',MML.LENGTH.NEGATIVEMEDIUMMATHSPACE],
|
||||||
|
negthickspace: ['Spacer',MML.LENGTH.NEGATIVETHICKMATHSPACE],
|
||||||
|
|
||||||
|
intI: ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'],
|
||||||
|
// iint: ['MultiIntegral','\\int\\intI'], // now in core TeX input jax
|
||||||
|
// iiint: ['MultiIntegral','\\int\\intI\\intI'], // now in core TeX input jax
|
||||||
|
iiiint: ['MultiIntegral','\\int\\intI\\intI\\intI'],
|
||||||
|
idotsint: ['MultiIntegral','\\int\\cdots\\int'],
|
||||||
|
|
||||||
|
dddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}}',1],
|
||||||
|
ddddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle \\mathord{.}\\mathord{.}\\mathord{.}\\mathord{.}}',1],
|
||||||
|
|
||||||
|
sideset: ['Macro','\\mathop{\\mathop{\\rlap{\\phantom{#3}}}\\nolimits#1\\!\\mathop{#3}\\nolimits#2}',3],
|
||||||
|
|
||||||
|
boxed: ['Macro','\\fbox{$\\displaystyle{#1}$}',1],
|
||||||
|
|
||||||
|
tag: 'HandleTag',
|
||||||
|
notag: 'HandleNoTag',
|
||||||
|
label: 'HandleLabel',
|
||||||
|
ref: 'HandleRef',
|
||||||
|
eqref: ['HandleRef',true],
|
||||||
|
|
||||||
|
substack: ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1],
|
||||||
|
|
||||||
|
injlim: ['Macro','\\mathop{\\rm inj\\,lim}'],
|
||||||
|
projlim: ['Macro','\\mathop{\\rm proj\\,lim}'],
|
||||||
|
varliminf: ['Macro','\\mathop{\\underline{\\rm lim}}'],
|
||||||
|
varlimsup: ['Macro','\\mathop{\\overline{\\rm lim}}'],
|
||||||
|
varinjlim: ['Macro','\\mathop{\\underrightarrow{\\rm lim\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'],
|
||||||
|
varprojlim: ['Macro','\\mathop{\\underleftarrow{\\rm lim\\Rule{-1pt}{0pt}{1pt}}\\Rule{0pt}{0pt}{.45em}}'],
|
||||||
|
|
||||||
|
DeclareMathOperator: 'HandleDeclareOp',
|
||||||
|
operatorname: 'HandleOperatorName',
|
||||||
|
|
||||||
|
genfrac: 'Genfrac',
|
||||||
|
frac: ['Genfrac',"","","",""],
|
||||||
|
tfrac: ['Genfrac',"","","",1],
|
||||||
|
dfrac: ['Genfrac',"","","",0],
|
||||||
|
binom: ['Genfrac',"(",")","0em",""],
|
||||||
|
tbinom: ['Genfrac',"(",")","0em",1],
|
||||||
|
dbinom: ['Genfrac',"(",")","0em",0],
|
||||||
|
|
||||||
|
cfrac: 'CFrac',
|
||||||
|
|
||||||
|
shoveleft: ['HandleShove',MML.ALIGN.LEFT],
|
||||||
|
shoveright: ['HandleShove',MML.ALIGN.RIGHT],
|
||||||
|
|
||||||
|
xrightarrow: ['xArrow',0x2192,5,6],
|
||||||
|
xleftarrow: ['xArrow',0x2190,7,3]
|
||||||
|
},
|
||||||
|
|
||||||
|
environment: {
|
||||||
|
align: ['AMSarray',null,true,true, 'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18])],
|
||||||
|
'align*': ['AMSarray',null,false,true, 'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18])],
|
||||||
|
multline: ['Multline',null,true],
|
||||||
|
'multline*': ['Multline',null,false],
|
||||||
|
split: ['AMSarray',null,false,false,'rl',COLS([5/18])],
|
||||||
|
gather: ['AMSarray',null,true,true, 'c'],
|
||||||
|
'gather*': ['AMSarray',null,false,true, 'c'],
|
||||||
|
|
||||||
|
alignat: ['AlignAt',null,true,true],
|
||||||
|
'alignat*': ['AlignAt',null,false,true],
|
||||||
|
alignedat: ['AlignAt',null,false,false],
|
||||||
|
|
||||||
|
aligned: ['AlignedArray',null,null,null,'rlrlrlrlrlrl',COLS([5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18]),".5em",'D'],
|
||||||
|
gathered: ['AlignedArray',null,null,null,'c',null,".5em",'D'],
|
||||||
|
|
||||||
|
subarray: ['Array',null,null,null,null,COLS([0,0,0,0]),"0.1em",'S',1],
|
||||||
|
smallmatrix: ['Array',null,null,null,'c',COLS([1/3]),".2em",'S',1],
|
||||||
|
|
||||||
|
'equation': ['EquationBegin','Equation',true],
|
||||||
|
'equation*': ['EquationBegin','EquationStar',false]
|
||||||
|
},
|
||||||
|
|
||||||
|
delimiter: {
|
||||||
|
'\\lvert': ['2223',{texClass:MML.TEXCLASS.OPEN}],
|
||||||
|
'\\rvert': ['2223',{texClass:MML.TEXCLASS.CLOSE}],
|
||||||
|
'\\lVert': ['2225',{texClass:MML.TEXCLASS.OPEN}],
|
||||||
|
'\\rVert': ['2225',{texClass:MML.TEXCLASS.CLOSE}]
|
||||||
|
}
|
||||||
|
},null,true);
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the tag to the environment (to be added to the table row later)
|
||||||
|
*/
|
||||||
|
HandleTag: function (name) {
|
||||||
|
var star = this.GetStar();
|
||||||
|
var arg = this.trimSpaces(this.GetArgument(name)), tag = arg;
|
||||||
|
if (!star) {arg = CONFIG.formatTag(arg)}
|
||||||
|
var global = this.stack.global; global.tagID = tag;
|
||||||
|
if (global.notags) {TEX.Error(name+" not allowed in "+global.notags+" environment")}
|
||||||
|
if (global.tag) {TEX.Error("Multiple "+name)}
|
||||||
|
global.tag = MML.mtd.apply(MML,this.InternalMath(arg)).With({id:CONFIG.formatID(tag)});
|
||||||
|
},
|
||||||
|
HandleNoTag: function (name) {
|
||||||
|
if (this.stack.global.tag) {delete this.stack.global.tag}
|
||||||
|
this.stack.global.notag = true; // prevent auto-tagging
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record a label name for a tag
|
||||||
|
*/
|
||||||
|
HandleLabel: function (name) {
|
||||||
|
var global = this.stack.global, label = this.GetArgument(name);
|
||||||
|
if (!AMS.refUpdate) {
|
||||||
|
if (global.label) {TEX.Error("Multiple "+name+"'s")}
|
||||||
|
global.label = label;
|
||||||
|
if (AMS.labels[label] || AMS.eqlabels[label]) {TEX.Error("Label '"+label+"' mutiply defined")}
|
||||||
|
AMS.eqlabels[label] = "???"; // will be replaced by tag value later
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle a label reference
|
||||||
|
*/
|
||||||
|
HandleRef: function (name,eqref) {
|
||||||
|
var label = this.GetArgument(name);
|
||||||
|
var ref = AMS.labels[label] || AMS.eqlabels[label];
|
||||||
|
if (!ref) {ref = "??"; AMS.badref = !AMS.refUpdate}
|
||||||
|
var tag = ref; if (eqref) {tag = CONFIG.formatTag(tag)}
|
||||||
|
if (CONFIG.useLabelIds) {ref = label}
|
||||||
|
this.Push(MML.mrow.apply(MML,this.InternalMath(tag)).With({
|
||||||
|
href:CONFIG.formatURL(CONFIG.formatID(ref)), "class":"MathJax_ref"
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle \DeclareMathOperator
|
||||||
|
*/
|
||||||
|
HandleDeclareOp: function (name) {
|
||||||
|
var limits = (this.GetStar() ? "\\limits" : "");
|
||||||
|
var cs = this.trimSpaces(this.GetArgument(name));
|
||||||
|
if (cs.charAt(0) == "\\") {cs = cs.substr(1)}
|
||||||
|
var op = this.GetArgument(name);
|
||||||
|
op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}');
|
||||||
|
TEX.Definitions.macros[cs] = ['Macro','\\mathop{\\rm '+op+'}'+limits];
|
||||||
|
},
|
||||||
|
|
||||||
|
HandleOperatorName: function (name) {
|
||||||
|
var limits = (this.GetStar() ? "\\limits" : "\\nolimits");
|
||||||
|
var op = this.trimSpaces(this.GetArgument(name));
|
||||||
|
op = op.replace(/\*/g,'\\text{*}').replace(/-/g,'\\text{-}');
|
||||||
|
this.string = '\\mathop{\\rm '+op+'}'+limits+" "+this.string.slice(this.i);
|
||||||
|
this.i = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record presence of \shoveleft and \shoveright
|
||||||
|
*/
|
||||||
|
HandleShove: function (name,shove) {
|
||||||
|
var top = this.stack.Top();
|
||||||
|
if (top.type !== "multline" || top.data.length) {TEX.Error(name+" must come at the beginning of the line")}
|
||||||
|
top.data.shove = shove;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle \cfrac
|
||||||
|
*/
|
||||||
|
CFrac: function (name) {
|
||||||
|
var lr = this.trimSpaces(this.GetBrackets(name,"")),
|
||||||
|
num = this.GetArgument(name),
|
||||||
|
den = this.GetArgument(name);
|
||||||
|
var frac = MML.mfrac(TEX.Parse('\\strut\\textstyle{'+num+'}',this.stack.env).mml(),
|
||||||
|
TEX.Parse('\\strut\\textstyle{'+den+'}',this.stack.env).mml());
|
||||||
|
lr = ({l:MML.ALIGN.LEFT, r:MML.ALIGN.RIGHT,"":""})[lr];
|
||||||
|
if (lr == null) {TEX.Error("Illegal alignment specified in "+name)}
|
||||||
|
if (lr) {frac.numalign = frac.denomalign = lr}
|
||||||
|
this.Push(frac);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement AMS generalized fraction
|
||||||
|
*/
|
||||||
|
Genfrac: function (name,left,right,thick,style) {
|
||||||
|
if (left == null) {left = this.GetDelimiterArg(name)} else {left = this.convertDelimiter(left)}
|
||||||
|
if (right == null) {right = this.GetDelimiterArg(name)} else {right = this.convertDelimiter(right)}
|
||||||
|
if (thick == null) {thick = this.GetArgument(name)}
|
||||||
|
if (style == null) {style = this.trimSpaces(this.GetArgument(name))}
|
||||||
|
var num = this.ParseArg(name);
|
||||||
|
var den = this.ParseArg(name);
|
||||||
|
var frac = MML.mfrac(num,den);
|
||||||
|
if (thick !== "") {frac.linethickness = thick}
|
||||||
|
if (left || right) {frac = MML.mfenced(frac).With({open: left, close: right})}
|
||||||
|
if (style !== "") {
|
||||||
|
var STYLE = (["D","T","S","SS"])[style];
|
||||||
|
if (STYLE == null) {TEX.Error("Bad math style for "+name)}
|
||||||
|
frac = MML.mstyle(frac);
|
||||||
|
if (STYLE === "D") {frac.displaystyle = true; frac.scriptlevel = 0}
|
||||||
|
else {frac.displaystyle = false; frac.scriptlevel = style - 1}
|
||||||
|
}
|
||||||
|
this.Push(frac);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implements multline environment (mostly handled through STACKITEM below)
|
||||||
|
*/
|
||||||
|
Multline: function (begin,numbered) {
|
||||||
|
this.Push(begin); this.checkEqnEnv();
|
||||||
|
return STACKITEM.multline(numbered,this.stack).With({
|
||||||
|
arraydef: {
|
||||||
|
displaystyle: true,
|
||||||
|
rowspacing: ".5em",
|
||||||
|
width: TEX.config.MultLineWidth, columnwidth:"100%",
|
||||||
|
side: TEX.config.TagSide,
|
||||||
|
minlabelspacing: TEX.config.TagIndent
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle AMS aligned environments
|
||||||
|
*/
|
||||||
|
AMSarray: function (begin,numbered,taggable,align,spacing) {
|
||||||
|
this.Push(begin); if (taggable) {this.checkEqnEnv()}
|
||||||
|
align = align.replace(/[^clr]/g,'').split('').join(' ');
|
||||||
|
align = align.replace(/l/g,'left').replace(/r/g,'right').replace(/c/g,'center');
|
||||||
|
return STACKITEM.AMSarray(begin.name,numbered,taggable,this.stack).With({
|
||||||
|
arraydef: {
|
||||||
|
displaystyle: true,
|
||||||
|
rowspacing: ".5em",
|
||||||
|
columnalign: align,
|
||||||
|
columnspacing: (spacing||"1em"),
|
||||||
|
rowspacing: "3pt",
|
||||||
|
side: TEX.config.TagSide,
|
||||||
|
minlabelspacing: TEX.config.TagIndent
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle alignat environments
|
||||||
|
*/
|
||||||
|
AlignAt: function (begin,numbered,taggable) {
|
||||||
|
var n, valign, align = "", spacing = [];
|
||||||
|
if (!taggable) {valign = this.GetBrackets("\\begin{"+begin.name+"}")}
|
||||||
|
n = this.GetArgument("\\begin{"+begin.name+"}");
|
||||||
|
if (n.match(/[^0-9]/)) {TEX.Error("Argument to \\begin{"+begin.name+"} must me a positive integer")}
|
||||||
|
while (n > 0) {align += "rl"; spacing.push("0em 0em"); n--}
|
||||||
|
spacing = spacing.join(" ");
|
||||||
|
if (taggable) {return this.AMSarray(begin,numbered,taggable,align,spacing)}
|
||||||
|
var array = this.Array.call(this,begin,null,null,align,spacing,".5em",'D');
|
||||||
|
return this.setArrayAlign(array,valign);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle equation environment
|
||||||
|
*/
|
||||||
|
EquationBegin: function (begin,force) {
|
||||||
|
this.checkEqnEnv();
|
||||||
|
this.stack.global.forcetag = (force && CONFIG.autoNumber !== "none");
|
||||||
|
return begin;
|
||||||
|
},
|
||||||
|
EquationStar: function (begin,row) {
|
||||||
|
this.stack.global.tagged = true; // prevent automatic tagging
|
||||||
|
return row;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for bad nesting of equation environments
|
||||||
|
*/
|
||||||
|
checkEqnEnv: function () {
|
||||||
|
if (this.stack.global.eqnenv) {TEX.Error("Erroneous nesting of equation structures")}
|
||||||
|
this.stack.global.eqnenv = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle multiple integrals (make a mathop if followed by limits)
|
||||||
|
*/
|
||||||
|
MultiIntegral: function (name,integral) {
|
||||||
|
var next = this.GetNext();
|
||||||
|
if (next === "\\") {
|
||||||
|
var i = this.i; next = this.GetArgument(name); this.i = i;
|
||||||
|
if (next === "\\limits") {
|
||||||
|
if (name === "\\idotsint") {integral = "\\!\\!\\mathop{\\,\\,"+integral+"}"}
|
||||||
|
else {integral = "\\!\\!\\!\\mathop{\\,\\,\\,"+integral+"}"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.string = integral + " " + this.string.slice(this.i);
|
||||||
|
this.i = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle stretchable arrows
|
||||||
|
*/
|
||||||
|
xArrow: function (name,chr,l,r) {
|
||||||
|
var def = {width: "+"+(l+r)+"mu", lspace: l+"mu"};
|
||||||
|
var bot = this.GetBrackets(name),
|
||||||
|
top = this.ParseArg(name);
|
||||||
|
var arrow = MML.mo(MML.chars(String.fromCharCode(chr))).With({
|
||||||
|
stretchy: true, texClass: MML.TEXCLASS.REL
|
||||||
|
});
|
||||||
|
var mml = MML.munderover(arrow);
|
||||||
|
mml.SetData(mml.over,MML.mpadded(top).With(def).With({voffset:".15em"}));
|
||||||
|
if (bot) {
|
||||||
|
bot = TEX.Parse(bot,this.stack.env).mml()
|
||||||
|
mml.SetData(mml.under,MML.mpadded(bot).With(def).With({voffset:"-.24em"}));
|
||||||
|
}
|
||||||
|
this.Push(mml);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a delimiter or empty argument
|
||||||
|
*/
|
||||||
|
GetDelimiterArg: function (name) {
|
||||||
|
var c = this.trimSpaces(this.GetArgument(name));
|
||||||
|
if (c == "") {return null}
|
||||||
|
if (TEXDEF.delimiter[c] == null) {TEX.Error("Missing or unrecognized delimiter for "+name)}
|
||||||
|
return this.convertDelimiter(c);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a star following a control sequence name, if any
|
||||||
|
*/
|
||||||
|
GetStar: function () {
|
||||||
|
var star = (this.GetNext() === "*");
|
||||||
|
if (star) {this.i++}
|
||||||
|
return star;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
STACKITEM.Augment({
|
||||||
|
/*
|
||||||
|
* Increment equation number and form tag mtd element
|
||||||
|
*/
|
||||||
|
autoTag: function () {
|
||||||
|
var global = this.global;
|
||||||
|
if (!global.notag) {
|
||||||
|
AMS.number++; global.tagID = CONFIG.formatNumber(AMS.number.toString());
|
||||||
|
var mml = TEX.Parse("\\text{"+CONFIG.formatTag(global.tagID)+"}",{}).mml();
|
||||||
|
global.tag = MML.mtd(mml.With({id:CONFIG.formatID(global.tagID)}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the tag and record the label, if any
|
||||||
|
*/
|
||||||
|
getTag: function () {
|
||||||
|
var global = this.global, tag = global.tag; global.tagged = true;
|
||||||
|
if (global.label) {
|
||||||
|
AMS.eqlabels[global.label] = global.tagID;
|
||||||
|
if (CONFIG.useLabelIds) {tag.id = CONFIG.formatID(global.label)}
|
||||||
|
}
|
||||||
|
delete global.tag; delete global.tagID; delete global.label;
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement multline environment via a STACKITEM
|
||||||
|
*/
|
||||||
|
STACKITEM.multline = STACKITEM.array.Subclass({
|
||||||
|
type: "multline",
|
||||||
|
Init: function (numbered,stack) {
|
||||||
|
this.SUPER(arguments).Init.apply(this);
|
||||||
|
this.numbered = (numbered && CONFIG.autoNumber !== "none");
|
||||||
|
this.save = {notag: stack.global.notag};
|
||||||
|
stack.global.tagged = !numbered && !stack.global.forcetag; // prevent automatic tagging in starred environments
|
||||||
|
},
|
||||||
|
EndEntry: function () {
|
||||||
|
var mtd = MML.mtd.apply(MML,this.data);
|
||||||
|
if (this.data.shove) {mtd.columnalign = this.data.shove}
|
||||||
|
this.row.push(mtd);
|
||||||
|
this.data = [];
|
||||||
|
},
|
||||||
|
EndRow: function () {
|
||||||
|
if (this.row.length != 1) {TEX.Error("multline rows must have exactly one column")}
|
||||||
|
this.table.push(this.row); this.row = [];
|
||||||
|
},
|
||||||
|
EndTable: function () {
|
||||||
|
this.SUPER(arguments).EndTable.call(this);
|
||||||
|
if (this.table.length) {
|
||||||
|
var m = this.table.length-1, i, label = -1;
|
||||||
|
if (!this.table[0][0].columnalign) {this.table[0][0].columnalign = MML.ALIGN.LEFT}
|
||||||
|
if (!this.table[m][0].columnalign) {this.table[m][0].columnalign = MML.ALIGN.RIGHT}
|
||||||
|
if (!this.global.tag && this.numbered) {this.autoTag()}
|
||||||
|
if (this.global.tag && !this.global.notags) {
|
||||||
|
label = (this.arraydef.side === "left" ? 0 : this.table.length - 1);
|
||||||
|
this.table[label] = [this.getTag()].concat(this.table[label]);
|
||||||
|
}
|
||||||
|
for (i = 0, m = this.table.length; i < m; i++) {
|
||||||
|
var mtr = (i === label ? MML.mlabeledtr : MML.mtr);
|
||||||
|
this.table[i] = mtr.apply(MML,this.table[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.global.notag = this.save.notag;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save data about numbering and taging equations, and add
|
||||||
|
* tags at the ends of rows.
|
||||||
|
*/
|
||||||
|
STACKITEM.AMSarray = STACKITEM.array.Subclass({
|
||||||
|
type: "AMSarray",
|
||||||
|
Init: function (name,numbered,taggable,stack) {
|
||||||
|
this.SUPER(arguments).Init.apply(this);
|
||||||
|
this.numbered = (numbered && CONFIG.autoNumber !== "none");
|
||||||
|
this.save = {notags: stack.global.notags, notag: stack.global.notag};
|
||||||
|
stack.global.notags = (taggable ? null : name);
|
||||||
|
stack.global.tagged = !numbered && !stack.global.forcetag; // prevent automatic tagging in starred environments
|
||||||
|
},
|
||||||
|
EndRow: function () {
|
||||||
|
var mtr = MML.mtr;
|
||||||
|
if (!this.global.tag && this.numbered) {this.autoTag()}
|
||||||
|
if (this.global.tag &&! this.global.notags) {
|
||||||
|
this.row = [this.getTag()].concat(this.row);
|
||||||
|
mtr = MML.mlabeledtr;
|
||||||
|
}
|
||||||
|
if (this.numbered) {delete this.global.notag}
|
||||||
|
this.table.push(mtr.apply(MML,this.row)); this.row = [];
|
||||||
|
},
|
||||||
|
EndTable: function () {
|
||||||
|
this.SUPER(arguments).EndTable.call(this);
|
||||||
|
this.global.notags = this.save.notags;
|
||||||
|
this.global.notag = this.save.notag;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for \tag on a formula and make an mtable to include it
|
||||||
|
//
|
||||||
|
STACKITEM.start.Augment({
|
||||||
|
oldCheckItem: STACKITEM.start.prototype.checkItem,
|
||||||
|
checkItem: function (item) {
|
||||||
|
if (item.type === "stop") {
|
||||||
|
var mml = this.mmlData(), global = this.global;
|
||||||
|
if (AMS.display && !global.tag && !global.tagged && !global.isInner &&
|
||||||
|
(CONFIG.autoNumber === "all" || global.forcetag)) {this.autoTag()}
|
||||||
|
if (global.tag) {
|
||||||
|
var row = [this.getTag(),MML.mtd(mml)];
|
||||||
|
var def = {
|
||||||
|
side: TEX.config.TagSide,
|
||||||
|
minlabelspacing: TEX.config.TagIndent,
|
||||||
|
columnalign: mml.displayAlign
|
||||||
|
};
|
||||||
|
if (mml.displayAlign === MML.INDENTALIGN.LEFT) {
|
||||||
|
def.width = "100%";
|
||||||
|
if (mml.displayIndent && !String(mml.displayIndent).match(/^0+(\.0*)?($|[a-z%])/)) {
|
||||||
|
def.columnwidth = mml.displayIndent + " fit"; def.columnspacing = "0"
|
||||||
|
row = [row[0],MML.mtd(),row[1]];
|
||||||
|
}
|
||||||
|
} else if (mml.displayAlign === MML.INDENTALIGN.RIGHT) {
|
||||||
|
def.width = "100%";
|
||||||
|
if (mml.displayIndent && !String(mml.displayIndent).match(/^0+(\.0*)?($|[a-z%])/)) {
|
||||||
|
def.columnwidth = "fit "+mml.displayIndent; def.columnspacing = "0"
|
||||||
|
row[2] = MML.mtd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mml = MML.mtable(MML.mlabeledtr.apply(MML,row)).With(def);
|
||||||
|
}
|
||||||
|
return STACKITEM.mml(mml);
|
||||||
|
}
|
||||||
|
return this.oldCheckItem.call(this,item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add pre- and post-filters to handle the equation number maintainance.
|
||||||
|
*/
|
||||||
|
TEX.prefilterHooks.Add(function (data) {
|
||||||
|
AMS.display = data.display;
|
||||||
|
AMS.number = AMS.startNumber; // reset equation numbers (in case the equation restarted)
|
||||||
|
AMS.eqlabels = {}; AMS.badref = false;
|
||||||
|
if (AMS.refUpdate) {AMS.number = data.script.MathJax.startNumber}
|
||||||
|
});
|
||||||
|
TEX.postfilterHooks.Add(function (data) {
|
||||||
|
data.script.MathJax.startNumber = AMS.startNumber;
|
||||||
|
AMS.startNumber = AMS.number; // equation numbers for next equation
|
||||||
|
MathJax.Hub.Insert(AMS.labels,AMS.eqlabels); // save labels from this equation
|
||||||
|
if (AMS.badref && !data.math.texError) {AMS.refs.push(data.script)} // reprocess later
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.MessageHook("Begin Math Input",function () {
|
||||||
|
AMS.refs = []; // array of jax with bad references
|
||||||
|
AMS.refUpdate = false;
|
||||||
|
});
|
||||||
|
MathJax.Hub.Register.MessageHook("End Math Input",function (message) {
|
||||||
|
if (AMS.refs.length) {
|
||||||
|
AMS.refUpdate = true;
|
||||||
|
for (var i = 0, m = AMS.refs.length; i < m; i++)
|
||||||
|
{AMS.refs[i].MathJax.state = MathJax.ElementJax.STATE.UPDATE}
|
||||||
|
return MathJax.Hub.processInput({
|
||||||
|
scripts:AMS.refs,
|
||||||
|
start: new Date().getTime(),
|
||||||
|
i:0, j:0, jax:{}, jaxIDs:[]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clear the equation numbers and labels
|
||||||
|
//
|
||||||
|
TEX.resetEquationNumbers = function (n,keepLabels) {
|
||||||
|
AMS.startNumber = (n || 0);
|
||||||
|
if (!keepLabels) {AMS.labels = {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX AMSmath Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSmath.js");
|
401
resources/viewer/mathjax/extensions/TeX/AMSsymbols.js
Normal file
401
resources/viewer/mathjax/extensions/TeX/AMSsymbols.js
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/AMSsymbols.js
|
||||||
|
*
|
||||||
|
* Implements macros for accessing the AMS symbol fonts.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/AMSsymbols"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml,
|
||||||
|
TEXDEF = MathJax.InputJax.TeX.Definitions;
|
||||||
|
|
||||||
|
TEXDEF.Add({
|
||||||
|
|
||||||
|
mathchar0mi: {
|
||||||
|
// Lowercase Greek letters
|
||||||
|
digamma: '03DD',
|
||||||
|
varkappa: '03F0',
|
||||||
|
|
||||||
|
// Uppercase Greek letters
|
||||||
|
varGamma: ['0393',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varDelta: ['0394',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varTheta: ['0398',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varLambda: ['039B',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varXi: ['039E',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varPi: ['03A0',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varSigma: ['03A3',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varUpsilon: ['03A5',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varPhi: ['03A6',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varPsi: ['03A8',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
varOmega: ['03A9',{mathvariant: MML.VARIANT.ITALIC}],
|
||||||
|
|
||||||
|
// Hebrew letters
|
||||||
|
beth: '2136',
|
||||||
|
gimel: '2137',
|
||||||
|
daleth: '2138',
|
||||||
|
|
||||||
|
// Miscellaneous symbols
|
||||||
|
// hbar: '0127', // in MathJax_Main
|
||||||
|
backprime: ['2035',{variantForm: true}],
|
||||||
|
hslash: ['210F',{variantForm: true}],
|
||||||
|
varnothing: ['2205',{variantForm: true}],
|
||||||
|
blacktriangle: '25B2',
|
||||||
|
triangledown: '25BD',
|
||||||
|
blacktriangledown: '25BC',
|
||||||
|
square: '25A1',
|
||||||
|
Box: '25A1',
|
||||||
|
blacksquare: '25A0',
|
||||||
|
lozenge: '25CA',
|
||||||
|
Diamond: '25CA',
|
||||||
|
blacklozenge: '29EB',
|
||||||
|
circledS: ['24C8',{mathvariant: MML.VARIANT.NORMAL}],
|
||||||
|
bigstar: '2605',
|
||||||
|
// angle: '2220', // in MathJax_Main
|
||||||
|
sphericalangle: '2222',
|
||||||
|
measuredangle: '2221',
|
||||||
|
nexists: '2204',
|
||||||
|
complement: '2201',
|
||||||
|
mho: '2127',
|
||||||
|
eth: ['00F0',{mathvariant: MML.VARIANT.NORMAL}],
|
||||||
|
Finv: '2132',
|
||||||
|
diagup: '2571',
|
||||||
|
Game: '2141',
|
||||||
|
diagdown: '2572',
|
||||||
|
Bbbk: ['006B',{mathvariant: MML.VARIANT.DOUBLESTRUCK}],
|
||||||
|
|
||||||
|
yen: '00A5',
|
||||||
|
circledR: '00AE',
|
||||||
|
checkmark: '2713',
|
||||||
|
maltese: '2720'
|
||||||
|
},
|
||||||
|
|
||||||
|
mathchar0mo: {
|
||||||
|
// Binary operators
|
||||||
|
dotplus: '2214',
|
||||||
|
ltimes: '22C9',
|
||||||
|
smallsetminus: ['2216',{variantForm: true}],
|
||||||
|
rtimes: '22CA',
|
||||||
|
Cap: '22D2',
|
||||||
|
doublecap: '22D2',
|
||||||
|
leftthreetimes: '22CB',
|
||||||
|
Cup: '22D3',
|
||||||
|
doublecup: '22D3',
|
||||||
|
rightthreetimes: '22CC',
|
||||||
|
barwedge: '22BC',
|
||||||
|
curlywedge: '22CF',
|
||||||
|
veebar: '22BB',
|
||||||
|
curlyvee: '22CE',
|
||||||
|
doublebarwedge: '2A5E',
|
||||||
|
boxminus: '229F',
|
||||||
|
circleddash: '229D',
|
||||||
|
boxtimes: '22A0',
|
||||||
|
circledast: '229B',
|
||||||
|
boxdot: '22A1',
|
||||||
|
circledcirc: '229A',
|
||||||
|
boxplus: '229E',
|
||||||
|
centerdot: '22C5',
|
||||||
|
divideontimes: '22C7',
|
||||||
|
intercal: '22BA',
|
||||||
|
|
||||||
|
// Binary relations
|
||||||
|
leqq: '2266',
|
||||||
|
geqq: '2267',
|
||||||
|
leqslant: '2A7D',
|
||||||
|
geqslant: '2A7E',
|
||||||
|
eqslantless: '2A95',
|
||||||
|
eqslantgtr: '2A96',
|
||||||
|
lesssim: '2272',
|
||||||
|
gtrsim: '2273',
|
||||||
|
lessapprox: '2A85',
|
||||||
|
gtrapprox: '2A86',
|
||||||
|
approxeq: '224A',
|
||||||
|
lessdot: '22D6',
|
||||||
|
gtrdot: '22D7',
|
||||||
|
lll: '22D8',
|
||||||
|
llless: '22D8',
|
||||||
|
ggg: '22D9',
|
||||||
|
gggtr: '22D9',
|
||||||
|
lessgtr: '2276',
|
||||||
|
gtrless: '2277',
|
||||||
|
lesseqgtr: '22DA',
|
||||||
|
gtreqless: '22DB',
|
||||||
|
lesseqqgtr: '2A8B',
|
||||||
|
gtreqqless: '2A8C',
|
||||||
|
doteqdot: '2251',
|
||||||
|
Doteq: '2251',
|
||||||
|
eqcirc: '2256',
|
||||||
|
risingdotseq: '2253',
|
||||||
|
circeq: '2257',
|
||||||
|
fallingdotseq: '2252',
|
||||||
|
triangleq: '225C',
|
||||||
|
backsim: '223D',
|
||||||
|
thicksim: ['223C',{variantForm: true}],
|
||||||
|
backsimeq: '22CD',
|
||||||
|
thickapprox: ['2248',{variantForm: true}],
|
||||||
|
subseteqq: '2AC5',
|
||||||
|
supseteqq: '2AC6',
|
||||||
|
Subset: '22D0',
|
||||||
|
Supset: '22D1',
|
||||||
|
sqsubset: '228F',
|
||||||
|
sqsupset: '2290',
|
||||||
|
preccurlyeq: '227C',
|
||||||
|
succcurlyeq: '227D',
|
||||||
|
curlyeqprec: '22DE',
|
||||||
|
curlyeqsucc: '22DF',
|
||||||
|
precsim: '227E',
|
||||||
|
succsim: '227F',
|
||||||
|
precapprox: '2AB7',
|
||||||
|
succapprox: '2AB8',
|
||||||
|
vartriangleleft: '22B2',
|
||||||
|
lhd: '22B2',
|
||||||
|
vartriangleright: '22B3',
|
||||||
|
rhd: '22B3',
|
||||||
|
trianglelefteq: '22B4',
|
||||||
|
unlhd: '22B4',
|
||||||
|
trianglerighteq: '22B5',
|
||||||
|
unrhd: '22B5',
|
||||||
|
vDash: '22A8',
|
||||||
|
Vdash: '22A9',
|
||||||
|
Vvdash: '22AA',
|
||||||
|
smallsmile: '2323',
|
||||||
|
shortmid: ['2223',{variantForm: true}],
|
||||||
|
smallfrown: '2322',
|
||||||
|
shortparallel: ['2225',{variantForm: true}],
|
||||||
|
bumpeq: '224F',
|
||||||
|
between: '226C',
|
||||||
|
Bumpeq: '224E',
|
||||||
|
pitchfork: '22D4',
|
||||||
|
varpropto: '221D',
|
||||||
|
backepsilon: '220D',
|
||||||
|
blacktriangleleft: '25C0',
|
||||||
|
blacktriangleright: '25B6',
|
||||||
|
therefore: '2234',
|
||||||
|
because: '2235',
|
||||||
|
eqsim: '2242',
|
||||||
|
vartriangle: ['25B3',{variantForm: true}],
|
||||||
|
Join: '22C8',
|
||||||
|
|
||||||
|
// Negated relations
|
||||||
|
nless: '226E',
|
||||||
|
ngtr: '226F',
|
||||||
|
nleq: '2270',
|
||||||
|
ngeq: '2271',
|
||||||
|
nleqslant: ['2A87',{variantForm: true}],
|
||||||
|
ngeqslant: ['2A88',{variantForm: true}],
|
||||||
|
nleqq: ['2270',{variantForm: true}],
|
||||||
|
ngeqq: ['2271',{variantForm: true}],
|
||||||
|
lneq: '2A87',
|
||||||
|
gneq: '2A88',
|
||||||
|
lneqq: '2268',
|
||||||
|
gneqq: '2269',
|
||||||
|
lvertneqq: ['2268',{variantForm: true}],
|
||||||
|
gvertneqq: ['2269',{variantForm: true}],
|
||||||
|
lnsim: '22E6',
|
||||||
|
gnsim: '22E7',
|
||||||
|
lnapprox: '2A89',
|
||||||
|
gnapprox: '2A8A',
|
||||||
|
nprec: '2280',
|
||||||
|
nsucc: '2281',
|
||||||
|
npreceq: ['22E0',{variantForm: true}],
|
||||||
|
nsucceq: ['22E1',{variantForm: true}],
|
||||||
|
precneqq: '2AB5',
|
||||||
|
succneqq: '2AB6',
|
||||||
|
precnsim: '22E8',
|
||||||
|
succnsim: '22E9',
|
||||||
|
precnapprox: '2AB9',
|
||||||
|
succnapprox: '2ABA',
|
||||||
|
nsim: '2241',
|
||||||
|
ncong: '2246',
|
||||||
|
nshortmid: ['2224',{variantForm: true}],
|
||||||
|
nshortparallel: ['2226',{variantForm: true}],
|
||||||
|
nmid: '2224',
|
||||||
|
nparallel: '2226',
|
||||||
|
nvdash: '22AC',
|
||||||
|
nvDash: '22AD',
|
||||||
|
nVdash: '22AE',
|
||||||
|
nVDash: '22AF',
|
||||||
|
ntriangleleft: '22EA',
|
||||||
|
ntriangleright: '22EB',
|
||||||
|
ntrianglelefteq: '22EC',
|
||||||
|
ntrianglerighteq: '22ED',
|
||||||
|
nsubseteq: '2288',
|
||||||
|
nsupseteq: '2289',
|
||||||
|
nsubseteqq: ['2288',{variantForm: true}],
|
||||||
|
nsupseteqq: ['2289',{variantForm: true}],
|
||||||
|
subsetneq: '228A',
|
||||||
|
supsetneq: '228B',
|
||||||
|
varsubsetneq: ['228A',{variantForm: true}],
|
||||||
|
varsupsetneq: ['228B',{variantForm: true}],
|
||||||
|
subsetneqq: '2ACB',
|
||||||
|
supsetneqq: '2ACC',
|
||||||
|
varsubsetneqq: ['2ACB',{variantForm: true}],
|
||||||
|
varsupsetneqq: ['2ACC',{variantForm: true}],
|
||||||
|
|
||||||
|
|
||||||
|
// Arrows
|
||||||
|
leftleftarrows: '21C7',
|
||||||
|
rightrightarrows: '21C9',
|
||||||
|
leftrightarrows: '21C6',
|
||||||
|
rightleftarrows: '21C4',
|
||||||
|
Lleftarrow: '21DA',
|
||||||
|
Rrightarrow: '21DB',
|
||||||
|
twoheadleftarrow: '219E',
|
||||||
|
twoheadrightarrow: '21A0',
|
||||||
|
leftarrowtail: '21A2',
|
||||||
|
rightarrowtail: '21A3',
|
||||||
|
looparrowleft: '21AB',
|
||||||
|
looparrowright: '21AC',
|
||||||
|
leftrightharpoons: '21CB',
|
||||||
|
rightleftharpoons: ['21CC',{variantForm: true}],
|
||||||
|
curvearrowleft: '21B6',
|
||||||
|
curvearrowright: '21B7',
|
||||||
|
circlearrowleft: '21BA',
|
||||||
|
circlearrowright: '21BB',
|
||||||
|
Lsh: '21B0',
|
||||||
|
Rsh: '21B1',
|
||||||
|
upuparrows: '21C8',
|
||||||
|
downdownarrows: '21CA',
|
||||||
|
upharpoonleft: '21BF',
|
||||||
|
upharpoonright: '21BE',
|
||||||
|
downharpoonleft: '21C3',
|
||||||
|
restriction: '21BE',
|
||||||
|
multimap: '22B8',
|
||||||
|
downharpoonright: '21C2',
|
||||||
|
leftrightsquigarrow: '21AD',
|
||||||
|
rightsquigarrow: '21DD',
|
||||||
|
leadsto: '21DD',
|
||||||
|
dashrightarrow: '21E2',
|
||||||
|
dashleftarrow: '21E0',
|
||||||
|
|
||||||
|
// Negated arrows
|
||||||
|
nleftarrow: '219A',
|
||||||
|
nrightarrow: '219B',
|
||||||
|
nLeftarrow: '21CD',
|
||||||
|
nRightarrow: '21CF',
|
||||||
|
nleftrightarrow: '21AE',
|
||||||
|
nLeftrightarrow: '21CE'
|
||||||
|
},
|
||||||
|
|
||||||
|
delimiter: {
|
||||||
|
// corners
|
||||||
|
"\\ulcorner": '231C',
|
||||||
|
"\\urcorner": '231D',
|
||||||
|
"\\llcorner": '231E',
|
||||||
|
"\\lrcorner": '231F'
|
||||||
|
},
|
||||||
|
|
||||||
|
macros: {
|
||||||
|
implies: ['Macro','\\;\\Longrightarrow\\;'],
|
||||||
|
impliedby: ['Macro','\\;\\Longleftarrow\\;']
|
||||||
|
}
|
||||||
|
|
||||||
|
},null,true);
|
||||||
|
|
||||||
|
var REL = MML.mo.OPTYPES.REL;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u2322': REL, // smallfrown
|
||||||
|
'\u2323': REL, // smallsmile
|
||||||
|
'\u25B3': REL, // vartriangle
|
||||||
|
'\uE006': REL, // nshortmid
|
||||||
|
'\uE007': REL, // nshortparallel
|
||||||
|
'\uE00C': REL, // lvertneqq
|
||||||
|
'\uE00D': REL, // gvertneqq
|
||||||
|
'\uE00E': REL, // ngeqq
|
||||||
|
'\uE00F': REL, // ngeqslant
|
||||||
|
'\uE010': REL, // nleqslant
|
||||||
|
'\uE011': REL, // nleqq
|
||||||
|
'\uE016': REL, // nsubseteqq
|
||||||
|
'\uE017': REL, // varsubsetneqq
|
||||||
|
'\uE018': REL, // nsupseteqq
|
||||||
|
'\uE019': REL, // varsupsetneqq
|
||||||
|
'\uE01A': REL, // varsubsetneq
|
||||||
|
'\uE01B': REL, // varsupsetneq
|
||||||
|
'\uE04B': REL, // npreceq
|
||||||
|
'\uE04F': REL // nsucceq
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX AMSsymbols Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
|
||||||
|
var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
|
||||||
|
var VARIANT = HTMLCSS.FONTDATA.VARIANT;
|
||||||
|
if (HTMLCSS.fontInUse === "TeX") {
|
||||||
|
VARIANT["-TeX-variant"] = {
|
||||||
|
fonts: ["MathJax_AMS","MathJax_Main","MathJax_Size1"],
|
||||||
|
remap: {0x2268: 0xE00C, 0x2269: 0xE00D, 0x2270: 0xE011, 0x2271: 0xE00E,
|
||||||
|
0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2224: 0xE006, 0x2226: 0xE007,
|
||||||
|
0x2288: 0xE016, 0x2289: 0xE018, 0x228A: 0xE01A, 0x228B: 0xE01B,
|
||||||
|
0x2ACB: 0xE017, 0x2ACC: 0xE019, 0x03DC: 0xE008, 0x03F0: 0xE009}
|
||||||
|
};
|
||||||
|
if (HTMLCSS.msieIE6) {
|
||||||
|
MathJax.Hub.Insert(VARIANT["-TeX-variant"].remap,{
|
||||||
|
0x2190:[0xE2C1,"-WinIE6"], 0x2192:[0xE2C0,"-WinIE6"],
|
||||||
|
0x2223:[0xE2C2,"-WinIE6"], 0x2225:[0xE2C3,"-WinIE6"],
|
||||||
|
0x223C:[0xE2C4,"-WinIE6"], 0x25B3:[0xE2D3,"-WinIE6"]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (HTMLCSS.fontInUse === "STIX") {
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEXDEF = MathJax.InputJax.TeX.Definitions;
|
||||||
|
TEXDEF.mathchar0mi.varnothing = '2205';
|
||||||
|
TEXDEF.mathchar0mi.hslash = '210F';
|
||||||
|
TEXDEF.mathchar0mi.blacktriangle = '25B4';
|
||||||
|
TEXDEF.mathchar0mi.blacktriangledown = '25BE';
|
||||||
|
TEXDEF.mathchar0mi.square = '25FB';
|
||||||
|
TEXDEF.mathchar0mi.blacksquare = '25FC';
|
||||||
|
TEXDEF.mathchar0mi.vartriangle = ['25B3',{mathsize:"71%"}];
|
||||||
|
TEXDEF.mathchar0mi.triangledown = ['25BD',{mathsize:"71%"}];
|
||||||
|
TEXDEF.mathchar0mo.blacktriangleleft = '25C2';
|
||||||
|
TEXDEF.mathchar0mo.blacktriangleright = '25B8';
|
||||||
|
TEXDEF.mathchar0mo.smallsetminus = '2216';
|
||||||
|
MathJax.Hub.Insert(VARIANT["-STIX-variant"],{
|
||||||
|
remap: {0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2270: 0xE011, 0x2271: 0xE00E,
|
||||||
|
0x22E0: 0xE04B, 0x22E1: 0xE04F, 0x2288: 0xE016, 0x2289: 0xE018}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
|
||||||
|
var SVG = MathJax.OutputJax.SVG;
|
||||||
|
var VARIANT = SVG.FONTDATA.VARIANT;
|
||||||
|
|
||||||
|
VARIANT["-TeX-variant"] = {
|
||||||
|
fonts: ["MathJax_AMS","MathJax_Main","MathJax_Size1"],
|
||||||
|
remap: {0x2268: 0xE00C, 0x2269: 0xE00D, 0x2270: 0xE011, 0x2271: 0xE00E,
|
||||||
|
0x2A87: 0xE010, 0x2A88: 0xE00F, 0x2224: 0xE006, 0x2226: 0xE007,
|
||||||
|
0x2288: 0xE016, 0x2289: 0xE018, 0x228A: 0xE01A, 0x228B: 0xE01B,
|
||||||
|
0x2ACB: 0xE017, 0x2ACC: 0xE019, 0x03DC: 0xE008, 0x03F0: 0xE009}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/AMSsymbols.js");
|
103
resources/viewer/mathjax/extensions/TeX/HTML.js
Normal file
103
resources/viewer/mathjax/extensions/TeX/HTML.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/HTML.js
|
||||||
|
*
|
||||||
|
* Implements the \href, \class, \style, \cssId macros.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/HTML"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
TEXDEF.Add({
|
||||||
|
macros: {
|
||||||
|
href: 'HREF_attribute',
|
||||||
|
"class": 'CLASS_attribute',
|
||||||
|
style: 'STYLE_attribute',
|
||||||
|
cssId: 'ID_attribute'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \href{url}{math}
|
||||||
|
//
|
||||||
|
HREF_attribute: function (name) {
|
||||||
|
var url = this.GetArgument(name),
|
||||||
|
arg = this.GetArgumentMML(name);
|
||||||
|
this.Push(arg.With({href:url}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \class{name}{math}
|
||||||
|
//
|
||||||
|
CLASS_attribute: function (name) {
|
||||||
|
var CLASS = this.GetArgument(name),
|
||||||
|
arg = this.GetArgumentMML(name);
|
||||||
|
if (arg["class"] != null) {CLASS = arg["class"] + " " + CLASS}
|
||||||
|
this.Push(arg.With({"class":CLASS}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \style{style-string}{math}
|
||||||
|
//
|
||||||
|
STYLE_attribute: function (name) {
|
||||||
|
var style = this.GetArgument(name),
|
||||||
|
arg = this.GetArgumentMML(name);
|
||||||
|
// check that it looks like a style string
|
||||||
|
if (arg.style != null) {
|
||||||
|
if (style.charAt(style.length-1) !== ";") {style += ";"}
|
||||||
|
style = arg.style + " " + style;
|
||||||
|
}
|
||||||
|
this.Push(arg.With({style: style}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \cssId{id}{math}
|
||||||
|
//
|
||||||
|
ID_attribute: function (name) {
|
||||||
|
var ID = this.GetArgument(name),
|
||||||
|
arg = this.GetArgumentMML(name);
|
||||||
|
this.Push(arg.With({id:ID}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// returns an argument that is a single MathML element
|
||||||
|
// (in an mrow if necessary)
|
||||||
|
//
|
||||||
|
GetArgumentMML: function (name) {
|
||||||
|
var arg = this.ParseArg(name);
|
||||||
|
if (arg.inferred && arg.data.length == 1)
|
||||||
|
{arg = arg.data[0]} else {delete arg.inferred}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX HTML Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/HTML.js");
|
76
resources/viewer/mathjax/extensions/TeX/action.js
Normal file
76
resources/viewer/mathjax/extensions/TeX/action.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/action.js
|
||||||
|
*
|
||||||
|
* Implements the \mathtip, \texttip, and \toggle macros, which give
|
||||||
|
* access from TeX to the <maction> tag in the MathML that underlies
|
||||||
|
* MathJax's internal format.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* \mathtip{math}{tip} % use "tip" (in math mode) as tooltip for "math"
|
||||||
|
* \texttip{math}{tip} % use "tip" (in text mode) as tooltip for "math"
|
||||||
|
* \toggle{math1}{math2}...\endtoggle
|
||||||
|
* % show math1, and when clicked, show math2, and so on.
|
||||||
|
* % When the last one is clicked, go back to math1.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/action"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MML = MathJax.ElementJax.mml;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up control sequenecs
|
||||||
|
//
|
||||||
|
TEX.Definitions.macros.toggle = 'Toggle';
|
||||||
|
TEX.Definitions.macros.mathtip = 'Mathtip';
|
||||||
|
TEX.Definitions.macros.texttip = ['Macro','\\mathtip{#1}{\\text{#2}}',2];
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement \toggle {math1} {math2} ... \endtoggle
|
||||||
|
// (as an <maction actiontype="toggle">)
|
||||||
|
//
|
||||||
|
Toggle: function (name) {
|
||||||
|
var data = [], arg;
|
||||||
|
while ((arg = this.GetArgument(name)) !== "\\endtoggle")
|
||||||
|
{data.push(TEX.Parse(arg,this.stack.env).mml())}
|
||||||
|
this.Push(MML.maction.apply(MML,data).With({actiontype: MML.ACTIONTYPE.TOGGLE}));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement \mathtip{math}{tip}
|
||||||
|
// (an an <maction actiontype="tooltip">)
|
||||||
|
//
|
||||||
|
Mathtip: function(name) {
|
||||||
|
var arg = this.ParseArg(name), tip = this.ParseArg(name);
|
||||||
|
this.Push(MML.maction(arg,tip).With({actiontype: MML.ACTIONTYPE.TOOLTIP}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX action Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/action.js");
|
45
resources/viewer/mathjax/extensions/TeX/autobold.js
Normal file
45
resources/viewer/mathjax/extensions/TeX/autobold.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/autobold.js
|
||||||
|
*
|
||||||
|
* Adds \boldsymbol around mathematics that appears in a section
|
||||||
|
* of an HTML page that is in bold.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/autobold"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
|
||||||
|
TEX.prefilterHooks.Add(function (data) {
|
||||||
|
var span = data.script.parentNode.insertBefore(document.createElement("span"),data.script);
|
||||||
|
span.visibility = "hidden";
|
||||||
|
span.style.fontFamily = "Times, serif";
|
||||||
|
span.appendChild(document.createTextNode("ABCXYZabcxyz"));
|
||||||
|
var W = span.offsetWidth;
|
||||||
|
span.style.fontWeight = "bold";
|
||||||
|
if (W && span.offsetWidth === W) {data.math = "\\boldsymbol{"+data.math+"}"}
|
||||||
|
span.parentNode.removeChild(span);
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX autobold Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/autobold.js");
|
71
resources/viewer/mathjax/extensions/TeX/autoload-all.js
Normal file
71
resources/viewer/mathjax/extensions/TeX/autoload-all.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/autoload-all.js
|
||||||
|
*
|
||||||
|
* Provides pre-defined macros to autoload all the extensions
|
||||||
|
* so that all macros that MathJax knows about are available.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/autoload-all"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MACROS = TEX.Definitions.macros,
|
||||||
|
ENVS = TEX.Definitions.environment;
|
||||||
|
|
||||||
|
|
||||||
|
var EXTENSIONS = {
|
||||||
|
action: ["mathtip","texttip","toggle"],
|
||||||
|
AMSmath: ["mathring","nobreakspace","negmedspace","negthickspace","intI",
|
||||||
|
"iiiint","idotsint","dddot","ddddot","sideset","boxed",
|
||||||
|
"substack","injlim","projlim","varliminf","varlimsup",
|
||||||
|
"varinjlim","varprojlim","DeclareMathOperator","operatorname",
|
||||||
|
"genfrac","tfrac","dfrac","binom","tbinom","dbinom","cfrac",
|
||||||
|
"shoveleft","shoveright","xrightarrow","xleftarrow"],
|
||||||
|
begingroup: ["begingroup","endgroup","gdef","global"],
|
||||||
|
cancel: ["cancel","bcancel","xcancel","cancelto"],
|
||||||
|
color: ["color","colorbox","fcolorbox","DefineColor"],
|
||||||
|
enclose: ["enclose"],
|
||||||
|
extpfeil: ["Newextarrow","xlongequal","xmapsto","xtofrom",
|
||||||
|
"xtwoheadleftarrow","xtwoheadrightarrow"],
|
||||||
|
mhchem: ["ce","cee","cf"]
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var name in EXTENSIONS) {if (EXTENSIONS.hasOwnProperty(name)) {
|
||||||
|
var macros = EXTENSIONS[name];
|
||||||
|
for (var i = 0, m = macros.length; i < m; i++) {
|
||||||
|
MACROS[macros[i]] = ["Extension",name];
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
ENVS["subarray"] = ['ExtensionEnv',null,'AMSmath'];
|
||||||
|
ENVS["smallmatrix"] = ['ExtensionEnv',null,'AMSmath'];
|
||||||
|
ENVS["equation"] = ['ExtensionEnv',null,'AMSmath'];
|
||||||
|
ENVS["equation*"] = ['ExtensionEnv',null,'AMSmath'];
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX autoload-all Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Callback.Queue(
|
||||||
|
["Require",MathJax.Ajax,"[MathJax]/extensions/TeX/AMSsymbols.js"],
|
||||||
|
["loadComplete",MathJax.Ajax,"[MathJax]/extensions/TeX/autoload-all.js"]
|
||||||
|
);
|
90
resources/viewer/mathjax/extensions/TeX/bbox.js
Normal file
90
resources/viewer/mathjax/extensions/TeX/bbox.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/bbox.js
|
||||||
|
*
|
||||||
|
* This file implements the \bbox macro, which creates an box that
|
||||||
|
* can be styled (for background colors, and so on). You can include
|
||||||
|
* an optional dimension that tells how much extra padding to include
|
||||||
|
* around the bounding box for the mathematics, or a color specification
|
||||||
|
* for the background color to use, or both. E.g.,
|
||||||
|
*
|
||||||
|
* \bbox[2pt]{x+y} % an invisible box around x+y with 2pt of extra space
|
||||||
|
* \bbox[green]{x+y} % a green box around x+y
|
||||||
|
* \bbox[green,2pt]{x+y} % a green box with 2pt of extra space
|
||||||
|
*
|
||||||
|
* You can also specify style attributes, for example
|
||||||
|
*
|
||||||
|
* \bbox[red,border:3px solid blue,5px]{x+y}
|
||||||
|
*
|
||||||
|
* would give a red background with a 3px solid blue border that has 5px
|
||||||
|
* of padding between the border and the mathematics. Note that not all
|
||||||
|
* output formats support the style specifications. In particular, the
|
||||||
|
* NativeMML output depends on the browser to render the attributes, and
|
||||||
|
* not all MathML renderers will honor them (e.g., MathPlayer2 doesn't
|
||||||
|
* render border styles).
|
||||||
|
*
|
||||||
|
* This file will be loaded automatically when \bbox is first used.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/bbox"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MML = MathJax.ElementJax.mml;
|
||||||
|
|
||||||
|
TEX.Definitions.macros.bbox = "BBox";
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
BBox: function (name) {
|
||||||
|
var bbox = this.GetBrackets(name,""),
|
||||||
|
math = this.ParseArg(name);
|
||||||
|
var parts = bbox.split(/,/), def, background, style;
|
||||||
|
for (var i in parts) {
|
||||||
|
var part = parts[i].replace(/^\s+/,'').replace(/\s+$/,'');
|
||||||
|
var match = part.match(/^(\.\d+|\d+(\.\d*)?)(pt|em|ex|mu|px|in|cm|mm)$/);
|
||||||
|
if (match) {
|
||||||
|
var pad = match[1]+match[3];
|
||||||
|
if (def) {TEX.Error("Padding specified twice in "+name)}
|
||||||
|
def = {height:"+"+pad, depth:"+"+pad, lspace:pad, width:"+"+(2*match[1])+match[3]};
|
||||||
|
} else if (part.match(/^([a-z0-9]+|\#[0-9a-f]{6}|\#[0-9a-f]{3})$/i)) {
|
||||||
|
if (background) {TEX.Error("Background specified twice in "+name)}
|
||||||
|
background = part;
|
||||||
|
} else if (part.match(/^[-a-z]+:/i)) {
|
||||||
|
if (style) {TEX.Error("Style specified twice in "+name)}
|
||||||
|
style = part;
|
||||||
|
} else if (part !== "") {
|
||||||
|
TEX.Error("'"+part+"' doesn't look like a color, a padding dimension, or a style");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (def) {math = MML.mpadded(math).With(def)}
|
||||||
|
if (background || style) {
|
||||||
|
math = MML.mstyle(math).With({mathbackground:background, style:style});
|
||||||
|
}
|
||||||
|
this.Push(math);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX bbox Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/bbox.js");
|
296
resources/viewer/mathjax/extensions/TeX/begingroup.js
Normal file
296
resources/viewer/mathjax/extensions/TeX/begingroup.js
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/begingroup.js
|
||||||
|
*
|
||||||
|
* Implements \begingroup and \endgroup commands that make local
|
||||||
|
* definitions possible and are removed when the \endgroup occurs.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/begingroup"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// A namespace for localizing macros and environments
|
||||||
|
// (\begingroup and \endgroup create and destroy these)
|
||||||
|
//
|
||||||
|
var NSFRAME = MathJax.Object.Subclass({
|
||||||
|
macros: null, // the local macro definitions
|
||||||
|
environments: null, // the local environments
|
||||||
|
Init: function (macros,environments) {
|
||||||
|
this.macros = (macros || {});
|
||||||
|
this.environments = (environments || {});
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Find a macro or environment by name
|
||||||
|
//
|
||||||
|
Find: function (name,type) {if (this[type][name]) {return this[type][name]}},
|
||||||
|
//
|
||||||
|
// Define or remove a macro or environment
|
||||||
|
//
|
||||||
|
Def: function (name,value,type) {this[type][name] = value},
|
||||||
|
Undef: function (name,type) {delete this[type][name]},
|
||||||
|
//
|
||||||
|
// Merge two namespaces (used when the equation namespace is combined with the root one)
|
||||||
|
//
|
||||||
|
Merge: function (frame) {
|
||||||
|
MathJax.Hub.Insert(this.macros,frame.macros);
|
||||||
|
MathJax.Hub.Insert(this.environments,frame.environments);
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Move global macros to the stack (globally) and remove from the frame
|
||||||
|
//
|
||||||
|
MergeGlobals: function (stack) {
|
||||||
|
var macros = this.macros;
|
||||||
|
for (var cs in macros) {if (macros.hasOwnProperty(cs) && macros[cs].global) {
|
||||||
|
stack.Def(cs,macros[cs],"macros",true);
|
||||||
|
delete macros[cs].global; delete macros[cs];
|
||||||
|
}}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Clear the macro and environment lists
|
||||||
|
// (but not global macros unless "all" is true)
|
||||||
|
//
|
||||||
|
Clear: function (all) {
|
||||||
|
this.environments = {};
|
||||||
|
if (all) {this.macros = {}} else {
|
||||||
|
var macros = this.macros;
|
||||||
|
for (var cs in macros) {
|
||||||
|
if (macros.hasOwnProperty(cs) && !macros[cs].global) {delete macros[cs]}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// A Stack of namespace frames
|
||||||
|
//
|
||||||
|
var NSSTACK = TEX.nsStack = MathJax.Object.Subclass({
|
||||||
|
stack: null, // the namespace frames
|
||||||
|
top: 0, // the current top one (we don't pop for real until the equation completes)
|
||||||
|
isEqn: false, // true if this is the equation stack (not the global one)
|
||||||
|
//
|
||||||
|
// Set up the initial stack frame
|
||||||
|
//
|
||||||
|
Init: function (eqn) {
|
||||||
|
this.isEqn = eqn; this.stack = [];
|
||||||
|
if (!eqn) {this.Push(NSFRAME(TEXDEF.macros,TEXDEF.environments))}
|
||||||
|
else {this.Push(NSFRAME())}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Define a macro or environment in the top frame
|
||||||
|
//
|
||||||
|
Def: function (name,value,type,global) {
|
||||||
|
var n = this.top-1;
|
||||||
|
if (global) {
|
||||||
|
//
|
||||||
|
// Define global macros in the base frame and remove that cs
|
||||||
|
// from all other frames. Mark the global ones in equations
|
||||||
|
// so they can be made global when merged with the root stack.
|
||||||
|
//
|
||||||
|
while (n > 0) {this.stack[n].Undef(name,type); n--}
|
||||||
|
if (!(value instanceof Array)) {value = [value]}
|
||||||
|
if (this.isEqn) {value.global = true}
|
||||||
|
}
|
||||||
|
this.stack[n].Def(name,value,type);
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Push a new namespace frame on the stack
|
||||||
|
//
|
||||||
|
Push: function (frame) {
|
||||||
|
this.stack.push(frame);
|
||||||
|
this.top = this.stack.length;
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Pop the top stack frame
|
||||||
|
// (if it is the root, just keep track of the pop so we can
|
||||||
|
// reset it if the equation is reprocessed)
|
||||||
|
//
|
||||||
|
Pop: function () {
|
||||||
|
var top;
|
||||||
|
if (this.top > 1) {
|
||||||
|
top = this.stack[--this.top];
|
||||||
|
if (this.isEqn) {this.stack.pop()}
|
||||||
|
} else if (this.isEqn) {
|
||||||
|
this.Clear();
|
||||||
|
}
|
||||||
|
return top;
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Search the stack from top to bottom for the first
|
||||||
|
// definition of the given control sequence in the given type
|
||||||
|
//
|
||||||
|
Find: function (name,type) {
|
||||||
|
for (var i = this.top-1; i >= 0; i--) {
|
||||||
|
var def = this.stack[i].Find(name,type);
|
||||||
|
if (def) {return def}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Combine the equation stack with the global one
|
||||||
|
// (The bottom frame of the equation goes with the top frame of the global one,
|
||||||
|
// and the remainder are pushed on the global stack, truncated to the
|
||||||
|
// position where items were poped from it.)
|
||||||
|
//
|
||||||
|
Merge: function (stack) {
|
||||||
|
stack.stack[0].MergeGlobals(this);
|
||||||
|
this.stack[this.top-1].Merge(stack.stack[0]);
|
||||||
|
var data = [this.top,this.stack.length-this.top].concat(stack.stack.slice(1));
|
||||||
|
this.stack.splice.apply(this.stack,data);
|
||||||
|
this.top = this.stack.length;
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Put back the temporarily poped items
|
||||||
|
//
|
||||||
|
Reset: function () {this.top = this.stack.length},
|
||||||
|
//
|
||||||
|
// Clear the stack and start with a blank frame
|
||||||
|
//
|
||||||
|
Clear: function (all) {
|
||||||
|
this.stack = [this.stack[0].Clear()];
|
||||||
|
this.top = this.stack.length;
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
nsFrame: NSFRAME
|
||||||
|
});
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the new macros
|
||||||
|
//
|
||||||
|
TEXDEF.macros.begingroup = "BeginGroup";
|
||||||
|
TEXDEF.macros.endgroup = "EndGroup";
|
||||||
|
TEXDEF.macros.global = ["Extension","newcommand"];
|
||||||
|
TEXDEF.macros.gdef = ["Extension","newcommand"];
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
//
|
||||||
|
// Implement \begingroup
|
||||||
|
//
|
||||||
|
BeginGroup: function (name) {
|
||||||
|
TEX.eqnStack.Push(NSFRAME());
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Implements \endgroup
|
||||||
|
//
|
||||||
|
EndGroup: function (name) {
|
||||||
|
//
|
||||||
|
// If the equation has pushed frames, pop one,
|
||||||
|
// Otherwise clear the equation stack and pop the top global one
|
||||||
|
//
|
||||||
|
if (TEX.eqnStack.top > 1) {
|
||||||
|
TEX.eqnStack.Pop();
|
||||||
|
} else if (TEX.rootStack.top === 1) {
|
||||||
|
TEX.Error("Extra "+name+" or missing \\begingroup");
|
||||||
|
} else {
|
||||||
|
TEX.eqnStack.Clear();
|
||||||
|
TEX.rootStack.Pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Replace the original routines with ones that looks through the
|
||||||
|
// equation and root stacks for the given name
|
||||||
|
//
|
||||||
|
csFindMacro: function (name) {
|
||||||
|
return (TEX.eqnStack.Find(name,"macros") || TEX.rootStack.Find(name,"macros"));
|
||||||
|
},
|
||||||
|
envFindName: function (name) {
|
||||||
|
return (TEX.eqnStack.Find(name,"environments") || TEX.rootStack.Find(name,"environments"));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/****************************************************/
|
||||||
|
|
||||||
|
TEX.rootStack = NSSTACK(); // the global namespace stack
|
||||||
|
TEX.eqnStack = NSSTACK(true); // the equation stack
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reset the global stack and clear the equation stack
|
||||||
|
// (this gets us back to the initial stack state as it was
|
||||||
|
// before the equation was first processed, in case the equation
|
||||||
|
// get restarted due to an autoloaded file)
|
||||||
|
//
|
||||||
|
TEX.prefilterHooks.Add(function () {TEX.rootStack.Reset(); TEX.eqnStack.Clear(true)});
|
||||||
|
|
||||||
|
//
|
||||||
|
// We only get here if there were no errors and the equation is fully
|
||||||
|
// processed (all restarts are complete). So we merge the equation
|
||||||
|
// stack into the global stack, thus making the changes from this
|
||||||
|
// equation permanent.
|
||||||
|
//
|
||||||
|
TEX.postfilterHooks.Add(function () {TEX.rootStack.Merge(TEX.eqnStack)});
|
||||||
|
|
||||||
|
/*********************************************************/
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX newcommand Ready",function () {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the commands that depend on the newcommand code
|
||||||
|
//
|
||||||
|
TEXDEF.macros.global = "Global";
|
||||||
|
TEXDEF.macros.gdef = ["Macro","\\global\\def"];
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
//
|
||||||
|
// Modify the way macros and environments are defined
|
||||||
|
// to make them go into the equation namespace stack
|
||||||
|
//
|
||||||
|
setDef: function (name,value) {
|
||||||
|
value.isUser = true;
|
||||||
|
TEX.eqnStack.Def(name,value,"macros",this.stack.env.isGlobal);
|
||||||
|
delete this.stack.env.isGlobal;
|
||||||
|
},
|
||||||
|
setEnv: function (name,value) {
|
||||||
|
value.isUser = true;
|
||||||
|
TEX.eqnStack.Def(name,value,"environments")
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement \global (for \global\let, \global\def and \global\newcommand)
|
||||||
|
//
|
||||||
|
Global: function (name) {
|
||||||
|
var i = this.i; var cs = this.GetCSname(name); this.i = i;
|
||||||
|
if (cs !== "let" && cs !== "def" && cs !== "newcommand")
|
||||||
|
{TEX.Error(name+" not followed by \\let, \\def, or \\newcommand")}
|
||||||
|
this.stack.env.isGlobal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX begingroup Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/begingroup.js");
|
126
resources/viewer/mathjax/extensions/TeX/boldsymbol.js
Normal file
126
resources/viewer/mathjax/extensions/TeX/boldsymbol.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/boldsymbol.js
|
||||||
|
*
|
||||||
|
* Implements the \boldsymbol{...} command to make bold
|
||||||
|
* versions of all math characters (not just variables).
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/boldsymbol"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
var BOLDVARIANT = {};
|
||||||
|
BOLDVARIANT[MML.VARIANT.NORMAL] = MML.VARIANT.BOLD;
|
||||||
|
BOLDVARIANT[MML.VARIANT.ITALIC] = MML.VARIANT.BOLDITALIC;
|
||||||
|
BOLDVARIANT[MML.VARIANT.FRAKTUR] = MML.VARIANT.BOLDFRAKTUR;
|
||||||
|
BOLDVARIANT[MML.VARIANT.SCRIPT] = MML.VARIANT.BOLDSCRIPT;
|
||||||
|
BOLDVARIANT[MML.VARIANT.SANSSERIF] = MML.VARIANT.BOLDSANSSERIF;
|
||||||
|
BOLDVARIANT["-tex-caligraphic"] = "-tex-caligraphic-bold";
|
||||||
|
BOLDVARIANT["-tex-oldstyle"] = "-tex-oldstyle-bold";
|
||||||
|
|
||||||
|
TEXDEF.macros.boldsymbol = 'Boldsymbol';
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
mmlToken: function (token) {
|
||||||
|
if (this.stack.env.boldsymbol) {
|
||||||
|
var variant = token.Get("mathvariant");
|
||||||
|
if (variant == null) {token.mathvariant = MML.VARIANT.BOLD}
|
||||||
|
else {token.mathvariant = (BOLDVARIANT[variant]||variant)}
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
},
|
||||||
|
|
||||||
|
Boldsymbol: function (name) {
|
||||||
|
var boldsymbol = this.stack.env.boldsymbol,
|
||||||
|
font = this.stack.env.font;
|
||||||
|
this.stack.env.boldsymbol = true;
|
||||||
|
this.stack.env.font = null;
|
||||||
|
var mml = this.ParseArg(name);
|
||||||
|
this.stack.env.font = font;
|
||||||
|
this.stack.env.boldsymbol = boldsymbol;
|
||||||
|
this.Push(mml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX boldsymbol Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
|
||||||
|
var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
|
||||||
|
var FONTS = HTMLCSS.FONTDATA.FONTS;
|
||||||
|
var VARIANT = HTMLCSS.FONTDATA.VARIANT;
|
||||||
|
|
||||||
|
if (HTMLCSS.fontInUse === "TeX") {
|
||||||
|
FONTS["MathJax_Caligraphic-bold"] = "Caligraphic/Bold/Main.js";
|
||||||
|
|
||||||
|
VARIANT["-tex-caligraphic-bold"] =
|
||||||
|
{fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"],
|
||||||
|
offsetA: 0x41, variantA: "bold-italic"};
|
||||||
|
VARIANT["-tex-oldstyle-bold"] =
|
||||||
|
{fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"]};
|
||||||
|
|
||||||
|
if (HTMLCSS.msieCheckGreek && HTMLCSS.Font.testFont({
|
||||||
|
family:"MathJax_Greek", weight:"bold", style:"italic", testString: HTMLCSS.msieCheckGreek
|
||||||
|
})) {
|
||||||
|
VARIANT["bold-italic"].offsetG = 0x391; VARIANT["bold-italic"].variantG = "-Greek-Bold-Italic";
|
||||||
|
VARIANT["-Greek-Bold-Italic"] = {fonts:["MathJax_Greek-bold-italic"]};
|
||||||
|
FONTS["MathJax_Greek-bold-italic"] = "Greek/BoldItalic/Main.js";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MathJax.Hub.Browser.isChrome && !MathJax.Hub.Browser.versionAtLeast("5.0")) {
|
||||||
|
VARIANT["-tex-caligraphic-bold"].remap = {0x54: [0xE2F0,"-WinChrome"]};
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (HTMLCSS.fontInUse === "STIX") {
|
||||||
|
VARIANT["-tex-caligraphic-bold"] = {
|
||||||
|
fonts:["STIXGeneral-bold-italic","STIXNonUnicode-bold-italic","STIXNonUnicode","STIXGeneral","STIXSizeOneSym"],
|
||||||
|
offsetA: 0xE247, noLowerCase: 1
|
||||||
|
};
|
||||||
|
VARIANT["-tex-oldstyle-bold"] = {
|
||||||
|
fonts:["STIXGeneral-bold","STIXNonUnicode-bold","STIXGeneral","STIXSizeOneSym"], offsetN: 0xE263,
|
||||||
|
remap: {0xE264: 0xE267, 0xE265: 0xE26B, 0xE266: 0xE26F, 0xE267: 0xE273,
|
||||||
|
0xE268: 0xE277, 0xE269: 0xE27B, 0xE26A: 0xE27F, 0xE26B: 0xE283,
|
||||||
|
0xE26C: 0xE287}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
|
||||||
|
var SVG = MathJax.OutputJax.SVG;
|
||||||
|
var FONTS = SVG.FONTDATA.FONTS;
|
||||||
|
var VARIANT = SVG.FONTDATA.VARIANT;
|
||||||
|
|
||||||
|
FONTS["MathJax_Caligraphic-bold"] = "Caligraphic/Bold/Main.js";
|
||||||
|
|
||||||
|
VARIANT["-tex-caligraphic-bold"] =
|
||||||
|
{fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"],
|
||||||
|
offsetA: 0x41, variantA: "bold-italic"};
|
||||||
|
VARIANT["-tex-oldstyle-bold"] =
|
||||||
|
{fonts:["MathJax_Caligraphic-bold","MathJax_Main-bold","MathJax_Main","MathJax_Math","MathJax_Size1"]};
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/boldsymbol.js");
|
105
resources/viewer/mathjax/extensions/TeX/cancel.js
Normal file
105
resources/viewer/mathjax/extensions/TeX/cancel.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/cancel.js
|
||||||
|
*
|
||||||
|
* Implements the \cancel, \bcancel, \xcancel, and \cancelto macros.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* \cancel{math} % strikeout math from lower left to upper right
|
||||||
|
* \bcancel{math} % strikeout from upper left to lower right
|
||||||
|
* \xcancel{math} % strikeout with an X
|
||||||
|
* \cancelto{value}{math} % strikeout with arrow going to value
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/cancel"] = {
|
||||||
|
version: "2.0",
|
||||||
|
|
||||||
|
//
|
||||||
|
// The attributes allowed in \enclose{notation}[attributes]{math}
|
||||||
|
//
|
||||||
|
ALLOWED: {
|
||||||
|
arrow: 1,
|
||||||
|
color: 1, mathcolor: 1,
|
||||||
|
background: 1, mathbackground: 1,
|
||||||
|
padding: 1,
|
||||||
|
thickness: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MACROS = TEX.Definitions.macros,
|
||||||
|
MML = MathJax.ElementJax.mml,
|
||||||
|
CANCEL = MathJax.Extension["TeX/cancel"];
|
||||||
|
|
||||||
|
CANCEL.setAttributes = function (def,attr) {
|
||||||
|
if (attr !== "") {
|
||||||
|
attr = attr.replace(/ /g,"").split(/,/);
|
||||||
|
for (var i = 0, m = attr.length; i < m; i++) {
|
||||||
|
var keyvalue = attr[i].split(/[:=]/);
|
||||||
|
if (CANCEL.ALLOWED[keyvalue[0]]) {
|
||||||
|
if (keyvalue[1] === "true") {keyvalue[1] = true}
|
||||||
|
if (keyvalue[1] === "false") {keyvalue[1] = false}
|
||||||
|
def[keyvalue[0]] = keyvalue[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up macro
|
||||||
|
//
|
||||||
|
MACROS.cancel = ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE];
|
||||||
|
MACROS.bcancel = ['Cancel',MML.NOTATION.DOWNDIAGONALSTRIKE];
|
||||||
|
MACROS.xcancel = ['Cancel',MML.NOTATION.UPDIAGONALSTRIKE+" "+MML.NOTATION.DOWNDIAGONALSTRIKE];
|
||||||
|
MACROS.cancelto = 'CancelTo';
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
//
|
||||||
|
// Implement \cancel[attributes]{math},
|
||||||
|
// \bcancel[attributes]{math}, and
|
||||||
|
// \xcancel[attributes]{math}
|
||||||
|
//
|
||||||
|
Cancel: function(name,notation) {
|
||||||
|
var attr = this.GetBrackets(name,""), math = this.ParseArg(name);
|
||||||
|
var def = CANCEL.setAttributes({notation: notation},attr);
|
||||||
|
this.Push(MML.menclose(math).With(def));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implement \cancelto{value}[attributes]{math}
|
||||||
|
//
|
||||||
|
CancelTo: function(name,notation) {
|
||||||
|
var value = this.ParseArg(name),
|
||||||
|
attr = this.GetBrackets(name,""),
|
||||||
|
math = this.ParseArg(name);
|
||||||
|
var def = CANCEL.setAttributes({notation: MML.NOTATION.UPDIAGONALSTRIKE, arrow:true},attr);
|
||||||
|
value = MML.mpadded(value).With({depth:"-.1em",height:"+.1em",voffset:".1em"});
|
||||||
|
this.Push(MML.msup(MML.menclose(math).With(def),value));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX cancel Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/cancel.js");
|
229
resources/viewer/mathjax/extensions/TeX/color.js
Normal file
229
resources/viewer/mathjax/extensions/TeX/color.js
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/color.js
|
||||||
|
*
|
||||||
|
* Implements LaTeX-compatible \color macro rather than MathJax's
|
||||||
|
* original (non-standard) version. It includes the rgb, gray, and
|
||||||
|
* named color models, and the \definecolor macro.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// The configuration defaults, augmented by the user settings
|
||||||
|
//
|
||||||
|
MathJax.Extension["TeX/color"] = {
|
||||||
|
version: "2.0",
|
||||||
|
|
||||||
|
config: MathJax.Hub.CombineConfig("TeX.color",{
|
||||||
|
padding: "5px",
|
||||||
|
border: "2px"
|
||||||
|
}),
|
||||||
|
|
||||||
|
colors: {
|
||||||
|
Apricot: "#FBB982",
|
||||||
|
Aquamarine: "#00B5BE",
|
||||||
|
Bittersweet: "#C04F17",
|
||||||
|
Black: "#221E1F",
|
||||||
|
Blue: "#2D2F92",
|
||||||
|
BlueGreen: "#00B3B8",
|
||||||
|
BlueViolet: "#473992",
|
||||||
|
BrickRed: "#B6321C",
|
||||||
|
Brown: "#792500",
|
||||||
|
BurntOrange: "#F7921D",
|
||||||
|
CadetBlue: "#74729A",
|
||||||
|
CarnationPink: "#F282B4",
|
||||||
|
Cerulean: "#00A2E3",
|
||||||
|
CornflowerBlue: "#41B0E4",
|
||||||
|
Cyan: "#00AEEF",
|
||||||
|
Dandelion: "#FDBC42",
|
||||||
|
DarkOrchid: "#A4538A",
|
||||||
|
Emerald: "#00A99D",
|
||||||
|
ForestGreen: "#009B55",
|
||||||
|
Fuchsia: "#8C368C",
|
||||||
|
Goldenrod: "#FFDF42",
|
||||||
|
Gray: "#949698",
|
||||||
|
Green: "#00A64F",
|
||||||
|
GreenYellow: "#DFE674",
|
||||||
|
JungleGreen: "#00A99A",
|
||||||
|
Lavender: "#F49EC4",
|
||||||
|
LimeGreen: "#8DC73E",
|
||||||
|
Magenta: "#EC008C",
|
||||||
|
Mahogany: "#A9341F",
|
||||||
|
Maroon: "#AF3235",
|
||||||
|
Melon: "#F89E7B",
|
||||||
|
MidnightBlue: "#006795",
|
||||||
|
Mulberry: "#A93C93",
|
||||||
|
NavyBlue: "#006EB8",
|
||||||
|
OliveGreen: "#3C8031",
|
||||||
|
Orange: "#F58137",
|
||||||
|
OrangeRed: "#ED135A",
|
||||||
|
Orchid: "#AF72B0",
|
||||||
|
Peach: "#F7965A",
|
||||||
|
Periwinkle: "#7977B8",
|
||||||
|
PineGreen: "#008B72",
|
||||||
|
Plum: "#92268F",
|
||||||
|
ProcessBlue: "#00B0F0",
|
||||||
|
Purple: "#99479B",
|
||||||
|
RawSienna: "#974006",
|
||||||
|
Red: "#ED1B23",
|
||||||
|
RedOrange: "#F26035",
|
||||||
|
RedViolet: "#A1246B",
|
||||||
|
Rhodamine: "#EF559F",
|
||||||
|
RoyalBlue: "#0071BC",
|
||||||
|
RoyalPurple: "#613F99",
|
||||||
|
RubineRed: "#ED017D",
|
||||||
|
Salmon: "#F69289",
|
||||||
|
SeaGreen: "#3FBC9D",
|
||||||
|
Sepia: "#671800",
|
||||||
|
SkyBlue: "#46C5DD",
|
||||||
|
SpringGreen: "#C6DC67",
|
||||||
|
Tan: "#DA9D76",
|
||||||
|
TealBlue: "#00AEB3",
|
||||||
|
Thistle: "#D883B7",
|
||||||
|
Turquoise: "#00B4CE",
|
||||||
|
Violet: "#58429B",
|
||||||
|
VioletRed: "#EF58A0",
|
||||||
|
White: "#FFFFFF",
|
||||||
|
WildStrawberry: "#EE2967",
|
||||||
|
Yellow: "#FFF200",
|
||||||
|
YellowGreen: "#98CC70",
|
||||||
|
YellowOrange: "#FAA21A"
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up a color based on its model and definition
|
||||||
|
*/
|
||||||
|
getColor: function (model,def) {
|
||||||
|
if (!model) {model = "named"}
|
||||||
|
var fn = this["get_"+model];
|
||||||
|
if (!fn) {this.TEX.Error("Color model '"+model+"' not defined")}
|
||||||
|
return fn.call(this,def);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get an RGB color
|
||||||
|
*/
|
||||||
|
get_rgb: function (rgb) {
|
||||||
|
rgb = rgb.split(/,/); var RGB = "#";
|
||||||
|
if (rgb.length !== 3) {this.TEX.Error("RGB colors require 3 decimal numbers")}
|
||||||
|
for (var i = 0; i < 3; i++) {
|
||||||
|
if (!rgb[i].match(/^(\d+(\.\d*)?|\.\d+)$/)) {this.TEX.Error("Invalid decimal number")}
|
||||||
|
var n = parseFloat(rgb[i]);
|
||||||
|
if (n < 0 || n > 1) {this.TEX.Error("RGB values must be between 0 and 1")}
|
||||||
|
n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
|
||||||
|
RGB += n;
|
||||||
|
}
|
||||||
|
return RGB;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a gray-scale value
|
||||||
|
*/
|
||||||
|
get_gray: function (gray) {
|
||||||
|
if (!gray.match(/^(\d+(\.\d*)?|\.\d+)$/)) {this.TEX.Error("Invalid decimal number")}
|
||||||
|
var n = parseFloat(gray);
|
||||||
|
if (n < 0 || n > 1) {this.TEX.Error("Grey-scale values must be between 0 and 1")}
|
||||||
|
n = Math.floor(n*255).toString(16); if (n.length < 2) {n = "0"+n}
|
||||||
|
return "#"+n+n+n;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a named value
|
||||||
|
*/
|
||||||
|
get_named: function (name) {
|
||||||
|
if (this.colors[name]) {return this.colors[name]}
|
||||||
|
return name;
|
||||||
|
},
|
||||||
|
|
||||||
|
padding: function () {
|
||||||
|
var pad = "+"+this.config.padding;
|
||||||
|
var unit = this.config.padding.replace(/^.*?([a-z]*)$/,"$1");
|
||||||
|
var pad2 = "+"+(2*parseFloat(pad))+unit;
|
||||||
|
return {width:pad2, height:pad, depth:pad, lspace:this.config.padding};
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MML = MathJax.ElementJax.mml;
|
||||||
|
var STACKITEM = TEX.Stack.Item;
|
||||||
|
var COLOR = MathJax.Extension["TeX/color"];
|
||||||
|
|
||||||
|
COLOR.TEX = TEX; // for reference in getColor above
|
||||||
|
|
||||||
|
TEX.Definitions.macros.color = "Color";
|
||||||
|
TEX.Definitions.macros.definecolor = "DefineColor";
|
||||||
|
TEX.Definitions.macros.colorbox = "ColorBox";
|
||||||
|
TEX.Definitions.macros.fcolorbox = "fColorBox";
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override \color macro definition
|
||||||
|
//
|
||||||
|
Color: function (name) {
|
||||||
|
var model = this.GetBrackets(name),
|
||||||
|
color = this.GetArgument(name);
|
||||||
|
color = COLOR.getColor(model,color);
|
||||||
|
var mml = STACKITEM.style().With({styles:{mathcolor:color}});
|
||||||
|
this.stack.env.color = color;
|
||||||
|
this.Push(mml);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the \definecolor macro
|
||||||
|
//
|
||||||
|
DefineColor: function (name) {
|
||||||
|
var cname = this.GetArgument(name),
|
||||||
|
model = this.GetArgument(name),
|
||||||
|
def = this.GetArgument(name);
|
||||||
|
COLOR.colors[cname] = COLOR.getColor(model,def);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Produce a text box with a colored background
|
||||||
|
//
|
||||||
|
ColorBox: function (name) {
|
||||||
|
var cname = this.GetArgument(name),
|
||||||
|
arg = this.InternalMath(this.GetArgument(name));
|
||||||
|
this.Push(MML.mpadded.apply(MML,arg).With({
|
||||||
|
mathbackground:COLOR.getColor("named",cname)
|
||||||
|
}).With(COLOR.padding()));
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Procude a framed text box with a colored background
|
||||||
|
//
|
||||||
|
fColorBox: function (name) {
|
||||||
|
var fname = this.GetArgument(name),
|
||||||
|
cname = this.GetArgument(name),
|
||||||
|
arg = this.InternalMath(this.GetArgument(name));
|
||||||
|
this.Push(MML.mpadded.apply(MML,arg).With({
|
||||||
|
mathbackground: COLOR.getColor("named",cname),
|
||||||
|
style: "border: "+COLOR.config.border+" solid "+COLOR.getColor("named",fname)
|
||||||
|
}).With(COLOR.padding()));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX color Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/color.js");
|
86
resources/viewer/mathjax/extensions/TeX/enclose.js
Normal file
86
resources/viewer/mathjax/extensions/TeX/enclose.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/enclose.js
|
||||||
|
*
|
||||||
|
* Implements the \enclose macros, which give access from TeX to the
|
||||||
|
* <menclose> tag in the MathML that underlies MathJax's internal format.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* \enclose{notation}{math} % enclose math using given notation
|
||||||
|
* \enclose{notation,notation,...}{math} % enclose with several notations
|
||||||
|
* \enclose{notation}[attributes]{math} % enclose with attributes
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/enclose"] = {
|
||||||
|
version: "2.0",
|
||||||
|
|
||||||
|
//
|
||||||
|
// The attributes allowed in \enclose{notation}[attributes]{math}
|
||||||
|
//
|
||||||
|
ALLOWED: {
|
||||||
|
arrow: 1,
|
||||||
|
color: 1, mathcolor: 1,
|
||||||
|
background: 1, mathbackground: 1,
|
||||||
|
padding: 1,
|
||||||
|
thickness: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MML = MathJax.ElementJax.mml,
|
||||||
|
ALLOW = MathJax.Extension["TeX/enclose"].ALLOWED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up macro
|
||||||
|
//
|
||||||
|
TEX.Definitions.macros.enclose = 'Enclose';
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
//
|
||||||
|
// Implement \enclose{notation}[attr]{math}
|
||||||
|
// (create <menclose notation="notation">math</menclose>)
|
||||||
|
//
|
||||||
|
Enclose: function(name) {
|
||||||
|
var notation = this.GetArgument(name),
|
||||||
|
attr = this.GetBrackets(name),
|
||||||
|
math = this.ParseArg(name);
|
||||||
|
var def = {notation: notation.replace(/,/g," ")};
|
||||||
|
if (attr) {
|
||||||
|
attr = attr.replace(/ /g,"").split(/,/);
|
||||||
|
for (var i = 0, m = attr.length; i < m; i++) {
|
||||||
|
var keyvalue = attr[i].split(/[:=]/);
|
||||||
|
if (ALLOW[keyvalue[0]]) {
|
||||||
|
keyvalue[1] = keyvalue[1].replace(/^"(.*)"$/,"$1");
|
||||||
|
if (keyvalue[1] === "true") {keyvalue[1] = true}
|
||||||
|
if (keyvalue[1] === "false") {keyvalue[1] = false}
|
||||||
|
def[keyvalue[0]] = keyvalue[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Push(MML.menclose(math).With(def));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX enclose Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/enclose.js");
|
87
resources/viewer/mathjax/extensions/TeX/extpfeil.js
Normal file
87
resources/viewer/mathjax/extensions/TeX/extpfeil.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/extpfeil.js
|
||||||
|
*
|
||||||
|
* Implements additional stretchy arrow macros.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/extpfeil"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define the arrows to load the AMSmath extension
|
||||||
|
// (since they need its xArrow method)
|
||||||
|
//
|
||||||
|
MathJax.Hub.Insert(TEXDEF,{
|
||||||
|
macros: {
|
||||||
|
xtwoheadrightarrow: ['Extension','AMSmath'],
|
||||||
|
xtwoheadleftarrow: ['Extension','AMSmath'],
|
||||||
|
xmapsto: ['Extension','AMSmath'],
|
||||||
|
xlongequal: ['Extension','AMSmath'],
|
||||||
|
xtofrom: ['Extension','AMSmath'],
|
||||||
|
Newextarrow: ['Extension','AMSmath']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Redefine the macros when AMSmath is loaded
|
||||||
|
//
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX AMSmath Ready",function () {
|
||||||
|
MathJax.Hub.Insert(TEXDEF,{
|
||||||
|
macros: {
|
||||||
|
xtwoheadrightarrow: ['xArrow',0x21A0,12,16],
|
||||||
|
xtwoheadleftarrow: ['xArrow',0x219E,17,13],
|
||||||
|
xmapsto: ['xArrow',0x21A6,6,7],
|
||||||
|
xlongequal: ['xArrow',0x003D,7,7],
|
||||||
|
xtofrom: ['xArrow',0x21C4,12,12],
|
||||||
|
Newextarrow: 'NewExtArrow'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \Newextarrow to define a new arrow (not compatible with \newextarrow, but
|
||||||
|
// the equivalent for MathJax)
|
||||||
|
//
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
NewExtArrow: function (name) {
|
||||||
|
var cs = this.GetArgument(name),
|
||||||
|
space = this.GetArgument(name),
|
||||||
|
chr = this.GetArgument(name);
|
||||||
|
if (!cs.match(/^\\([a-z]+|.)$/i))
|
||||||
|
{TEX.Error("First argument to "+name+" must be a control sequence name")}
|
||||||
|
if (!space.match(/^(\d+),(\d+)$/))
|
||||||
|
{TEX.Error("Second argument to "+name+" must be two integers separated by a comma")}
|
||||||
|
if (!chr.match(/^(\d+|0x[0-9A-F]+)$/i))
|
||||||
|
{TEX.Error("Third argument to "+name+" must be a unicode character number")}
|
||||||
|
cs = cs.substr(1); space = space.split(","); chr = parseInt(chr);
|
||||||
|
TEXDEF.macros[cs] = ['xArrow',chr,parseInt(space[0]),parseInt(space[1])];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX extpfeil Ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/extpfeil.js");
|
78
resources/viewer/mathjax/extensions/TeX/mathchoice.js
Normal file
78
resources/viewer/mathjax/extensions/TeX/mathchoice.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/mathchoice.js
|
||||||
|
*
|
||||||
|
* Implements the \mathchoice macro (rarely used)
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
TEXDEF.macros.mathchoice = 'MathChoice';
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
MathChoice: function (name) {
|
||||||
|
var D = this.ParseArg(name),
|
||||||
|
T = this.ParseArg(name),
|
||||||
|
S = this.ParseArg(name),
|
||||||
|
SS = this.ParseArg(name);
|
||||||
|
this.Push(MML.TeXmathchoice(D,T,S,SS));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.TeXmathchoice = MML.mbase.Subclass({
|
||||||
|
type: "TeXmathchoice",
|
||||||
|
choice: function () {
|
||||||
|
var values = this.getValues("displaystyle","scriptlevel");
|
||||||
|
if (values.scriptlevel > 0) {return Math.min(3,values.scriptlevel + 1)}
|
||||||
|
return (values.displaystyle ? 0 : 1);
|
||||||
|
},
|
||||||
|
setTeXclass: function (prev) {return this.Core().setTeXclass(prev)},
|
||||||
|
isSpacelike: function () {return this.Core().isSpacelike()},
|
||||||
|
isEmbellished: function () {return this.Core().isEmbellished()},
|
||||||
|
Core: function () {return this.data[this.choice()]},
|
||||||
|
toHTML: function (span) {
|
||||||
|
span = this.HTMLcreateSpan(span);
|
||||||
|
span.bbox = this.Core().toHTML(span).bbox;
|
||||||
|
// Firefox doesn't correctly handle a span with a negatively sized content,
|
||||||
|
// so move marginLeft to main span (this is a hack to get \iiiint to work).
|
||||||
|
// FIXME: This is a symptom of a more general problem with Firefox, and
|
||||||
|
// there probably needs to be a more general solution (e.g., modifying
|
||||||
|
// HTMLhandleSpace() to get the width and adjust the right margin to
|
||||||
|
// compensate for negative-width contents)
|
||||||
|
if (span.firstChild && span.firstChild.style.marginLeft) {
|
||||||
|
span.style.marginLeft = span.firstChild.style.marginLeft;
|
||||||
|
span.firstChild.style.marginLeft = "";
|
||||||
|
}
|
||||||
|
return span;
|
||||||
|
},
|
||||||
|
toSVG: function () {return this.Core().toSVG()}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX mathchoice Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mathchoice.js");
|
413
resources/viewer/mathjax/extensions/TeX/mhchem.js
Normal file
413
resources/viewer/mathjax/extensions/TeX/mhchem.js
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/mhchem.js
|
||||||
|
*
|
||||||
|
* Implements the \ce command for handling chemical formulas
|
||||||
|
* from the mhchem LaTeX package.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/mhchem"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX,
|
||||||
|
MACROS = TEX.Definitions.macros;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the main class for handing the \ce and related commands.
|
||||||
|
* Its main method is Parse() which takes the argument to \ce and
|
||||||
|
* returns the corresponding TeX string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var CE = MathJax.Object.Subclass({
|
||||||
|
string: "", // the \ce string being parsed
|
||||||
|
i: 0, // the current position in the string
|
||||||
|
tex: "", // the processed TeX result
|
||||||
|
atom: false, // last processed token is an atom
|
||||||
|
sup: "", // pending superscript
|
||||||
|
sub: "", // pending subscript
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store the string when a CE object is created
|
||||||
|
//
|
||||||
|
Init: function (string) {this.string = string},
|
||||||
|
|
||||||
|
//
|
||||||
|
// These are the special characters and the methods that
|
||||||
|
// handle them. All others are passed through verbatim.
|
||||||
|
//
|
||||||
|
ParseTable: {
|
||||||
|
'-': "Minus",
|
||||||
|
'+': "Plus",
|
||||||
|
'(': "Open",
|
||||||
|
')': "Close",
|
||||||
|
'[': "Open",
|
||||||
|
']': "Close",
|
||||||
|
'<': "Less",
|
||||||
|
'^': "Superscript",
|
||||||
|
'_': "Subscript",
|
||||||
|
'*': "Dot",
|
||||||
|
'.': "Dot",
|
||||||
|
'=': "Equal",
|
||||||
|
'#': "Pound",
|
||||||
|
'$': "Math",
|
||||||
|
'\\': "Macro",
|
||||||
|
' ': "Space"
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Basic arrow names for reactions
|
||||||
|
//
|
||||||
|
Arrows: {
|
||||||
|
'->': "rightarrow",
|
||||||
|
'<-': "leftarrow",
|
||||||
|
'<->': "leftrightarrow",
|
||||||
|
'<=>': "rightleftharpoons",
|
||||||
|
'<=>>': "Rightleftharpoons",
|
||||||
|
'^': "uparrow",
|
||||||
|
'v': "downarrow"
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementations for the various bonds
|
||||||
|
// (the ~ ones are hacks that don't work well in NativeMML)
|
||||||
|
//
|
||||||
|
Bonds: {
|
||||||
|
'-': "-",
|
||||||
|
'=': "=",
|
||||||
|
'#': "\\equiv",
|
||||||
|
'~': "\\tripledash",
|
||||||
|
'~-': "\\begin{CEstack}{}\\tripledash\\\\-\\end{CEstack}",
|
||||||
|
'~=': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
|
||||||
|
'~--': "\\raise2mu{\\begin{CEstack}{}\\tripledash\\\\-\\\\-\\end{CEstack}}",
|
||||||
|
'-~-': "\\raise2mu{\\begin{CEstack}{}-\\\\\\tripledash\\\\-\\end{CEstack}}",
|
||||||
|
'...': "{\\cdot}{\\cdot}{\\cdot}",
|
||||||
|
'....': "{\\cdot}{\\cdot}{\\cdot}{\\cdot}",
|
||||||
|
'->': "\\rightarrow",
|
||||||
|
'<-': "\\leftarrow",
|
||||||
|
'??': "\\text{??}" // unknown bond
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// This converts the CE string to a TeX string.
|
||||||
|
// It loops through the string and calls the proper
|
||||||
|
// method depending on the ccurrent character.
|
||||||
|
//
|
||||||
|
Parse: function () {
|
||||||
|
this.tex = ""; this.atom = false;
|
||||||
|
while (this.i < this.string.length) {
|
||||||
|
var c = this.string.charAt(this.i);
|
||||||
|
if (c.match(/[a-z]/i)) {this.ParseLetter()}
|
||||||
|
else if (c.match(/[0-9]/)) {this.ParseNumber()}
|
||||||
|
else {this["Parse"+(this.ParseTable[c]||"Other")](c)}
|
||||||
|
}
|
||||||
|
this.FinishAtom();
|
||||||
|
return this.tex;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make an atom name or a down arrow
|
||||||
|
//
|
||||||
|
ParseLetter: function () {
|
||||||
|
this.FinishAtom();
|
||||||
|
if (this.Match(/^v( |$)/)) {
|
||||||
|
this.tex += "{\\"+this.Arrows["v"]+"}";
|
||||||
|
} else {
|
||||||
|
this.tex += "\\text{"+this.Match(/^[a-z]+/i)+"}";
|
||||||
|
this.atom = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a number of fraction preceeding an atom,
|
||||||
|
// or a subscript for an atom.
|
||||||
|
//
|
||||||
|
ParseNumber: function () {
|
||||||
|
var n = this.Match(/^\d+/);
|
||||||
|
if (this.atom && !this.sub) {
|
||||||
|
this.sub = n;
|
||||||
|
} else {
|
||||||
|
this.FinishAtom();
|
||||||
|
var match = this.Match(/^\/\d+/);
|
||||||
|
if (match) {
|
||||||
|
var frac = "\\frac{"+n+"}{"+match.substr(1)+"}";
|
||||||
|
this.tex += "\\mathchoice{\\textstyle"+frac+"}{"+frac+"}{"+frac+"}{"+frac+"}";
|
||||||
|
} else {
|
||||||
|
this.tex += n;
|
||||||
|
if (this.i < this.string.length) {this.tex += "\\,"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a superscript minus, or an arrow, or a single bond.
|
||||||
|
//
|
||||||
|
ParseMinus: function (c) {
|
||||||
|
if (this.atom && (this.i === this.string.length-1 || this.string.charAt(this.i+1) === " ")) {
|
||||||
|
this.sup += c;
|
||||||
|
} else {
|
||||||
|
this.FinishAtom();
|
||||||
|
if (this.string.substr(this.i,2) === "->") {this.i += 2; this.AddArrow("->"); return}
|
||||||
|
else {this.tex += "{-}"}
|
||||||
|
}
|
||||||
|
this.i++;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a superscript plus, or pass it through
|
||||||
|
//
|
||||||
|
ParsePlus: function (c) {
|
||||||
|
if (this.atom) {this.sup += c} else {this.FinishAtom(); this.tex += c}
|
||||||
|
this.i++;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle dots and double or triple bonds
|
||||||
|
//
|
||||||
|
ParseDot: function (c) {this.FinishAtom(); this.tex += "\\cdot "; this.i++},
|
||||||
|
ParseEqual: function (c) {this.FinishAtom(); this.tex += "{=}"; this.i++},
|
||||||
|
ParsePound: function (c) {this.FinishAtom(); this.tex += "{\\equiv}"; this.i++},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for (v) or (^), or pass it through
|
||||||
|
//
|
||||||
|
ParseOpen: function (c) {
|
||||||
|
this.FinishAtom();
|
||||||
|
var match = this.Match(/^\([v^]\)/);
|
||||||
|
if (match) {this.tex += "{\\"+this.Arrows[match.charAt(1)]+"}"}
|
||||||
|
else {this.tex += "{"+c; this.i++}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Allow ) and ] to get super- and subscripts
|
||||||
|
//
|
||||||
|
ParseClose: function (c) {this.FinishAtom(); this.atom = true; this.tex += c+"}"; this.i++},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the proper arrow
|
||||||
|
//
|
||||||
|
ParseLess: function (c) {
|
||||||
|
this.FinishAtom();
|
||||||
|
var arrow = this.Match(/^(<->?|<=>>?)/);
|
||||||
|
if (!arrow) {this.tex += c; this.i++} else {this.AddArrow(arrow)}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for a superscript, or an up arrow
|
||||||
|
//
|
||||||
|
ParseSuperscript: function (c) {
|
||||||
|
c = this.string.charAt(++this.i);
|
||||||
|
if (c === "{") {
|
||||||
|
this.i++; var m = this.Find("}");
|
||||||
|
if (m === "-.") {this.sup += "{-}{\\cdot}"} else if (m) {this.sup += CE(m).Parse()}
|
||||||
|
} else if (c === " " || c === "") {
|
||||||
|
this.tex += "{\\"+this.Arrows["^"]+"}"; this.i++;
|
||||||
|
} else {
|
||||||
|
var n = this.Match(/^(\d+|-\.)/);
|
||||||
|
if (n) {this.sup += n}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//
|
||||||
|
// Look for subscripts
|
||||||
|
//
|
||||||
|
ParseSubscript: function (c) {
|
||||||
|
if (this.string.charAt(++this.i) == "{") {
|
||||||
|
this.i++; this.sub += CE(this.Find("}")).Parse();
|
||||||
|
} else {
|
||||||
|
var n = this.Match(/^\d+/);
|
||||||
|
if (n) {this.sub += n}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for raw TeX code to include
|
||||||
|
//
|
||||||
|
ParseMath: function (c) {
|
||||||
|
this.FinishAtom();
|
||||||
|
this.i++; this.tex += this.Find(c);
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look for specific macros for bonds
|
||||||
|
// and allow \} to have subscripts
|
||||||
|
//
|
||||||
|
ParseMacro: function (c) {
|
||||||
|
this.FinishAtom();
|
||||||
|
this.i++; var match = this.Match(/^([a-z]+|.)/i)||" ";
|
||||||
|
if (match === "sbond") {this.tex += "{-}"}
|
||||||
|
else if (match === "dbond") {this.tex += "{=}"}
|
||||||
|
else if (match === "tbond") {this.tex += "{\\equiv}"}
|
||||||
|
else if (match === "bond") {
|
||||||
|
var bond = (this.Match(/^\{.*?\}/)||"");
|
||||||
|
bond = bond.substr(1,bond.length-2);
|
||||||
|
this.tex += "{"+(this.Bonds[bond]||"\\text{??}")+"}";
|
||||||
|
}
|
||||||
|
else if (match === "{") {this.tex += "{\\{"}
|
||||||
|
else if (match === "}") {this.tex += "\\}}"; this.atom = true}
|
||||||
|
else {this.tex += c+match}
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ignore spaces
|
||||||
|
//
|
||||||
|
ParseSpace: function (c) {this.FinishAtom(); this.i++},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pass anything else on verbatim
|
||||||
|
//
|
||||||
|
ParseOther: function (c) {this.FinishAtom(); this.tex += c; this.i++},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process an arrow (looking for brackets for above and below)
|
||||||
|
//
|
||||||
|
AddArrow: function (arrow) {
|
||||||
|
var c = this.Match(/^[CT]\[/);
|
||||||
|
if (c) {this.i--; c = c.charAt(0)}
|
||||||
|
var above = this.GetBracket(c), below = this.GetBracket(c);
|
||||||
|
arrow = this.Arrows[arrow];
|
||||||
|
if (above || below) {
|
||||||
|
if (below) {arrow += "["+below+"]"}
|
||||||
|
arrow += "{"+above+"}";
|
||||||
|
arrow = "\\mathrel{\\x"+arrow+"}";
|
||||||
|
} else {
|
||||||
|
arrow = "\\long"+arrow+" ";
|
||||||
|
}
|
||||||
|
this.tex += arrow;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle the super and subscripts for an atom
|
||||||
|
//
|
||||||
|
FinishAtom: function () {
|
||||||
|
if (this.sup || this.sub) {
|
||||||
|
if (this.sup && this.sub && !this.atom) {
|
||||||
|
//
|
||||||
|
// right-justify super- and subscripts when they are before the atom
|
||||||
|
//
|
||||||
|
var n = Math.abs(this.sup.length-this.sub.length);
|
||||||
|
if (n) {
|
||||||
|
var zeros = "0000000000".substr(0,n);
|
||||||
|
var script = (this.sup.length > this.sub.length ? "sub" : "sup");
|
||||||
|
this[script] = "\\phantom{"+zeros+"}" + this[script];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.sup) {this.sup = "\\Space{0pt}{0pt}{.2em}"} // forces subscripts to align properly
|
||||||
|
this.tex += "^{"+this.sup+"}_{"+this.sub+"}";
|
||||||
|
this.sup = this.sub = "";
|
||||||
|
}
|
||||||
|
this.atom = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a bracket group and handle C and T prefixes
|
||||||
|
//
|
||||||
|
GetBracket: function (c) {
|
||||||
|
if (this.string.charAt(this.i) !== "[") {return ""}
|
||||||
|
this.i++; var bracket = this.Find("]");
|
||||||
|
if (c === "C") {bracket = "\\ce{"+bracket+"}"} else
|
||||||
|
if (c === "T") {
|
||||||
|
if (!bracket.match(/^\{.*\}$/)) {bracket = "{"+bracket+"}"}
|
||||||
|
bracket = "\\text"+bracket;
|
||||||
|
};
|
||||||
|
return bracket;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if the string matches a regular expression
|
||||||
|
// and move past it if so, returning the match
|
||||||
|
//
|
||||||
|
Match: function (regex) {
|
||||||
|
var match = regex.exec(this.string.substr(this.i));
|
||||||
|
if (match) {match = match[0]; this.i += match.length}
|
||||||
|
return match;
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find a particular character, skipping over braced groups
|
||||||
|
//
|
||||||
|
Find: function (c) {
|
||||||
|
var m = this.string.length, i = this.i, braces = 0;
|
||||||
|
while (this.i < m) {
|
||||||
|
var C = this.string.charAt(this.i++);
|
||||||
|
if (C === c && braces === 0) {return this.string.substr(i,this.i-i-1)}
|
||||||
|
if (C === "{") {braces++} else
|
||||||
|
if (C === "}") {
|
||||||
|
if (braces) {braces--}
|
||||||
|
else {TEX.Error("Extra close brace or missing open brace")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (braces) {TEX.Error("Missing close brace")};
|
||||||
|
TEX.Error("Can't find closing "+c);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up the macros for chemistry
|
||||||
|
//
|
||||||
|
MACROS.ce = 'CE';
|
||||||
|
MACROS.cf = 'CE';
|
||||||
|
MACROS.cee = 'CE';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Include some missing arrows (some are hacks)
|
||||||
|
//
|
||||||
|
MACROS.xleftrightarrow = ['xArrow',0x2194,6,6];
|
||||||
|
MACROS.xrightleftharpoons = ['xArrow',0x21CC,5,7]; // FIXME: doesn't stretch in HTML-CSS output
|
||||||
|
MACROS.xRightleftharpoons = ['xArrow',0x21CC,5,7]; // FIXME: how should this be handled?
|
||||||
|
|
||||||
|
// FIXME: These don't work well in FF NativeMML mode
|
||||||
|
MACROS.longrightleftharpoons = ["Macro","\\stackrel{\\textstyle{{-}\\!\\!{\\rightharpoonup}}}{\\smash{{\\leftharpoondown}\\!\\!{-}}}"];
|
||||||
|
MACROS.longRightleftharpoons = ["Macro","\\stackrel{\\textstyle{-}\\!\\!{\\rightharpoonup}}{\\small\\smash\\leftharpoondown}"];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Needed for \bond for the ~ forms
|
||||||
|
//
|
||||||
|
MACROS.tripledash = ["Macro","\\raise3mu{\\tiny\\text{-}\\kern2mu\\text{-}\\kern2mu\\text{-}}"];
|
||||||
|
TEX.Definitions.environment.CEstack = ['Array',null,null,null,'r',null,"0.001em",'T',1]
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add \hyphen used in some mhchem examples
|
||||||
|
//
|
||||||
|
MACROS.hyphen = ["Macro","\\text{-}"];
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements \ce and friends
|
||||||
|
//
|
||||||
|
CE: function (name) {
|
||||||
|
var arg = this.GetArgument(name);
|
||||||
|
var tex = CE(arg).Parse();
|
||||||
|
this.string = tex + this.string.substr(this.i); this.i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Indicate that the extension is ready
|
||||||
|
//
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX mhchem Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/mhchem.js");
|
237
resources/viewer/mathjax/extensions/TeX/newcommand.js
Normal file
237
resources/viewer/mathjax/extensions/TeX/newcommand.js
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/newcommand.js
|
||||||
|
*
|
||||||
|
* Implements the \newcommand, \newenvironment and \def
|
||||||
|
* macros, and is loaded automatically when needed.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/newcommand"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
TEXDEF.Add({
|
||||||
|
macros: {
|
||||||
|
newcommand: 'NewCommand',
|
||||||
|
renewcommand: 'NewCommand',
|
||||||
|
newenvironment: 'NewEnvironment',
|
||||||
|
renewenvironment: 'NewEnvironment',
|
||||||
|
def: 'MacroDef',
|
||||||
|
let: 'Let'
|
||||||
|
}
|
||||||
|
},null,true);
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement \newcommand{\name}[n]{...}
|
||||||
|
*/
|
||||||
|
NewCommand: function (name) {
|
||||||
|
var cs = this.trimSpaces(this.GetArgument(name)),
|
||||||
|
n = this.GetBrackets(name),
|
||||||
|
opt = this.GetBrackets(name),
|
||||||
|
def = this.GetArgument(name);
|
||||||
|
if (cs.charAt(0) === "\\") {cs = cs.substr(1)}
|
||||||
|
if (!cs.match(/^(.|[a-z]+)$/i)) {TEX.Error("Illegal control sequence name for "+name)}
|
||||||
|
if (n) {
|
||||||
|
n = this.trimSpaces(n);
|
||||||
|
if (!n.match(/^[0-9]+$/)) {TEX.Error("Illegal number of parameters specified in "+name)}
|
||||||
|
}
|
||||||
|
this.setDef(cs,['Macro',def,n,opt]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement \newenvironment{name}[n][default]{begincmd}{endcmd}
|
||||||
|
*/
|
||||||
|
NewEnvironment: function (name) {
|
||||||
|
var env = this.trimSpaces(this.GetArgument(name)),
|
||||||
|
n = this.GetBrackets(name),
|
||||||
|
bdef = this.GetArgument(name),
|
||||||
|
edef = this.GetArgument(name);
|
||||||
|
if (n) {
|
||||||
|
n = this.trimSpaces(n);
|
||||||
|
if (!n.match(/^[0-9]+$/)) {TEX.Error("Illegal number of parameters specified in "+name)}
|
||||||
|
}
|
||||||
|
this.setEnv(env,['BeginEnv','EndEnv',bdef,edef,n]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement \def command
|
||||||
|
*/
|
||||||
|
MacroDef: function (name) {
|
||||||
|
var cs = this.GetCSname(name),
|
||||||
|
params = this.GetTemplate(name,"\\"+cs),
|
||||||
|
def = this.GetArgument(name);
|
||||||
|
if (!(params instanceof Array)) {this.setDef(cs,['Macro',def,params])}
|
||||||
|
else {this.setDef(cs,['MacroWithTemplate',def].concat(params))}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implements the \let command
|
||||||
|
*/
|
||||||
|
Let: function (name) {
|
||||||
|
var cs = this.GetCSname(name), macro;
|
||||||
|
var c = this.GetNext(); if (c === "=") {this.i++; c = this.GetNext()}
|
||||||
|
//
|
||||||
|
// All \let commands create entries in the macros array, but we
|
||||||
|
// have to look in the various mathchar and delimiter arrays if
|
||||||
|
// the source isn't a macro already, and attach the data to a
|
||||||
|
// macro with the proper routine to process it.
|
||||||
|
//
|
||||||
|
// A command of the form \let\cs=char produces a macro equivalent
|
||||||
|
// to \def\cs{char}, which is as close as MathJax can get for this.
|
||||||
|
// So \let\bgroup={ is possible, but doesn't work as it does in TeX.
|
||||||
|
//
|
||||||
|
if (c === "\\") {
|
||||||
|
name = this.GetCSname(name);
|
||||||
|
macro = this.csFindMacro(name);
|
||||||
|
if (!macro) {
|
||||||
|
if (TEXDEF.mathchar0mi[name]) {macro = ["csMathchar0mi",TEXDEF.mathchar0mi[name]]} else
|
||||||
|
if (TEXDEF.mathchar0mo[name]) {macro = ["csMathchar0mo",TEXDEF.mathchar0mo[name]]} else
|
||||||
|
if (TEXDEF.mathchar7[name]) {macro = ["csMathchar7",TEXDEF.mathchar7[name]]} else
|
||||||
|
if (TEXDEF.delimiter["\\"+name] != null) {macro = ["csDelimiter",TEXDEF.delimiter["\\"+name]]}
|
||||||
|
}
|
||||||
|
} else {macro = ["Macro",c]; this.i++}
|
||||||
|
this.setDef(cs,macro);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routines to set the macro and environment definitions
|
||||||
|
* (overridden by begingroup to make localized versions)
|
||||||
|
*/
|
||||||
|
setDef: function (name,value) {value.isUser = true; TEXDEF.macros[name] = value},
|
||||||
|
setEnv: function (name,value) {value.isUser = true; TEXDEF.environment[name] = value},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a CS name or give an error
|
||||||
|
*/
|
||||||
|
GetCSname: function (cmd) {
|
||||||
|
var c = this.GetNext();
|
||||||
|
if (c !== "\\") {TEX.Error("\\ must be followed by a control sequence")}
|
||||||
|
var cs = this.trimSpaces(this.GetArgument(cmd));
|
||||||
|
return cs.substr(1);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a \def parameter template
|
||||||
|
*/
|
||||||
|
GetTemplate: function (cmd,cs) {
|
||||||
|
var c, params = [], n = 0;
|
||||||
|
c = this.GetNext(); var i = this.i;
|
||||||
|
while (this.i < this.string.length) {
|
||||||
|
c = this.GetNext();
|
||||||
|
if (c === '#') {
|
||||||
|
if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)}
|
||||||
|
c = this.string.charAt(++this.i);
|
||||||
|
if (!c.match(/^[1-9]$/)) {TEX.Error("Illegal use of # in template for "+cs)}
|
||||||
|
if (parseInt(c) != ++n) {TEX.Error("Parameters for "+cs+" must be numbered sequentially")}
|
||||||
|
i = this.i+1;
|
||||||
|
} else if (c === '{') {
|
||||||
|
if (i !== this.i) {params[n] = this.string.substr(i,this.i-i)}
|
||||||
|
if (params.length > 0) {return [n,params]} else {return n}
|
||||||
|
}
|
||||||
|
this.i++;
|
||||||
|
}
|
||||||
|
TEX.Error("Missing replacement string for definition of "+cmd);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process a macro with a parameter template
|
||||||
|
*/
|
||||||
|
MacroWithTemplate: function (name,text,n,params) {
|
||||||
|
if (n) {
|
||||||
|
var args = []; this.GetNext();
|
||||||
|
if (params[0] && !this.MatchParam(params[0]))
|
||||||
|
{TEX.Error("Use of "+name+" doesn't match its definition")}
|
||||||
|
for (var i = 0; i < n; i++) {args.push(this.GetParameter(name,params[i+1]))}
|
||||||
|
text = this.SubstituteArgs(args,text);
|
||||||
|
}
|
||||||
|
this.string = this.AddArgs(text,this.string.slice(this.i));
|
||||||
|
this.i = 0;
|
||||||
|
if (++this.macroCount > TEX.config.MAXMACROS)
|
||||||
|
{TEX.Error("MathJax maximum macro substitution count exceeded; is there a recursive macro call?")}
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process a user-defined environment
|
||||||
|
*/
|
||||||
|
BeginEnv: function (begin,bdef,edef,n) {
|
||||||
|
if (n) {
|
||||||
|
var args = [];
|
||||||
|
for (var i = 0; i < n; i++) {args.push(this.GetArgument("\\begin{"+name+"}"))}
|
||||||
|
bdef = this.SubstituteArgs(args,bdef);
|
||||||
|
edef = this.SubstituteArgs(args,edef);
|
||||||
|
}
|
||||||
|
begin.edef = edef;
|
||||||
|
this.string = this.AddArgs(bdef,this.string.slice(this.i)); this.i = 0;
|
||||||
|
return begin;
|
||||||
|
},
|
||||||
|
EndEnv: function (begin,row) {
|
||||||
|
this.string = this.AddArgs(begin.edef,this.string.slice(this.i)); this.i = 0
|
||||||
|
return row;
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a single parameter delimited by a trailing template
|
||||||
|
*/
|
||||||
|
GetParameter: function (name,param) {
|
||||||
|
if (param == null) {return this.GetArgument(name)}
|
||||||
|
var i = this.i, j = 0, hasBraces = 0;
|
||||||
|
while (this.i < this.string.length) {
|
||||||
|
if (this.string.charAt(this.i) === '{') {
|
||||||
|
if (this.i === i) {hasBraces = 1}
|
||||||
|
this.GetArgument(name); j = this.i - i;
|
||||||
|
} else if (this.MatchParam(param)) {
|
||||||
|
if (hasBraces) {i++; j -= 2}
|
||||||
|
return this.string.substr(i,j);
|
||||||
|
} else {
|
||||||
|
this.i++; j++; hasBraces = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEX.Error("Runaway argument for "+name+"?");
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a template is at the current location.
|
||||||
|
* (The match must be exact, with no spacing differences. TeX is
|
||||||
|
* a little more forgiving than this about spaces after macro names)
|
||||||
|
*/
|
||||||
|
MatchParam: function (param) {
|
||||||
|
if (this.string.substr(this.i,param.length) !== param) {return 0}
|
||||||
|
this.i += param.length;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
TEX.Environment = function (name) {
|
||||||
|
TEXDEF.environment[name] = ['BeginEnv','EndEnv'].concat([].slice.call(arguments,1));
|
||||||
|
TEXDEF.environment[name].isUser = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX newcommand Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/newcommand.js");
|
306
resources/viewer/mathjax/extensions/TeX/noErrors.js
Normal file
306
resources/viewer/mathjax/extensions/TeX/noErrors.js
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/noErrors.js
|
||||||
|
*
|
||||||
|
* Prevents the TeX error messages from being displayed and shows the
|
||||||
|
* original TeX code instead. You can configure whether the dollar signs
|
||||||
|
* are shown or not for in-line math, and whether to put all the TeX on
|
||||||
|
* one line or use multiple-lines.
|
||||||
|
*
|
||||||
|
* To configure this extension, use
|
||||||
|
*
|
||||||
|
* MathJax.Hub.Config({
|
||||||
|
* TeX: {
|
||||||
|
* noErrors: {
|
||||||
|
* inlineDelimiters: ["",""], // or ["$","$"] or ["\\(","\\)"]
|
||||||
|
* multiLine: true, // false for TeX on all one line
|
||||||
|
* style: {
|
||||||
|
* "font-size": "90%",
|
||||||
|
* "text-align": "left",
|
||||||
|
* "color": "black",
|
||||||
|
* "padding": "1px 3px",
|
||||||
|
* "border": "1px solid"
|
||||||
|
* // add any additional CSS styles that you want
|
||||||
|
* // (be sure there is no extra comma at the end of the last item)
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Display-style math is always shown in multi-line format, and without
|
||||||
|
* delimiters, as it will already be set off in its own centered
|
||||||
|
* paragraph, like standard display mathematics.
|
||||||
|
*
|
||||||
|
* The default settings place the invalid TeX in a multi-line box with a
|
||||||
|
* black border. If you want it to look as though the TeX is just part of
|
||||||
|
* the paragraph, use
|
||||||
|
*
|
||||||
|
* MathJax.Hub.Config({
|
||||||
|
* TeX: {
|
||||||
|
* noErrors: {
|
||||||
|
* inlineDelimiters: ["$","$"], // or ["",""] or ["\\(","\\)"]
|
||||||
|
* multiLine: false,
|
||||||
|
* style: {
|
||||||
|
* "font-size": "normal",
|
||||||
|
* "border": ""
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* You may also wish to set the font family, as the default is "serif"
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (HUB,HTML) {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var CONFIG = HUB.CombineConfig("TeX.noErrors",{
|
||||||
|
disabled: false, // set to true to return to original error messages
|
||||||
|
multiLine: true,
|
||||||
|
inlineDelimiters: ["",""], // or use ["$","$"] or ["\\(","\\)"]
|
||||||
|
style: {
|
||||||
|
"font-size": "90%",
|
||||||
|
"text-align": "left",
|
||||||
|
"color": "black",
|
||||||
|
"padding": "1px 3px",
|
||||||
|
"border": "1px solid"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var NBSP = "\u00A0";
|
||||||
|
|
||||||
|
//
|
||||||
|
// The configuration defaults, augmented by the user settings
|
||||||
|
//
|
||||||
|
MathJax.Extension["TeX/noErrors"] = {
|
||||||
|
version: VERSION,
|
||||||
|
config: CONFIG
|
||||||
|
};
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var FORMAT = MathJax.InputJax.TeX.formatError;
|
||||||
|
|
||||||
|
MathJax.InputJax.TeX.Augment({
|
||||||
|
//
|
||||||
|
// Make error messages be the original TeX code
|
||||||
|
// Mark them as errors and multi-line or not, and for
|
||||||
|
// multi-line TeX, make spaces non-breakable (to get formatting right)
|
||||||
|
//
|
||||||
|
formatError: function (err,math,displaystyle,script) {
|
||||||
|
if (CONFIG.disabled) {return FORMAT.apply(this,arguments)}
|
||||||
|
var message = err.message.replace(/\n.*/,"");
|
||||||
|
HUB.signal.Post(["TeX Jax - parse error",message,math,displaystyle,script]);
|
||||||
|
var delim = CONFIG.inlineDelimiters;
|
||||||
|
var multiLine = (displaystyle || CONFIG.multiLine);
|
||||||
|
if (!displaystyle) {math = delim[0] + math + delim[1]}
|
||||||
|
if (multiLine) {math = math.replace(/ /g,NBSP)} else {math = math.replace(/\n/g," ")}
|
||||||
|
return MathJax.ElementJax.mml.merror(math).With({isError:true, multiLine: multiLine});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Fix HTML-CSS output
|
||||||
|
*/
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("HTML-CSS Jax Config",function () {
|
||||||
|
HUB.Config({
|
||||||
|
"HTML-CSS": {
|
||||||
|
styles: {
|
||||||
|
".MathJax .noError": HUB.Insert({
|
||||||
|
"vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
|
||||||
|
},CONFIG.style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("HTML-CSS Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var HTMLCSS = MathJax.OutputJax["HTML-CSS"];
|
||||||
|
|
||||||
|
var MATH = MML.math.prototype.toHTML,
|
||||||
|
MERROR = MML.merror.prototype.toHTML;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override math toHTML routine so that error messages
|
||||||
|
// don't have the clipping and other unneeded overhead
|
||||||
|
//
|
||||||
|
MML.math.Augment({
|
||||||
|
toHTML: function (span,node) {
|
||||||
|
var data = this.data[0];
|
||||||
|
if (data && data.data[0] && data.data[0].isError) {
|
||||||
|
span.style.fontSize = "";
|
||||||
|
span = this.HTMLcreateSpan(span);
|
||||||
|
span.bbox = data.data[0].toHTML(span).bbox;
|
||||||
|
} else {
|
||||||
|
span = MATH.call(this,span,node);
|
||||||
|
}
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override merror toHTML routine so that it puts out the
|
||||||
|
// TeX code in an inline-block with line breaks as in the original
|
||||||
|
//
|
||||||
|
MML.merror.Augment({
|
||||||
|
toHTML: function (span) {
|
||||||
|
if (!this.isError) {return MERROR.call(this,span)}
|
||||||
|
span = this.HTMLcreateSpan(span); span.className = "noError"
|
||||||
|
if (this.multiLine) {span.style.display = "inline-block"}
|
||||||
|
var text = this.data[0].data[0].data.join("").split(/\n/);
|
||||||
|
for (var i = 0, m = text.length; i < m; i++) {
|
||||||
|
HTMLCSS.addText(span,text[i]);
|
||||||
|
if (i !== m-1) {HTMLCSS.addElement(span,"br",{isMathJax:true})}
|
||||||
|
}
|
||||||
|
var HD = HTMLCSS.getHD(span.parentNode), W = HTMLCSS.getW(span.parentNode);
|
||||||
|
if (m > 1) {
|
||||||
|
var H = (HD.h + HD.d)/2, x = HTMLCSS.TeX.x_height/2;
|
||||||
|
span.parentNode.style.verticalAlign = HTMLCSS.Em(HD.d+(x-H));
|
||||||
|
HD.h = x + H; HD.d = H - x;
|
||||||
|
}
|
||||||
|
span.bbox = {h: HD.h, d: HD.d, w: W, lw: 0, rw: W};
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Fix SVG output
|
||||||
|
*/
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("SVG Jax Config",function () {
|
||||||
|
HUB.Config({
|
||||||
|
"SVG": {
|
||||||
|
styles: {
|
||||||
|
".MathJax_SVG .noError": HUB.Insert({
|
||||||
|
"vertical-align": (HUB.Browser.isMSIE && CONFIG.multiLine ? "-2px" : "")
|
||||||
|
},CONFIG.style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("SVG Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
|
||||||
|
var MATH = MML.math.prototype.toSVG,
|
||||||
|
MERROR = MML.merror.prototype.toSVG;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override math toSVG routine so that error messages
|
||||||
|
// don't have the clipping and other unneeded overhead
|
||||||
|
//
|
||||||
|
MML.math.Augment({
|
||||||
|
toSVG: function (span,node) {
|
||||||
|
var data = this.data[0];
|
||||||
|
if (data && data.data[0] && data.data[0].isError)
|
||||||
|
{span = data.data[0].toSVG(span)} else {span = MATH.call(this,span,node)}
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override merror toSVG routine so that it puts out the
|
||||||
|
// TeX code in an inline-block with line breaks as in the original
|
||||||
|
//
|
||||||
|
MML.merror.Augment({
|
||||||
|
toSVG: function (span) {
|
||||||
|
if (!this.isError || this.Parent().type !== "math") {return MERROR.call(this,span)}
|
||||||
|
span = HTML.addElement(span,"span",{className: "noError", isMathJax:true});
|
||||||
|
if (this.multiLine) {span.style.display = "inline-block"}
|
||||||
|
var text = this.data[0].data[0].data.join("").split(/\n/);
|
||||||
|
for (var i = 0, m = text.length; i < m; i++) {
|
||||||
|
HTML.addText(span,text[i]);
|
||||||
|
if (i !== m-1) {HTML.addElement(span,"br",{isMathJax:true})}
|
||||||
|
}
|
||||||
|
if (m > 1) {
|
||||||
|
var H = span.offsetHeight/2;
|
||||||
|
span.style.verticalAlign = (-H+(H/m))+"px";
|
||||||
|
}
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* Fix NativeMML output
|
||||||
|
*/
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("NativeMML Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var CONFIG = MathJax.Extension["TeX/noErrors"].config;
|
||||||
|
|
||||||
|
var MATH = MML.math.prototype.toNativeMML,
|
||||||
|
MERROR = MML.merror.prototype.toNativeMML;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override math toNativeMML routine so that error messages
|
||||||
|
// don't get placed inside math tags.
|
||||||
|
//
|
||||||
|
MML.math.Augment({
|
||||||
|
toNativeMML: function (span) {
|
||||||
|
var data = this.data[0];
|
||||||
|
if (data && data.data[0] && data.data[0].isError)
|
||||||
|
{span = data.data[0].toNativeMML(span)} else {span = MATH.call(this,span)}
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override merror toNativeMML routine so that it puts out the
|
||||||
|
// TeX code in an inline-block with line breaks as in the original
|
||||||
|
//
|
||||||
|
MML.merror.Augment({
|
||||||
|
toNativeMML: function (span) {
|
||||||
|
if (!this.isError) {return MERROR.call(this,span)}
|
||||||
|
span = span.appendChild(document.createElement("span"));
|
||||||
|
var text = this.data[0].data[0].data.join("").split(/\n/);
|
||||||
|
for (var i = 0, m = text.length; i < m; i++) {
|
||||||
|
span.appendChild(document.createTextNode(text[i]));
|
||||||
|
if (i !== m-1) {span.appendChild(document.createElement("br"))}
|
||||||
|
}
|
||||||
|
if (this.multiLine) {
|
||||||
|
span.style.display = "inline-block";
|
||||||
|
if (m > 1) {span.style.verticalAlign = "middle"}
|
||||||
|
}
|
||||||
|
for (var id in CONFIG.style) {if (CONFIG.style.hasOwnProperty(id)) {
|
||||||
|
var ID = id.replace(/-./g,function (c) {return c.charAt(1).toUpperCase()});
|
||||||
|
span.style[ID] = CONFIG.style[id];
|
||||||
|
}}
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
HUB.Startup.signal.Post("TeX noErrors Ready");
|
||||||
|
|
||||||
|
})(MathJax.Hub,MathJax.HTML);
|
||||||
|
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noErrors.js");
|
69
resources/viewer/mathjax/extensions/TeX/noUndefined.js
Normal file
69
resources/viewer/mathjax/extensions/TeX/noUndefined.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/noUndefined.js
|
||||||
|
*
|
||||||
|
* This causes undefined control sequences to be shown as their macro
|
||||||
|
* names rather than producing an error message. So $X_{\xxx}$ would
|
||||||
|
* display as an X with a subscript consiting of the text "\xxx".
|
||||||
|
*
|
||||||
|
* To configure this extension, use for example
|
||||||
|
*
|
||||||
|
* MathJax.Hub.Config({
|
||||||
|
* TeX: {
|
||||||
|
* noUndefined: {
|
||||||
|
* attributes: {
|
||||||
|
* mathcolor: "red",
|
||||||
|
* mathbackground: "#FFEEEE",
|
||||||
|
* mathsize: "90%"
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// The configuration defaults, augmented by the user settings
|
||||||
|
//
|
||||||
|
MathJax.Extension["TeX/noUndefined"] = {
|
||||||
|
version: "2.0",
|
||||||
|
config: MathJax.Hub.CombineConfig("TeX.noUndefined",{
|
||||||
|
disabled: false, // set to true to return to original error messages
|
||||||
|
attributes: {
|
||||||
|
mathcolor: "red"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var CONFIG = MathJax.Extension["TeX/noUndefined"].config;
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var UNDEFINED = MathJax.InputJax.TeX.Parse.prototype.csUndefined;
|
||||||
|
|
||||||
|
MathJax.InputJax.TeX.Parse.Augment({
|
||||||
|
csUndefined: function (name) {
|
||||||
|
if (CONFIG.disabled) {return UNDEFINED.apply(this,arguments)}
|
||||||
|
MathJax.Hub.signal.Post(["TeX Jax - undefined control sequence",name]);
|
||||||
|
this.Push(MML.mtext(name).With(CONFIG.attributes));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX noUndefined Ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/noUndefined.js");
|
164
resources/viewer/mathjax/extensions/TeX/unicode.js
Normal file
164
resources/viewer/mathjax/extensions/TeX/unicode.js
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/unicode.js
|
||||||
|
*
|
||||||
|
* Implements the \unicode extension to TeX to allow arbitrary unicode
|
||||||
|
* code points to be entered into the TeX file. You can specify
|
||||||
|
* the height and depth of the character (the width is determined by
|
||||||
|
* the browser), and the default font from which to take the character.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* \unicode{65} % the character 'A'
|
||||||
|
* \unicode{x41} % the character 'A'
|
||||||
|
* \unicode[.55,0.05]{x22D6} % less-than with dot, with height .55 and depth 0.05
|
||||||
|
* \unicode[.55,0.05][Geramond]{x22D6} % same taken from Geramond font
|
||||||
|
* \unicode[Garamond]{x22D6} % same, but with default height, depth of .8,.2
|
||||||
|
*
|
||||||
|
* Once a size and font are provided for a given code point, they need
|
||||||
|
* not be specified again in subsequent \unicode calls for that character.
|
||||||
|
* Note that a font list can be given, but Internet Explorer has a buggy
|
||||||
|
* implementation of font-family where it only looks in the first
|
||||||
|
* available font and if the glyph is not in that, it does not look at
|
||||||
|
* later fonts, but goes directly to the default font as set in the
|
||||||
|
* Internet-Options/Font panel. For this reason, the default font list is
|
||||||
|
* "STIXGeneral,'Arial Unicode MS'", so if the user has STIX fonts, the
|
||||||
|
* symbol will be taken from that (almost all the symbols are in
|
||||||
|
* STIXGeneral), otherwise Arial Unicode MS is tried.
|
||||||
|
*
|
||||||
|
* To configure the default font list, use
|
||||||
|
*
|
||||||
|
* MathJax.Hub.Config({
|
||||||
|
* TeX: {
|
||||||
|
* unicode: {
|
||||||
|
* fonts: "STIXGeneral,'Arial Unicode MS'"
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* The result of \unicode will have TeX class ORD (i.e., it will act like a
|
||||||
|
* variable). Use \mathbin, \mathrel, etc, to specify a different class.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// The configuration defaults, augmented by the user settings
|
||||||
|
//
|
||||||
|
MathJax.Extension["TeX/unicode"] = {
|
||||||
|
version: "2.0",
|
||||||
|
unicode: {},
|
||||||
|
config: MathJax.Hub.CombineConfig("TeX.unicode",{
|
||||||
|
fonts: "STIXGeneral,'Arial Unicode MS'"
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var UNICODE = MathJax.Extension["TeX/unicode"].unicode;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add \unicode macro
|
||||||
|
//
|
||||||
|
TEX.Definitions.macros.unicode = 'Unicode';
|
||||||
|
//
|
||||||
|
// Implementation of \unicode in parser
|
||||||
|
//
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
Unicode: function(name) {
|
||||||
|
var HD = this.GetBrackets(name), font;
|
||||||
|
if (HD) {
|
||||||
|
if (HD.replace(/ /g,"").match(/^(\d+(\.\d*)?|\.\d+),(\d+(\.\d*)?|\.\d+)$/))
|
||||||
|
{HD = HD.replace(/ /g,"").split(/,/); font = this.GetBrackets(name)}
|
||||||
|
else {font = HD; HD = null}
|
||||||
|
}
|
||||||
|
var n = this.trimSpaces(this.GetArgument(name)),
|
||||||
|
N = parseInt(n.match(/^x/) ? "0"+n : n);
|
||||||
|
if (!UNICODE[N]) {UNICODE[N] = [800,200,font,N]}
|
||||||
|
else if (!font) {font = UNICODE[N][2]}
|
||||||
|
if (HD) {
|
||||||
|
UNICODE[N][0] = Math.floor(HD[0]*1000);
|
||||||
|
UNICODE[N][1] = Math.floor(HD[1]*1000);
|
||||||
|
}
|
||||||
|
var variant = this.stack.env.font, def = {};
|
||||||
|
if (font) {
|
||||||
|
UNICODE[N][2] = def.fontfamily = font.replace(/"/g,"'");
|
||||||
|
if (variant) {
|
||||||
|
if (variant.match(/bold/)) {def.fontweight = "bold"}
|
||||||
|
if (variant.match(/italic|-mathit/)) {def.fontstyle = "italic"}
|
||||||
|
}
|
||||||
|
} else if (variant) {def.mathvariant = variant}
|
||||||
|
def.unicode = [].concat(UNICODE[N]); // make a copy
|
||||||
|
this.Push(MML.mtext(MML.entity("#"+n)).With(def));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX unicode Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override getVariant to make one that includes the font and size
|
||||||
|
//
|
||||||
|
var GETVARIANT = MML.mbase.prototype.HTMLgetVariant;
|
||||||
|
MML.mbase.Augment({
|
||||||
|
HTMLgetVariant: function () {
|
||||||
|
var variant = GETVARIANT.call(this);
|
||||||
|
if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
|
||||||
|
if (!this.unicode) {return variant}
|
||||||
|
variant.unicode = true;
|
||||||
|
if (!variant.defaultFont) {
|
||||||
|
variant = MathJax.Hub.Insert({},variant); // make a copy
|
||||||
|
variant.defaultFont = {family:FONTS};
|
||||||
|
}
|
||||||
|
var family = this.unicode[2]; if (family) {family += ","+FONTS} else {family = FONTS}
|
||||||
|
variant.defaultFont[this.unicode[3]] = [
|
||||||
|
this.unicode[0],this.unicode[1],500,0,500,
|
||||||
|
{isUnknown:true, isUnicode:true, font:family}
|
||||||
|
];
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () {
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var FONTS = MathJax.Extension["TeX/unicode"].config.fonts;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Override getVariant to make one that includes the font and size
|
||||||
|
//
|
||||||
|
var GETVARIANT = MML.mbase.prototype.SVGgetVariant;
|
||||||
|
MML.mbase.Augment({
|
||||||
|
SVGgetVariant: function () {
|
||||||
|
var variant = GETVARIANT.call(this);
|
||||||
|
if (variant.unicode) {delete variant.unicode; delete variant.FONTS} // clear font cache in case of restart
|
||||||
|
if (!this.unicode) {return variant}
|
||||||
|
variant.unicode = true;
|
||||||
|
if (!variant.forceFamily) {variant = MathJax.Hub.Insert({},variant)} // make a copy
|
||||||
|
variant.defaultFamily = FONTS; variant.noRemap = true;
|
||||||
|
variant.h = this.unicode[0]; variant.d = this.unicode[1];
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/unicode.js");
|
58
resources/viewer/mathjax/extensions/TeX/verb.js
Normal file
58
resources/viewer/mathjax/extensions/TeX/verb.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/TeX/verb.js
|
||||||
|
*
|
||||||
|
* Implements the \verb|...| command for including text verbatim
|
||||||
|
* (with no processing of macros or special characters).
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension["TeX/verb"] = {
|
||||||
|
version: "2.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
|
||||||
|
|
||||||
|
var MML = MathJax.ElementJax.mml;
|
||||||
|
var TEX = MathJax.InputJax.TeX;
|
||||||
|
var TEXDEF = TEX.Definitions;
|
||||||
|
|
||||||
|
TEXDEF.macros.verb = 'Verb';
|
||||||
|
|
||||||
|
TEX.Parse.Augment({
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement \verb|...|
|
||||||
|
*/
|
||||||
|
Verb: function (name) {
|
||||||
|
var c = this.GetNext(); var start = ++this.i;
|
||||||
|
if (c == "" ) {TEX.Error(name+" requires an argument")}
|
||||||
|
while (this.i < this.string.length && this.string.charAt(this.i) != c) {this.i++}
|
||||||
|
if (this.i == this.string.length)
|
||||||
|
{TEX.Error("Can't find closing delimiter for "+name)}
|
||||||
|
var text = this.string.slice(start,this.i); this.i++;
|
||||||
|
this.Push(MML.mtext(text).With({mathvariant:MML.VARIANT.MONOSPACE}));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("TeX verb Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/TeX/verb.js");
|
228
resources/viewer/mathjax/extensions/asciimath2jax.js
Normal file
228
resources/viewer/mathjax/extensions/asciimath2jax.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/asciimath2jax.js
|
||||||
|
*
|
||||||
|
* Implements the AsciiMath to Jax preprocessor that locates AsciiMath
|
||||||
|
* code within the text of a document and replaces it with SCRIPT tags for
|
||||||
|
* processing by MathJax.
|
||||||
|
*
|
||||||
|
* Modified by David Lippman, based on tex2jax.js.
|
||||||
|
* Additional work by Davide P. Cervone.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension.asciimath2jax = {
|
||||||
|
version: "2.0",
|
||||||
|
config: {
|
||||||
|
delimiters: [['`','`']], // The star/stop delimiter pairs for asciimath code
|
||||||
|
|
||||||
|
skipTags: ["script","noscript","style","textarea","pre","code"],
|
||||||
|
// The names of the tags whose contents will not be
|
||||||
|
// scanned for math delimiters
|
||||||
|
|
||||||
|
ignoreClass: "asciimath2jax_ignore", // the class name of elements whose contents should
|
||||||
|
// NOT be processed by asciimath2jax. Note that this
|
||||||
|
// is a regular expression, so be sure to quote any
|
||||||
|
// regexp special characters
|
||||||
|
|
||||||
|
processClass: "asciimath2jax_process", // the class name of elements whose contents SHOULD
|
||||||
|
// be processed when they appear inside ones that
|
||||||
|
// are ignored. Note that this is a regular expression,
|
||||||
|
// so be sure to quote any regexp special characters
|
||||||
|
|
||||||
|
preview: "AsciiMath" // set to "none" to not insert MathJax_Preview spans
|
||||||
|
// or set to an array specifying an HTML snippet
|
||||||
|
// to use the same preview for every equation.
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
PreProcess: function (element) {
|
||||||
|
if (!this.configured) {
|
||||||
|
this.config = MathJax.Hub.CombineConfig("asciimath2jax",this.config);
|
||||||
|
if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)}
|
||||||
|
this.configured = true;
|
||||||
|
}
|
||||||
|
if (typeof(element) === "string") {element = document.getElementById(element)}
|
||||||
|
if (!element) {element = document.body}
|
||||||
|
if (this.createPatterns()) {this.scanElement(element,element.nextSibling)}
|
||||||
|
},
|
||||||
|
|
||||||
|
createPatterns: function () {
|
||||||
|
var starts = [], i, m, config = this.config; this.match = {};
|
||||||
|
if (config.delimiters.length === 0) {return false}
|
||||||
|
for (i = 0, m = config.delimiters.length; i < m; i++) {
|
||||||
|
starts.push(this.patternQuote(config.delimiters[i][0]));
|
||||||
|
this.match[config.delimiters[i][0]] = {
|
||||||
|
mode: "",
|
||||||
|
end: config.delimiters[i][1],
|
||||||
|
pattern: this.endPattern(config.delimiters[i][1])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.start = new RegExp(starts.sort(this.sortLength).join("|"),"g");
|
||||||
|
this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i");
|
||||||
|
this.ignoreClass = new RegExp("(^| )("+config.ignoreClass+")( |$)");
|
||||||
|
this.processClass = new RegExp("(^| )("+config.processClass+")( |$)");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
patternQuote: function (s) {return s.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,'\\$1')},
|
||||||
|
|
||||||
|
endPattern: function (end) {
|
||||||
|
return new RegExp(this.patternQuote(end)+"|\\\\.","g");
|
||||||
|
},
|
||||||
|
|
||||||
|
sortLength: function (a,b) {
|
||||||
|
if (a.length !== b.length) {return b.length - a.length}
|
||||||
|
return (a == b ? 0 : (a < b ? -1 : 1));
|
||||||
|
},
|
||||||
|
|
||||||
|
scanElement: function (element,stop,ignore) {
|
||||||
|
var cname, tname, ignoreChild, process;
|
||||||
|
while (element && element != stop) {
|
||||||
|
if (element.nodeName.toLowerCase() === '#text') {
|
||||||
|
if (!ignore) {element = this.scanText(element)}
|
||||||
|
} else {
|
||||||
|
cname = (typeof(element.className) === "undefined" ? "" : element.className);
|
||||||
|
tname = (typeof(element.tagName) === "undefined" ? "" : element.tagName);
|
||||||
|
if (typeof(cname) !== "string") {cname = String(cname)} // jsxgraph uses non-string class names!
|
||||||
|
process = this.processClass.exec(cname);
|
||||||
|
if (element.firstChild && !cname.match(/(^| )MathJax/) &&
|
||||||
|
(process || !this.skipTags.exec(tname))) {
|
||||||
|
ignoreChild = (ignore || this.ignoreClass.exec(cname)) && !process;
|
||||||
|
this.scanElement(element.firstChild,stop,ignoreChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (element) {element = element.nextSibling}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
scanText: function (element) {
|
||||||
|
if (element.nodeValue.replace(/\s+/,'') == '') {return element}
|
||||||
|
var match, prev;
|
||||||
|
this.search = {start: true};
|
||||||
|
this.pattern = this.start;
|
||||||
|
while (element) {
|
||||||
|
this.pattern.lastIndex = 0;
|
||||||
|
while (element && element.nodeName.toLowerCase() === '#text' &&
|
||||||
|
(match = this.pattern.exec(element.nodeValue))) {
|
||||||
|
if (this.search.start) {element = this.startMatch(match,element)}
|
||||||
|
else {element = this.endMatch(match,element)}
|
||||||
|
}
|
||||||
|
if (this.search.matched) {element = this.encloseMath(element)}
|
||||||
|
if (element) {
|
||||||
|
do {prev = element; element = element.nextSibling}
|
||||||
|
while (element && (element.nodeName.toLowerCase() === 'br' ||
|
||||||
|
element.nodeName.toLowerCase() === '#comment'));
|
||||||
|
if (!element || element.nodeName !== '#text') {return prev}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
startMatch: function (match,element) {
|
||||||
|
var delim = this.match[match[0]];
|
||||||
|
if (delim != null) {
|
||||||
|
this.search = {
|
||||||
|
end: delim.end, mode: delim.mode,
|
||||||
|
open: element, olen: match[0].length,
|
||||||
|
opos: this.pattern.lastIndex - match[0].length
|
||||||
|
};
|
||||||
|
this.switchPattern(delim.pattern);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
endMatch: function (match,element) {
|
||||||
|
if (match[0] == this.search.end) {
|
||||||
|
this.search.close = element;
|
||||||
|
this.search.cpos = this.pattern.lastIndex;
|
||||||
|
this.search.clen = (this.search.isBeginEnd ? 0 : match[0].length);
|
||||||
|
this.search.matched = true;
|
||||||
|
element = this.encloseMath(element);
|
||||||
|
this.switchPattern(this.start);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
switchPattern: function (pattern) {
|
||||||
|
pattern.lastIndex = this.pattern.lastIndex;
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.search.start = (pattern === this.start);
|
||||||
|
},
|
||||||
|
|
||||||
|
encloseMath: function (element) {
|
||||||
|
var search = this.search, close = search.close, CLOSE, math;
|
||||||
|
if (search.cpos === close.length) {close = close.nextSibling}
|
||||||
|
else {close = close.splitText(search.cpos)}
|
||||||
|
if (!close) {CLOSE = close = MathJax.HTML.addText(search.close.parentNode,"")}
|
||||||
|
search.close = close;
|
||||||
|
math = (search.opos ? search.open.splitText(search.opos) : search.open);
|
||||||
|
while (math.nextSibling && math.nextSibling !== close) {
|
||||||
|
if (math.nextSibling.nodeValue !== null) {
|
||||||
|
if (math.nextSibling.nodeName === "#comment") {
|
||||||
|
math.nodeValue += math.nextSibling.nodeValue.replace(/^\[CDATA\[((.|\n|\r)*)\]\]$/,"$1");
|
||||||
|
} else {
|
||||||
|
math.nodeValue += math.nextSibling.nodeValue;
|
||||||
|
}
|
||||||
|
} else if (this.msieNewlineBug) {
|
||||||
|
math.nodeValue += (math.nextSibling.nodeName.toLowerCase() === "br" ? "\n" : " ");
|
||||||
|
} else {
|
||||||
|
math.nodeValue += " ";
|
||||||
|
}
|
||||||
|
math.parentNode.removeChild(math.nextSibling);
|
||||||
|
}
|
||||||
|
var AM = math.nodeValue.substr(search.olen,math.nodeValue.length-search.olen-search.clen);
|
||||||
|
math.parentNode.removeChild(math);
|
||||||
|
if (this.config.preview !== "none") {this.createPreview(search.mode,AM)}
|
||||||
|
math = this.createMathTag(search.mode,AM);
|
||||||
|
this.search = {}; this.pattern.lastIndex = 0;
|
||||||
|
if (CLOSE) {CLOSE.parentNode.removeChild(CLOSE)}
|
||||||
|
return math;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertNode: function (node) {
|
||||||
|
var search = this.search;
|
||||||
|
search.close.parentNode.insertBefore(node,search.close);
|
||||||
|
},
|
||||||
|
|
||||||
|
createPreview: function (mode,asciimath) {
|
||||||
|
var preview;
|
||||||
|
if (this.config.preview === "AsciiMath") {preview = [this.filterPreview(asciimath)]}
|
||||||
|
else if (this.config.preview instanceof Array) {preview = this.config.preview}
|
||||||
|
if (preview) {
|
||||||
|
preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview);
|
||||||
|
this.insertNode(preview);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createMathTag: function (mode,asciimath) {
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.type = "math/asciimath" + mode;
|
||||||
|
MathJax.HTML.setScript(script,asciimath);
|
||||||
|
this.insertNode(script);
|
||||||
|
return script;
|
||||||
|
},
|
||||||
|
|
||||||
|
filterPreview: function (asciimath) {return asciimath},
|
||||||
|
|
||||||
|
msieNewlineBug: (MathJax.Hub.Browser.isMSIE && (document.documentMode||0) < 9)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.asciimath2jax]);
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/asciimath2jax.js");
|
95
resources/viewer/mathjax/extensions/jsMath2jax.js
Normal file
95
resources/viewer/mathjax/extensions/jsMath2jax.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/jsMath2jax.js
|
||||||
|
*
|
||||||
|
* Implements a jsMath to Jax preprocessor that locates jsMath-style
|
||||||
|
* <SPAN CLASS="math">...</SPAN> and <DIV CLASS="math">...</DIV> tags
|
||||||
|
* and replaces them with SCRIPT tags for processing by MathJax.
|
||||||
|
* (Note: use the tex2jax preprocessor to convert TeX delimiters or
|
||||||
|
* custom delimiters to MathJax SCRIPT tags. This preprocessor is
|
||||||
|
* only for the SPAN and DIV form of jsMath delimiters).
|
||||||
|
*
|
||||||
|
* To use this preprocessor, include "jsMath2jax.js" in the extensions
|
||||||
|
* array in your config/MathJax.js file, or the MathJax.Hub.Config() call
|
||||||
|
* in your HTML document.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension.jsMath2jax = {
|
||||||
|
version: "2.0",
|
||||||
|
|
||||||
|
config: {
|
||||||
|
preview: "TeX" // Set to "none" to prevent preview strings from being inserted
|
||||||
|
// or to an array that specifies an HTML snippet to use for
|
||||||
|
// the preview.
|
||||||
|
},
|
||||||
|
|
||||||
|
PreProcess: function (element) {
|
||||||
|
if (!this.configured) {
|
||||||
|
this.config = MathJax.Hub.CombineConfig("jsMath2jax",this.config);
|
||||||
|
if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)}
|
||||||
|
if (typeof(this.config.previewTeX) !== "undefined" && !this.config.previewTeX)
|
||||||
|
{this.config.preview = "none"} // backward compatibility for previewTeX parameter
|
||||||
|
this.previewClass = MathJax.Hub.config.preRemoveClass;
|
||||||
|
this.configured = true;
|
||||||
|
}
|
||||||
|
if (typeof(element) === "string") {element = document.getElementById(element)}
|
||||||
|
if (!element) {element = document.body}
|
||||||
|
var span = element.getElementsByTagName("span"), i;
|
||||||
|
for (i = span.length-1; i >= 0; i--)
|
||||||
|
{if (String(span[i].className).match(/(^| )math( |$)/)) {this.ConvertMath(span[i],"")}}
|
||||||
|
var div = element.getElementsByTagName("div");
|
||||||
|
for (i = div.length-1; i >= 0; i--)
|
||||||
|
{if (String(div[i].className).match(/(^| )math( |$)/)) {this.ConvertMath(div[i],"; mode=display")}}
|
||||||
|
},
|
||||||
|
|
||||||
|
ConvertMath: function (node,mode) {
|
||||||
|
if (node.getElementsByTagName("script").length === 0) {
|
||||||
|
var parent = node.parentNode,
|
||||||
|
script = this.createMathTag(mode,node.innerHTML);
|
||||||
|
if (node.nextSibling) {parent.insertBefore(script,node.nextSibling)}
|
||||||
|
else {parent.appendChild(script)}
|
||||||
|
if (this.config.preview !== "none") {this.createPreview(node)}
|
||||||
|
parent.removeChild(node);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createPreview: function (node) {
|
||||||
|
var preview;
|
||||||
|
if (this.config.preview === "TeX") {preview = [this.filterPreview(node.innerHTML)]}
|
||||||
|
else if (this.config.preview instanceof Array) {preview = this.config.preview}
|
||||||
|
if (preview) {
|
||||||
|
preview = MathJax.HTML.Element("span",{className: MathJax.Hub.config.preRemoveClass},preview);
|
||||||
|
node.parentNode.insertBefore(preview,node);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createMathTag: function (mode,tex) {
|
||||||
|
tex = tex.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&");
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.type = "math/tex" + mode;
|
||||||
|
MathJax.HTML.setScript(script,tex);
|
||||||
|
return script;
|
||||||
|
},
|
||||||
|
|
||||||
|
filterPreview: function (tex) {return tex}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.jsMath2jax]);
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/jsMath2jax.js");
|
205
resources/viewer/mathjax/extensions/mml2jax.js
Normal file
205
resources/viewer/mathjax/extensions/mml2jax.js
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/mml2jax.js
|
||||||
|
*
|
||||||
|
* Implements the MathML to Jax preprocessor that locates <math> nodes
|
||||||
|
* within the text of a document and replaces them with SCRIPT tags
|
||||||
|
* for processing by MathJax.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension.mml2jax = {
|
||||||
|
version: "2.0",
|
||||||
|
config: {
|
||||||
|
preview: "alttext" // Use the <math> element's alttext as the
|
||||||
|
// preview. Set to "none" for no preview,
|
||||||
|
// or set to an array specifying an HTML snippet
|
||||||
|
// to use a fixed preview for all math
|
||||||
|
|
||||||
|
},
|
||||||
|
MMLnamespace: "http://www.w3.org/1998/Math/MathML",
|
||||||
|
|
||||||
|
PreProcess: function (element) {
|
||||||
|
if (!this.configured) {
|
||||||
|
this.config = MathJax.Hub.CombineConfig("mml2jax",this.config);
|
||||||
|
if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)}
|
||||||
|
this.InitBrowser();
|
||||||
|
this.configured = true;
|
||||||
|
}
|
||||||
|
if (typeof(element) === "string") {element = document.getElementById(element)}
|
||||||
|
if (!element) {element = document.body}
|
||||||
|
//
|
||||||
|
// Handle all math tags with no namespaces
|
||||||
|
//
|
||||||
|
this.ProcessMathArray(element.getElementsByTagName("math"));
|
||||||
|
//
|
||||||
|
// Handle math with namespaces in XHTML
|
||||||
|
//
|
||||||
|
if (element.getElementsByTagNameNS)
|
||||||
|
{this.ProcessMathArray(element.getElementsByTagNameNS(this.MMLnamespace,"math"))}
|
||||||
|
//
|
||||||
|
// Handle math with namespaces in HTML
|
||||||
|
//
|
||||||
|
var i, m;
|
||||||
|
if (document.namespaces) {
|
||||||
|
//
|
||||||
|
// IE namespaces are listed in document.namespaces
|
||||||
|
//
|
||||||
|
for (i = 0, m = document.namespaces.length; i < m; i++) {
|
||||||
|
var ns = document.namespaces[i];
|
||||||
|
if (ns.urn === this.MMLnamespace)
|
||||||
|
{this.ProcessMathArray(element.getElementsByTagName(ns.name+":math"))}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Everybody else
|
||||||
|
//
|
||||||
|
var html = document.getElementsByTagName("html")[0];
|
||||||
|
if (html) {
|
||||||
|
for (i = 0, m = html.attributes.length; i < m; i++) {
|
||||||
|
var attr = html.attributes[i];
|
||||||
|
if (attr.nodeName.substr(0,6) === "xmlns:" && attr.nodeValue === this.MMLnamespace)
|
||||||
|
{this.ProcessMathArray(element.getElementsByTagName(attr.nodeName.substr(6)+":math"))}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ProcessMathArray: function (math) {
|
||||||
|
var i;
|
||||||
|
if (math.length) {
|
||||||
|
if (this.MathTagBug) {
|
||||||
|
for (i = math.length-1; i >= 0; i--) {
|
||||||
|
if (math[i].nodeName === "MATH") {this.ProcessMathFlattened(math[i])}
|
||||||
|
else {this.ProcessMath(math[i])}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = math.length-1; i >= 0; i--) {this.ProcessMath(math[i])}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ProcessMath: function (math) {
|
||||||
|
var parent = math.parentNode;
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.type = "math/mml";
|
||||||
|
parent.insertBefore(script,math);
|
||||||
|
if (this.AttributeBug) {
|
||||||
|
var html = this.OuterHTML(math);
|
||||||
|
if (this.CleanupHTML) {
|
||||||
|
html = html.replace(/<\?import .*?>/i,"").replace(/<\?xml:namespace .*?\/>/i,"");
|
||||||
|
html = html.replace(/ /g," ");
|
||||||
|
}
|
||||||
|
MathJax.HTML.setScript(script,html); parent.removeChild(math);
|
||||||
|
} else {
|
||||||
|
var span = MathJax.HTML.Element("span"); span.appendChild(math);
|
||||||
|
MathJax.HTML.setScript(script,span.innerHTML);
|
||||||
|
}
|
||||||
|
if (this.config.preview !== "none") {this.createPreview(math,script)}
|
||||||
|
},
|
||||||
|
|
||||||
|
ProcessMathFlattened: function (math) {
|
||||||
|
var parent = math.parentNode;
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.type = "math/mml";
|
||||||
|
parent.insertBefore(script,math);
|
||||||
|
var mml = "", node, MATH = math;
|
||||||
|
while (math && math.nodeName !== "/MATH") {
|
||||||
|
node = math; math = math.nextSibling;
|
||||||
|
mml += this.NodeHTML(node);
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
}
|
||||||
|
if (math && math.nodeName === "/MATH") {math.parentNode.removeChild(math)}
|
||||||
|
script.text = mml + "</math>";
|
||||||
|
if (this.config.preview !== "none") {this.createPreview(MATH,script)}
|
||||||
|
},
|
||||||
|
|
||||||
|
NodeHTML: function (node) {
|
||||||
|
var html, i, m;
|
||||||
|
if (node.nodeName === "#text") {
|
||||||
|
html = this.quoteHTML(node.nodeValue);
|
||||||
|
} else if (node.nodeName === "#comment") {
|
||||||
|
html = "<!--" + node.nodeValue + "-->"
|
||||||
|
} else {
|
||||||
|
// In IE, outerHTML doesn't properly quote attributes, so quote them by hand
|
||||||
|
// In Opera, HTML special characters aren't quoted in attributes, so quote them
|
||||||
|
html = "<"+node.nodeName.toLowerCase();
|
||||||
|
for (i = 0, m = node.attributes.length; i < m; i++) {
|
||||||
|
var attribute = node.attributes[i];
|
||||||
|
if (attribute.specified) {
|
||||||
|
// Opera 11.5 beta turns xmlns into xmlns:xmlns, so put it back (*** check after 11.5 is out ***)
|
||||||
|
html += " "+attribute.nodeName.toLowerCase().replace(/xmlns:xmlns/,"xmlns")+"=";
|
||||||
|
var value = attribute.nodeValue; // IE < 8 doesn't properly set style by setAttributes
|
||||||
|
if (value == null && attribute.nodeName === "style" && node.style) {value = node.style.cssText}
|
||||||
|
html += '"'+this.quoteHTML(value)+'"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html += ">";
|
||||||
|
// Handle internal HTML (possibly due to <semantics> annotation or missing </math>)
|
||||||
|
if (node.outerHTML != null && node.outerHTML.match(/(.<\/[A-Z]+>|\/>)$/)) {
|
||||||
|
for (i = 0, m = node.childNodes.length; i < m; i++)
|
||||||
|
{html += this.OuterHTML(node.childNodes[i])}
|
||||||
|
html += "</"+node.nodeName.toLowerCase()+">";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
OuterHTML: function (node) {
|
||||||
|
if (node.nodeName.charAt(0) === "#") {return this.NodeHTML(node)}
|
||||||
|
if (!this.AttributeBug) {return node.outerHTML}
|
||||||
|
var html = this.NodeHTML(node);
|
||||||
|
for (var i = 0, m = node.childNodes.length; i < m; i++)
|
||||||
|
{html += this.OuterHTML(node.childNodes[i]);}
|
||||||
|
html += "</"+node.nodeName.toLowerCase()+">";
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
quoteHTML: function (string) {
|
||||||
|
if (string == null) {string = ""}
|
||||||
|
return string.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");
|
||||||
|
},
|
||||||
|
|
||||||
|
createPreview: function (math,script) {
|
||||||
|
var preview;
|
||||||
|
if (this.config.preview === "alttext") {
|
||||||
|
var text = math.getAttribute("alttext");
|
||||||
|
if (text != null) {preview = [this.filterPreview(text)]}
|
||||||
|
} else if (this.config.preview instanceof Array) {preview = this.config.preview}
|
||||||
|
if (preview) {
|
||||||
|
preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview);
|
||||||
|
script.parentNode.insertBefore(preview,script);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
filterPreview: function (text) {return text},
|
||||||
|
|
||||||
|
InitBrowser: function () {
|
||||||
|
var test = MathJax.HTML.Element("span",{id:"<", className: "mathjax", innerHTML: "<math><mi>x</mi><mspace /></math>"});
|
||||||
|
var html = test.outerHTML || "";
|
||||||
|
this.AttributeBug = html !== "" && !(
|
||||||
|
html.match(/id="<"/) && // "<" should convert to "<"
|
||||||
|
html.match(/class="mathjax"/) && // IE leaves out quotes
|
||||||
|
html.match(/<\/math>/) // Opera 9 drops tags after self-closing tags
|
||||||
|
);
|
||||||
|
this.MathTagBug = test.childNodes.length > 1; // IE < 9 flattens unknown tags
|
||||||
|
this.CleanupHTML = MathJax.Hub.Browser.isMSIE; // remove namespace and other added tags
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.mml2jax]);
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/mml2jax.js");
|
298
resources/viewer/mathjax/extensions/tex2jax.js
Normal file
298
resources/viewer/mathjax/extensions/tex2jax.js
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/tex2jax.js
|
||||||
|
*
|
||||||
|
* Implements the TeX to Jax preprocessor that locates TeX code
|
||||||
|
* within the text of a document and replaces it with SCRIPT tags
|
||||||
|
* for processing by MathJax.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Extension.tex2jax = {
|
||||||
|
version: "2.0",
|
||||||
|
config: {
|
||||||
|
inlineMath: [ // The start/stop pairs for in-line math
|
||||||
|
// ['$','$'], // (comment out any you don't want, or add your own, but
|
||||||
|
['\\(','\\)'] // be sure that you don't have an extra comma at the end)
|
||||||
|
],
|
||||||
|
|
||||||
|
displayMath: [ // The start/stop pairs for display math
|
||||||
|
['$$','$$'], // (comment out any you don't want, or add your own, but
|
||||||
|
['\\[','\\]'] // be sure that you don't have an extra comma at the end)
|
||||||
|
],
|
||||||
|
|
||||||
|
balanceBraces: true, // determines whether tex2jax requires braces to be
|
||||||
|
// balanced within math delimiters (allows for nested
|
||||||
|
// dollar signs). Set to false to get pre-v2.0 compatibility.
|
||||||
|
|
||||||
|
skipTags: ["script","noscript","style","textarea","pre","code"],
|
||||||
|
// The names of the tags whose contents will not be
|
||||||
|
// scanned for math delimiters
|
||||||
|
|
||||||
|
ignoreClass: "tex2jax_ignore", // the class name of elements whose contents should
|
||||||
|
// NOT be processed by tex2jax. Note that this
|
||||||
|
// is a regular expression, so be sure to quote any
|
||||||
|
// regexp special characters
|
||||||
|
|
||||||
|
processClass: "tex2jax_process", // the class name of elements whose contents SHOULD
|
||||||
|
// be processed when they appear inside ones that
|
||||||
|
// are ignored. Note that this is a regular expression,
|
||||||
|
// so be sure to quote any regexp special characters
|
||||||
|
|
||||||
|
processEscapes: false, // set to true to allow \$ to produce a dollar without
|
||||||
|
// starting in-line math mode
|
||||||
|
|
||||||
|
processEnvironments: true, // set to true to process \begin{xxx}...\end{xxx} outside
|
||||||
|
// of math mode, false to prevent that
|
||||||
|
|
||||||
|
processRefs: true, // set to true to process \ref{...} outside of math mode
|
||||||
|
|
||||||
|
|
||||||
|
preview: "TeX" // set to "none" to not insert MathJax_Preview spans
|
||||||
|
// or set to an array specifying an HTML snippet
|
||||||
|
// to use the same preview for every equation.
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
PreProcess: function (element) {
|
||||||
|
if (!this.configured) {
|
||||||
|
this.config = MathJax.Hub.CombineConfig("tex2jax",this.config);
|
||||||
|
if (this.config.Augment) {MathJax.Hub.Insert(this,this.config.Augment)}
|
||||||
|
if (typeof(this.config.previewTeX) !== "undefined" && !this.config.previewTeX)
|
||||||
|
{this.config.preview = "none"} // backward compatibility for previewTeX parameter
|
||||||
|
this.configured = true;
|
||||||
|
}
|
||||||
|
if (typeof(element) === "string") {element = document.getElementById(element)}
|
||||||
|
if (!element) {element = document.body}
|
||||||
|
if (this.createPatterns()) {this.scanElement(element,element.nextSibling)}
|
||||||
|
},
|
||||||
|
|
||||||
|
createPatterns: function () {
|
||||||
|
var starts = [], parts = [], i, m, config = this.config;
|
||||||
|
this.match = {};
|
||||||
|
for (i = 0, m = config.inlineMath.length; i < m; i++) {
|
||||||
|
starts.push(this.patternQuote(config.inlineMath[i][0]));
|
||||||
|
this.match[config.inlineMath[i][0]] = {
|
||||||
|
mode: "",
|
||||||
|
end: config.inlineMath[i][1],
|
||||||
|
pattern: this.endPattern(config.inlineMath[i][1])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (i = 0, m = config.displayMath.length; i < m; i++) {
|
||||||
|
starts.push(this.patternQuote(config.displayMath[i][0]));
|
||||||
|
this.match[config.displayMath[i][0]] = {
|
||||||
|
mode: "; mode=display",
|
||||||
|
end: config.displayMath[i][1],
|
||||||
|
pattern: this.endPattern(config.displayMath[i][1])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (starts.length) {parts.push(starts.sort(this.sortLength).join("|"))}
|
||||||
|
if (config.processEnvironments) {parts.push("\\\\begin\\{([^}]*)\\}")}
|
||||||
|
if (config.processEscapes) {parts.push("\\\\*\\\\\\\$")}
|
||||||
|
if (config.processRefs) {parts.push("\\\\(eq)?ref\\{[^}]*\\}")}
|
||||||
|
this.start = new RegExp(parts.join("|"),"g");
|
||||||
|
this.skipTags = new RegExp("^("+config.skipTags.join("|")+")$","i");
|
||||||
|
this.ignoreClass = new RegExp("(^| )("+config.ignoreClass+")( |$)");
|
||||||
|
this.processClass = new RegExp("(^| )("+config.processClass+")( |$)");
|
||||||
|
return (parts.length > 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
patternQuote: function (s) {return s.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,'\\$1')},
|
||||||
|
|
||||||
|
endPattern: function (end) {
|
||||||
|
return new RegExp(this.patternQuote(end)+"|\\\\.|[{}]","g");
|
||||||
|
},
|
||||||
|
|
||||||
|
sortLength: function (a,b) {
|
||||||
|
if (a.length !== b.length) {return b.length - a.length}
|
||||||
|
return (a == b ? 0 : (a < b ? -1 : 1));
|
||||||
|
},
|
||||||
|
|
||||||
|
scanElement: function (element,stop,ignore) {
|
||||||
|
var cname, tname, ignoreChild, process;
|
||||||
|
while (element && element != stop) {
|
||||||
|
if (element.nodeName.toLowerCase() === '#text') {
|
||||||
|
if (!ignore) {element = this.scanText(element)}
|
||||||
|
} else {
|
||||||
|
cname = (typeof(element.className) === "undefined" ? "" : element.className);
|
||||||
|
tname = (typeof(element.tagName) === "undefined" ? "" : element.tagName);
|
||||||
|
if (typeof(cname) !== "string") {cname = String(cname)} // jsxgraph uses non-string class names!
|
||||||
|
process = this.processClass.exec(cname);
|
||||||
|
if (element.firstChild && !cname.match(/(^| )MathJax/) &&
|
||||||
|
(process || !this.skipTags.exec(tname))) {
|
||||||
|
ignoreChild = (ignore || this.ignoreClass.exec(cname)) && !process;
|
||||||
|
this.scanElement(element.firstChild,stop,ignoreChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (element) {element = element.nextSibling}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
scanText: function (element) {
|
||||||
|
if (element.nodeValue.replace(/\s+/,'') == '') {return element}
|
||||||
|
var match, prev;
|
||||||
|
this.search = {start: true};
|
||||||
|
this.pattern = this.start;
|
||||||
|
while (element) {
|
||||||
|
this.pattern.lastIndex = 0;
|
||||||
|
while (element && element.nodeName.toLowerCase() === '#text' &&
|
||||||
|
(match = this.pattern.exec(element.nodeValue))) {
|
||||||
|
if (this.search.start) {element = this.startMatch(match,element)}
|
||||||
|
else {element = this.endMatch(match,element)}
|
||||||
|
}
|
||||||
|
if (this.search.matched) {element = this.encloseMath(element)}
|
||||||
|
if (element) {
|
||||||
|
do {prev = element; element = element.nextSibling}
|
||||||
|
while (element && (element.nodeName.toLowerCase() === 'br' ||
|
||||||
|
element.nodeName.toLowerCase() === '#comment'));
|
||||||
|
if (!element || element.nodeName !== '#text')
|
||||||
|
{return (this.search.close ? this.prevEndMatch() : prev)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
startMatch: function (match,element) {
|
||||||
|
var delim = this.match[match[0]];
|
||||||
|
if (delim != null) { // a start delimiter
|
||||||
|
this.search = {
|
||||||
|
end: delim.end, mode: delim.mode, pcount: 0,
|
||||||
|
open: element, olen: match[0].length, opos: this.pattern.lastIndex - match[0].length
|
||||||
|
};
|
||||||
|
this.switchPattern(delim.pattern);
|
||||||
|
} else if (match[0].substr(0,6) === "\\begin") { // \begin{...}
|
||||||
|
this.search = {
|
||||||
|
end: "\\end{"+match[1]+"}", mode: "; mode=display", pcount: 0,
|
||||||
|
open: element, olen: 0, opos: this.pattern.lastIndex - match[0].length,
|
||||||
|
isBeginEnd: true
|
||||||
|
};
|
||||||
|
this.switchPattern(this.endPattern(this.search.end));
|
||||||
|
} else if (match[0].substr(0,4) === "\\ref" || match[0].substr(0,6) === "\\eqref") {
|
||||||
|
this.search = {
|
||||||
|
mode: "", end: "", open: element, pcount: 0,
|
||||||
|
olen: 0, opos: this.pattern.lastIndex - match[0].length
|
||||||
|
}
|
||||||
|
return this.endMatch([""],element);
|
||||||
|
} else { // escaped dollar signs
|
||||||
|
// put $ in a span so it doesn't get processed again
|
||||||
|
// split off backslashes so they don't get removed later
|
||||||
|
var slashes = match[0].substr(0,match[0].length-1), n, span;
|
||||||
|
if (slashes.length % 2 === 0) {span = [slashes.replace(/\\\\/g,"\\")]; n = 1}
|
||||||
|
else {span = [slashes.substr(1).replace(/\\\\/g,"\\"),"$"]; n = 0}
|
||||||
|
span = MathJax.HTML.Element("span",null,span);
|
||||||
|
var text = MathJax.HTML.TextNode(element.nodeValue.substr(0,match.index));
|
||||||
|
element.nodeValue = element.nodeValue.substr(match.index + match[0].length - n);
|
||||||
|
element.parentNode.insertBefore(span,element);
|
||||||
|
element.parentNode.insertBefore(text,span);
|
||||||
|
this.pattern.lastIndex = n;
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
endMatch: function (match,element) {
|
||||||
|
var search = this.search;
|
||||||
|
if (match[0] == search.end) {
|
||||||
|
if (!search.close || search.pcount === 0) {
|
||||||
|
search.close = element;
|
||||||
|
search.cpos = this.pattern.lastIndex;
|
||||||
|
search.clen = (search.isBeginEnd ? 0 : match[0].length);
|
||||||
|
}
|
||||||
|
if (search.pcount === 0) {
|
||||||
|
search.matched = true;
|
||||||
|
element = this.encloseMath(element);
|
||||||
|
this.switchPattern(this.start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (match[0] === "{") {search.pcount++}
|
||||||
|
else if (match[0] === "}" && search.pcount) {search.pcount--}
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
prevEndMatch: function () {
|
||||||
|
this.search.matched = true;
|
||||||
|
var element = this.encloseMath(this.search.close);
|
||||||
|
this.switchPattern(this.start);
|
||||||
|
return element;
|
||||||
|
},
|
||||||
|
|
||||||
|
switchPattern: function (pattern) {
|
||||||
|
pattern.lastIndex = this.pattern.lastIndex;
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.search.start = (pattern === this.start);
|
||||||
|
},
|
||||||
|
|
||||||
|
encloseMath: function (element) {
|
||||||
|
var search = this.search, close = search.close, CLOSE, math;
|
||||||
|
if (search.cpos === close.length) {close = close.nextSibling}
|
||||||
|
else {close = close.splitText(search.cpos)}
|
||||||
|
if (!close) {CLOSE = close = MathJax.HTML.addText(search.close.parentNode,"")}
|
||||||
|
search.close = close;
|
||||||
|
math = (search.opos ? search.open.splitText(search.opos) : search.open);
|
||||||
|
while (math.nextSibling && math.nextSibling !== close) {
|
||||||
|
if (math.nextSibling.nodeValue !== null) {
|
||||||
|
if (math.nextSibling.nodeName === "#comment") {
|
||||||
|
math.nodeValue += math.nextSibling.nodeValue.replace(/^\[CDATA\[((.|\n|\r)*)\]\]$/,"$1");
|
||||||
|
} else {
|
||||||
|
math.nodeValue += math.nextSibling.nodeValue;
|
||||||
|
}
|
||||||
|
} else if (this.msieNewlineBug) {
|
||||||
|
math.nodeValue += (math.nextSibling.nodeName.toLowerCase() === "br" ? "\n" : " ");
|
||||||
|
} else {
|
||||||
|
math.nodeValue += " ";
|
||||||
|
}
|
||||||
|
math.parentNode.removeChild(math.nextSibling);
|
||||||
|
}
|
||||||
|
var TeX = math.nodeValue.substr(search.olen,math.nodeValue.length-search.olen-search.clen);
|
||||||
|
math.parentNode.removeChild(math);
|
||||||
|
if (this.config.preview !== "none") {this.createPreview(search.mode,TeX)}
|
||||||
|
math = this.createMathTag(search.mode,TeX);
|
||||||
|
this.search = {}; this.pattern.lastIndex = 0;
|
||||||
|
if (CLOSE) {CLOSE.parentNode.removeChild(CLOSE)}
|
||||||
|
return math;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertNode: function (node) {
|
||||||
|
var search = this.search;
|
||||||
|
search.close.parentNode.insertBefore(node,search.close);
|
||||||
|
},
|
||||||
|
|
||||||
|
createPreview: function (mode,tex) {
|
||||||
|
var preview;
|
||||||
|
if (this.config.preview === "TeX") {preview = [this.filterPreview(tex)]}
|
||||||
|
else if (this.config.preview instanceof Array) {preview = this.config.preview}
|
||||||
|
if (preview) {
|
||||||
|
preview = MathJax.HTML.Element("span",{className:MathJax.Hub.config.preRemoveClass},preview);
|
||||||
|
this.insertNode(preview);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createMathTag: function (mode,tex) {
|
||||||
|
var script = document.createElement("script");
|
||||||
|
script.type = "math/tex" + mode;
|
||||||
|
MathJax.HTML.setScript(script,tex);
|
||||||
|
this.insertNode(script);
|
||||||
|
return script;
|
||||||
|
},
|
||||||
|
|
||||||
|
filterPreview: function (tex) {return tex},
|
||||||
|
|
||||||
|
msieNewlineBug: (MathJax.Hub.Browser.isMSIE && document.documentMode < 9)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.tex2jax]);
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/tex2jax.js");
|
178
resources/viewer/mathjax/extensions/toMathML.js
Normal file
178
resources/viewer/mathjax/extensions/toMathML.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/toMathML.js
|
||||||
|
*
|
||||||
|
* Implements a toMathML() method for the mml Element Jax that returns
|
||||||
|
* a MathML string from a given math expression.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var MML = MathJax.ElementJax.mml
|
||||||
|
SETTINGS = MathJax.Hub.config.menuSettings;
|
||||||
|
|
||||||
|
MML.mbase.Augment({
|
||||||
|
|
||||||
|
toMathML: function (space) {
|
||||||
|
var inferred = (this.inferred && this.parent.inferRow);
|
||||||
|
if (space == null) {space = ""}
|
||||||
|
var tag = this.type, attr = this.toMathMLattributes();
|
||||||
|
if (tag === "mspace") {return space + "<"+tag+attr+" />"}
|
||||||
|
var data = []; var SPACE = (this.isToken ? "" : space+(inferred ? "" : " "));
|
||||||
|
for (var i = 0, m = this.data.length; i < m; i++) {
|
||||||
|
if (this.data[i]) {data.push(this.data[i].toMathML(SPACE))}
|
||||||
|
else if (!this.isToken) {data.push(SPACE+"<mrow />")}
|
||||||
|
}
|
||||||
|
if (this.isToken) {return space + "<"+tag+attr+">"+data.join("")+"</"+tag+">"}
|
||||||
|
if (inferred) {return data.join("\n")}
|
||||||
|
if (data.length === 0 || (data.length === 1 && data[0] === ""))
|
||||||
|
{return space + "<"+tag+attr+" />"}
|
||||||
|
return space + "<"+tag+attr+">\n"+data.join("\n")+"\n"+ space +"</"+tag+">";
|
||||||
|
},
|
||||||
|
|
||||||
|
toMathMLattributes: function () {
|
||||||
|
var attr = [], defaults = this.defaults;
|
||||||
|
var copy = (this.attrNames||MML.copyAttributeNames), skip = MML.skipAttributes;
|
||||||
|
|
||||||
|
if (this.type === "math") {attr.push('xmlns="http://www.w3.org/1998/Math/MathML"')}
|
||||||
|
if (!this.attrNames) {
|
||||||
|
if (this.type === "mstyle") {defaults = MML.math.prototype.defaults}
|
||||||
|
for (var id in defaults) {if (!skip[id] && defaults.hasOwnProperty(id)) {
|
||||||
|
var force = (id === "open" || id === "close");
|
||||||
|
if (this[id] != null && (force || this[id] !== defaults[id])) {
|
||||||
|
var value = this[id]; delete this[id];
|
||||||
|
if (force || this.Get(id) !== value)
|
||||||
|
{attr.push(id+'="'+this.toMathMLattribute(value)+'"')}
|
||||||
|
this[id] = value;
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
for (var i = 0, m = copy.length; i < m; i++) {
|
||||||
|
if (copy[i] === "class") continue; // this is handled separately below
|
||||||
|
value = (this.attr||{})[copy[i]]; if (value == null) {value = this[copy[i]]}
|
||||||
|
if (value != null) {attr.push(copy[i]+'="'+this.toMathMLquote(value)+'"')}
|
||||||
|
}
|
||||||
|
this.toMathMLclass(attr);
|
||||||
|
if (attr.length) {return " "+attr.join(" ")} else {return ""}
|
||||||
|
},
|
||||||
|
toMathMLclass: function (attr) {
|
||||||
|
var CLASS = []; if (this["class"]) {CLASS.push(this["class"])}
|
||||||
|
if (this.isa(MML.TeXAtom) && SETTINGS.texHints) {
|
||||||
|
var TEXCLASS = ["ORD","OP","BIN","REL","OPEN","CLOSE","PUNCT","INNER","VCENTER"][this.texClass];
|
||||||
|
if (TEXCLASS) {CLASS.push("MJX-TeXAtom-"+TEXCLASS)}
|
||||||
|
}
|
||||||
|
if (this.mathvariant && this.toMathMLvariants[this.mathvariant])
|
||||||
|
{CLASS.push("MJX"+this.mathvariant)}
|
||||||
|
if (this.arrow) {CLASS.push("MJX-arrow")}
|
||||||
|
if (this.variantForm) {CLASS.push("MJX-variant")}
|
||||||
|
if (CLASS.length) {attr.unshift('class="'+CLASS.join(" ")+'"')}
|
||||||
|
},
|
||||||
|
toMathMLattribute: function (value) {
|
||||||
|
if (typeof(value) === "string" &&
|
||||||
|
value.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)) {
|
||||||
|
// FIXME: should take scriptlevel into account
|
||||||
|
return ((1/18)*RegExp.$1).toFixed(3).replace(/\.?0+$/,"")+"em";
|
||||||
|
}
|
||||||
|
else if (this.toMathMLvariants[value]) {return this.toMathMLvariants[value]}
|
||||||
|
return this.toMathMLquote(value);
|
||||||
|
},
|
||||||
|
toMathMLvariants: {
|
||||||
|
"-tex-caligraphic": MML.VARIANT.SCRIPT,
|
||||||
|
"-tex-caligraphic-bold": MML.VARIANT.BOLDSCRIPT,
|
||||||
|
"-tex-oldstyle": MML.VARIANT.NORMAL,
|
||||||
|
"-tex-oldstyle-bold": MML.VARIANT.BOLD,
|
||||||
|
"-tex-mathit": MML.VARIANT.ITALIC
|
||||||
|
},
|
||||||
|
|
||||||
|
toMathMLquote: function (string) {
|
||||||
|
string = String(string).split("");
|
||||||
|
for (var i = 0, m = string.length; i < m; i++) {
|
||||||
|
var n = string[i].charCodeAt(0);
|
||||||
|
if (n < 0x20 || n > 0x7E) {
|
||||||
|
string[i] = "&#x"+n.toString(16).toUpperCase()+";";
|
||||||
|
} else {
|
||||||
|
var c = {'&':'&', '<':'<', '>':'>', '"':'"'}[string[i]];
|
||||||
|
if (c) {string[i] = c}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.join("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.msubsup.Augment({
|
||||||
|
toMathML: function (space) {
|
||||||
|
var tag = this.type;
|
||||||
|
if (this.data[this.sup] == null) {tag = "msub"}
|
||||||
|
if (this.data[this.sub] == null) {tag = "msup"}
|
||||||
|
var attr = this.toMathMLattributes();
|
||||||
|
delete this.data[0].inferred;
|
||||||
|
var data = [];
|
||||||
|
for (var i = 0, m = this.data.length; i < m; i++)
|
||||||
|
{if (this.data[i]) {data.push(this.data[i].toMathML(space+" "))}}
|
||||||
|
return space + "<"+tag+attr+">\n" + data.join("\n") + "\n" + space + "</"+tag+">";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.munderover.Augment({
|
||||||
|
toMathML: function (space) {
|
||||||
|
var tag = this.type;
|
||||||
|
if (this.data[this.under] == null) {tag = "mover"}
|
||||||
|
if (this.data[this.over] == null) {tag = "munder"}
|
||||||
|
var attr = this.toMathMLattributes();
|
||||||
|
delete this.data[0].inferred;
|
||||||
|
var data = [];
|
||||||
|
for (var i = 0, m = this.data.length; i < m; i++)
|
||||||
|
{if (this.data[i]) {data.push(this.data[i].toMathML(space+" "))}}
|
||||||
|
return space + "<"+tag+attr+">\n" + data.join("\n") + "\n" + space + "</"+tag+">";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.TeXAtom.Augment({
|
||||||
|
toMathML: function (space) {
|
||||||
|
// FIXME: Handle spacing using mpadded?
|
||||||
|
var attr = this.toMathMLattributes();
|
||||||
|
if (!attr && this.data[0].data.length === 1) {return space.substr(2) + this.data[0].toMathML(space)}
|
||||||
|
return space+"<mrow"+attr+">\n" + this.data[0].toMathML(space+" ")+"\n"+space+"</mrow>";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.chars.Augment({
|
||||||
|
toMathML: function (space) {return (space||"") + this.toMathMLquote(this.toString())}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.entity.Augment({
|
||||||
|
toMathML: function (space) {return (space||"") + "&"+this.data[0]+";<!-- "+this.toString()+" -->"}
|
||||||
|
});
|
||||||
|
|
||||||
|
MML.xml.Augment({
|
||||||
|
toMathML: function (space) {return (space||"") + this.toString()}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function () {
|
||||||
|
MML.TeXmathchoice.Augment({
|
||||||
|
toMathML: function (space) {return this.Core().toMathML(space)}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Hub.Startup.signal.Post("toMathML Ready");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/toMathML.js");
|
92
resources/viewer/mathjax/extensions/v1.0-warning.js
Normal file
92
resources/viewer/mathjax/extensions/v1.0-warning.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/extensions/v1.0-warning.js
|
||||||
|
*
|
||||||
|
* This extension file is loaded when no jax are configured
|
||||||
|
* as a backward-compatible measure to help people convert to the
|
||||||
|
* new configuration process.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011-2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (HUB,HTML) {
|
||||||
|
var VERSION = "2.0";
|
||||||
|
|
||||||
|
var CONFIG = {
|
||||||
|
style: {
|
||||||
|
position:"fixed", bottom:"4em", left:"3em", width:"40em",
|
||||||
|
border: "3px solid #880000", "background-color": "#E0E0E0", color: "black",
|
||||||
|
padding: "1em", "font-size":"small", "white-space":"normal",
|
||||||
|
|
||||||
|
"border-radius": ".75em", // Opera 10.5 and IE9
|
||||||
|
"-webkit-border-radius": ".75em", // Safari and Chrome
|
||||||
|
"-moz-border-radius": ".75em", // Firefox
|
||||||
|
"-khtml-border-radius": ".75em", // Konqueror
|
||||||
|
|
||||||
|
"box-shadow": "4px 4px 10px #AAAAAA", // Opera 10.5 and IE9
|
||||||
|
"-webkit-box-shadow": "4px 4px 10px #AAAAAA", // Safari 3 and Chrome
|
||||||
|
"-moz-box-shadow": "4px 4px 10px #AAAAAA", // Forefox 3.5
|
||||||
|
"-khtml-box-shadow": "4px 4px 10px #AAAAAA", // Konqueror
|
||||||
|
filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=3, OffY=3, Color='gray', Positive='true')" // IE
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (HUB.Browser.isIE9 && document.documentMode >= 9) {delete CONFIG.style.filter}
|
||||||
|
|
||||||
|
var DIV;
|
||||||
|
|
||||||
|
HUB.Register.StartupHook("onLoad",function () {
|
||||||
|
var frame = document.body;
|
||||||
|
if (HUB.Browser.isMSIE) {
|
||||||
|
MathJax.Message.Init(); // make sure MathJax_MSIE_frame exists
|
||||||
|
frame = document.getElementById("MathJax_MSIE_frame") || frame; // in IE8 and 9 it may not anyway
|
||||||
|
CONFIG.style.position = "absolute";
|
||||||
|
} else {delete CONFIG.style.filter}
|
||||||
|
CONFIG.style.maxWidth = (document.body.clientWidth-75) + "px";
|
||||||
|
DIV = HTML.addElement(frame,"div",{id:"MathJax_ConfigWarning",style:CONFIG.style},[
|
||||||
|
[
|
||||||
|
"div",{
|
||||||
|
style: {
|
||||||
|
position:"absolute", overflow:"hidden", top:".1em", right:".1em",
|
||||||
|
border: "1px outset", width:"1em", height:"1em",
|
||||||
|
"text-align": "center", cursor: "pointer",
|
||||||
|
"background-color": "#EEEEEE", color:"#606060",
|
||||||
|
|
||||||
|
"border-radius": ".5em", // Opera 10.5
|
||||||
|
"-webkit-border-radius": ".5em", // Safari and Chrome
|
||||||
|
"-moz-border-radius": ".5em", // Firefox
|
||||||
|
"-khtml-border-radius": ".5em" // Konqueror
|
||||||
|
},
|
||||||
|
onclick: function () {DIV.style.display = "none"}
|
||||||
|
},
|
||||||
|
[["span",{style:{position:"relative", bottom:".2em"}},["x"]]]
|
||||||
|
],
|
||||||
|
"MathJax no longer loads a default configuration file; " +
|
||||||
|
"you must specify such files explicitly. " +
|
||||||
|
"This page seems to use the older default ",["code",{},["config/MathJax.js"]],
|
||||||
|
" file, and so needs to be updated. This is explained further at",
|
||||||
|
["p",{style:{"text-align":"center"}},[
|
||||||
|
["a",
|
||||||
|
{href:"http://www.mathjax.org/help/configuration"},
|
||||||
|
["http://www.mathjax.org/help/configuration"]
|
||||||
|
]
|
||||||
|
]]
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
})(MathJax.Hub,MathJax.HTML);
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete("[MathJax]/extensions/v1.0-warning.js");
|
1605
resources/viewer/mathjax/jax/element/mml/jax.js
Normal file
1605
resources/viewer/mathjax/jax/element/mml/jax.js
Normal file
File diff suppressed because it is too large
Load Diff
122
resources/viewer/mathjax/jax/element/mml/optable/Arrows.js
Normal file
122
resources/viewer/mathjax/jax/element/mml/optable/Arrows.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/Arrows.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u219A': MO.RELACCENT, // leftwards arrow with stroke
|
||||||
|
'\u219B': MO.RELACCENT, // rightwards arrow with stroke
|
||||||
|
'\u219C': MO.WIDEREL, // leftwards wave arrow
|
||||||
|
'\u219D': MO.WIDEREL, // rightwards wave arrow
|
||||||
|
'\u219E': MO.WIDEREL, // leftwards two headed arrow
|
||||||
|
'\u219F': MO.WIDEREL, // upwards two headed arrow
|
||||||
|
'\u21A0': MO.WIDEREL, // rightwards two headed arrow
|
||||||
|
'\u21A1': MO.RELSTRETCH, // downwards two headed arrow
|
||||||
|
'\u21A2': MO.WIDEREL, // leftwards arrow with tail
|
||||||
|
'\u21A3': MO.WIDEREL, // rightwards arrow with tail
|
||||||
|
'\u21A4': MO.WIDEREL, // leftwards arrow from bar
|
||||||
|
'\u21A5': MO.RELSTRETCH, // upwards arrow from bar
|
||||||
|
'\u21A7': MO.RELSTRETCH, // downwards arrow from bar
|
||||||
|
'\u21A8': MO.RELSTRETCH, // up down arrow with base
|
||||||
|
'\u21AB': MO.WIDEREL, // leftwards arrow with loop
|
||||||
|
'\u21AC': MO.WIDEREL, // rightwards arrow with loop
|
||||||
|
'\u21AD': MO.WIDEREL, // left right wave arrow
|
||||||
|
'\u21AE': MO.RELACCENT, // left right arrow with stroke
|
||||||
|
'\u21AF': MO.RELSTRETCH, // downwards zigzag arrow
|
||||||
|
'\u21B0': MO.RELSTRETCH, // upwards arrow with tip leftwards
|
||||||
|
'\u21B1': MO.RELSTRETCH, // upwards arrow with tip rightwards
|
||||||
|
'\u21B2': MO.RELSTRETCH, // downwards arrow with tip leftwards
|
||||||
|
'\u21B3': MO.RELSTRETCH, // downwards arrow with tip rightwards
|
||||||
|
'\u21B4': MO.RELSTRETCH, // rightwards arrow with corner downwards
|
||||||
|
'\u21B5': MO.RELSTRETCH, // downwards arrow with corner leftwards
|
||||||
|
'\u21B6': MO.RELACCENT, // anticlockwise top semicircle arrow
|
||||||
|
'\u21B7': MO.RELACCENT, // clockwise top semicircle arrow
|
||||||
|
'\u21B8': MO.REL, // north west arrow to long bar
|
||||||
|
'\u21B9': MO.WIDEREL, // leftwards arrow to bar over rightwards arrow to bar
|
||||||
|
'\u21BA': MO.REL, // anticlockwise open circle arrow
|
||||||
|
'\u21BB': MO.REL, // clockwise open circle arrow
|
||||||
|
'\u21BE': MO.RELSTRETCH, // upwards harpoon with barb rightwards
|
||||||
|
'\u21BF': MO.RELSTRETCH, // upwards harpoon with barb leftwards
|
||||||
|
'\u21C2': MO.RELSTRETCH, // downwards harpoon with barb rightwards
|
||||||
|
'\u21C3': MO.RELSTRETCH, // downwards harpoon with barb leftwards
|
||||||
|
'\u21C4': MO.WIDEREL, // rightwards arrow over leftwards arrow
|
||||||
|
'\u21C5': MO.RELSTRETCH, // upwards arrow leftwards of downwards arrow
|
||||||
|
'\u21C6': MO.WIDEREL, // leftwards arrow over rightwards arrow
|
||||||
|
'\u21C7': MO.WIDEREL, // leftwards paired arrows
|
||||||
|
'\u21C8': MO.RELSTRETCH, // upwards paired arrows
|
||||||
|
'\u21C9': MO.WIDEREL, // rightwards paired arrows
|
||||||
|
'\u21CA': MO.RELSTRETCH, // downwards paired arrows
|
||||||
|
'\u21CB': MO.WIDEREL, // leftwards harpoon over rightwards harpoon
|
||||||
|
'\u21CD': MO.RELACCENT, // leftwards double arrow with stroke
|
||||||
|
'\u21CE': MO.RELACCENT, // left right double arrow with stroke
|
||||||
|
'\u21CF': MO.RELACCENT, // rightwards double arrow with stroke
|
||||||
|
'\u21D6': MO.RELSTRETCH, // north west double arrow
|
||||||
|
'\u21D7': MO.RELSTRETCH, // north east double arrow
|
||||||
|
'\u21D8': MO.RELSTRETCH, // south east double arrow
|
||||||
|
'\u21D9': MO.RELSTRETCH, // south west double arrow
|
||||||
|
'\u21DA': MO.WIDEREL, // leftwards triple arrow
|
||||||
|
'\u21DB': MO.WIDEREL, // rightwards triple arrow
|
||||||
|
'\u21DC': MO.WIDEREL, // leftwards squiggle arrow
|
||||||
|
'\u21DD': MO.WIDEREL, // rightwards squiggle arrow
|
||||||
|
'\u21DE': MO.REL, // upwards arrow with double stroke
|
||||||
|
'\u21DF': MO.REL, // downwards arrow with double stroke
|
||||||
|
'\u21E0': MO.WIDEREL, // leftwards dashed arrow
|
||||||
|
'\u21E1': MO.RELSTRETCH, // upwards dashed arrow
|
||||||
|
'\u21E2': MO.WIDEREL, // rightwards dashed arrow
|
||||||
|
'\u21E3': MO.RELSTRETCH, // downwards dashed arrow
|
||||||
|
'\u21E4': MO.WIDEREL, // leftwards arrow to bar
|
||||||
|
'\u21E5': MO.WIDEREL, // rightwards arrow to bar
|
||||||
|
'\u21E6': MO.WIDEREL, // leftwards white arrow
|
||||||
|
'\u21E7': MO.RELSTRETCH, // upwards white arrow
|
||||||
|
'\u21E8': MO.WIDEREL, // rightwards white arrow
|
||||||
|
'\u21E9': MO.RELSTRETCH, // downwards white arrow
|
||||||
|
'\u21EA': MO.RELSTRETCH, // upwards white arrow from bar
|
||||||
|
'\u21EB': MO.RELSTRETCH, // upwards white arrow on pedestal
|
||||||
|
'\u21EC': MO.RELSTRETCH, // upwards white arrow on pedestal with horizontal bar
|
||||||
|
'\u21ED': MO.RELSTRETCH, // upwards white arrow on pedestal with vertical bar
|
||||||
|
'\u21EE': MO.RELSTRETCH, // upwards white double arrow
|
||||||
|
'\u21EF': MO.RELSTRETCH, // upwards white double arrow on pedestal
|
||||||
|
'\u21F0': MO.WIDEREL, // rightwards white arrow from wall
|
||||||
|
'\u21F1': MO.REL, // north west arrow to corner
|
||||||
|
'\u21F2': MO.REL, // south east arrow to corner
|
||||||
|
'\u21F3': MO.RELSTRETCH, // up down white arrow
|
||||||
|
'\u21F4': MO.RELACCENT, // right arrow with small circle
|
||||||
|
'\u21F5': MO.RELSTRETCH, // downwards arrow leftwards of upwards arrow
|
||||||
|
'\u21F6': MO.WIDEREL, // three rightwards arrows
|
||||||
|
'\u21F7': MO.RELACCENT, // leftwards arrow with vertical stroke
|
||||||
|
'\u21F8': MO.RELACCENT, // rightwards arrow with vertical stroke
|
||||||
|
'\u21F9': MO.RELACCENT, // left right arrow with vertical stroke
|
||||||
|
'\u21FA': MO.RELACCENT, // leftwards arrow with double vertical stroke
|
||||||
|
'\u21FB': MO.RELACCENT, // rightwards arrow with double vertical stroke
|
||||||
|
'\u21FC': MO.RELACCENT, // left right arrow with double vertical stroke
|
||||||
|
'\u21FD': MO.WIDEREL, // leftwards open-headed arrow
|
||||||
|
'\u21FE': MO.WIDEREL, // rightwards open-headed arrow
|
||||||
|
'\u21FF': MO.WIDEREL // left right open-headed arrow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/Arrows.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,65 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/BasicLatin.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'||': [0,0,TEXCLASS.BIN,{fence: true, stretchy: true, symmetric: true}], // multiple character operator: ||
|
||||||
|
'|||': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true, symmetric: true}] // multiple character operator: |||
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
'!!': [1,0,TEXCLASS.BIN], // multiple character operator: !!
|
||||||
|
'\'': MO.ACCENT, // apostrophe
|
||||||
|
'++': [0,0,TEXCLASS.BIN], // multiple character operator: ++
|
||||||
|
'--': [0,0,TEXCLASS.BIN], // multiple character operator: --
|
||||||
|
'..': [0,0,TEXCLASS.BIN], // multiple character operator: ..
|
||||||
|
'...': MO.ORD, // multiple character operator: ...
|
||||||
|
'||': [0,0,TEXCLASS.BIN,{fence: true, stretchy: true, symmetric: true}], // multiple character operator: ||
|
||||||
|
'|||': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true, symmetric: true}] // multiple character operator: |||
|
||||||
|
},
|
||||||
|
infix: {
|
||||||
|
'!=': MO.BIN4, // multiple character operator: !=
|
||||||
|
'&&': MO.BIN4, // multiple character operator: &&
|
||||||
|
'**': [1,1,TEXCLASS.BIN], // multiple character operator: **
|
||||||
|
'*=': MO.BIN4, // multiple character operator: *=
|
||||||
|
'+=': MO.BIN4, // multiple character operator: +=
|
||||||
|
'-=': MO.BIN4, // multiple character operator: -=
|
||||||
|
'->': MO.BIN5, // multiple character operator: ->
|
||||||
|
'//': [1,1,TEXCLASS.BIN], // multiple character operator: //
|
||||||
|
'/=': MO.BIN4, // multiple character operator: /=
|
||||||
|
':=': MO.BIN4, // multiple character operator: :=
|
||||||
|
'<=': MO.BIN5, // multiple character operator: <=
|
||||||
|
'<>': [1,1,TEXCLASS.BIN], // multiple character operator: <>
|
||||||
|
'==': MO.BIN4, // multiple character operator: ==
|
||||||
|
'>=': MO.BIN5, // multiple character operator: >=
|
||||||
|
'@': MO.ORD11, // commercial at
|
||||||
|
'||': [2,2,TEXCLASS.BIN,{fence: true, stretchy: true, symmetric: true}], // multiple character operator: ||
|
||||||
|
'|||': [2,2,TEXCLASS.ORD,{fence: true, stretchy: true, symmetric: true}] // multiple character operator: |||
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/BasicLatin.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,35 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/CombDiacritMarks.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
postfix: {
|
||||||
|
'\u0311': MO.ACCENT // combining inverted breve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/CombDiacritMarks.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,36 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/CombDiactForSymbols.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
postfix: {
|
||||||
|
'\u20DB': MO.ACCENT, // combining three dots above
|
||||||
|
'\u20DC': MO.ACCENT // combining four dots above
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/CombDiactForSymbols.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
38
resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js
Normal file
38
resources/viewer/mathjax/jax/element/mml/optable/Dingbats.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/Dingbats.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2772': MO.OPEN // light left tortoise shell bracket ornament
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
'\u2773': MO.CLOSE // light right tortoise shell bracket ornament
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/Dingbats.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,42 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/GeneralPunctuation.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2016': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true}], // double vertical line
|
||||||
|
'\u2018': [0,0,TEXCLASS.OPEN,{fence: true}], // left single quotation mark
|
||||||
|
'\u201C': [0,0,TEXCLASS.OPEN,{fence: true}] // left double quotation mark
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
'\u2016': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true}], // double vertical line
|
||||||
|
'\u2019': [0,0,TEXCLASS.CLOSE,{fence: true}], // right single quotation mark
|
||||||
|
'\u201D': [0,0,TEXCLASS.CLOSE,{fence: true}] // right double quotation mark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/GeneralPunctuation.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,66 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/GeometricShapes.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u25A0': MO.BIN3, // black square
|
||||||
|
'\u25A1': MO.BIN3, // white square
|
||||||
|
'\u25AA': MO.BIN3, // black small square
|
||||||
|
'\u25AB': MO.BIN3, // white small square
|
||||||
|
'\u25AD': MO.BIN3, // white rectangle
|
||||||
|
'\u25AE': MO.BIN3, // black vertical rectangle
|
||||||
|
'\u25AF': MO.BIN3, // white vertical rectangle
|
||||||
|
'\u25B0': MO.BIN3, // black parallelogram
|
||||||
|
'\u25B1': MO.BIN3, // white parallelogram
|
||||||
|
'\u25B2': MO.BIN4, // black up-pointing triangle
|
||||||
|
'\u25B4': MO.BIN4, // black up-pointing small triangle
|
||||||
|
'\u25B6': MO.BIN4, // black right-pointing triangle
|
||||||
|
'\u25B7': MO.BIN4, // white right-pointing triangle
|
||||||
|
'\u25B8': MO.BIN4, // black right-pointing small triangle
|
||||||
|
'\u25BC': MO.BIN4, // black down-pointing triangle
|
||||||
|
'\u25BE': MO.BIN4, // black down-pointing small triangle
|
||||||
|
'\u25C0': MO.BIN4, // black left-pointing triangle
|
||||||
|
'\u25C1': MO.BIN4, // white left-pointing triangle
|
||||||
|
'\u25C2': MO.BIN4, // black left-pointing small triangle
|
||||||
|
'\u25C4': MO.BIN4, // black left-pointing pointer
|
||||||
|
'\u25C5': MO.BIN4, // white left-pointing pointer
|
||||||
|
'\u25C6': MO.BIN4, // black diamond
|
||||||
|
'\u25C7': MO.BIN4, // white diamond
|
||||||
|
'\u25C8': MO.BIN4, // white diamond containing black small diamond
|
||||||
|
'\u25C9': MO.BIN4, // fisheye
|
||||||
|
'\u25CC': MO.BIN4, // dotted circle
|
||||||
|
'\u25CD': MO.BIN4, // circle with vertical fill
|
||||||
|
'\u25CE': MO.BIN4, // bullseye
|
||||||
|
'\u25CF': MO.BIN4, // black circle
|
||||||
|
'\u25D6': MO.BIN4, // left half black circle
|
||||||
|
'\u25D7': MO.BIN4, // right half black circle
|
||||||
|
'\u25E6': MO.BIN4 // white bullet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/GeometricShapes.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,35 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/GreekAndCoptic.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u03F6': MO.REL // greek reversed lunate epsilon symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/GreekAndCoptic.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,37 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/Latin1Supplement.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
postfix: {
|
||||||
|
'\u00B0': MO.ORD, // degree sign
|
||||||
|
'\u00B4': MO.ACCENT, // acute accent
|
||||||
|
'\u00B8': MO.ACCENT // cedilla
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/Latin1Supplement.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,36 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/LetterlikeSymbols.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2145': MO.ORD21, // double-struck italic capital d
|
||||||
|
'\u2146': [2,0,TEXCLASS.ORD] // double-struck italic small d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/LetterlikeSymbols.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,228 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/MathOperators.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2204': MO.ORD21, // there does not exist
|
||||||
|
'\u221B': MO.ORD11, // cube root
|
||||||
|
'\u221C': MO.ORD11, // fourth root
|
||||||
|
'\u2221': MO.ORD, // measured angle
|
||||||
|
'\u2222': MO.ORD, // spherical angle
|
||||||
|
'\u222C': MO.INTEGRAL, // double integral
|
||||||
|
'\u222D': MO.INTEGRAL, // triple integral
|
||||||
|
'\u222F': MO.INTEGRAL, // surface integral
|
||||||
|
'\u2230': MO.INTEGRAL, // volume integral
|
||||||
|
'\u2231': MO.INTEGRAL, // clockwise integral
|
||||||
|
'\u2232': MO.INTEGRAL, // clockwise contour integral
|
||||||
|
'\u2233': MO.INTEGRAL // anticlockwise contour integral
|
||||||
|
},
|
||||||
|
infix: {
|
||||||
|
'\u2201': [1,2,TEXCLASS.ORD], // complement
|
||||||
|
'\u2206': MO.BIN3, // increment
|
||||||
|
'\u220A': MO.REL, // small element of
|
||||||
|
'\u220C': MO.REL, // does not contain as member
|
||||||
|
'\u220D': MO.REL, // small contains as member
|
||||||
|
'\u220E': MO.BIN3, // end of proof
|
||||||
|
'\u2214': MO.BIN4, // dot plus
|
||||||
|
'\u221F': MO.REL, // right angle
|
||||||
|
'\u2224': MO.REL, // does not divide
|
||||||
|
'\u2226': MO.REL, // not parallel to
|
||||||
|
'\u2234': MO.REL, // therefore
|
||||||
|
'\u2235': MO.REL, // because
|
||||||
|
'\u2236': MO.REL, // ratio
|
||||||
|
'\u2237': MO.REL, // proportion
|
||||||
|
'\u2238': MO.BIN4, // dot minus
|
||||||
|
'\u2239': MO.REL, // excess
|
||||||
|
'\u223A': MO.BIN4, // geometric proportion
|
||||||
|
'\u223B': MO.REL, // homothetic
|
||||||
|
'\u223D': MO.REL, // reversed tilde
|
||||||
|
'\u223D\u0331': MO.BIN3, // reversed tilde with underline
|
||||||
|
'\u223E': MO.REL, // inverted lazy s
|
||||||
|
'\u223F': MO.BIN3, // sine wave
|
||||||
|
'\u2241': MO.REL, // not tilde
|
||||||
|
'\u2242': MO.REL, // minus tilde
|
||||||
|
'\u2242\u0338': MO.REL, // minus tilde with slash
|
||||||
|
'\u2244': MO.REL, // not asymptotically equal to
|
||||||
|
'\u2246': MO.REL, // approximately but not actually equal to
|
||||||
|
'\u2247': MO.REL, // neither approximately nor actually equal to
|
||||||
|
'\u2249': MO.REL, // not almost equal to
|
||||||
|
'\u224A': MO.REL, // almost equal or equal to
|
||||||
|
'\u224B': MO.REL, // triple tilde
|
||||||
|
'\u224C': MO.REL, // all equal to
|
||||||
|
'\u224E': MO.REL, // geometrically equivalent to
|
||||||
|
'\u224E\u0338': MO.REL, // geometrically equivalent to with slash
|
||||||
|
'\u224F': MO.REL, // difference between
|
||||||
|
'\u224F\u0338': MO.REL, // difference between with slash
|
||||||
|
'\u2251': MO.REL, // geometrically equal to
|
||||||
|
'\u2252': MO.REL, // approximately equal to or the image of
|
||||||
|
'\u2253': MO.REL, // image of or approximately equal to
|
||||||
|
'\u2254': MO.REL, // colon equals
|
||||||
|
'\u2255': MO.REL, // equals colon
|
||||||
|
'\u2256': MO.REL, // ring in equal to
|
||||||
|
'\u2257': MO.REL, // ring equal to
|
||||||
|
'\u2258': MO.REL, // corresponds to
|
||||||
|
'\u2259': MO.REL, // estimates
|
||||||
|
'\u225A': MO.REL, // equiangular to
|
||||||
|
'\u225C': MO.REL, // delta equal to
|
||||||
|
'\u225D': MO.REL, // equal to by definition
|
||||||
|
'\u225E': MO.REL, // measured by
|
||||||
|
'\u225F': MO.REL, // questioned equal to
|
||||||
|
'\u2262': MO.REL, // not identical to
|
||||||
|
'\u2263': MO.REL, // strictly equivalent to
|
||||||
|
'\u2266': MO.REL, // less-than over equal to
|
||||||
|
'\u2266\u0338': MO.REL, // less-than over equal to with slash
|
||||||
|
'\u2267': MO.REL, // greater-than over equal to
|
||||||
|
'\u2268': MO.REL, // less-than but not equal to
|
||||||
|
'\u2269': MO.REL, // greater-than but not equal to
|
||||||
|
'\u226A\u0338': MO.REL, // much less than with slash
|
||||||
|
'\u226B\u0338': MO.REL, // much greater than with slash
|
||||||
|
'\u226C': MO.REL, // between
|
||||||
|
'\u226D': MO.REL, // not equivalent to
|
||||||
|
'\u226E': MO.REL, // not less-than
|
||||||
|
'\u226F': MO.REL, // not greater-than
|
||||||
|
'\u2270': MO.REL, // neither less-than nor equal to
|
||||||
|
'\u2271': MO.REL, // neither greater-than nor equal to
|
||||||
|
'\u2272': MO.REL, // less-than or equivalent to
|
||||||
|
'\u2273': MO.REL, // greater-than or equivalent to
|
||||||
|
'\u2274': MO.REL, // neither less-than nor equivalent to
|
||||||
|
'\u2275': MO.REL, // neither greater-than nor equivalent to
|
||||||
|
'\u2276': MO.REL, // less-than or greater-than
|
||||||
|
'\u2277': MO.REL, // greater-than or less-than
|
||||||
|
'\u2278': MO.REL, // neither less-than nor greater-than
|
||||||
|
'\u2279': MO.REL, // neither greater-than nor less-than
|
||||||
|
'\u227C': MO.REL, // precedes or equal to
|
||||||
|
'\u227D': MO.REL, // succeeds or equal to
|
||||||
|
'\u227E': MO.REL, // precedes or equivalent to
|
||||||
|
'\u227F': MO.REL, // succeeds or equivalent to
|
||||||
|
'\u227F\u0338': MO.REL, // succeeds or equivalent to with slash
|
||||||
|
'\u2280': MO.REL, // does not precede
|
||||||
|
'\u2281': MO.REL, // does not succeed
|
||||||
|
'\u2282\u20D2': MO.REL, // subset of with vertical line
|
||||||
|
'\u2283\u20D2': MO.REL, // superset of with vertical line
|
||||||
|
'\u2284': MO.REL, // not a subset of
|
||||||
|
'\u2285': MO.REL, // not a superset of
|
||||||
|
'\u2288': MO.REL, // neither a subset of nor equal to
|
||||||
|
'\u2289': MO.REL, // neither a superset of nor equal to
|
||||||
|
'\u228A': MO.REL, // subset of with not equal to
|
||||||
|
'\u228B': MO.REL, // superset of with not equal to
|
||||||
|
'\u228C': MO.BIN4, // multiset
|
||||||
|
'\u228D': MO.BIN4, // multiset multiplication
|
||||||
|
'\u228F': MO.REL, // square image of
|
||||||
|
'\u228F\u0338': MO.REL, // square image of with slash
|
||||||
|
'\u2290': MO.REL, // square original of
|
||||||
|
'\u2290\u0338': MO.REL, // square original of with slash
|
||||||
|
'\u229A': MO.BIN4, // circled ring operator
|
||||||
|
'\u229B': MO.BIN4, // circled asterisk operator
|
||||||
|
'\u229C': MO.BIN4, // circled equals
|
||||||
|
'\u229D': MO.BIN4, // circled dash
|
||||||
|
'\u229E': MO.BIN4, // squared plus
|
||||||
|
'\u229F': MO.BIN4, // squared minus
|
||||||
|
'\u22A0': MO.BIN4, // squared times
|
||||||
|
'\u22A1': MO.BIN4, // squared dot operator
|
||||||
|
'\u22A6': MO.REL, // assertion
|
||||||
|
'\u22A7': MO.REL, // models
|
||||||
|
'\u22A9': MO.REL, // forces
|
||||||
|
'\u22AA': MO.REL, // triple vertical bar right turnstile
|
||||||
|
'\u22AB': MO.REL, // double vertical bar double right turnstile
|
||||||
|
'\u22AC': MO.REL, // does not prove
|
||||||
|
'\u22AD': MO.REL, // not true
|
||||||
|
'\u22AE': MO.REL, // does not force
|
||||||
|
'\u22AF': MO.REL, // negated double vertical bar double right turnstile
|
||||||
|
'\u22B0': MO.REL, // precedes under relation
|
||||||
|
'\u22B1': MO.REL, // succeeds under relation
|
||||||
|
'\u22B2': MO.REL, // normal subgroup of
|
||||||
|
'\u22B3': MO.REL, // contains as normal subgroup
|
||||||
|
'\u22B4': MO.REL, // normal subgroup of or equal to
|
||||||
|
'\u22B5': MO.REL, // contains as normal subgroup or equal to
|
||||||
|
'\u22B6': MO.REL, // original of
|
||||||
|
'\u22B7': MO.REL, // image of
|
||||||
|
'\u22B8': MO.REL, // multimap
|
||||||
|
'\u22B9': MO.REL, // hermitian conjugate matrix
|
||||||
|
'\u22BA': MO.BIN4, // intercalate
|
||||||
|
'\u22BB': MO.BIN4, // xor
|
||||||
|
'\u22BC': MO.BIN4, // nand
|
||||||
|
'\u22BD': MO.BIN4, // nor
|
||||||
|
'\u22BE': MO.BIN3, // right angle with arc
|
||||||
|
'\u22BF': MO.BIN3, // right triangle
|
||||||
|
'\u22C7': MO.BIN4, // division times
|
||||||
|
'\u22C9': MO.BIN4, // left normal factor semidirect product
|
||||||
|
'\u22CA': MO.BIN4, // right normal factor semidirect product
|
||||||
|
'\u22CB': MO.BIN4, // left semidirect product
|
||||||
|
'\u22CC': MO.BIN4, // right semidirect product
|
||||||
|
'\u22CD': MO.REL, // reversed tilde equals
|
||||||
|
'\u22CE': MO.BIN4, // curly logical or
|
||||||
|
'\u22CF': MO.BIN4, // curly logical and
|
||||||
|
'\u22D0': MO.REL, // double subset
|
||||||
|
'\u22D1': MO.REL, // double superset
|
||||||
|
'\u22D2': MO.BIN4, // double intersection
|
||||||
|
'\u22D3': MO.BIN4, // double union
|
||||||
|
'\u22D4': MO.REL, // pitchfork
|
||||||
|
'\u22D5': MO.REL, // equal and parallel to
|
||||||
|
'\u22D6': MO.REL, // less-than with dot
|
||||||
|
'\u22D7': MO.REL, // greater-than with dot
|
||||||
|
'\u22D8': MO.REL, // very much less-than
|
||||||
|
'\u22D9': MO.REL, // very much greater-than
|
||||||
|
'\u22DA': MO.REL, // less-than equal to or greater-than
|
||||||
|
'\u22DB': MO.REL, // greater-than equal to or less-than
|
||||||
|
'\u22DC': MO.REL, // equal to or less-than
|
||||||
|
'\u22DD': MO.REL, // equal to or greater-than
|
||||||
|
'\u22DE': MO.REL, // equal to or precedes
|
||||||
|
'\u22DF': MO.REL, // equal to or succeeds
|
||||||
|
'\u22E0': MO.REL, // does not precede or equal
|
||||||
|
'\u22E1': MO.REL, // does not succeed or equal
|
||||||
|
'\u22E2': MO.REL, // not square image of or equal to
|
||||||
|
'\u22E3': MO.REL, // not square original of or equal to
|
||||||
|
'\u22E4': MO.REL, // square image of or not equal to
|
||||||
|
'\u22E5': MO.REL, // square original of or not equal to
|
||||||
|
'\u22E6': MO.REL, // less-than but not equivalent to
|
||||||
|
'\u22E7': MO.REL, // greater-than but not equivalent to
|
||||||
|
'\u22E8': MO.REL, // precedes but not equivalent to
|
||||||
|
'\u22E9': MO.REL, // succeeds but not equivalent to
|
||||||
|
'\u22EA': MO.REL, // not normal subgroup of
|
||||||
|
'\u22EB': MO.REL, // does not contain as normal subgroup
|
||||||
|
'\u22EC': MO.REL, // not normal subgroup of or equal to
|
||||||
|
'\u22ED': MO.REL, // does not contain as normal subgroup or equal
|
||||||
|
'\u22F0': MO.REL, // up right diagonal ellipsis
|
||||||
|
'\u22F2': MO.REL, // element of with long horizontal stroke
|
||||||
|
'\u22F3': MO.REL, // element of with vertical bar at end of horizontal stroke
|
||||||
|
'\u22F4': MO.REL, // small element of with vertical bar at end of horizontal stroke
|
||||||
|
'\u22F5': MO.REL, // element of with dot above
|
||||||
|
'\u22F6': MO.REL, // element of with overbar
|
||||||
|
'\u22F7': MO.REL, // small element of with overbar
|
||||||
|
'\u22F8': MO.REL, // element of with underbar
|
||||||
|
'\u22F9': MO.REL, // element of with two horizontal strokes
|
||||||
|
'\u22FA': MO.REL, // contains with long horizontal stroke
|
||||||
|
'\u22FB': MO.REL, // contains with vertical bar at end of horizontal stroke
|
||||||
|
'\u22FC': MO.REL, // small contains with vertical bar at end of horizontal stroke
|
||||||
|
'\u22FD': MO.REL, // contains with overbar
|
||||||
|
'\u22FE': MO.REL, // small contains with overbar
|
||||||
|
'\u22FF': MO.REL // z notation bag membership
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/MathOperators.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,42 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/MiscMathSymbolsA.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u27E6': MO.OPEN, // mathematical left white square bracket
|
||||||
|
'\u27EA': MO.OPEN, // mathematical left double angle bracket
|
||||||
|
'\u27EC': MO.OPEN // mathematical left white tortoise shell bracket
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
'\u27E7': MO.CLOSE, // mathematical right white square bracket
|
||||||
|
'\u27EB': MO.CLOSE, // mathematical right double angle bracket
|
||||||
|
'\u27ED': MO.CLOSE // mathematical right white tortoise shell bracket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/MiscMathSymbolsA.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,168 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/MiscMathSymbolsB.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2980': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true}], // triple vertical bar delimiter
|
||||||
|
'\u2983': MO.OPEN, // left white curly bracket
|
||||||
|
'\u2985': MO.OPEN, // left white parenthesis
|
||||||
|
'\u2987': MO.OPEN, // z notation left image bracket
|
||||||
|
'\u2989': MO.OPEN, // z notation left binding bracket
|
||||||
|
'\u298B': MO.OPEN, // left square bracket with underbar
|
||||||
|
'\u298D': MO.OPEN, // left square bracket with tick in top corner
|
||||||
|
'\u298F': MO.OPEN, // left square bracket with tick in bottom corner
|
||||||
|
'\u2991': MO.OPEN, // left angle bracket with dot
|
||||||
|
'\u2993': MO.OPEN, // left arc less-than bracket
|
||||||
|
'\u2995': MO.OPEN, // double left arc greater-than bracket
|
||||||
|
'\u2997': MO.OPEN, // left black tortoise shell bracket
|
||||||
|
'\u29FC': MO.OPEN // left-pointing curved angle bracket
|
||||||
|
},
|
||||||
|
postfix: {
|
||||||
|
'\u2980': [0,0,TEXCLASS.ORD,{fence: true, stretchy: true}], // triple vertical bar delimiter
|
||||||
|
'\u2984': MO.CLOSE, // right white curly bracket
|
||||||
|
'\u2986': MO.CLOSE, // right white parenthesis
|
||||||
|
'\u2988': MO.CLOSE, // z notation right image bracket
|
||||||
|
'\u298A': MO.CLOSE, // z notation right binding bracket
|
||||||
|
'\u298C': MO.CLOSE, // right square bracket with underbar
|
||||||
|
'\u298E': MO.CLOSE, // right square bracket with tick in bottom corner
|
||||||
|
'\u2990': MO.CLOSE, // right square bracket with tick in top corner
|
||||||
|
'\u2992': MO.CLOSE, // right angle bracket with dot
|
||||||
|
'\u2994': MO.CLOSE, // right arc greater-than bracket
|
||||||
|
'\u2996': MO.CLOSE, // double right arc less-than bracket
|
||||||
|
'\u2998': MO.CLOSE, // right black tortoise shell bracket
|
||||||
|
'\u29FD': MO.CLOSE // right-pointing curved angle bracket
|
||||||
|
},
|
||||||
|
infix: {
|
||||||
|
'\u2981': MO.BIN3, // z notation spot
|
||||||
|
'\u2982': MO.BIN3, // z notation type colon
|
||||||
|
'\u2999': MO.BIN3, // dotted fence
|
||||||
|
'\u299A': MO.BIN3, // vertical zigzag line
|
||||||
|
'\u299B': MO.BIN3, // measured angle opening left
|
||||||
|
'\u299C': MO.BIN3, // right angle variant with square
|
||||||
|
'\u299D': MO.BIN3, // measured right angle with dot
|
||||||
|
'\u299E': MO.BIN3, // angle with s inside
|
||||||
|
'\u299F': MO.BIN3, // acute angle
|
||||||
|
'\u29A0': MO.BIN3, // spherical angle opening left
|
||||||
|
'\u29A1': MO.BIN3, // spherical angle opening up
|
||||||
|
'\u29A2': MO.BIN3, // turned angle
|
||||||
|
'\u29A3': MO.BIN3, // reversed angle
|
||||||
|
'\u29A4': MO.BIN3, // angle with underbar
|
||||||
|
'\u29A5': MO.BIN3, // reversed angle with underbar
|
||||||
|
'\u29A6': MO.BIN3, // oblique angle opening up
|
||||||
|
'\u29A7': MO.BIN3, // oblique angle opening down
|
||||||
|
'\u29A8': MO.BIN3, // measured angle with open arm ending in arrow pointing up and right
|
||||||
|
'\u29A9': MO.BIN3, // measured angle with open arm ending in arrow pointing up and left
|
||||||
|
'\u29AA': MO.BIN3, // measured angle with open arm ending in arrow pointing down and right
|
||||||
|
'\u29AB': MO.BIN3, // measured angle with open arm ending in arrow pointing down and left
|
||||||
|
'\u29AC': MO.BIN3, // measured angle with open arm ending in arrow pointing right and up
|
||||||
|
'\u29AD': MO.BIN3, // measured angle with open arm ending in arrow pointing left and up
|
||||||
|
'\u29AE': MO.BIN3, // measured angle with open arm ending in arrow pointing right and down
|
||||||
|
'\u29AF': MO.BIN3, // measured angle with open arm ending in arrow pointing left and down
|
||||||
|
'\u29B0': MO.BIN3, // reversed empty set
|
||||||
|
'\u29B1': MO.BIN3, // empty set with overbar
|
||||||
|
'\u29B2': MO.BIN3, // empty set with small circle above
|
||||||
|
'\u29B3': MO.BIN3, // empty set with right arrow above
|
||||||
|
'\u29B4': MO.BIN3, // empty set with left arrow above
|
||||||
|
'\u29B5': MO.BIN3, // circle with horizontal bar
|
||||||
|
'\u29B6': MO.BIN4, // circled vertical bar
|
||||||
|
'\u29B7': MO.BIN4, // circled parallel
|
||||||
|
'\u29B8': MO.BIN4, // circled reverse solidus
|
||||||
|
'\u29B9': MO.BIN4, // circled perpendicular
|
||||||
|
'\u29BA': MO.BIN4, // circle divided by horizontal bar and top half divided by vertical bar
|
||||||
|
'\u29BB': MO.BIN4, // circle with superimposed x
|
||||||
|
'\u29BC': MO.BIN4, // circled anticlockwise-rotated division sign
|
||||||
|
'\u29BD': MO.BIN4, // up arrow through circle
|
||||||
|
'\u29BE': MO.BIN4, // circled white bullet
|
||||||
|
'\u29BF': MO.BIN4, // circled bullet
|
||||||
|
'\u29C0': MO.REL, // circled less-than
|
||||||
|
'\u29C1': MO.REL, // circled greater-than
|
||||||
|
'\u29C2': MO.BIN3, // circle with small circle to the right
|
||||||
|
'\u29C3': MO.BIN3, // circle with two horizontal strokes to the right
|
||||||
|
'\u29C4': MO.BIN4, // squared rising diagonal slash
|
||||||
|
'\u29C5': MO.BIN4, // squared falling diagonal slash
|
||||||
|
'\u29C6': MO.BIN4, // squared asterisk
|
||||||
|
'\u29C7': MO.BIN4, // squared small circle
|
||||||
|
'\u29C8': MO.BIN4, // squared square
|
||||||
|
'\u29C9': MO.BIN3, // two joined squares
|
||||||
|
'\u29CA': MO.BIN3, // triangle with dot above
|
||||||
|
'\u29CB': MO.BIN3, // triangle with underbar
|
||||||
|
'\u29CC': MO.BIN3, // s in triangle
|
||||||
|
'\u29CD': MO.BIN3, // triangle with serifs at bottom
|
||||||
|
'\u29CE': MO.REL, // right triangle above left triangle
|
||||||
|
'\u29CF': MO.REL, // left triangle beside vertical bar
|
||||||
|
'\u29CF\u0338': MO.REL, // left triangle beside vertical bar with slash
|
||||||
|
'\u29D0': MO.REL, // vertical bar beside right triangle
|
||||||
|
'\u29D0\u0338': MO.REL, // vertical bar beside right triangle with slash
|
||||||
|
'\u29D1': MO.REL, // bowtie with left half black
|
||||||
|
'\u29D2': MO.REL, // bowtie with right half black
|
||||||
|
'\u29D3': MO.REL, // black bowtie
|
||||||
|
'\u29D4': MO.REL, // times with left half black
|
||||||
|
'\u29D5': MO.REL, // times with right half black
|
||||||
|
'\u29D6': MO.BIN4, // white hourglass
|
||||||
|
'\u29D7': MO.BIN4, // black hourglass
|
||||||
|
'\u29D8': MO.BIN3, // left wiggly fence
|
||||||
|
'\u29D9': MO.BIN3, // right wiggly fence
|
||||||
|
'\u29DB': MO.BIN3, // right double wiggly fence
|
||||||
|
'\u29DC': MO.BIN3, // incomplete infinity
|
||||||
|
'\u29DD': MO.BIN3, // tie over infinity
|
||||||
|
'\u29DE': MO.REL, // infinity negated with vertical bar
|
||||||
|
'\u29DF': MO.BIN3, // double-ended multimap
|
||||||
|
'\u29E0': MO.BIN3, // square with contoured outline
|
||||||
|
'\u29E1': MO.REL, // increases as
|
||||||
|
'\u29E2': MO.BIN4, // shuffle product
|
||||||
|
'\u29E3': MO.REL, // equals sign and slanted parallel
|
||||||
|
'\u29E4': MO.REL, // equals sign and slanted parallel with tilde above
|
||||||
|
'\u29E5': MO.REL, // identical to and slanted parallel
|
||||||
|
'\u29E6': MO.REL, // gleich stark
|
||||||
|
'\u29E7': MO.BIN3, // thermodynamic
|
||||||
|
'\u29E8': MO.BIN3, // down-pointing triangle with left half black
|
||||||
|
'\u29E9': MO.BIN3, // down-pointing triangle with right half black
|
||||||
|
'\u29EA': MO.BIN3, // black diamond with down arrow
|
||||||
|
'\u29EB': MO.BIN3, // black lozenge
|
||||||
|
'\u29EC': MO.BIN3, // white circle with down arrow
|
||||||
|
'\u29ED': MO.BIN3, // black circle with down arrow
|
||||||
|
'\u29EE': MO.BIN3, // error-barred white square
|
||||||
|
'\u29EF': MO.BIN3, // error-barred black square
|
||||||
|
'\u29F0': MO.BIN3, // error-barred white diamond
|
||||||
|
'\u29F1': MO.BIN3, // error-barred black diamond
|
||||||
|
'\u29F2': MO.BIN3, // error-barred white circle
|
||||||
|
'\u29F3': MO.BIN3, // error-barred black circle
|
||||||
|
'\u29F4': MO.REL, // rule-delayed
|
||||||
|
'\u29F5': MO.BIN4, // reverse solidus operator
|
||||||
|
'\u29F6': MO.BIN4, // solidus with overbar
|
||||||
|
'\u29F7': MO.BIN4, // reverse solidus with horizontal stroke
|
||||||
|
'\u29F8': MO.BIN3, // big solidus
|
||||||
|
'\u29F9': MO.BIN3, // big reverse solidus
|
||||||
|
'\u29FA': MO.BIN3, // double plus
|
||||||
|
'\u29FB': MO.BIN3, // triple plus
|
||||||
|
'\u29FE': MO.BIN4, // tiny
|
||||||
|
'\u29FF': MO.BIN4 // miny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/MiscMathSymbolsB.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,36 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/MiscSymbolsAndArrows.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u2B45': MO.RELSTRETCH, // leftwards quadruple arrow
|
||||||
|
'\u2B46': MO.RELSTRETCH // rightwards quadruple arrow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/MiscSymbolsAndArrows.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,40 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/MiscTechnical.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
postfix: {
|
||||||
|
'\u23B4': MO.WIDEACCENT, // top square bracket
|
||||||
|
'\u23B5': MO.WIDEACCENT, // bottom square bracket
|
||||||
|
'\u23DC': MO.WIDEACCENT, // top parenthesis
|
||||||
|
'\u23DD': MO.WIDEACCENT, // bottom parenthesis
|
||||||
|
'\u23E0': MO.WIDEACCENT, // top tortoise shell bracket
|
||||||
|
'\u23E1': MO.WIDEACCENT // bottom tortoise shell bracket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/MiscTechnical.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,38 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/SpacingModLetters.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
postfix: {
|
||||||
|
'\u02CD': MO.WIDEACCENT, // modifier letter low macron
|
||||||
|
'\u02DA': MO.ACCENT, // ring above
|
||||||
|
'\u02DD': MO.ACCENT, // double acute accent
|
||||||
|
'\u02F7': MO.WIDEACCENT // modifier letter low tilde
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/SpacingModLetters.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,289 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/SuppMathOperators.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
prefix: {
|
||||||
|
'\u2A03': MO.OP, // n-ary union operator with dot
|
||||||
|
'\u2A05': MO.OP, // n-ary square intersection operator
|
||||||
|
'\u2A07': MO.OP, // two logical and operator
|
||||||
|
'\u2A08': MO.OP, // two logical or operator
|
||||||
|
'\u2A09': MO.OP, // n-ary times operator
|
||||||
|
'\u2A0A': MO.OP, // modulo two sum
|
||||||
|
'\u2A0B': MO.INTEGRAL2, // summation with integral
|
||||||
|
'\u2A0C': MO.INTEGRAL, // quadruple integral operator
|
||||||
|
'\u2A0D': MO.INTEGRAL2, // finite part integral
|
||||||
|
'\u2A0E': MO.INTEGRAL2, // integral with double stroke
|
||||||
|
'\u2A0F': MO.INTEGRAL2, // integral average with slash
|
||||||
|
'\u2A10': MO.OP, // circulation function
|
||||||
|
'\u2A11': MO.OP, // anticlockwise integration
|
||||||
|
'\u2A12': MO.OP, // line integration with rectangular path around pole
|
||||||
|
'\u2A13': MO.OP, // line integration with semicircular path around pole
|
||||||
|
'\u2A14': MO.OP, // line integration not including the pole
|
||||||
|
'\u2A15': MO.INTEGRAL2, // integral around a point operator
|
||||||
|
'\u2A16': MO.INTEGRAL2, // quaternion integral operator
|
||||||
|
'\u2A17': MO.INTEGRAL2, // integral with leftwards arrow with hook
|
||||||
|
'\u2A18': MO.INTEGRAL2, // integral with times sign
|
||||||
|
'\u2A19': MO.INTEGRAL2, // integral with intersection
|
||||||
|
'\u2A1A': MO.INTEGRAL2, // integral with union
|
||||||
|
'\u2A1B': MO.INTEGRAL2, // integral with overbar
|
||||||
|
'\u2A1C': MO.INTEGRAL2, // integral with underbar
|
||||||
|
'\u2AFC': MO.OP, // large triple vertical bar operator
|
||||||
|
'\u2AFF': MO.OP // n-ary white vertical bar
|
||||||
|
},
|
||||||
|
infix: {
|
||||||
|
'\u2A1D': MO.BIN3, // join
|
||||||
|
'\u2A1E': MO.BIN3, // large left triangle operator
|
||||||
|
'\u2A1F': MO.BIN3, // z notation schema composition
|
||||||
|
'\u2A20': MO.BIN3, // z notation schema piping
|
||||||
|
'\u2A21': MO.BIN3, // z notation schema projection
|
||||||
|
'\u2A22': MO.BIN4, // plus sign with small circle above
|
||||||
|
'\u2A23': MO.BIN4, // plus sign with circumflex accent above
|
||||||
|
'\u2A24': MO.BIN4, // plus sign with tilde above
|
||||||
|
'\u2A25': MO.BIN4, // plus sign with dot below
|
||||||
|
'\u2A26': MO.BIN4, // plus sign with tilde below
|
||||||
|
'\u2A27': MO.BIN4, // plus sign with subscript two
|
||||||
|
'\u2A28': MO.BIN4, // plus sign with black triangle
|
||||||
|
'\u2A29': MO.BIN4, // minus sign with comma above
|
||||||
|
'\u2A2A': MO.BIN4, // minus sign with dot below
|
||||||
|
'\u2A2B': MO.BIN4, // minus sign with falling dots
|
||||||
|
'\u2A2C': MO.BIN4, // minus sign with rising dots
|
||||||
|
'\u2A2D': MO.BIN4, // plus sign in left half circle
|
||||||
|
'\u2A2E': MO.BIN4, // plus sign in right half circle
|
||||||
|
'\u2A30': MO.BIN4, // multiplication sign with dot above
|
||||||
|
'\u2A31': MO.BIN4, // multiplication sign with underbar
|
||||||
|
'\u2A32': MO.BIN4, // semidirect product with bottom closed
|
||||||
|
'\u2A33': MO.BIN4, // smash product
|
||||||
|
'\u2A34': MO.BIN4, // multiplication sign in left half circle
|
||||||
|
'\u2A35': MO.BIN4, // multiplication sign in right half circle
|
||||||
|
'\u2A36': MO.BIN4, // circled multiplication sign with circumflex accent
|
||||||
|
'\u2A37': MO.BIN4, // multiplication sign in double circle
|
||||||
|
'\u2A38': MO.BIN4, // circled division sign
|
||||||
|
'\u2A39': MO.BIN4, // plus sign in triangle
|
||||||
|
'\u2A3A': MO.BIN4, // minus sign in triangle
|
||||||
|
'\u2A3B': MO.BIN4, // multiplication sign in triangle
|
||||||
|
'\u2A3C': MO.BIN4, // interior product
|
||||||
|
'\u2A3D': MO.BIN4, // righthand interior product
|
||||||
|
'\u2A3E': MO.BIN4, // z notation relational composition
|
||||||
|
'\u2A40': MO.BIN4, // intersection with dot
|
||||||
|
'\u2A41': MO.BIN4, // union with minus sign
|
||||||
|
'\u2A42': MO.BIN4, // union with overbar
|
||||||
|
'\u2A43': MO.BIN4, // intersection with overbar
|
||||||
|
'\u2A44': MO.BIN4, // intersection with logical and
|
||||||
|
'\u2A45': MO.BIN4, // union with logical or
|
||||||
|
'\u2A46': MO.BIN4, // union above intersection
|
||||||
|
'\u2A47': MO.BIN4, // intersection above union
|
||||||
|
'\u2A48': MO.BIN4, // union above bar above intersection
|
||||||
|
'\u2A49': MO.BIN4, // intersection above bar above union
|
||||||
|
'\u2A4A': MO.BIN4, // union beside and joined with union
|
||||||
|
'\u2A4B': MO.BIN4, // intersection beside and joined with intersection
|
||||||
|
'\u2A4C': MO.BIN4, // closed union with serifs
|
||||||
|
'\u2A4D': MO.BIN4, // closed intersection with serifs
|
||||||
|
'\u2A4E': MO.BIN4, // double square intersection
|
||||||
|
'\u2A4F': MO.BIN4, // double square union
|
||||||
|
'\u2A50': MO.BIN4, // closed union with serifs and smash product
|
||||||
|
'\u2A51': MO.BIN4, // logical and with dot above
|
||||||
|
'\u2A52': MO.BIN4, // logical or with dot above
|
||||||
|
'\u2A53': MO.BIN4, // double logical and
|
||||||
|
'\u2A54': MO.BIN4, // double logical or
|
||||||
|
'\u2A55': MO.BIN4, // two intersecting logical and
|
||||||
|
'\u2A56': MO.BIN4, // two intersecting logical or
|
||||||
|
'\u2A57': MO.BIN4, // sloping large or
|
||||||
|
'\u2A58': MO.BIN4, // sloping large and
|
||||||
|
'\u2A59': MO.REL, // logical or overlapping logical and
|
||||||
|
'\u2A5A': MO.BIN4, // logical and with middle stem
|
||||||
|
'\u2A5B': MO.BIN4, // logical or with middle stem
|
||||||
|
'\u2A5C': MO.BIN4, // logical and with horizontal dash
|
||||||
|
'\u2A5D': MO.BIN4, // logical or with horizontal dash
|
||||||
|
'\u2A5E': MO.BIN4, // logical and with double overbar
|
||||||
|
'\u2A5F': MO.BIN4, // logical and with underbar
|
||||||
|
'\u2A60': MO.BIN4, // logical and with double underbar
|
||||||
|
'\u2A61': MO.BIN4, // small vee with underbar
|
||||||
|
'\u2A62': MO.BIN4, // logical or with double overbar
|
||||||
|
'\u2A63': MO.BIN4, // logical or with double underbar
|
||||||
|
'\u2A64': MO.BIN4, // z notation domain antirestriction
|
||||||
|
'\u2A65': MO.BIN4, // z notation range antirestriction
|
||||||
|
'\u2A66': MO.REL, // equals sign with dot below
|
||||||
|
'\u2A67': MO.REL, // identical with dot above
|
||||||
|
'\u2A68': MO.REL, // triple horizontal bar with double vertical stroke
|
||||||
|
'\u2A69': MO.REL, // triple horizontal bar with triple vertical stroke
|
||||||
|
'\u2A6A': MO.REL, // tilde operator with dot above
|
||||||
|
'\u2A6B': MO.REL, // tilde operator with rising dots
|
||||||
|
'\u2A6C': MO.REL, // similar minus similar
|
||||||
|
'\u2A6D': MO.REL, // congruent with dot above
|
||||||
|
'\u2A6E': MO.REL, // equals with asterisk
|
||||||
|
'\u2A6F': MO.REL, // almost equal to with circumflex accent
|
||||||
|
'\u2A70': MO.REL, // approximately equal or equal to
|
||||||
|
'\u2A71': MO.BIN4, // equals sign above plus sign
|
||||||
|
'\u2A72': MO.BIN4, // plus sign above equals sign
|
||||||
|
'\u2A73': MO.REL, // equals sign above tilde operator
|
||||||
|
'\u2A74': MO.REL, // double colon equal
|
||||||
|
'\u2A75': MO.REL, // two consecutive equals signs
|
||||||
|
'\u2A76': MO.REL, // three consecutive equals signs
|
||||||
|
'\u2A77': MO.REL, // equals sign with two dots above and two dots below
|
||||||
|
'\u2A78': MO.REL, // equivalent with four dots above
|
||||||
|
'\u2A79': MO.REL, // less-than with circle inside
|
||||||
|
'\u2A7A': MO.REL, // greater-than with circle inside
|
||||||
|
'\u2A7B': MO.REL, // less-than with question mark above
|
||||||
|
'\u2A7C': MO.REL, // greater-than with question mark above
|
||||||
|
'\u2A7D': MO.REL, // less-than or slanted equal to
|
||||||
|
'\u2A7D\u0338': MO.REL, // less-than or slanted equal to with slash
|
||||||
|
'\u2A7E': MO.REL, // greater-than or slanted equal to
|
||||||
|
'\u2A7E\u0338': MO.REL, // greater-than or slanted equal to with slash
|
||||||
|
'\u2A7F': MO.REL, // less-than or slanted equal to with dot inside
|
||||||
|
'\u2A80': MO.REL, // greater-than or slanted equal to with dot inside
|
||||||
|
'\u2A81': MO.REL, // less-than or slanted equal to with dot above
|
||||||
|
'\u2A82': MO.REL, // greater-than or slanted equal to with dot above
|
||||||
|
'\u2A83': MO.REL, // less-than or slanted equal to with dot above right
|
||||||
|
'\u2A84': MO.REL, // greater-than or slanted equal to with dot above left
|
||||||
|
'\u2A85': MO.REL, // less-than or approximate
|
||||||
|
'\u2A86': MO.REL, // greater-than or approximate
|
||||||
|
'\u2A87': MO.REL, // less-than and single-line not equal to
|
||||||
|
'\u2A88': MO.REL, // greater-than and single-line not equal to
|
||||||
|
'\u2A89': MO.REL, // less-than and not approximate
|
||||||
|
'\u2A8A': MO.REL, // greater-than and not approximate
|
||||||
|
'\u2A8B': MO.REL, // less-than above double-line equal above greater-than
|
||||||
|
'\u2A8C': MO.REL, // greater-than above double-line equal above less-than
|
||||||
|
'\u2A8D': MO.REL, // less-than above similar or equal
|
||||||
|
'\u2A8E': MO.REL, // greater-than above similar or equal
|
||||||
|
'\u2A8F': MO.REL, // less-than above similar above greater-than
|
||||||
|
'\u2A90': MO.REL, // greater-than above similar above less-than
|
||||||
|
'\u2A91': MO.REL, // less-than above greater-than above double-line equal
|
||||||
|
'\u2A92': MO.REL, // greater-than above less-than above double-line equal
|
||||||
|
'\u2A93': MO.REL, // less-than above slanted equal above greater-than above slanted equal
|
||||||
|
'\u2A94': MO.REL, // greater-than above slanted equal above less-than above slanted equal
|
||||||
|
'\u2A95': MO.REL, // slanted equal to or less-than
|
||||||
|
'\u2A96': MO.REL, // slanted equal to or greater-than
|
||||||
|
'\u2A97': MO.REL, // slanted equal to or less-than with dot inside
|
||||||
|
'\u2A98': MO.REL, // slanted equal to or greater-than with dot inside
|
||||||
|
'\u2A99': MO.REL, // double-line equal to or less-than
|
||||||
|
'\u2A9A': MO.REL, // double-line equal to or greater-than
|
||||||
|
'\u2A9B': MO.REL, // double-line slanted equal to or less-than
|
||||||
|
'\u2A9C': MO.REL, // double-line slanted equal to or greater-than
|
||||||
|
'\u2A9D': MO.REL, // similar or less-than
|
||||||
|
'\u2A9E': MO.REL, // similar or greater-than
|
||||||
|
'\u2A9F': MO.REL, // similar above less-than above equals sign
|
||||||
|
'\u2AA0': MO.REL, // similar above greater-than above equals sign
|
||||||
|
'\u2AA1': MO.REL, // double nested less-than
|
||||||
|
'\u2AA1\u0338': MO.REL, // double nested less-than with slash
|
||||||
|
'\u2AA2': MO.REL, // double nested greater-than
|
||||||
|
'\u2AA2\u0338': MO.REL, // double nested greater-than with slash
|
||||||
|
'\u2AA3': MO.REL, // double nested less-than with underbar
|
||||||
|
'\u2AA4': MO.REL, // greater-than overlapping less-than
|
||||||
|
'\u2AA5': MO.REL, // greater-than beside less-than
|
||||||
|
'\u2AA6': MO.REL, // less-than closed by curve
|
||||||
|
'\u2AA7': MO.REL, // greater-than closed by curve
|
||||||
|
'\u2AA8': MO.REL, // less-than closed by curve above slanted equal
|
||||||
|
'\u2AA9': MO.REL, // greater-than closed by curve above slanted equal
|
||||||
|
'\u2AAA': MO.REL, // smaller than
|
||||||
|
'\u2AAB': MO.REL, // larger than
|
||||||
|
'\u2AAC': MO.REL, // smaller than or equal to
|
||||||
|
'\u2AAD': MO.REL, // larger than or equal to
|
||||||
|
'\u2AAE': MO.REL, // equals sign with bumpy above
|
||||||
|
'\u2AAF\u0338': MO.REL, // precedes above single-line equals sign with slash
|
||||||
|
'\u2AB0\u0338': MO.REL, // succeeds above single-line equals sign with slash
|
||||||
|
'\u2AB1': MO.REL, // precedes above single-line not equal to
|
||||||
|
'\u2AB2': MO.REL, // succeeds above single-line not equal to
|
||||||
|
'\u2AB3': MO.REL, // precedes above equals sign
|
||||||
|
'\u2AB4': MO.REL, // succeeds above equals sign
|
||||||
|
'\u2AB5': MO.REL, // precedes above not equal to
|
||||||
|
'\u2AB6': MO.REL, // succeeds above not equal to
|
||||||
|
'\u2AB7': MO.REL, // precedes above almost equal to
|
||||||
|
'\u2AB8': MO.REL, // succeeds above almost equal to
|
||||||
|
'\u2AB9': MO.REL, // precedes above not almost equal to
|
||||||
|
'\u2ABA': MO.REL, // succeeds above not almost equal to
|
||||||
|
'\u2ABB': MO.REL, // double precedes
|
||||||
|
'\u2ABC': MO.REL, // double succeeds
|
||||||
|
'\u2ABD': MO.REL, // subset with dot
|
||||||
|
'\u2ABE': MO.REL, // superset with dot
|
||||||
|
'\u2ABF': MO.REL, // subset with plus sign below
|
||||||
|
'\u2AC0': MO.REL, // superset with plus sign below
|
||||||
|
'\u2AC1': MO.REL, // subset with multiplication sign below
|
||||||
|
'\u2AC2': MO.REL, // superset with multiplication sign below
|
||||||
|
'\u2AC3': MO.REL, // subset of or equal to with dot above
|
||||||
|
'\u2AC4': MO.REL, // superset of or equal to with dot above
|
||||||
|
'\u2AC5': MO.REL, // subset of above equals sign
|
||||||
|
'\u2AC6': MO.REL, // superset of above equals sign
|
||||||
|
'\u2AC7': MO.REL, // subset of above tilde operator
|
||||||
|
'\u2AC8': MO.REL, // superset of above tilde operator
|
||||||
|
'\u2AC9': MO.REL, // subset of above almost equal to
|
||||||
|
'\u2ACA': MO.REL, // superset of above almost equal to
|
||||||
|
'\u2ACB': MO.REL, // subset of above not equal to
|
||||||
|
'\u2ACC': MO.REL, // superset of above not equal to
|
||||||
|
'\u2ACD': MO.REL, // square left open box operator
|
||||||
|
'\u2ACE': MO.REL, // square right open box operator
|
||||||
|
'\u2ACF': MO.REL, // closed subset
|
||||||
|
'\u2AD0': MO.REL, // closed superset
|
||||||
|
'\u2AD1': MO.REL, // closed subset or equal to
|
||||||
|
'\u2AD2': MO.REL, // closed superset or equal to
|
||||||
|
'\u2AD3': MO.REL, // subset above superset
|
||||||
|
'\u2AD4': MO.REL, // superset above subset
|
||||||
|
'\u2AD5': MO.REL, // subset above subset
|
||||||
|
'\u2AD6': MO.REL, // superset above superset
|
||||||
|
'\u2AD7': MO.REL, // superset beside subset
|
||||||
|
'\u2AD8': MO.REL, // superset beside and joined by dash with subset
|
||||||
|
'\u2AD9': MO.REL, // element of opening downwards
|
||||||
|
'\u2ADA': MO.REL, // pitchfork with tee top
|
||||||
|
'\u2ADB': MO.REL, // transversal intersection
|
||||||
|
'\u2ADC': MO.REL, // forking
|
||||||
|
'\u2ADD': MO.REL, // nonforking
|
||||||
|
'\u2ADE': MO.REL, // short left tack
|
||||||
|
'\u2ADF': MO.REL, // short down tack
|
||||||
|
'\u2AE0': MO.REL, // short up tack
|
||||||
|
'\u2AE1': MO.REL, // perpendicular with s
|
||||||
|
'\u2AE2': MO.REL, // vertical bar triple right turnstile
|
||||||
|
'\u2AE3': MO.REL, // double vertical bar left turnstile
|
||||||
|
'\u2AE4': MO.REL, // vertical bar double left turnstile
|
||||||
|
'\u2AE5': MO.REL, // double vertical bar double left turnstile
|
||||||
|
'\u2AE6': MO.REL, // long dash from left member of double vertical
|
||||||
|
'\u2AE7': MO.REL, // short down tack with overbar
|
||||||
|
'\u2AE8': MO.REL, // short up tack with underbar
|
||||||
|
'\u2AE9': MO.REL, // short up tack above short down tack
|
||||||
|
'\u2AEA': MO.REL, // double down tack
|
||||||
|
'\u2AEB': MO.REL, // double up tack
|
||||||
|
'\u2AEC': MO.REL, // double stroke not sign
|
||||||
|
'\u2AED': MO.REL, // reversed double stroke not sign
|
||||||
|
'\u2AEE': MO.REL, // does not divide with reversed negation slash
|
||||||
|
'\u2AEF': MO.REL, // vertical line with circle above
|
||||||
|
'\u2AF0': MO.REL, // vertical line with circle below
|
||||||
|
'\u2AF1': MO.REL, // down tack with circle below
|
||||||
|
'\u2AF2': MO.REL, // parallel with horizontal stroke
|
||||||
|
'\u2AF3': MO.REL, // parallel with tilde operator
|
||||||
|
'\u2AF4': MO.BIN4, // triple vertical bar binary relation
|
||||||
|
'\u2AF5': MO.BIN4, // triple vertical bar with horizontal stroke
|
||||||
|
'\u2AF6': MO.BIN4, // triple colon operator
|
||||||
|
'\u2AF7': MO.REL, // triple nested less-than
|
||||||
|
'\u2AF8': MO.REL, // triple nested greater-than
|
||||||
|
'\u2AF9': MO.REL, // double-line slanted less-than or equal to
|
||||||
|
'\u2AFA': MO.REL, // double-line slanted greater-than or equal to
|
||||||
|
'\u2AFB': MO.BIN4, // triple solidus binary relation
|
||||||
|
'\u2AFD': MO.BIN4, // double solidus operator
|
||||||
|
'\u2AFE': MO.BIN3 // white vertical bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/SuppMathOperators.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,40 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/SupplementalArrowsA.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u27F0': MO.RELSTRETCH, // upwards quadruple arrow
|
||||||
|
'\u27F1': MO.RELSTRETCH, // downwards quadruple arrow
|
||||||
|
'\u27FB': MO.WIDEREL, // long leftwards arrow from bar
|
||||||
|
'\u27FD': MO.WIDEREL, // long leftwards double arrow from bar
|
||||||
|
'\u27FE': MO.WIDEREL, // long rightwards double arrow from bar
|
||||||
|
'\u27FF': MO.WIDEREL // long rightwards squiggle arrow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/SupplementalArrowsA.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
@ -0,0 +1,162 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/output/HTML-CSS/optable/SupplementalArrowsB.js
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (MML) {
|
||||||
|
var MO = MML.mo.OPTYPES;
|
||||||
|
var TEXCLASS = MML.TEXCLASS;
|
||||||
|
|
||||||
|
MathJax.Hub.Insert(MML.mo.prototype,{
|
||||||
|
OPTABLE: {
|
||||||
|
infix: {
|
||||||
|
'\u2900': MO.RELACCENT, // rightwards two-headed arrow with vertical stroke
|
||||||
|
'\u2901': MO.RELACCENT, // rightwards two-headed arrow with double vertical stroke
|
||||||
|
'\u2902': MO.RELACCENT, // leftwards double arrow with vertical stroke
|
||||||
|
'\u2903': MO.RELACCENT, // rightwards double arrow with vertical stroke
|
||||||
|
'\u2904': MO.RELACCENT, // left right double arrow with vertical stroke
|
||||||
|
'\u2905': MO.RELACCENT, // rightwards two-headed arrow from bar
|
||||||
|
'\u2906': MO.RELACCENT, // leftwards double arrow from bar
|
||||||
|
'\u2907': MO.RELACCENT, // rightwards double arrow from bar
|
||||||
|
'\u2908': MO.REL, // downwards arrow with horizontal stroke
|
||||||
|
'\u2909': MO.REL, // upwards arrow with horizontal stroke
|
||||||
|
'\u290A': MO.RELSTRETCH, // upwards triple arrow
|
||||||
|
'\u290B': MO.RELSTRETCH, // downwards triple arrow
|
||||||
|
'\u290C': MO.WIDEREL, // leftwards double dash arrow
|
||||||
|
'\u290D': MO.WIDEREL, // rightwards double dash arrow
|
||||||
|
'\u290E': MO.WIDEREL, // leftwards triple dash arrow
|
||||||
|
'\u290F': MO.WIDEREL, // rightwards triple dash arrow
|
||||||
|
'\u2910': MO.WIDEREL, // rightwards two-headed triple dash arrow
|
||||||
|
'\u2911': MO.RELACCENT, // rightwards arrow with dotted stem
|
||||||
|
'\u2912': MO.RELSTRETCH, // upwards arrow to bar
|
||||||
|
'\u2913': MO.RELSTRETCH, // downwards arrow to bar
|
||||||
|
'\u2914': MO.RELACCENT, // rightwards arrow with tail with vertical stroke
|
||||||
|
'\u2915': MO.RELACCENT, // rightwards arrow with tail with double vertical stroke
|
||||||
|
'\u2916': MO.RELACCENT, // rightwards two-headed arrow with tail
|
||||||
|
'\u2917': MO.RELACCENT, // rightwards two-headed arrow with tail with vertical stroke
|
||||||
|
'\u2918': MO.RELACCENT, // rightwards two-headed arrow with tail with double vertical stroke
|
||||||
|
'\u2919': MO.RELACCENT, // leftwards arrow-tail
|
||||||
|
'\u291A': MO.RELACCENT, // rightwards arrow-tail
|
||||||
|
'\u291B': MO.RELACCENT, // leftwards double arrow-tail
|
||||||
|
'\u291C': MO.RELACCENT, // rightwards double arrow-tail
|
||||||
|
'\u291D': MO.RELACCENT, // leftwards arrow to black diamond
|
||||||
|
'\u291E': MO.RELACCENT, // rightwards arrow to black diamond
|
||||||
|
'\u291F': MO.RELACCENT, // leftwards arrow from bar to black diamond
|
||||||
|
'\u2920': MO.RELACCENT, // rightwards arrow from bar to black diamond
|
||||||
|
'\u2921': MO.RELSTRETCH, // north west and south east arrow
|
||||||
|
'\u2922': MO.RELSTRETCH, // north east and south west arrow
|
||||||
|
'\u2923': MO.REL, // north west arrow with hook
|
||||||
|
'\u2924': MO.REL, // north east arrow with hook
|
||||||
|
'\u2925': MO.REL, // south east arrow with hook
|
||||||
|
'\u2926': MO.REL, // south west arrow with hook
|
||||||
|
'\u2927': MO.REL, // north west arrow and north east arrow
|
||||||
|
'\u2928': MO.REL, // north east arrow and south east arrow
|
||||||
|
'\u2929': MO.REL, // south east arrow and south west arrow
|
||||||
|
'\u292A': MO.REL, // south west arrow and north west arrow
|
||||||
|
'\u292B': MO.REL, // rising diagonal crossing falling diagonal
|
||||||
|
'\u292C': MO.REL, // falling diagonal crossing rising diagonal
|
||||||
|
'\u292D': MO.REL, // south east arrow crossing north east arrow
|
||||||
|
'\u292E': MO.REL, // north east arrow crossing south east arrow
|
||||||
|
'\u292F': MO.REL, // falling diagonal crossing north east arrow
|
||||||
|
'\u2930': MO.REL, // rising diagonal crossing south east arrow
|
||||||
|
'\u2931': MO.REL, // north east arrow crossing north west arrow
|
||||||
|
'\u2932': MO.REL, // north west arrow crossing north east arrow
|
||||||
|
'\u2933': MO.RELACCENT, // wave arrow pointing directly right
|
||||||
|
'\u2934': MO.REL, // arrow pointing rightwards then curving upwards
|
||||||
|
'\u2935': MO.REL, // arrow pointing rightwards then curving downwards
|
||||||
|
'\u2936': MO.REL, // arrow pointing downwards then curving leftwards
|
||||||
|
'\u2937': MO.REL, // arrow pointing downwards then curving rightwards
|
||||||
|
'\u2938': MO.REL, // right-side arc clockwise arrow
|
||||||
|
'\u2939': MO.REL, // left-side arc anticlockwise arrow
|
||||||
|
'\u293A': MO.RELACCENT, // top arc anticlockwise arrow
|
||||||
|
'\u293B': MO.RELACCENT, // bottom arc anticlockwise arrow
|
||||||
|
'\u293C': MO.RELACCENT, // top arc clockwise arrow with minus
|
||||||
|
'\u293D': MO.RELACCENT, // top arc anticlockwise arrow with plus
|
||||||
|
'\u293E': MO.REL, // lower right semicircular clockwise arrow
|
||||||
|
'\u293F': MO.REL, // lower left semicircular anticlockwise arrow
|
||||||
|
'\u2940': MO.REL, // anticlockwise closed circle arrow
|
||||||
|
'\u2941': MO.REL, // clockwise closed circle arrow
|
||||||
|
'\u2942': MO.RELACCENT, // rightwards arrow above short leftwards arrow
|
||||||
|
'\u2943': MO.RELACCENT, // leftwards arrow above short rightwards arrow
|
||||||
|
'\u2944': MO.RELACCENT, // short rightwards arrow above leftwards arrow
|
||||||
|
'\u2945': MO.RELACCENT, // rightwards arrow with plus below
|
||||||
|
'\u2946': MO.RELACCENT, // leftwards arrow with plus below
|
||||||
|
'\u2947': MO.RELACCENT, // rightwards arrow through x
|
||||||
|
'\u2948': MO.RELACCENT, // left right arrow through small circle
|
||||||
|
'\u2949': MO.REL, // upwards two-headed arrow from small circle
|
||||||
|
'\u294A': MO.RELACCENT, // left barb up right barb down harpoon
|
||||||
|
'\u294B': MO.RELACCENT, // left barb down right barb up harpoon
|
||||||
|
'\u294C': MO.REL, // up barb right down barb left harpoon
|
||||||
|
'\u294D': MO.REL, // up barb left down barb right harpoon
|
||||||
|
'\u294E': MO.WIDEREL, // left barb up right barb up harpoon
|
||||||
|
'\u294F': MO.RELSTRETCH, // up barb right down barb right harpoon
|
||||||
|
'\u2950': MO.WIDEREL, // left barb down right barb down harpoon
|
||||||
|
'\u2951': MO.RELSTRETCH, // up barb left down barb left harpoon
|
||||||
|
'\u2952': MO.WIDEREL, // leftwards harpoon with barb up to bar
|
||||||
|
'\u2953': MO.WIDEREL, // rightwards harpoon with barb up to bar
|
||||||
|
'\u2954': MO.RELSTRETCH, // upwards harpoon with barb right to bar
|
||||||
|
'\u2955': MO.RELSTRETCH, // downwards harpoon with barb right to bar
|
||||||
|
'\u2956': MO.RELSTRETCH, // leftwards harpoon with barb down to bar
|
||||||
|
'\u2957': MO.RELSTRETCH, // rightwards harpoon with barb down to bar
|
||||||
|
'\u2958': MO.RELSTRETCH, // upwards harpoon with barb left to bar
|
||||||
|
'\u2959': MO.RELSTRETCH, // downwards harpoon with barb left to bar
|
||||||
|
'\u295A': MO.WIDEREL, // leftwards harpoon with barb up from bar
|
||||||
|
'\u295B': MO.WIDEREL, // rightwards harpoon with barb up from bar
|
||||||
|
'\u295C': MO.RELSTRETCH, // upwards harpoon with barb right from bar
|
||||||
|
'\u295D': MO.RELSTRETCH, // downwards harpoon with barb right from bar
|
||||||
|
'\u295E': MO.WIDEREL, // leftwards harpoon with barb down from bar
|
||||||
|
'\u295F': MO.WIDEREL, // rightwards harpoon with barb down from bar
|
||||||
|
'\u2960': MO.RELSTRETCH, // upwards harpoon with barb left from bar
|
||||||
|
'\u2961': MO.RELSTRETCH, // downwards harpoon with barb left from bar
|
||||||
|
'\u2962': MO.RELACCENT, // leftwards harpoon with barb up above leftwards harpoon with barb down
|
||||||
|
'\u2963': MO.REL, // upwards harpoon with barb left beside upwards harpoon with barb right
|
||||||
|
'\u2964': MO.RELACCENT, // rightwards harpoon with barb up above rightwards harpoon with barb down
|
||||||
|
'\u2965': MO.REL, // downwards harpoon with barb left beside downwards harpoon with barb right
|
||||||
|
'\u2966': MO.RELACCENT, // leftwards harpoon with barb up above rightwards harpoon with barb up
|
||||||
|
'\u2967': MO.RELACCENT, // leftwards harpoon with barb down above rightwards harpoon with barb down
|
||||||
|
'\u2968': MO.RELACCENT, // rightwards harpoon with barb up above leftwards harpoon with barb up
|
||||||
|
'\u2969': MO.RELACCENT, // rightwards harpoon with barb down above leftwards harpoon with barb down
|
||||||
|
'\u296A': MO.RELACCENT, // leftwards harpoon with barb up above long dash
|
||||||
|
'\u296B': MO.RELACCENT, // leftwards harpoon with barb down below long dash
|
||||||
|
'\u296C': MO.RELACCENT, // rightwards harpoon with barb up above long dash
|
||||||
|
'\u296D': MO.RELACCENT, // rightwards harpoon with barb down below long dash
|
||||||
|
'\u296E': MO.RELSTRETCH, // upwards harpoon with barb left beside downwards harpoon with barb right
|
||||||
|
'\u296F': MO.RELSTRETCH, // downwards harpoon with barb left beside upwards harpoon with barb right
|
||||||
|
'\u2970': MO.RELACCENT, // right double arrow with rounded head
|
||||||
|
'\u2971': MO.RELACCENT, // equals sign above rightwards arrow
|
||||||
|
'\u2972': MO.RELACCENT, // tilde operator above rightwards arrow
|
||||||
|
'\u2973': MO.RELACCENT, // leftwards arrow above tilde operator
|
||||||
|
'\u2974': MO.RELACCENT, // rightwards arrow above tilde operator
|
||||||
|
'\u2975': MO.RELACCENT, // rightwards arrow above almost equal to
|
||||||
|
'\u2976': MO.RELACCENT, // less-than above leftwards arrow
|
||||||
|
'\u2977': MO.RELACCENT, // leftwards arrow through less-than
|
||||||
|
'\u2978': MO.RELACCENT, // greater-than above rightwards arrow
|
||||||
|
'\u2979': MO.RELACCENT, // subset above rightwards arrow
|
||||||
|
'\u297A': MO.RELACCENT, // leftwards arrow through subset
|
||||||
|
'\u297B': MO.RELACCENT, // superset above leftwards arrow
|
||||||
|
'\u297C': MO.RELACCENT, // left fish tail
|
||||||
|
'\u297D': MO.RELACCENT, // right fish tail
|
||||||
|
'\u297E': MO.REL, // up fish tail
|
||||||
|
'\u297F': MO.REL // down fish tail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MathJax.Ajax.loadComplete(MML.optableDir+"/SupplementalArrowsB.js");
|
||||||
|
|
||||||
|
})(MathJax.ElementJax.mml);
|
41
resources/viewer/mathjax/jax/input/AsciiMath/config.js
Normal file
41
resources/viewer/mathjax/jax/input/AsciiMath/config.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*************************************************************
|
||||||
|
*
|
||||||
|
* MathJax/jax/input/AsciiMath/config.js
|
||||||
|
*
|
||||||
|
* Initializes the AsciiMath InputJax (the main definition is in
|
||||||
|
* MathJax/jax/input/AsciiMath/jax.js, which is loaded when needed).
|
||||||
|
*
|
||||||
|
* Originally adapted for MathJax by David Lippman.
|
||||||
|
* Additional work done by Davide P. Cervone.
|
||||||
|
*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Design Science, Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MathJax.InputJax.AsciiMath = MathJax.InputJax({
|
||||||
|
id: "AsciiMath",
|
||||||
|
version: "2.0",
|
||||||
|
directory: MathJax.InputJax.directory + "/AsciiMath",
|
||||||
|
extensionDir: MathJax.InputJax.extensionDir + "/AsciiMath",
|
||||||
|
|
||||||
|
config: {
|
||||||
|
displaystyle: true, // put limits above and below operators
|
||||||
|
decimal: "." // can change to "," but watch out for "(1,2)"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
MathJax.InputJax.AsciiMath.Register("math/asciimath");
|
||||||
|
|
||||||
|
MathJax.InputJax.AsciiMath.loadComplete("config.js");
|
1309
resources/viewer/mathjax/jax/input/AsciiMath/jax.js
Normal file
1309
resources/viewer/mathjax/jax/input/AsciiMath/jax.js
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user