Initial code commit
This commit is contained in:
parent
b5e9d2a858
commit
61227c428e
|
@ -0,0 +1,3 @@
|
|||
The package is a container for the [madIS](https://code.google.com/p/madis/) Python-based system developed by [NKUA](http://en.uoa.gr/).
|
||||
|
||||
It requires the `apsw` Python package to be installed in the operating system.
|
|
@ -0,0 +1,40 @@
|
|||
\.orig$
|
||||
\.orig\..*$
|
||||
\.chg\..*$
|
||||
\.rej$
|
||||
\.conflict\~$
|
||||
^src/tests/(?!readme.txt$).*$
|
||||
^nbproject/.*$
|
||||
^.idea/.*$
|
||||
^src/docs/build/_static/.*$
|
||||
^/src/docs/build/_static/.*$
|
||||
^src/docs/build/_sources/.*$
|
||||
^/src/docs/build/_sources/.*$
|
||||
^src/docs/html/(?!readme.txt$).*$
|
||||
^/src/docs/html/(?!readme.txt$).*$
|
||||
^src/libexternal/(?!__init__.py$).*$
|
||||
^src/functionslocal/row/(?!__init__.py$).*$
|
||||
^/src/functionslocal/row/(?!__init__.py$).*$
|
||||
^src/functionslocal/aggregate/(?!__init__.py$).*$
|
||||
^/src/functionslocal/aggregate/(?!__init__.py$).*$
|
||||
^src/functionslocal/vtable/(?!__init__.py$).*$
|
||||
^/src/functionslocal/vtable/(?!__init__.py$).*$
|
||||
^src/docs/build/.*$
|
||||
^/src/docs/build/.*$
|
||||
^src/docs/source/row\.txt$
|
||||
^/src/docs/source/row\.txt$
|
||||
^src/docs/source/aggregate\.txt$
|
||||
^/src/docs/source/aggregate\.txt$
|
||||
^src/docs/source/vtable\.txt$
|
||||
^/src/docs/source/vtable\.txt$
|
||||
|
||||
# use glob syntax.
|
||||
syntax: glob
|
||||
*.pyc
|
||||
*.db3
|
||||
mterm_tel
|
||||
project.properties
|
||||
project.xml
|
||||
private.xml
|
||||
private.properties
|
||||
src/docs/html/_sources/row.txt
|
|
@ -0,0 +1,32 @@
|
|||
Copyright and License
|
||||
=====================
|
||||
|
||||
Copyright (C) 2009-2013 Lefteris Stamatogiannakis, Mei Li Triantafyllidi,
|
||||
Ioannis Foufoulas, Maria Vayanou, Marialena Kyriakidi.
|
||||
|
||||
The external libraries used throughout the madIS project are copyright
|
||||
of their respective authors.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
* The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
* Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
* This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
|
||||
Alternatively you may strike the license above and use it under any
|
||||
OSI approved open source license such as those listed at
|
||||
http://opensource.org/licenses/alphabetical
|
|
@ -0,0 +1,257 @@
|
|||
Asia AF
|
||||
Europe AL
|
||||
Africa AG
|
||||
Oceania AQ
|
||||
Europe AN
|
||||
Africa AO
|
||||
Americas AV
|
||||
Americas AC
|
||||
Americas AR
|
||||
Asia AM
|
||||
Americas AA
|
||||
Oceania AS
|
||||
Europe AU
|
||||
Asia AJ
|
||||
Americas BF
|
||||
Asia BA
|
||||
Asia BG
|
||||
Americas BB
|
||||
Europe BO
|
||||
Europe BE
|
||||
Americas BH
|
||||
Africa BN
|
||||
Americas BD
|
||||
Asia BT
|
||||
Americas BL
|
||||
Europe BK
|
||||
Africa BC
|
||||
Americas BR
|
||||
Americas VI
|
||||
Asia BX
|
||||
Europe BU
|
||||
Africa UV
|
||||
Africa BY
|
||||
Asia CB
|
||||
Africa CM
|
||||
Americas CA
|
||||
Africa CV
|
||||
Americas CJ
|
||||
Africa CT
|
||||
Africa CD
|
||||
Americas CI
|
||||
Asia CH
|
||||
Asia KT
|
||||
Asia CK
|
||||
Americas CO
|
||||
Africa CN
|
||||
Africa CF
|
||||
Oceania CW
|
||||
Americas CS
|
||||
Africa IV
|
||||
Europe HR
|
||||
Americas CU
|
||||
Asia CY
|
||||
Europe EZ
|
||||
Europe DA
|
||||
Africa DJ
|
||||
Americas DO
|
||||
Americas DR
|
||||
Americas EC
|
||||
Africa EG
|
||||
Americas ES
|
||||
Africa EK
|
||||
Africa ER
|
||||
Europe EN
|
||||
Africa ET
|
||||
Americas FA
|
||||
Europe FO
|
||||
Oceania FJ
|
||||
Europe FI
|
||||
Europe FR
|
||||
Americas FG
|
||||
Oceania FP
|
||||
Africa GB
|
||||
Africa GA
|
||||
Asia GG
|
||||
Europe GM
|
||||
Africa GH
|
||||
Europe GI
|
||||
Europe GR
|
||||
Americas GL
|
||||
Americas GJ
|
||||
Americas GP
|
||||
Oceania GQ
|
||||
Americas GT
|
||||
Africa GV
|
||||
Africa PU
|
||||
Americas GY
|
||||
Americas HA
|
||||
Europe VT
|
||||
Americas HO
|
||||
Europe HU
|
||||
Europe IC
|
||||
Asia IN
|
||||
Asia ID
|
||||
Asia IR
|
||||
Asia IZ
|
||||
Europe EI
|
||||
Asia IS
|
||||
Europe IT
|
||||
Americas JM
|
||||
Asia JA
|
||||
Asia JO
|
||||
Asia KZ
|
||||
Africa KE
|
||||
Oceania KR
|
||||
Asia KN
|
||||
Asia KS
|
||||
Asia KU
|
||||
Asia KG
|
||||
Asia LA
|
||||
Europe LG
|
||||
Asia LE
|
||||
Africa LT
|
||||
Africa LI
|
||||
Africa LY
|
||||
Europe LS
|
||||
Europe LH
|
||||
Europe LU
|
||||
Europe MK
|
||||
Africa MA
|
||||
Africa MI
|
||||
Asia MY
|
||||
Asia MV
|
||||
Africa ML
|
||||
Europe MT
|
||||
Oceania RM
|
||||
Americas MB
|
||||
Africa MR
|
||||
Africa MP
|
||||
Africa MF
|
||||
Americas MX
|
||||
Oceania
|
||||
Europe MD
|
||||
Europe MN
|
||||
Asia MG
|
||||
Americas MH
|
||||
Africa MO
|
||||
Africa MZ
|
||||
Asia BM
|
||||
Africa WA
|
||||
Oceania NR
|
||||
Asia NP
|
||||
Europe NL
|
||||
Americas NT
|
||||
Oceania NC
|
||||
Oceania NZ
|
||||
Americas NU
|
||||
Africa NG
|
||||
Africa NI
|
||||
Oceania NE
|
||||
Oceania NF
|
||||
Oceania CQ
|
||||
Europe NO
|
||||
Asia MU
|
||||
Asia PK
|
||||
Oceania PS
|
||||
Americas PM
|
||||
Oceania PP
|
||||
Americas PA
|
||||
Americas PE
|
||||
Asia RP
|
||||
Oceania PC
|
||||
Europe PL
|
||||
Europe PO
|
||||
Americas RQ
|
||||
Asia QA
|
||||
Africa RE
|
||||
Europe RO
|
||||
Asia RS
|
||||
Africa RW
|
||||
Americas SC
|
||||
Americas ST
|
||||
Americas SB
|
||||
Americas VC
|
||||
Europe SM
|
||||
Africa TP
|
||||
Asia SA
|
||||
Africa SG
|
||||
Europe SR
|
||||
Africa SE
|
||||
Africa SL
|
||||
Asia SN
|
||||
Europe LO
|
||||
Europe SI
|
||||
Oceania BP
|
||||
Africa SO
|
||||
Africa SF
|
||||
Europe SP
|
||||
Asia CE
|
||||
Africa SU
|
||||
Americas NS
|
||||
Europe SV
|
||||
Africa WZ
|
||||
Europe SW
|
||||
Europe SZ
|
||||
Asia SY
|
||||
Asia TW
|
||||
Asia TI
|
||||
Africa TZ
|
||||
Asia TH
|
||||
Africa TO
|
||||
Oceania TL
|
||||
Oceania TN
|
||||
Americas TD
|
||||
Africa TS
|
||||
Asia TU
|
||||
Asia TX
|
||||
Americas TK
|
||||
Oceania TV
|
||||
Africa UG
|
||||
Europe UP
|
||||
Asia TC
|
||||
Europe UK
|
||||
Americas US
|
||||
Americas UY
|
||||
Asia UZ
|
||||
Oceania NH
|
||||
Americas VE
|
||||
Asia VM
|
||||
Americas VQ
|
||||
Oceania WF
|
||||
Africa WI
|
||||
Oceania WS
|
||||
Asia YM
|
||||
Africa CG
|
||||
Africa ZA
|
||||
Africa ZI
|
||||
Asia HK
|
||||
Asia MC
|
||||
Antarctica AY
|
||||
Atlantic Ocean BV
|
||||
Asia IO
|
||||
Indian Ocean FS
|
||||
Indian Ocean HM
|
||||
Europe MW
|
||||
Atlantic Ocean SH
|
||||
Atlantic Ocean SX
|
||||
Asia AT
|
||||
Americas BQ
|
||||
Oceania CR
|
||||
Europe EE
|
||||
Asia GZ
|
||||
Europe IM
|
||||
Oceania FM
|
||||
Americas FA
|
||||
Europe GK
|
||||
Europe JE
|
||||
Americas IP
|
||||
Europe JN
|
||||
Europe MJ
|
||||
Asia PF
|
||||
Asia PG
|
||||
Europe RB
|
||||
Asia TT
|
||||
Asia WE
|
||||
Oceania WQ
|
||||
Americas UM
|
|
|
@ -0,0 +1,259 @@
|
|||
id name total_area land_area water_area coastline total_border population p_young p_adult p_old p_growth labor_force phone_mobiles phone_mainlines internet_users isps birth_rate death_rate
|
||||
AA Aruba 193.00 193.00 0.00 69 0.00 100018.00 19.70 70.20 10.10 1.52 41500.00 98400 37100 24000 12.83 7.61
|
||||
AC Antigua and Barbuda 442.60 442.60 0.00 153 0.00 69481.00 27.30 69.00 3.70 0.53 30000.00 54000 38000 20000 16 16.62 5.31
|
||||
TC United Arab Emirates 83600.00 83600.00 0.00 1318 867.00 4444011.00 20.60 78.50 0.90 4.00 2968000.00 4535000 1237000 1397000 1 16.09 2.16
|
||||
AF Afghanistan 647500.00 647500.00 0.00 0 5529.00 31889923.00 44.60 53.00 2.40 2.63 15000000.00 1400000 280000 30000 1 46.21 19.96
|
||||
AG Algeria 2381740.00 2381740.00 0.00 998 6343.00 33333216.00 27.20 67.90 4.80 1.22 9310000.00 13661000 2572000 1920000 2 17.11 4.62
|
||||
AJ Azerbaijan 86600.00 86100.00 500.00 0 2013.00 8120247.00 25.40 67.70 7.00 0.69 5191000.00 2242000 1091000 678800 2 17.47 8.35
|
||||
AL Albania 28748.00 27398.00 1350.00 362 720.00 3600523.00 24.10 66.60 9.30 0.53 1090000.00 1259000 255000 75000 10 15.16 5.33
|
||||
AM Armenia 29800.00 28400.00 1400.00 0 1254.00 2971650.00 19.50 69.30 11.20 -0.13 1200000.00 320000 600000 150000 9 12.34 8.29
|
||||
AN Andorra 468.00 468.00 0.00 0 120.30 71822.00 14.50 71.20 14.30 0.84 42420.00 64600 35400 21900 1 8.45 6.45
|
||||
AO Angola 1246700.00 1246700.00 0.00 1600 5198.00 12263596.00 43.70 53.50 2.80 2.18 6393000.00 1094000 94300 172000 1 44.51 24.81
|
||||
AQ American Samoa 199.00 199.00 0.00 116 0.00 57663.00 33.60 63.50 2.90 -0.26 17630.00 2377 15000 1 21.83 3.24
|
||||
AR Argentina 2766890.00 2736690.00 30200.00 4989 9861.00 40301927.00 24.90 64.40 10.70 0.94 15350000.00 22100000 8800000 10000000 33 16.53 7.55
|
||||
AS Australia 7686850.00 7617930.00 68920.00 25760 0.00 20434176.00 19.30 67.40 13.20 0.82 10660000.00 18420000 11460000 14664000 571 12.02 7.56
|
||||
AT Ashmore and Cartier Islands 5.00 5.00 0.00 74 0.00 0.00
|
||||
AU Austria 83870.00 82444.00 1426.00 0 2562.00 8199783.00 15.10 67.50 17.50 0.08 3880000.00 8160000 3705000 4650000 37 8.69 9.84
|
||||
AV Anguilla 102.00 102.00 0.00 61 0.00 13677.00 22.30 70.80 6.90 1.38 6049.00 1800 6200 3000 16 13.97 5.34
|
||||
AX Akrotiri 123.00 56 47.40 0.00
|
||||
AY Antarctica 14000000.00 14000000.00 17968 0.00 0.00 0
|
||||
BA Bahrain 665.00 665.00 0.00 161 0.00 708573.00 26.90 69.50 3.70 1.39 352000.00 748700 196500 152700 1 17.53 4.21
|
||||
BB Barbados 431.00 431.00 0.00 97 0.00 280946.00 19.70 71.40 8.90 0.37 128500.00 206200 134900 160000 19 12.61 8.61
|
||||
BC Botswana 600370.00 585370.00 15000.00 0 4013.00 1815508.00 35.80 60.30 3.90 1.50 288400.00 823100 132000 60000 11 23.17 13.63
|
||||
BD Bermuda 53.30 53.30 0.00 103 0.00 66163.00 18.30 69.20 12.50 0.58 38360.00 49000 56000 39000 20 11.26 7.84
|
||||
BE Belgium 30528.00 30278.00 250.00 67 1385.00 10392226.00 16.50 66.10 17.40 0.12 4890000.00 9460000 4801000 5100000 61 10.29 10.32
|
||||
BF The Bahamas 13940.00 10070.00 3870.00 3542 0.00 305655.00 27.00 66.50 6.50 0.60 176300.00 186000 139900 93000 19 17.30 9.13
|
||||
BG Bangladesh 144000.00 133910.00 10090.00 580 4246.00 150448339.00 33.10 63.40 3.50 2.06 68000000.00 9000000 1070000 300000 10 29.36 8.13
|
||||
BH Belize 22966.00 22806.00 160.00 386 516.00 294385.00 38.90 57.50 3.50 2.26 113000.00 93100 33300 35000 2 28.34 5.76
|
||||
BK Bosnia and Herzegovina 51129.00 51129.00 0.00 20 1459.00 4552198.00 15.00 70.40 14.60 1.00 1026000.00 1594000 968900 806400 3 8.80 8.42
|
||||
BL Bolivia 1098580.00 1084390.00 14190.00 0 6940.00 9119152.00 34.30 61.10 4.60 1.42 4300000.00 2421000 646300 480000 9 22.82 7.44
|
||||
BM Burma 678500.00 657740.00 20760.00 1930 5876.00 47373958.00 26.10 68.60 5.30 0.82 28490000.00 183400 476200 78000 1 17.48 9.33
|
||||
BN Benin 112620.00 110620.00 2000.00 121 1989.00 8078314.00 43.90 53.70 2.40 2.67 3211000.00 386700 76300 425000 4 38.10 11.94
|
||||
BO Belarus 207600.00 207600.00 0.00 0 2900.00 9724723.00 14.70 70.40 14.90 -0.41 4300000.00 4098000 3284300 3394000 23 9.50 13.98
|
||||
BP Solomon Islands 28450.00 27540.00 910.00 5313 0.00 566842.00 40.70 55.90 3.30 2.54 249200.00 6000 7400 8400 1 29.27 3.87
|
||||
BQ Navassa Island 5.40 5.40 0.00 8 0.00 0.00
|
||||
BR Brazil 8511965.00 8456510.00 55455.00 7491 16885.00 190010647.00 25.30 68.40 6.30 1.01 96340000.00 86210000 42382000 25900000 50 16.30 6.19
|
||||
BT Bhutan 47000.00 47000.00 0.00 0 1075.00 2327849.00 38.60 57.40 4.00 2.08 37800 32700 25000 33.28 12.46
|
||||
BU Bulgaria 110910.00 110550.00 360.00 354 1808.00 7322858.00 13.90 68.70 17.40 -0.84 3510000.00 6245000 2483000 2200000 200 9.62 14.28
|
||||
BV Bouvet Island 49.00 49.00 0.00 30 0.00 0.00
|
||||
BX Brunei 5770.00 5270.00 500.00 161 381.00 374577.00 27.80 69.00 3.20 1.81 180400.00 205900 90000 56000 2 18.56 3.26
|
||||
BY Burundi 27830.00 25650.00 2180.00 0 974.00 8390505.00 46.30 51.20 2.60 3.59 2990000.00 153000 27700 25000 1 41.97 13.17
|
||||
CA Canada 9984670.00 9093507.00 891163.00 202080 8893.00 33390141.00 17.30 69.20 13.50 0.87 17590000.00 16600000 18276000 21900000 760 10.75 7.86
|
||||
CB Cambodia 181040.00 176520.00 4520.00 443 2572.00 13995904.00 34.00 62.40 3.60 1.73 7000000.00 1062000 36400 41000 2 25.53 8.24
|
||||
CD Chad 1284000.00 1259200.00 24800.00 0 5968.00 9885661.00 47.30 49.80 2.90 2.32 2719000.00 210000 13000 35000 1 42.35 16.69
|
||||
CE Sri Lanka 65610.00 64740.00 870.00 1340 0.00 20926315.00 24.30 67.90 7.80 0.98 7500000.00 4284000 1510000 280000 5 17.00 6.01
|
||||
CF Republic of the Congo 342000.00 341500.00 500.00 169 5504.00 3800610.00 46.30 50.80 2.90 2.64 490000 13800 36000 1 42.16 12.59
|
||||
CG Democratic Republic of the Congo 2345410.00 2267600.00 77810.00 37 10730.00 65751512.00 47.60 49.90 2.60 3.39 15000000.00 2746000 10600 140600 1 42.96 10.34
|
||||
CH China 9596960.00 9326410.00 270550.00 14500 22117.00 1321851888.00 20.40 71.70 7.90 0.61 798000000.00 437480000 350433000 123000000 3 13.45 7.00
|
||||
CI Chile 756950.00 748800.00 8150.00 6435 6339.00 16284741.00 24.10 67.40 8.50 0.92 6940000.00 10570000 3436000 6700000 7 15.03 5.87
|
||||
CJ Cayman Islands 262.00 262.00 0.00 160 0.00 46600.00 20.30 71.00 8.60 2.50 23450.00 17000 38000 9909 16 12.60 4.98
|
||||
CK Cocos Islands 14.00 14.00 0.00 26 0.00 596.00 0.00 287 2
|
||||
CM Cameroon 475440.00 469440.00 6000.00 402 4591.00 18060382.00 41.30 55.50 3.20 2.24 6394000.00 2259000 99400 167000 1 35.07 12.66
|
||||
CN Comoros 2170.00 2170.00 0.00 340 0.00 711417.00 42.60 54.40 3.00 2.84 144500.00 16100 16900 20000 1 36.35 7.95
|
||||
CO Colombia 1138910.00 1038700.00 100210.00 3208 6309.00 44379598.00 29.80 64.80 5.40 1.43 20810000.00 21850000 7678800 4739000 18 20.16 5.54
|
||||
CQ Northern Mariana Islands 477.00 477.00 0.00 1482 0.00 84546.00 18.90 79.50 1.60 2.46 44470.00 20500 21000 10000 1 19.27 2.29
|
||||
CR Coral Sea Islands 0.00 3095 0.00 0.00
|
||||
CS Costa Rica 51100.00 50660.00 440.00 1290 639.00 4133884.00 27.80 66.40 5.80 1.41 1866000.00 1101000 1388000 1000000 3 18.02 4.39
|
||||
CT Central African Republic 622984.00 622984.00 0.00 0 5203.00 4369038.00 41.60 54.20 4.10 1.51 60000 10000 9000 1 33.52 18.46
|
||||
CU Cuba 110860.00 110860.00 0.00 3735 29.00 11394043.00 18.80 70.50 10.70 0.27 4820000.00 134500 849900 190000 5 11.44 7.14
|
||||
CV Cape Verde 4033.00 4033.00 0.00 965 0.00 423613.00 36.90 56.40 6.70 0.61 120600.00 81700 71400 25000 1 24.40 6.50
|
||||
CW Cook Islands 236.70 236.70 0.00 120 0.00 21750.00 34.10 59.50 6.40 -1.20 6820.00 1500 6200 3600 3 21.00
|
||||
CY Cyprus 9250.00 9240.00 10.00 648 0.00 788457.00 19.90 68.30 11.80 0.53 298000 6 12.56 7.72
|
||||
DA Denmark 43094.00 42394.00 700.00 7314 68.00 5468120.00 18.60 66.00 15.40 0.31 2910000.00 5469000 3350000 3763000 13 10.91 10.30
|
||||
DJ Djibouti 23000.00 22980.00 20.00 314 516.00 496374.00 43.40 53.20 3.40 1.98 282000.00 34500 11100 9000 1 39.07 19.23
|
||||
DO Dominica 754.00 754.00 0.00 148 0.00 72386.00 25.60 64.20 10.20 0.18 25000.00 41800 21000 20500 16 15.75 8.44
|
||||
DR Dominican Republic 48730.00 48380.00 350.00 1288 360.00 9365818.00 32.10 62.20 5.70 1.50 3896000.00 3623000 894500 938300 24 22.91 5.32
|
||||
DX Dhekelia 130.80 28 360.00
|
||||
EC Ecuador 283560.00 276840.00 6720.00 2237 2010.00 13755680.00 32.60 62.30 5.10 1.55 4570000.00 6246000 1701000 616000 31 21.91 4.21
|
||||
EE European Union 4324782.00 65993 12440.80 490426060.00 15.72 67.16 17.11 0.16 222700000.00 466000000 238000000 247000000 10.00 10.00
|
||||
EG Egypt 1001450.00 995450.00 6000.00 2450 2665.00 80335036.00 32.20 63.20 4.60 1.72 21800000.00 14045000 10396000 5000000 50 22.53 5.11
|
||||
EI Ireland 70280.00 68890.00 1390.00 1448 360.00 4109086.00 20.80 67.50 11.70 1.14 2120000.00 4210000 2033000 2060000 22 14.40 7.79
|
||||
EK Equatorial Guinea 28051.00 28051.00 0.00 296 539.00 551201.00 41.50 54.80 3.80 2.02 96900 10000 5000 1 35.16 15.01
|
||||
EN Estonia 45226.00 43211.00 2015.00 3794 633.00 1315912.00 15.00 67.50 17.50 -0.64 673000.00 1445000 442000 690000 38 10.17 13.30
|
||||
ER Eritrea 121320.00 121320.00 0.00 2234 1626.00 4906585.00 43.50 52.90 3.60 2.46 58000 37700 70000 5 33.97 9.36
|
||||
ES El Salvador 21040.00 20720.00 320.00 307 545.00 6948073.00 36.10 58.70 5.20 1.70 2856000.00 2412000 971500 637100 4 26.13 5.60
|
||||
ET Ethiopia 1127127.00 1119683.00 7444.00 0 5328.00 76511887.00 43.40 53.80 2.70 2.27 27270000.00 410600 610300 113000 1 37.39 14.67
|
||||
EZ Czech Republic 78866.00 77276.00 1590.00 0 2290.20 10228744.00 14.10 71.20 14.70 -0.07 5310000.00 11776000 3217300 5100000 8.96 10.64
|
||||
FI Finland 338145.00 304473.00 33672.00 1250 2681.00 5238460.00 16.90 66.70 16.40 0.13 2620000.00 5231000 2120000 3286000 3 10.42 9.93
|
||||
FJ Fiji 18270.00 18270.00 0.00 1129 0.00 918675.00 30.90 64.70 4.40 1.39 137000.00 142200 102000 61000 2 22.37 5.66
|
||||
FA Falkland Islands 12173.00 12173.00 0.00 1288 0.00 3105.00 2.44 1724.00 0 2400 1900 2
|
||||
FM Federated States of Micronesia 702.00 702.00 0.00 6112 0.00 107862.00 35.90 61.20 2.90 -0.15 37410.00 14100 12400 14000 1 24.14 4.66
|
||||
FO Faroe Islands 1399.00 1399.00 0.00 1117 0.00 47511.00 20.60 65.30 14.10 0.54 24250.00 42500 23800 33000 2 14.12 8.69
|
||||
FP French Polynesia 4167.00 3660.00 507.00 2525 0.00 278963.00 25.40 68.20 6.30 1.46 65930.00 87000 53400 55000 2 16.41 4.61
|
||||
FR France 643427.00 640053.00 3374.00 4668 0.00 18.60 65.20 16.20 0.59 27880000.00 49370000 38433000 29945000 62 12.91 8.55
|
||||
FS French Southern and Antarctic Lands 28 0.00 0.00
|
||||
GA The Gambia 11300.00 10000.00 1300.00 80 740.00 1688359.00 44.10 53.20 2.80 2.78 400000.00 247500 44000 49000 2 38.86 11.99
|
||||
GB Gabon 267667.00 257667.00 10000.00 885 2551.00 1454867.00 42.10 53.90 4.00 2.04 581000.00 649800 39100 67000 1 35.96 12.45
|
||||
GG Georgia 69700.00 69700.00 0.00 310 1461.00 4646003.00 16.70 66.60 16.70 -0.33 2040000.00 1459000 683200 175600 6 10.54 9.37
|
||||
GH Ghana 239460.00 230940.00 8520.00 539 2094.00 22931299.00 38.20 58.20 3.60 1.97 10870000.00 2842000 321500 401300 12 29.85 9.55
|
||||
GI Gibraltar 6.50 6.50 0.00 12 1.20 27967.00 17.20 66.30 16.50 0.13 12690.00 9797 24512 6200 2 10.69 9.40
|
||||
GJ Grenada 344.00 344.00 0.00 121 0.00 89971.00 32.80 64.10 3.10 0.34 42300.00 43300 32700 19000 14 21.87 6.61
|
||||
GK Guernsey 78.00 78.00 0.00 50 0.00 65573.00 14.80 67.40 17.80 0.24 31470.00 43800 55100 36000 8.65 10.07
|
||||
GL Greenland 2166086.00 2166086.00 44087 0.00 56344.00 24.00 69.10 6.90 -0.03 32120.00 32200 25300 38000 1 16.01 7.93
|
||||
GM Germany 357021.00 349223.00 7798.00 2389 3621.00 82400996.00 13.90 66.30 19.80 -0.03 43660000.00 79200000 55046000 50616000 200 8.20 10.71
|
||||
GQ Guam 541.30 541.30 0.00 126 0.00 173456.00 28.60 64.50 6.90 1.40 62050.00 98000 84134 79000 20 18.56 4.56
|
||||
GR Greece 131940.00 130800.00 1140.00 13676 1228.00 10706290.00 14.30 66.70 19.00 0.16 4880000.00 10043000 6303000 3800000 27 9.62 10.33
|
||||
GT Guatemala 108890.00 108430.00 460.00 400 1687.00 12728111.00 40.80 55.50 3.60 2.15 5020000.00 3168000 1132000 756000 5 29.09 5.27
|
||||
GV Guinea 245857.00 245857.00 0.00 320 3399.00 9947814.00 44.30 52.50 3.20 2.62 3700000.00 189000 26200 46000 4 41.53 15.33
|
||||
GY Guyana 214970.00 196850.00 18120.00 459 2949.00 769095.00 26.10 68.60 5.30 0.23 418000.00 281400 110100 160000 3 18.09 8.28
|
||||
GZ Gaza Strip 360.00 360.00 0.00 40 62.00 1482405.00 47.60 49.90 2.50 3.66 259000.00 1095000 349000 243000 3 38.90 3.74
|
||||
HA Haiti 27750.00 27560.00 190.00 1771 360.00 8706497.00 42.10 54.40 3.50 2.45 3600000.00 400000 140000 500000 3 35.87 10.40
|
||||
HK Hong Kong 1092.00 1042.00 50.00 733 30.00 6980412.00 13.00 74.00 12.90 0.56 3630000.00 8693000 3795000 4879000 17 7.34 6.45
|
||||
HM Heard Island and McDonald Islands 412.00 412.00 0.00 102 0.00 0.00
|
||||
HO Honduras 112090.00 111890.00 200.00 820 1520.00 7483763.00 39.30 57.20 3.50 2.09 2589000.00 1282000 494400 223000 8 27.59 5.32
|
||||
HR Croatia 56542.00 56414.00 128.00 5835 2197.00 4493312.00 16.00 67.10 16.90 -0.04 1720000.00 2984000 1890000 1451000 9 9.63 11.57
|
||||
HU Hungary 93030.00 92340.00 690.00 0 2171.00 9956108.00 15.30 69.30 15.40 -0.25 4200000.00 9320000 3356000 3050000 16 9.66 13.05
|
||||
IC Iceland 103000.00 100250.00 2750.00 4970 0.00 301931.00 21.40 66.80 11.80 0.82 173000.00 304000 193900 258000 20 13.57 6.77
|
||||
ID Indonesia 1919440.00 1826440.00 93000.00 54716 2830.00 234693997.00 28.70 65.60 5.70 1.21 108200000.00 46910000 12772000 16000000 24 19.65 6.25
|
||||
IM Isle of Man 572.00 572.00 0.00 160 0.00 75831.00 17.10 65.80 17.10 0.51 39690.00 51000 10.96 11.10
|
||||
IN India 3287590.00 2973190.00 314400.00 7000 14103.00 1129866154.00 31.80 63.10 5.10 1.61 509300000.00 69193000 49750000 60000000 43 22.69 6.58
|
||||
IO British Indian Ocean Territory 54400.00 60.00 54340.00 698 0.00 0.00 1
|
||||
IP Clipperton Island 6.00 6.00 0.00 11 0.00 0.00
|
||||
IR Iran 1648000.00 1636000.00 12000.00 2440 5440.00 65397521.00 23.20 71.40 5.40 0.66 24360000.00 8500000 18986000 7500000 100 16.57 5.65
|
||||
IS Israel 20770.00 20330.00 440.00 273 1017.00 6426679.00 26.10 64.20 9.80 1.15 2600000.00 7757000 2936000 3700000 21 17.71 6.17
|
||||
IT Italy 301230.00 294020.00 7210.00 7600 1932.20 58147733.00 13.80 66.40 19.90 0.01 24630000.00 72200000 25049000 28870000 93 8.54 10.50
|
||||
IV Cote d'Ivoire 322460.00 318000.00 4460.00 515 3110.00 18013409.00 40.60 56.60 2.80 2.00 6738000.00 2190000 257900 160000 5 34.69 14.74
|
||||
IZ Iraq 437072.00 432162.00 4910.00 58 3650.00 27499638.00 39.40 57.60 3.00 2.62 7400000.00 8700000 1547000 36000 1 31.44 5.26
|
||||
JA Japan 377835.00 374744.00 3091.00 29751 0.00 127433494.00 13.80 65.20 21.00 -0.09 66440000.00 94745000 58780000 86300000 73 8.10 8.98
|
||||
JE Jersey 116.00 116.00 0.00 70 0.00 91321.00 16.90 67.30 15.80 0.24 53560.00 83900 73900 27000 9.02 9.32
|
||||
JM Jamaica 10991.00 10831.00 160.00 1022 0.00 2780132.00 32.50 60.10 7.40 0.78 1100000.00 2700000 342000 1067000 21 20.44 6.59
|
||||
JN Jan Mayen 377.00 377.00 0.00 124 0.00 0.00 13
|
||||
JO Jordan 92300.00 91971.00 329.00 26 1635.00 6053193.00 33.00 63.00 4.00 2.41 1512000.00 3013000 628200 629500 5 20.69 2.68
|
||||
KE Kenya 582650.00 569250.00 13400.00 536 3477.00 36913721.00 42.10 55.20 2.60 2.80 1955000.00 6500000 281800 1055000 65 38.94 10.95
|
||||
KG Kyrgyzstan 198500.00 191300.00 7200.00 0 3878.00 5284149.00 30.30 63.50 6.20 1.35 2700000.00 541700 438200 280000 23.08 7.02
|
||||
KN North Korea 120540.00 120410.00 130.00 2495 1673.00 23301725.00 23.30 68.10 8.50 0.79 9600000.00 980000 1 15.06 7.21
|
||||
KR Kiribati 811.00 811.00 0.00 1143 0.00 107817.00 38.20 58.40 3.40 2.24 7870.00 600 4500 2000 1 30.48 8.12
|
||||
KS South Korea 98480.00 98190.00 290.00 2413 238.00 49044790.00 18.30 72.10 9.60 0.39 23770000.00 38342000 23745000 33900000 11 9.93 5.99
|
||||
KT Christmas Island 135.00 135.00 0.00 139 0.00 1402.00 0.00 464 2
|
||||
KU Kuwait 17820.00 17820.00 0.00 499 462.00 2505559.00 26.70 70.50 2.80 3.56 1136000.00 2536000 510300 700000 3 21.95 2.39
|
||||
KZ Kazakhstan 2717300.00 2669800.00 47500.00 0 12012.00 15284929.00 22.50 69.20 8.30 0.35 7834000.00 4955000 2500000 400000 10 16.23 9.40
|
||||
LA Laos 236800.00 230800.00 6000.00 0 5083.00 6521998.00 41.20 55.70 3.10 2.37 2100000.00 520546 90067 25000 1 34.98 11.28
|
||||
LE Lebanon 10400.00 10230.00 170.00 225 454.00 3925502.00 26.20 66.70 7.10 1.20 1500000.00 1178000 990000 700000 22 18.08 6.10
|
||||
LG Latvia 64589.00 63589.00 1000.00 531 1368.00 2259810.00 13.60 69.60 16.70 -0.65 1136000.00 1872000 731000 1030000 41 9.43 13.64
|
||||
LH Lithuania 65200.00 90 1613.00 3575439.00 14.90 69.30 15.80 -0.29 1617000.00 4353000 801100 1222000 32 8.87 11.05
|
||||
LI Liberia 111370.00 96320.00 15050.00 579 1585.00 3195931.00 43.60 53.60 2.70 4.84 160000 6900 1000 2 43.75 22.24
|
||||
LO Slovakia 48845.00 48800.00 45.00 0 1524.00 5447502.00 16.40 71.50 12.20 0.15 2629000.00 4540000 1197000 2500000 6 10.65 9.48
|
||||
LS Liechtenstein 160.00 160.00 0.00 0 76.00 34247.00 17.10 70.00 12.80 0.75 29500.00 11400 19900 20000 44 10.02 7.30
|
||||
LT Lesotho 30355.00 30355.00 0.00 0 909.00 2125262.00 35.70 59.30 5.00 0.14 838000.00 245100 48000 43000 1 24.72 22.49
|
||||
LU Luxembourg 2586.00 2586.00 0.00 0 359.00 480222.00 18.80 66.60 14.70 1.21 203000.00 720000 244500 315000 8 11.84 8.42
|
||||
LY Libya 1759540.00 1759540.00 0.00 1770 4348.00 6036914.00 33.40 62.40 4.20 2.26 1787000.00 234800 750000 205000 1 26.09 3.47
|
||||
MA Madagascar 587040.00 581540.00 5500.00 4828 0.00 19448815.00 43.90 53.00 3.10 3.01 7300000.00 504700 66900 90000 2 38.60 8.51
|
||||
MC Macau 28.20 28.20 0.00 41 0.34 456989.00 15.40 76.60 8.00 0.84 248000.00 532800 174400 201000 1 8.57 4.59
|
||||
MD Moldova 33843.00 33371.00 472.00 0 1389.00 4320490.00 16.50 72.60 10.90 -0.11 1339000.00 1090000 929400 406000 2 10.88 10.85
|
||||
MF Mayotte 374.00 374.00 0.00 185 0.00 208783.00 45.80 52.50 1.80 3.62 44560.00 48100 10000 40.35 7.53
|
||||
MG Mongolia 1564116.00 0 8220.00 2951786.00 28.70 67.40 3.90 1.49 1577000.00 557200 156000 268300 5 21.07 6.21
|
||||
MH Montserrat 102.00 102.00 0.00 40 0.00 9538.00 23.50 65.70 10.80 1.05 4521.00 70 17 17.51 7.02
|
||||
MI Malawi 118480.00 94080.00 24400.00 0 2881.00 13603181.00 46.10 51.20 2.70 2.38 4500000.00 429300 102700 52500 3 42.09 18.25
|
||||
MJ Montenegro 14026.00 13812.00 214.00 294 625.00 684736.00 -1.00 259100.00 543220 177663 50000 11.18 8.39
|
||||
MK Macedonia 25333.00 24856.00 477.00 0 766.00 2055915.00 19.80 69.10 11.10 0.26 899000.00 1261000 533200 392671 6 12.02 8.78
|
||||
ML Mali 1240000.00 1220000.00 20000.00 0 7243.00 11995402.00 48.20 48.80 3.10 2.68 3930000.00 869600 75000 60000 13 49.61 16.51
|
||||
MN Monaco 1.95 1.95 0.00 4 4.40 32671.00 15.00 62.30 22.70 0.39 44000.00 19300 33700 16000 2 9.12 12.92
|
||||
MO Morocco 446550.00 446300.00 250.00 1835 2017.90 33757175.00 31.00 63.90 5.10 1.53 11250000.00 12393000 1341000 4600000 8 21.64 5.54
|
||||
MP Mauritius 2040.00 2030.00 10.00 177 0.00 1250882.00 23.50 69.80 6.70 0.80 555000.00 713300 359000 180000 2 15.26 6.88
|
||||
MR Mauritania 1030700.00 1030400.00 300.00 754 5074.00 3270065.00 45.50 52.40 2.20 2.87 786000.00 745600 41000 14000 5 40.56 11.89
|
||||
MT Malta 316.00 316.00 0.00 197 0.00 401880.00 16.70 69.50 13.80 0.41 164000.00 324000 202100 127200 6 10.28 8.19
|
||||
MU Oman 212460.00 212460.00 0.00 2092 1374.00 3204897.00 42.70 54.60 2.70 3.23 920000.00 1333000 265200 245000 1 35.76 3.78
|
||||
MV Maldives 300.00 300.00 0.00 644 0.00 369031.00 42.90 54.00 3.10 2.73 101300.00 271053 32181 19000 1 34.20 6.88
|
||||
MX Mexico 1972550.00 1923040.00 49510.00 9330 4353.00 108700891.00 30.10 64.00 5.90 1.15 38090000.00 47462000 19512000 18622000 51 20.36 4.76
|
||||
MY Malaysia 329750.00 328550.00 1200.00 4675 2669.00 24821286.00 32.20 62.90 4.80 1.76 10730000.00 19545000 4366000 11016000 7 22.65 5.05
|
||||
MZ Mozambique 801590.00 784090.00 17500.00 2470 4571.00 20905585.00 44.70 52.50 2.80 1.80 9400000.00 1220000 69700 138000 11 38.54 20.51
|
||||
NC New Caledonia 19060.00 18575.00 485.00 2254 0.00 221943.00 27.90 65.30 6.80 1.20 78990.00 134300 55300 76000 1 17.75 5.72
|
||||
NE Niue 260.00 260.00 0.00 64 0.00 1492.00 -0.03 663.00 400 1100 900 1
|
||||
NF Norfolk Island 34.60 34.60 0.00 32 0.00 2114.00 20.20 63.90 15.90 0.01 0 2532 700 2
|
||||
NG Niger 1267000.00 1266700.00 300.00 0 5697.00 12894865.00 46.90 50.60 2.40 2.90 70000.00 299900 24000 24000 1 50.16 20.59
|
||||
NH Vanuatu 12200.00 12200.00 0.00 2528 0.00 211971.00 31.90 64.30 3.80 1.46 76410.00 12700 6800 7500 1 22.35 7.75
|
||||
NI Nigeria 923768.00 910768.00 13000.00 853 4047.00 135031164.00 42.20 54.70 3.10 2.38 48990000.00 21571000 1223000 5000000 11 40.20 16.68
|
||||
NL Netherlands 41526.00 33883.00 7643.00 451 1027.00 16570613.00 17.80 67.80 14.40 0.46 7600000.00 15834000 7600000 10806000 52 10.70 8.69
|
||||
NO Norway 323802.00 307442.00 16360.00 25148 2542.00 4627926.00 19.00 66.10 14.80 0.36 2420000.00 4755000 2129000 3140000 13 11.27 9.37
|
||||
NP Nepal 147181.00 143181.00 4000.00 0 2926.00 28901790.00 38.30 57.90 3.80 2.13 11110000.00 248800 448600 175000 6 30.46 9.14
|
||||
NR Nauru 21.00 21.00 0.00 30 0.00 13528.00 36.40 61.60 2.00 1.78 1500 1900 300 1 24.47 6.65
|
||||
NS Suriname 163270.00 161470.00 1800.00 386 1703.00 470784.00 28.00 65.70 6.20 1.10 156700.00 232800 81100 30000 2 17.31 5.50
|
||||
NT Netherlands Antilles 960.00 960.00 0.00 364 15.00 223652.00 23.60 67.40 9.00 0.78 83600.00 200000 81000 2000 6 14.56 6.39
|
||||
NU Nicaragua 129494.00 120254.00 9240.00 910 1231.00 5675356.00 35.50 61.30 3.20 1.86 2261000.00 1119000 220900 140000 3 24.12 4.42
|
||||
NZ New Zealand 268680.00 268021.00 15134 0.00 4115771.00 20.80 67.30 11.90 0.95 2180000.00 3530000 1800000 3200000 36 13.61 7.54
|
||||
OO Southern Ocean 20327000.00 17968 0.00
|
||||
PA Paraguay 406750.00 397300.00 9450.00 0 3995.00 6669086.00 37.20 57.70 5.10 2.42 2742000.00 1887000 320300 200000 4 28.77 4.54
|
||||
PC Pitcairn Islands 47.00 47.00 0.00 51 0.00 48.00 0.00 15.00 1
|
||||
PE Peru 1285220.00 1280000.00 5220.00 2414 7461.00 28674757.00 30.30 64.20 5.40 1.29 9210000.00 5583000 2250000 4600000 10 20.09 6.21
|
||||
PF Paracel Islands 0.00 518 0.00 0.00
|
||||
PG Spratly Islands 0.00 926 0.00 0.00
|
||||
PK Pakistan 803940.00 778720.00 25220.00 1046 6774.00 164741924.00 36.90 58.80 4.30 1.83 48290000.00 48289136 5162798 10500000 30 27.52 8.00
|
||||
PL Poland 312685.00 304465.00 8220.00 491 3056.00 38518241.00 15.50 71.10 13.30 -0.05 17260000.00 29166000 11803000 10600000 19 9.94 9.94
|
||||
PM Panama 78200.00 75990.00 2210.00 2490 555.00 3242173.00 30.00 63.60 6.40 1.56 1441000.00 1352000 440100 300000 6 21.45 5.44
|
||||
PO Portugal 92391.00 91951.00 440.00 1793 1214.00 10642836.00 16.50 66.30 17.30 0.33 5580000.00 11448000 4234000 7783000 16 10.59 10.56
|
||||
PP Papua New Guinea 462840.00 452860.00 9980.00 5152 820.00 5795887.00 37.60 58.50 3.90 2.16 3477000.00 26000 62000 170000 3 28.76 7.14
|
||||
PS Palau 458.00 458.00 0.00 1519 0.00 20842.00 26.00 69.20 4.70 1.23 9777.00 1000 6700 1 17.70 6.77
|
||||
PU Guinea-Bissau 36120.00 28000.00 8120.00 350 724.00 1472780.00 41.20 55.80 3.00 2.05 480000.00 67000 10600 26000 2 36.81 16.29
|
||||
QA Qatar 11437.00 11437.00 0.00 563 60.00 907229.00 23.10 72.90 4.00 2.39 508000.00 854900 205400 219000 1 15.56 4.82
|
||||
RB Serbia 88361.00 88361.00 0.00 0 2027.00 10150265.00 2961000.00 5229000 2685000 1400000
|
||||
RM Marshall Islands 11854.30 181.30 11673.00 370 0.00 61815.00 38.30 58.90 2.80 2.21 14680.00 1198 5510 2000 1 32.37 4.66
|
||||
RO Romania 237500.00 230340.00 7160.00 225 2508.00 22276056.00 15.60 69.60 14.70 -0.13 9330000.00 13354000 4391000 4940000 38 10.67 11.81
|
||||
RP Philippines 300000.00 298170.00 1830.00 36289 0.00 91077287.00 34.50 61.30 4.10 1.76 35790000.00 32810000 3438000 7820000 33 24.48 5.36
|
||||
RQ Puerto Rico 13790.00 8870.00 4921.00 501 0.00 3944259.00 21.00 65.90 13.10 0.39 1300000.00 2682000 1112000 1000000 76 12.79 7.78
|
||||
RS Russia 17075200.00 16995800.00 79400.00 37653 20096.50 141377752.00 14.60 71.10 14.40 -0.48 73880000.00 120000000 40100000 23700000 300 10.92 16.04
|
||||
RW Rwanda 26338.00 24948.00 1390.00 0 893.00 9907509.00 41.90 55.70 2.50 2.77 4600000.00 290000 23000 38000 2 40.16 14.91
|
||||
SA Saudi Arabia 2149690.00 2149690.00 0.00 2640 4431.00 27601038.00 38.20 59.40 2.40 2.06 7125000.00 13300000 4500000 3200000 22 29.10 2.55
|
||||
SB Saint Pierre and Miquelon 242.00 242.00 0.00 120 0.00 7036.00 23.00 65.90 11.10 0.13 3450.00 4800 1 13.08 6.82
|
||||
SC Saint Kitts and Nevis 261.00 261.00 0.00 135 0.00 39349.00 27.20 64.90 7.90 0.62 18170.00 10000 25000 10000 16 17.89 8.16
|
||||
SE Seychelles 455.00 455.00 0.00 491 0.00 81895.00 25.40 68.50 6.10 0.43 30900.00 57000 21400 20000 1 15.83 6.25
|
||||
SF South Africa 1219912.00 1219912.00 0.00 2798 4862.00 43997828.00 29.10 65.50 5.40 -0.46 16090000.00 33960000 4729000 5100000 150 17.94 22.45
|
||||
SG Senegal 196190.00 192000.00 4190.00 531 2640.00 12521851.00 42.00 55.00 3.00 2.65 4749000.00 1730000 266600 540000 1 37.40 10.96
|
||||
SH Saint Helena 413.00 0.00 60 0.00 7543.00 18.70 71.10 10.20 0.53 2486.00 2200 1000 1 11.93 6.63
|
||||
SI Slovenia 20273.00 20151.00 122.00 47 1382.00 2009245.00 13.70 70.30 16.00 -0.07 1026000.00 1759000 816400 1090000 11 9.00 10.41
|
||||
SL Sierra Leone 71740.00 71620.00 120.00 402 958.00 6144562.00 44.80 52.00 3.20 2.29 1369000.00 113200 24000 10000 1 45.41 22.64
|
||||
SM San Marino 61.20 61.20 0.00 0 39.00 29615.00 16.80 66.10 17.10 1.22 20470.00 16800 20600 14300 2 9.89 8.27
|
||||
SN Singapore 692.70 682.70 10.00 193 0.00 4553009.00 15.20 76.30 8.50 1.28 2400000.00 4385000 1848000 2422000 9 9.17 4.40
|
||||
SO Somalia 637657.00 627337.00 10320.00 3025 2340.00 9118773.00 44.40 53.00 2.60 2.83 3700000.00 500000 100000 90000 3 44.60 16.28
|
||||
SP Spain 504782.00 499542.00 5240.00 4964 1917.80 40448191.00 14.40 67.80 17.80 0.12 21770000.00 41328000 18322000 19205000 56 9.98 9.81
|
||||
0.00 6852.00
|
||||
ST Saint Lucia 616.00 606.00 10.00 158 0.00 170649.00 29.40 65.50 5.10 1.30 43800.00 93000 51100 55000 15 19.28 5.03
|
||||
SU Sudan 2505810.00 2376000.00 129810.00 853 7687.00 39379358.00 41.60 56.00 2.40 2.08 7415000.00 1828000 670000 2800000 2 34.86 14.39
|
||||
SV Svalbard 61020.00 61020.00 0.00 3587 0.00 2214.00 -0.01 13
|
||||
SW Sweden 449964.00 410934.00 39030.00 3218 2233.00 9031088.00 16.40 65.70 17.90 0.16 4590000.00 8436000 6447000 6800000 29 10.20 10.27
|
||||
SX South Georgia and the South Sandwich Islands 3903.00 3903.00 0.00 0.00 0.00
|
||||
SY Syria 185180.00 184050.00 1130.00 193 2253.00 19314747.00 36.50 60.10 3.30 2.24 5505000.00 3128000 2903000 1100000 1 27.19 4.74
|
||||
SZ Switzerland 41290.00 39770.00 1520.00 0 1852.00 7554661.00 16.10 68.20 15.80 0.38 3810000.00 6847000 5123000 5098000 44 9.66 8.51
|
||||
TD Trinidad and Tobago 5128.00 5128.00 0.00 362 0.00 1056608.00 19.50 71.60 8.90 -0.88 618000.00 800000 323500 160000 17 13.07 10.76
|
||||
TH Thailand 514000.00 511770.00 2230.00 3219 4863.00 65068149.00 21.60 70.10 8.20 0.66 36410000.00 27379000 7035000 8420000 15 13.73 7.10
|
||||
TI Tajikistan 143100.00 142700.00 400.00 0 3651.00 7076598.00 35.00 61.20 3.80 1.90 3700000.00 265000 245200 5000 4 27.33 7.05
|
||||
TK Turks and Caicos Islands 430.00 430.00 0.00 389 0.00 21746.00 31.30 64.80 3.90 2.72 4848.00 1700 5700 14 21.48 4.23
|
||||
TL Tokelau 10.00 10.00 0.00 101 0.00 1449.00 42.00 53.00 5.00 -0.02 440.00 0 300 1
|
||||
TN Tonga 748.00 718.00 30.00 419 0.00 116921.00 34.60 61.20 4.20 1.85 33910.00 16400 11200 3000 2 23.67 5.20
|
||||
TO Togo 56785.00 54385.00 2400.00 56 1647.00 5701579.00 42.00 55.30 2.70 2.72 1302000.00 443600 58600 300000 3 36.83 9.65
|
||||
TP Sao Tome and Principe 1001.00 1001.00 0.00 209 0.00 199579.00 47.30 49.00 3.70 3.13 35050.00 12000 7000 20000 1 39.72 6.28
|
||||
TS Tunisia 163610.00 155360.00 8250.00 1148 1424.00 10276158.00 24.00 69.20 6.90 0.99 3502000.00 5681000 1258000 953800 1 15.54 5.17
|
||||
TT East Timor 15007.00 706 228.00 1084971.00 35.70 61.10 3.20 2.06 1000 26.77 6.19
|
||||
TU Turkey 780580.00 770760.00 9820.00 7200 2648.00 71158647.00 24.90 68.10 6.90 1.04 24800000.00 43609000 18978000 16000000 50 16.40 6.00
|
||||
TV Tuvalu 26.00 26.00 0.00 24 0.00 11992.00 29.80 65.20 5.00 1.54 3615.00 0 700 1300 1 22.43 7.00
|
||||
TW Taiwan 35980.00 32260.00 3720.00 1566 0.00 22858872.00 17.80 72.00 10.20 0.30 10460000.00 22170000 13615000 13210000 8 8.97 6.54
|
||||
TX Turkmenistan 488100.00 488100.00 0 3736.00 5097028.00 34.70 60.90 4.40 1.62 2320000.00 52000 495000 36000 1 25.36 6.17
|
||||
TZ Tanzania 945087.00 886037.00 59050.00 1424 3861.00 39384223.00 43.90 53.30 2.80 2.09 19350000.00 1942000 148400 333000 6 35.95 13.36
|
||||
UG Uganda 236040.00 199710.00 36330.00 0 2698.00 30262610.00 50.20 47.60 2.20 3.57 13760000.00 1525000 100800 500000 2 48.12 12.64
|
||||
UK United Kingdom 244820.00 241590.00 3230.00 12429 360.00 60776238.00 17.20 67.00 15.80 0.28 31100000.00 61091000 32943000 37600000 10.67 10.09
|
||||
UM United States Pacific Island Wildlife Refuges 5 360.00 0.00
|
||||
UP Ukraine 603700.00 603700.00 0.00 2782 4663.00 46299862.00 14.00 69.60 16.30 -0.68 22300000.00 17214000 12142000 5278000 260 9.45 16.07
|
||||
US United States 9826630.00 9161923.00 664707.00 19924 12034.00 301139947.00 20.20 67.20 12.60 0.89 151400000.00 219400000 268000000 205327000 7000 14.16 8.26
|
||||
UV Burkina Faso 274200.00 273800.00 400.00 0 3193.00 14326203.00 46.70 50.90 2.50 3.00 5000000.00 572200 97400 64600 1 45.28 15.31
|
||||
UY Uruguay 176220.00 173620.00 2600.00 660 1648.00 3460607.00 23.00 63.80 13.20 0.50 1270000.00 600000 1000000 680000 14 14.41 9.16
|
||||
UZ Uzbekistan 447400.00 425400.00 22000.00 0 6221.00 27780059.00 32.40 62.80 4.80 1.73 14440000.00 1100000 1717000 880000 42 26.46 7.73
|
||||
VC Saint Vincent and the Grenadines 389.00 389.00 0.00 84 0.00 118149.00 25.90 67.60 6.50 0.25 41680.00 70600 22500 8000 15 16.02 5.97
|
||||
VE Venezuela 912050.00 882050.00 30000.00 2800 4993.00 26023528.00 31.60 63.40 5.10 1.49 12500000.00 12496000 3605000 3040000 16 21.22 5.08
|
||||
VI British Virgin Islands 153.00 153.00 0.00 80 0.00 23552.00 20.20 74.50 5.40 1.92 12770.00 8000 11700 4000 16 14.82 4.42
|
||||
VM Vietnam 329560.00 325360.00 4200.00 3444 4639.00 85262356.00 26.30 67.90 5.80 1.00 44580000.00 9593000 15845000 13100000 5 16.63 6.19
|
||||
VQ Virgin Islands 1910.00 346.00 1564.00 188 0.00 108448.00 21.80 66.50 11.70 -0.17 43980.00 64200 70900 30000 50 13.68 6.59
|
||||
VT Holy See 0.44 0.44 0.00 0 3.20 821.00 0.00 5120 93
|
||||
WA Namibia 825418.00 825418.00 0.00 1572 3936.00 2055080.00 37.70 58.60 3.80 0.48 653000.00 495000 127900 75000 2 23.52 19.15
|
||||
WE West Bank 5860.00 5640.00 220.00 0 404.00 2535927.00 42.40 54.20 3.40 2.99 568000.00 1095000 349000 243000 8 30.99 3.85
|
||||
WF Wallis and Futuna 274.00 274.00 0.00 129 0.00 16309.00 3104.00 0 1900 900 1
|
||||
WI Western Sahara 266000.00 266000.00 0.00 1110 2046.00 382617.00 45.40 52.30 2.30 12000.00 0 1
|
||||
WQ Wake Island 6.50 6.50 0.00 19 0.00 0.00
|
||||
WS Samoa 2944.00 2934.00 10.00 403 0.00 214265.00 38.10 56.30 5.60 1.29 90000.00 24000 13300 6000 2 28.28 5.88
|
||||
WZ Swaziland 17363.00 17203.00 160.00 0 535.00 1133066.00 40.30 56.10 3.60 -0.34 300000.00 200000 35000 36000 5 26.98 30.35
|
||||
XO Indian Ocean 68556000.00 66526 535.00
|
||||
XQ Arctic Ocean 14056000.00 45389 535.00
|
||||
YM Yemen 527970.00 527970.00 0.00 1906 1746.00 22230531.00 46.30 51.10 2.60 3.46 5759000.00 2075000 900000 220000 1 42.67 8.05
|
||||
ZA Zambia 752614.00 740724.00 11890.00 0 5664.00 11477447.00 45.70 51.90 2.40 1.66 4903000.00 946600 94700 231000 5 40.78 21.46
|
||||
ZH Atlantic Ocean 76762000.00 111866 5664.00
|
||||
ZI Zimbabwe 390580.00 386670.00 3910.00 0 3066.00 12311143.00 37.20 59.30 3.50 0.60 3958000.00 699000 328000 1000000 6 27.72 21.76
|
||||
ZN Pacific Ocean 155557000.00 135663 3066.00
|
||||
ZZ Iles Eparses 35 3066.00 0.00
|
|
|
@ -0,0 +1,2 @@
|
|||
python generate_function_doc.py
|
||||
sphinx-build -E -b html ./source/ ./html
|
|
@ -0,0 +1,65 @@
|
|||
import sys, os
|
||||
sys.path.append((os.path.join(sys.path[0],'..')))
|
||||
|
||||
import functions
|
||||
from shutil import copyfile
|
||||
|
||||
functions.register()
|
||||
|
||||
curpath = os.path.abspath(sys.path[0])
|
||||
|
||||
def gendoc(funtype, toplevelonly=False):
|
||||
file=open(os.path.join(curpath, 'source', funtype+'.txt'),'w')
|
||||
|
||||
tmpstr=".. _"+(funtype.lower()+' functions list:').replace(' ','-')+'\n\n'
|
||||
tmpstr+=funtype[0].upper()+funtype[1:]+' functions list'
|
||||
file.write(tmpstr+'\n')
|
||||
file.write('='*len(tmpstr)+'\n\n')
|
||||
file.write('.. automodule:: functions.'+funtype+'.__init__\n\n')
|
||||
|
||||
docs={}
|
||||
|
||||
if not toplevelonly:
|
||||
for i,v in functions.functions[funtype].iteritems():
|
||||
if not v.__name__.startswith('functionslocal'):
|
||||
if v.__module__ not in docs:
|
||||
docs[v.__module__]=[]
|
||||
docs[v.__module__].append(i)
|
||||
else:
|
||||
for i,v in functions.functions[funtype].iteritems():
|
||||
if not v.__name__.startswith('functionslocal'):
|
||||
tstr='functions.vtable.'+i
|
||||
if tstr not in docs:
|
||||
docs[tstr]=True
|
||||
|
||||
for i,v in sorted(docs.items()):
|
||||
modulestr='.. module:: functions.'+funtype+'.'+i.split('.')[2]+'\n\n'
|
||||
|
||||
if not toplevelonly:
|
||||
modstr=':mod:`'+i.split('.')[2]+'` functions'
|
||||
else:
|
||||
modstr=':mod:`'+i.split('.')[2]+'` function'
|
||||
file.write(modstr+'\n')
|
||||
file.write('-'*len(modstr)+'\n\n')
|
||||
file.write(modulestr)
|
||||
file.write('')
|
||||
|
||||
if not toplevelonly:
|
||||
for i1 in sorted(v):
|
||||
|
||||
tmpstr='**'+i1+' function**'
|
||||
file.write(tmpstr)
|
||||
if not functions.functions[funtype][i1].__doc__:
|
||||
file.write('\n\n')
|
||||
else:
|
||||
file.write(str(functions.functions[funtype][i1].__doc__)+'\n\n')
|
||||
else:
|
||||
if not functions.functions[funtype][i.split('.')[-1]].__doc__:
|
||||
file.write('\n\n')
|
||||
else:
|
||||
file.write(str(functions.functions[funtype][i.split('.')[-1]].__doc__)+'\n\n')
|
||||
|
||||
copyfile(os.path.join(curpath, '..', 'LICENSE.txt'), os.path.join(curpath, 'source', 'license.txt'))
|
||||
gendoc('row')
|
||||
gendoc('aggregate')
|
||||
gendoc('vtable', True)
|
|
@ -0,0 +1,2 @@
|
|||
This directory contains Madis' html documentation. This directory isn't
|
||||
tracked by mercurial
|
Binary file not shown.
After Width: | Height: | Size: 43 B |
|
@ -0,0 +1,164 @@
|
|||
/**********************************************************************
|
||||
*
|
||||
* Customize the values given below to suit your needs.
|
||||
* You can make additional copies of this file with
|
||||
* different customizated settings if you need to load
|
||||
* jsMath with different parameters.
|
||||
*
|
||||
* Load this page via:
|
||||
*
|
||||
* <SCRIPT SRC="path-to-jsMath/easy/load.js"></SCRIPT>
|
||||
*
|
||||
* (If you are including this file into your page via Server-Side
|
||||
* Includes, you should remove line above.)
|
||||
*
|
||||
* You can make copies of this file with different settings
|
||||
* if you need to have several different configurations.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
|
||||
jsMath.Easy = {
|
||||
//
|
||||
// The URL of the root jsMath directory on your server
|
||||
// (it must be in the same domain as the HTML page).
|
||||
// It should include "http://yoursite.com/", or should
|
||||
// be relative to the root of your server. It is possible
|
||||
// to be a relative URL, but it will be relative to the
|
||||
// HTML page loading this file.
|
||||
//
|
||||
// If you leave this blank, jsMath will try to look it up from
|
||||
// the URL where it loaded this file, but that may not work.
|
||||
//
|
||||
root: "",
|
||||
|
||||
//
|
||||
// The default scaling factor for mathematics compared to the
|
||||
// surrounding text.
|
||||
//
|
||||
scale: 120,
|
||||
|
||||
//
|
||||
// 1 means use the autoload plug-in to decide if jsMath should be loaded
|
||||
// 0 means always load jsMath
|
||||
//
|
||||
autoload: 1,
|
||||
|
||||
//
|
||||
// Setting any of these will cause the tex2math plugin to be used
|
||||
// to add the <DIV> and <SPAN> tags that jsMath needs. See the
|
||||
// documentation for the tex2math plugin for more information.
|
||||
//
|
||||
processSlashParens: 1, // process \(...\) in text?
|
||||
processSlashBrackets: 1, // process \[...\] in text?
|
||||
processDoubleDollars: 1, // process $$...$$ in text?
|
||||
processSingleDollars: 0, // process $...$ in text?
|
||||
processLaTeXenvironments: 0, // process \begin{xxx}...\end{xxx} outside math mode?
|
||||
fixEscapedDollars: 0, // convert \$ to $ outside of math mode?
|
||||
doubleDollarsAreInLine: 0, // make $$...$$ be in-line math?
|
||||
allowDisableTag: 1, // allow ID="tex2math_off" to disable tex2math?
|
||||
//
|
||||
// If you want to use your own custom delimiters for math instead
|
||||
// of the usual ones, then uncomment the following four lines and
|
||||
// insert your own delimiters within the quotes. You may want to
|
||||
// turn off processing of the dollars and other delimiters above
|
||||
// as well, though you can use them in combination with the
|
||||
// custom delimiters if you wish. See the tex2math documentation
|
||||
// for more details.
|
||||
//
|
||||
//customDelimiters: [
|
||||
// '[math]','[/math]', // to begin and end in-line math
|
||||
// '[display]','[/display]' // to begin and end display math
|
||||
//],
|
||||
|
||||
//
|
||||
// Disallow the use of the @(...) mechanism for including raw HTML
|
||||
// in the contents of \hbox{}? (If used in a content-management system
|
||||
// where users are allowed to enter mathematics, setting this to 0
|
||||
// would allow them to enter arbitrary HTML code within their
|
||||
// math formulas, and that poses a security risk.)
|
||||
//
|
||||
safeHBoxes: 1,
|
||||
|
||||
//
|
||||
// Show TeX source when mathematics is double-clicked?
|
||||
//
|
||||
allowDoubleClicks: 1,
|
||||
|
||||
//
|
||||
// Show jsMath font warning messages? (Disabling this prevents yours
|
||||
// users from finding out that they can have a better experience on your
|
||||
// site by installing some fonts, so don't disable this).
|
||||
//
|
||||
showFontWarnings: 0,
|
||||
|
||||
//
|
||||
// Use "Process" or "ProcessBeforeShowing". See the jsMath
|
||||
// author's documentation for the difference between these
|
||||
// two routines.
|
||||
//
|
||||
method: "Process",
|
||||
|
||||
//
|
||||
// List of plug-ins and extensions that you want to be
|
||||
// loaded automatically. E.g.
|
||||
// ["plugins/mimeTeX.js","extensions/AMSsymbols.js"]
|
||||
//
|
||||
loadFiles: [],
|
||||
|
||||
//
|
||||
// List of fonts to load automatically. E.g.
|
||||
// ["cmmib10"]
|
||||
//
|
||||
loadFonts: [],
|
||||
|
||||
//
|
||||
// List of macros to define. These are of the form
|
||||
// name: value
|
||||
// where 'value' is the replacement text for the macro \name.
|
||||
// The 'value' can also be [value,n] where 'value' is the replacement
|
||||
// text and 'n' is the number of parameters for the macro.
|
||||
// Note that backslashes must be doubled in the replacement string.
|
||||
// E.g.,
|
||||
// {
|
||||
// RR: '{\\bf R}',
|
||||
// bold: ['{\\bf #1}', 1]
|
||||
// }
|
||||
//
|
||||
macros: {},
|
||||
|
||||
//
|
||||
// Allow jsMath to enter global mode?
|
||||
// (Uses frames, so may not always work with complex web sites)
|
||||
//
|
||||
allowGlobal: 1,
|
||||
|
||||
//
|
||||
// Disable image fonts? (In case you don't load them on your server.)
|
||||
//
|
||||
noImageFonts: 1
|
||||
|
||||
};
|
||||
|
||||
/****************************************************************/
|
||||
/****************************************************************/
|
||||
//
|
||||
// DO NOT MAKE CHANGES BELOW THIS
|
||||
//
|
||||
/****************************************************************/
|
||||
/****************************************************************/
|
||||
|
||||
if (jsMath.Easy.root == "") {
|
||||
jsMath.Easy.root = document.getElementsByTagName("script");
|
||||
jsMath.Easy.root = jsMath.Easy.root[jsMath.Easy.root.length-1].src
|
||||
if (jsMath.Easy.root.match(/\/easy\/[^\/]*$/)) {
|
||||
jsMath.Easy.root = jsMath.Easy.root.replace(/\/easy\/[^\/]*$/,"");
|
||||
} else {
|
||||
jsMath.Easy.root = jsMath.Easy.root.replace(/\/(jsMath\/(easy\/)?)?[^\/]*$/,"/jsMath");
|
||||
}
|
||||
}
|
||||
jsMath.Easy.root = jsMath.Easy.root.replace(/\/$/,""); // trim trailing "/" if any
|
||||
|
||||
document.write('<SCRIPT SRC="'+jsMath.Easy.root+'/jsMath-easy-load.js"><'+'/SCRIPT>');
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* extensions/AMSmath.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file defines most of the macros and environments from
|
||||
* the amsmath LaTeX package. You can activate it by calling
|
||||
*
|
||||
* jsMath.Extension.Require('AMSmath');
|
||||
*
|
||||
* once jsMath.js has been loaded, or by adding "extensions/AMSmath.js"
|
||||
* to the loadFiles array in jsMath/easy/load.js.
|
||||
*
|
||||
* You may wish to load AMSsymbols.js as well, but note that it
|
||||
* requires the extra msam10 and msb10 fonts that you will have
|
||||
* to install on your server first.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Extension.Require("moreArrows");
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
macros: {
|
||||
intI: ['Macro','\\mathchoice{\\!}{}{}{}\\!\\!\\int'],
|
||||
iint: ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI}'],
|
||||
iiint: ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI}'],
|
||||
iiiint: ['Macro','\\!\\!\\!\\mathop{\\,\\,\\,\\int\\intI\\intI\\intI}'],
|
||||
idotsint: ['Macro','\\!\\!\\mathop{\\,\\,\\int\\cdots\\int}'],
|
||||
|
||||
dddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle ...}',1],
|
||||
ddddot: ['Macro','\\mathop{#1}\\limits^{\\textstyle ....}',1],
|
||||
|
||||
sideset: ['Macro','\\mathop{\\rlap{\\phantom{#3}}}#1\\!{#3}#2',3],
|
||||
stackrel: ['Macro','\\mathrel{\\mathop{#2}\\limits^{#1}}',2],
|
||||
|
||||
boxed: ['Macro','\\fbox{$\\displaystyle{#1}$}',1],
|
||||
|
||||
tag: 'HandleTag',
|
||||
notag: ['Macro',''],
|
||||
|
||||
substack: ['Macro','\\begin{subarray}{c}#1\\end{subarray}',1],
|
||||
|
||||
varliminf: ['Macro','\\mathop{\\underline{\\raise1.5pt{\\rule{0pt}{.6em}{0pt}\\smash{\\lower1.5pt{\\rm lim}}}}}'],
|
||||
varlimsup: ['Macro','\\mathop{\\overline{\\rule{0pt}{.6em}{0pt}\\smash{\\rm lim}}}'],
|
||||
varinjlim: ['Macro','\\mathop{\\underrightarrow{\\rm lim}}'],
|
||||
varprojlim: ['Macro','\\mathop{\\underleftarrow{\\rm lim}}'],
|
||||
|
||||
DeclareMathOperator: 'HandleDeclareOp',
|
||||
operatorname: 'HandleOperatorName',
|
||||
|
||||
genfrac: 'Genfrac',
|
||||
frac: ['Genfrac',"","","",""],
|
||||
tfrac: ['Genfrac',"","","","1"],
|
||||
dfrac: ['Genfrac',"","","","0"],
|
||||
binom: ['Genfrac',"(",")","0pt",""],
|
||||
tbinom: ['Genfrac',"(",")","0pt","1"],
|
||||
dbinom: ['Genfrac',"(",")","0pt","0"],
|
||||
|
||||
cfrac: 'CFrac',
|
||||
|
||||
shoveleft: ['HandleShove','left'],
|
||||
shoveright: ['HandleShove','right']
|
||||
},
|
||||
|
||||
environments: {
|
||||
align: ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'],
|
||||
'align*': ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'],
|
||||
aligned: ['Array',null,null,'rlrlrlrlrlrl',[5/18,2,5/18,2,5/18,2,5/18,2,5/18,2,5/18],1,'D'],
|
||||
multline: 'Multline',
|
||||
'multline*': 'Multline',
|
||||
split: ['Array',null,null,'rl',[5/18],1,'D'],
|
||||
gather: ['Array',null,null,'c',null,1,'D'],
|
||||
'gather*': ['Array',null,null,'c',null,1,'D'],
|
||||
gathered: ['Array',null,null,'c',null,1,'D'],
|
||||
subarray: ['Array',null,null,null,[0,0,0,0],1,'S',0,.25],
|
||||
smallmatrix: ['Array',null,null,'cccccccccc',[1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3,1/3],1,'S',0]
|
||||
},
|
||||
|
||||
delimiter: {
|
||||
'\\lvert': [4,2,0x6A,3,0x0C],
|
||||
'\\rvert': [5,2,0x6A,3,0x0C],
|
||||
'\\lVert': [4,2,0x6B,3,0x0D],
|
||||
'\\rVert': [5,2,0x6B,3,0x0D]
|
||||
},
|
||||
|
||||
/*
|
||||
* Ignore the tag for now
|
||||
*/
|
||||
HandleTag: function (name) {
|
||||
var arg = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
if (arg == "*") this.GetArgument(this.cmd+name);
|
||||
},
|
||||
|
||||
/*
|
||||
* Handle \DeclareMathOperator
|
||||
*/
|
||||
HandleDeclareOp: function (name) {
|
||||
var limits = "";
|
||||
var cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
if (cs == "*") {
|
||||
limits = "\\limits";
|
||||
cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
}
|
||||
if (cs.charAt(0) == "\\") {cs = cs.substr(1)}
|
||||
var op = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}');
|
||||
jsMath.Parser.prototype.macros[cs] = ['Macro','\\mathop{\\rm '+op+'}'+limits];
|
||||
},
|
||||
|
||||
HandleOperatorName: function (name) {
|
||||
var limits = "\\nolimits";
|
||||
var op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
if (op == "*") {
|
||||
limits = "\\limits";
|
||||
op = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
}
|
||||
op = op.replace(/\*/g,'\\char{cmr10}{0x2A}').replace(/-/g,'\\char{cmr10}{0x2D}');
|
||||
this.string = '\\mathop{\\rm '+op+'}'+limits+this.string.slice(this.i);
|
||||
this.i = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
* Record presence of \shoveleft and \shoveright
|
||||
*/
|
||||
HandleShove: function (name,data) {
|
||||
if (this.mlist.data.entry == null) {this.mlist.data.entry = {}}
|
||||
this.mlist.data.entry.shove = data[0];
|
||||
},
|
||||
|
||||
/*
|
||||
* Handle \cfrac
|
||||
*/
|
||||
CFrac: function (name) {
|
||||
var lr = this.GetBrackets(this.cmd+name); if (this.error) return;
|
||||
var num = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
var den = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
|
||||
num = this.Process('\\strut\\textstyle{'+num+'}'); if (this.error) return;
|
||||
den = this.Process('\\strut\\textstyle{'+den+'}'); if (this.error) return;
|
||||
var data = this.mlist.data;
|
||||
var TeX = jsMath.Typeset.TeX(data.style,data.size);
|
||||
|
||||
if (lr != "") {
|
||||
if (lr != 'l' && lr != 'r') {this.Error("Illegal alignment specified in "+this.cmd+name); return}
|
||||
num = jsMath.Box.Set(num,data.style,data.size);
|
||||
den = jsMath.Box.Set(den,data.style,data.size);
|
||||
if (num.w > den.w) {
|
||||
if (lr == 'l') {den.html += jsMath.HTML.Spacer(num.w-den.w)}
|
||||
else {den.html = jsMath.HTML.Spacer(num.w-den.w) + den.html}
|
||||
den.w = num.w;
|
||||
} else if (num.w < den.w) {
|
||||
if (lr == 'l') {num.html += jsMath.HTML.Spacer(den.w-num.w)}
|
||||
else {num.html = jsMath.HTML.Spacer(den.w-num.w) + num.html}
|
||||
num.w = den.w;
|
||||
}
|
||||
}
|
||||
|
||||
this.mlist.Add(jsMath.mItem.Fraction(name,num,den,TeX.default_rule_thickness));
|
||||
},
|
||||
|
||||
/*
|
||||
* Implement AMS generalized fraction
|
||||
*/
|
||||
Genfrac: function (name,data) {
|
||||
var left = data[0]; var right = data[1];
|
||||
var thickness = data[2]; var style = data[3];
|
||||
|
||||
if (left != null) {left = this.delimiter[left]} else
|
||||
{left = this.GetDelimiterArg(this.cmd+name); if (this.error) return}
|
||||
if (right != null) {right = this.delimiter[right]} else
|
||||
{right = this.GetDelimiterArg(this.cmd+name); if (this.error) return}
|
||||
if (thickness == null) {thickness = this.GetArgument(this.cmd+name); if (this.error) return}
|
||||
if (style == null) {style = this.GetArgument(this.cmd+name); if (this.error) return}
|
||||
|
||||
var num = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var den = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
|
||||
if (left == "") {left = null}; if (right == "") {right = null}
|
||||
if (thickness == "") {
|
||||
var TeX =jsMath.Typeset.TeX(this.mlist.data.style,this.mlist.data.size);
|
||||
thickness = TeX.default_rule_thickness;
|
||||
} else {
|
||||
thickness = this.ParseDimen(thickness,this.cmd+name,0,0);
|
||||
}
|
||||
|
||||
var frac = jsMath.mItem.Fraction(name,num,den,thickness,left,right);
|
||||
|
||||
if (style != "") {
|
||||
style = (["D","T","S","SS"])[style];
|
||||
if (style == null) {this.Error("Bad math style for "+this.cmd+name); return}
|
||||
var mlist = new jsMath.mList([new jsMath.mItem('style',{style:style}),frac]);
|
||||
this.mlist.Add(jsMath.mItem.Atom('inner',{type:'mlist',mlist: mlist}));
|
||||
} else {
|
||||
this.mlist.Add(frac);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Implements the multline environment
|
||||
*/
|
||||
Multline: function (name,delim) {
|
||||
var data = this.mlist.data;
|
||||
var width = this.GetBrackets(this.cmd+'begin{'+name+'}'); if (this.error) return;
|
||||
var arg = this.GetEnd(name); if (this.error) return;
|
||||
|
||||
var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,'D');
|
||||
parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
|
||||
parse.Parse(); if (parse.error) {this.Error(parse); return}
|
||||
parse.HandleRow(name,1); // be sure the last row is recorded
|
||||
|
||||
//
|
||||
// check rows for extra columns and maximum width
|
||||
//
|
||||
var i; var row; var W = 0;
|
||||
for (i = 0; i < parse.table.length; i++) {
|
||||
row = parse.table[i];
|
||||
if (row.length > 1) {
|
||||
this.Error("Rows can contain only one equation in '"+name+"' environment");
|
||||
return;
|
||||
}
|
||||
if (row[0].w > W) {W = row[0].w}
|
||||
}
|
||||
|
||||
//
|
||||
// Determine width of display
|
||||
//
|
||||
if (width == "") {width = W+2} else {
|
||||
width = this.ParseDimen(width,name,0,0);
|
||||
if (width < W) {width = W}
|
||||
}
|
||||
|
||||
//
|
||||
// Shove the top and bottom lines
|
||||
//
|
||||
if (parse.table.length > 1) {
|
||||
parse.table[0][0].entry.shove = 'left';
|
||||
row = parse.table[parse.table.length-1];
|
||||
if (!row[0].entry.shove) {row[0].entry.shove = 'right'}
|
||||
}
|
||||
//
|
||||
// Adjust widths of shoved lines
|
||||
//
|
||||
for (i = 0; i < parse.table.length; i++) {
|
||||
row = parse.table[i][0];
|
||||
if (row.entry.shove && row.w < width) {
|
||||
switch (row.entry.shove) {
|
||||
case 'left':
|
||||
row.html += jsMath.HTML.Spacer(width-row.w);
|
||||
break;
|
||||
|
||||
case 'right':
|
||||
row.html = jsMath.HTML.Spacer(width-row.w)+row.html;
|
||||
break;
|
||||
}
|
||||
row.w = width;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do the layout
|
||||
//
|
||||
var box = jsMath.Box.Layout(data.size,parse.table);
|
||||
this.mlist.Add(jsMath.mItem.Atom('ord',box));
|
||||
},
|
||||
|
||||
/*
|
||||
* Get a delimiter or empty argument
|
||||
*/
|
||||
GetDelimiterArg: function (name) {
|
||||
var c = this.trimSpaces(this.GetArgument(name)); if (this.error) return null;
|
||||
if (c == "") return null;
|
||||
if (this.delimiter[c]) return this.delimiter[c];
|
||||
this.Error("Missing or unrecognized delimiter for "+name);
|
||||
return null;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* extensions/AMSsymbol.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file defines the macros needed to access the AMS symbol fonts
|
||||
* available in msam10 and msbm10. You can activate it by calling
|
||||
*
|
||||
* jsMath.Extension.Require('AMSsymbols');
|
||||
*
|
||||
* once jsMath.js has been loaded.
|
||||
*
|
||||
* Note that you will need to install the msam10 and msbm10 fonts
|
||||
* that are available from the jsMath extra font page at
|
||||
*
|
||||
* http://www.math.union.edu/locate/jsMath/download/extra-fonts/
|
||||
*
|
||||
* in order to make this work in image mode. Note that there is no
|
||||
* unicode fallback mode for these fonts at this time.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
delete jsMath.Parser.prototype.macros['hbar'];
|
||||
delete jsMath.Parser.prototype.macros['angle'];
|
||||
delete jsMath.Parser.prototype.macros['rightleftharpoons'];
|
||||
|
||||
jsMath.Extension.MathChar("msam10",{
|
||||
// Miscellaneous symbols
|
||||
vartriangle: [3,0x4D],
|
||||
triangledown: [0,0x4F],
|
||||
square: [0,0x03],
|
||||
lozenge: [0,0x06],
|
||||
circledS: [0,0x73],
|
||||
angle: [0,0x5C],
|
||||
measuredangle: [0,0x5D],
|
||||
backprime: [0,0x38],
|
||||
blacktriangle: [0,0x4E],
|
||||
blacktriangledown: [0,0x48],
|
||||
blacksquare: [0,0x04],
|
||||
blacklozenge: [0,0x07],
|
||||
bigstar: [0,0x46],
|
||||
sphericalangle: [0,0x5E],
|
||||
complement: [0,0x7B],
|
||||
|
||||
// Binary operators
|
||||
dotplus: [2,0x75],
|
||||
Cap: [2,0x65],
|
||||
doublecap: [2,0x65],
|
||||
Cup: [2,0x64],
|
||||
doublecup: [2,0x64],
|
||||
barwedge: [2,0x5A],
|
||||
veebar: [2,0x59],
|
||||
doublebarwedge: [2,0x5B],
|
||||
boxminus: [2,0x0C],
|
||||
boxtimes: [2,0x02],
|
||||
boxdot: [2,0x00],
|
||||
boxplus: [2,0x01],
|
||||
leftthreetimes: [2,0x68],
|
||||
rightthreetimes: [2,0x69],
|
||||
curlywedge: [2,0x66],
|
||||
curlyvee: [2,0x67],
|
||||
circleddash: [2,0x7F],
|
||||
circledast: [2,0x7E],
|
||||
circledcirc: [2,0x7D],
|
||||
centerdot: [2,0x05],
|
||||
intercal: [2,0x7C],
|
||||
|
||||
// Binary relations
|
||||
leqq: [3,0x35],
|
||||
leqslant: [3,0x36],
|
||||
eqslantless: [3,0x30],
|
||||
lesssim: [3,0x2E],
|
||||
lessapprox: [3,0x2F],
|
||||
lll: [3,0x6E],
|
||||
llless: [3,0x6E],
|
||||
lessgtr: [3,0x37],
|
||||
lesseqgtr: [3,0x51],
|
||||
lesseqqgtr: [3,0x53],
|
||||
doteqdot: [3,0x2B],
|
||||
Doteq: [3,0x2B],
|
||||
risingdotseq: [3,0x3A],
|
||||
fallingdotseq: [3,0x3B],
|
||||
backsim: [3,0x76],
|
||||
backsimeq: [3,0x77],
|
||||
subseteqq: [3,0x6A],
|
||||
Subset: [3,0x62],
|
||||
sqsubset: [3,0x40],
|
||||
preccurlyeq: [3,0x34],
|
||||
curlyeqprec: [3,0x32],
|
||||
precsim: [3,0x2D],
|
||||
vartriangleleft: [3,0x43],
|
||||
trianglelefteq: [3,0x45],
|
||||
vDash: [3,0x0F],
|
||||
Vvdash: [3,0x0E],
|
||||
smallsmile: [3,0x60],
|
||||
smallfrown: [3,0x61],
|
||||
bumpeq: [3,0x6C],
|
||||
Bumpeq: [3,0x6D],
|
||||
varpropto: [3,0x5F],
|
||||
blacktriangleleft: [3,0x4A],
|
||||
therefore: [3,0x29],
|
||||
geqq: [3,0x3D],
|
||||
geqslant: [3,0x3E],
|
||||
eqslantgtr: [3,0x31],
|
||||
gtrsim: [3,0x26],
|
||||
gtrapprox: [3,0x27],
|
||||
ggg: [3,0x6F],
|
||||
gggtr: [3,0x6F],
|
||||
gtrless: [3,0x3F],
|
||||
gtreqless: [3,0x52],
|
||||
gtreqqless: [3,0x54],
|
||||
eqcirc: [3,0x50],
|
||||
circeq: [3,0x24],
|
||||
triangleq: [3,0x2C],
|
||||
supseteqq: [3,0x6B],
|
||||
Supset: [3,0x63],
|
||||
sqsupset: [3,0x41],
|
||||
succcurlyeq: [3,0x3C],
|
||||
curlyeqsucc: [3,0x33],
|
||||
succsim: [3,0x25],
|
||||
vartriangleright: [3,0x42],
|
||||
trianglerighteq: [3,0x44],
|
||||
Vdash: [3,0x0D],
|
||||
between: [3,0x47],
|
||||
pitchfork: [3,0x74],
|
||||
blacktriangleright: [3,0x49],
|
||||
because: [3,0x2A],
|
||||
|
||||
// Arrows
|
||||
leftleftarrows: [3,0x12],
|
||||
leftrightarrows: [3,0x1C],
|
||||
Lleftarrow: [3,0x57],
|
||||
twoheadleftarrow: [3,0x11],
|
||||
leftarrowtail: [3,0x1B],
|
||||
looparrowleft: [3,0x22],
|
||||
leftrightharpoons: [3,0x0B],
|
||||
circlearrowleft: [3,0x09],
|
||||
Lsh: [3,0x1E],
|
||||
upuparrows: [3,0x14],
|
||||
upharpoonleft: [3,0x18],
|
||||
downharpoonleft: [3,0x19],
|
||||
multimap: [3,0x28],
|
||||
leftrightsquigarrow:[3,0x21],
|
||||
rightrightarrows: [3,0x13],
|
||||
rightleftarrows: [3,0x1D],
|
||||
Rrightarrow: [3,0x56],
|
||||
twoheadrightarrow: [3,0x10],
|
||||
rightarrowtail: [3,0x1A],
|
||||
looparrowright: [3,0x23],
|
||||
rightleftharpoons: [3,0x0A],
|
||||
circlearrowright: [3,0x08],
|
||||
Rsh: [3,0x1F],
|
||||
downdownarrows: [3,0x15],
|
||||
upharpoonright: [3,0x16],
|
||||
downharpoonright: [3,0x17],
|
||||
rightsquigarrow: [3,0x20]
|
||||
});
|
||||
|
||||
jsMath.Extension.MathChar("msbm10",{
|
||||
// Lowercase Greek letters
|
||||
digamma: [0,0x7A],
|
||||
varkappa: [0,0x7B],
|
||||
|
||||
// Hebrew letters
|
||||
beth: [0,0x69],
|
||||
daleth: [0,0x6B],
|
||||
gimel: [0,0x6A],
|
||||
|
||||
// Miscellaneous symbols
|
||||
hbar: [0,0x7E],
|
||||
hslash: [0,0x7D],
|
||||
nexists: [0,0x40],
|
||||
mho: [0,0x66],
|
||||
Finv: [0,0x60],
|
||||
Game: [0,0x61],
|
||||
Bbbk: [0,0x7C],
|
||||
varnothing: [0,0x3F],
|
||||
eth: [0,0x67],
|
||||
diagup: [0,0x1E],
|
||||
diagdown: [0,0x1F],
|
||||
|
||||
// Binary operators
|
||||
smallsetminus: [2,0x72],
|
||||
divideontimes: [2,0x3E],
|
||||
ltimes: [2,0x6E],
|
||||
rtimes: [2,0x6F],
|
||||
|
||||
// Binary relations
|
||||
approxeq: [3,0x75],
|
||||
lessdot: [3,0x6C],
|
||||
precapprox: [3,0x77],
|
||||
gtrdot: [3,0x6D],
|
||||
thicksim: [3,0x73],
|
||||
thickapprox: [3,0x74],
|
||||
succapprox: [3,0x76],
|
||||
shortmid: [3,0x70],
|
||||
shortparallel: [3,0x71],
|
||||
backepsilon: [3,0x7F],
|
||||
|
||||
// Negated relations
|
||||
nless: [3,0x04],
|
||||
nleq: [3,0x02],
|
||||
nleqslant: [3,0x0A],
|
||||
nleqq: [3,0x14],
|
||||
lneq: [3,0x0C],
|
||||
lneqq: [3,0x08],
|
||||
lvertneqq: [3,0x00],
|
||||
lnsim: [3,0x12],
|
||||
lnapprox: [3,0x1A],
|
||||
nprec: [3,0x06],
|
||||
npreceq: [3,0x0E],
|
||||
precneqq: [3,0x16],
|
||||
precnsim: [3,0x10],
|
||||
precnapprox: [3,0x18],
|
||||
nsim: [3,0x1C],
|
||||
nshortmid: [3,0x2E],
|
||||
nmid: [3,0x2D],
|
||||
nvdash: [3,0x30],
|
||||
nVdash: [3,0x31],
|
||||
ntriangleleft: [3,0x36],
|
||||
ntrianglelefteq: [3,0x35],
|
||||
nsubseteq: [3,0x2A],
|
||||
nsubseteqq: [3,0x22],
|
||||
subsetneq: [3,0x28],
|
||||
varsubsetneq: [3,0x20],
|
||||
subsetneqq: [3,0x24],
|
||||
varsubsetneqq: [3,0x26],
|
||||
ngtr: [3,0x05],
|
||||
ngeq: [3,0x03],
|
||||
ngeqslant: [3,0x0B],
|
||||
ngeqq: [3,0x15],
|
||||
gneq: [3,0x0D],
|
||||
gneqq: [3,0x09],
|
||||
gvertneqq: [3,0x01],
|
||||
gnsim: [3,0x13],
|
||||
gnapprox: [3,0x1B],
|
||||
nsucc: [3,0x07],
|
||||
nsucceq: [3,0x0F],
|
||||
succneqq: [3,0x17],
|
||||
succnsim: [3,0x11],
|
||||
succnapprox: [3,0x19],
|
||||
ncong: [3,0x1D],
|
||||
nshortparallel: [3,0x2F],
|
||||
nparallel: [3,0x2C],
|
||||
nvDash: [3,0x32],
|
||||
nVDash: [3,0x33],
|
||||
ntriangleright: [3,0x37],
|
||||
ntrianglerighteq: [3,0x34],
|
||||
nsupseteq: [3,0x2B],
|
||||
nsupseteqq: [3,0x23],
|
||||
supsetneq: [3,0x29],
|
||||
varsupsetneq: [3,0x21],
|
||||
supsetneqq: [3,0x25],
|
||||
varsupsetneqq: [3,0x27],
|
||||
|
||||
// Arrows
|
||||
curvearrowleft: [3,0x78],
|
||||
curvearrowright: [3,0x79],
|
||||
|
||||
// Negated arrows
|
||||
nleftarrow: [3,0x38],
|
||||
nLeftarrow: [3,0x3A],
|
||||
nleftrightarrow: [3,0x3D],
|
||||
nrightarrow: [3,0x39],
|
||||
nRightarrow: [3,0x3B],
|
||||
nLeftrightarrow: [3,0x3C]
|
||||
});
|
||||
|
||||
jsMath.Macro('Bbb','{\\msbm #1}',1);
|
||||
jsMath.Macro('mathbb','{\\msbm #1}',1);
|
||||
jsMath.Extension.Font('msbm');
|
||||
jsMath.Extension.Font('msam');
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* extensions/HTML.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements a number of HTML-specific extensions to TeX,
|
||||
* including \color, \style, \class, \unicode, etc. It will be loaded
|
||||
* automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('HTML');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {
|
||||
color: 'Color',
|
||||
href: 'Href',
|
||||
'class': 'Class',
|
||||
style: 'Style',
|
||||
cssId: 'CSSId',
|
||||
unicode: 'Unicode'
|
||||
},
|
||||
|
||||
/*
|
||||
* Show the argument in a particular color
|
||||
*/
|
||||
Color: function (name) {
|
||||
var color = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(color,name); if (this.error) return;
|
||||
// check that it looks like a color?
|
||||
this.AddHTML(name,['<span style="color: '+color+'">','</span>']);
|
||||
},
|
||||
|
||||
/*
|
||||
* Make the argument be a link
|
||||
*/
|
||||
Href: function (name) {
|
||||
var href = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(href,name); if (this.error) return;
|
||||
this.AddHTML(name,['<a class="link" href="'+href+'">','</a>']);
|
||||
},
|
||||
|
||||
/*
|
||||
* Apply a CSS class to the argument
|
||||
*/
|
||||
Class: function (name) {
|
||||
var clss = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(clss,name); if (this.error) return;
|
||||
this.AddHTML(name,['<span class="'+clss+'">','</span>']);
|
||||
},
|
||||
|
||||
/*
|
||||
* Apply a CSS style to the argument
|
||||
*/
|
||||
Style: function (name) {
|
||||
var style = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(style,name); if (this.error) return;
|
||||
this.AddHTML(name,['<span style="'+style+'">','</span>']);
|
||||
},
|
||||
|
||||
/*
|
||||
* Add a CSS element ID to the argument
|
||||
*/
|
||||
CSSId: function (name) {
|
||||
var id = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(id,name); if (this.error) return;
|
||||
this.AddHTML(name,['<span id="'+id+'">','</span>']);
|
||||
},
|
||||
|
||||
/*
|
||||
* Insert some raw HTML around the argument (this will not affect
|
||||
* the spacing or other TeX features)
|
||||
*/
|
||||
AddHTML: function (name,params) {
|
||||
var data = this.mlist.data;
|
||||
var arg = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
arg = jsMath.Parse(arg,data.font,data.size,data.style);
|
||||
if (arg.error) {this.Error(arg); return}
|
||||
this.mlist.Add(jsMath.mItem.HTML(params[0]));
|
||||
for (var i = 0; i < arg.mlist.Length(); i++) {this.mlist.Add(arg.mlist.Get(i))}
|
||||
this.mlist.Add(jsMath.mItem.HTML(params[1]));
|
||||
},
|
||||
|
||||
CheckHTML: function (data,name) {
|
||||
if (data.match(/[<>&"]/))
|
||||
{this.Error("Can't include raw HTML in first argument of "+this.cmd+name)}
|
||||
},
|
||||
|
||||
/*
|
||||
* Insert a unicode reference as an Ord atom. Its argument should
|
||||
* be the unicode code point, e.g. \unicode{8211}, or \unicode{x203F}.
|
||||
* You can also specify the height (offset from the x height) and depth
|
||||
* in ems, together with a CSS class for the character, e.g.,
|
||||
* \unicode{8211,class,.2,-.3}
|
||||
*/
|
||||
Unicode: function (name) {
|
||||
var arg = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
this.CheckHTML(arg,name); if (this.error) return;
|
||||
arg = arg.split(','); arg[0] = '&#'+arg[0]+';';
|
||||
if (!arg[1]) {arg[1] = 'normal'}
|
||||
this.mlist.Add(jsMath.mItem.TextAtom('ord',arg[0],arg[1],arg[2],arg[3]));
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* extensions/autobold.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file causes jsMath to use \boldsymbol{...} around mathematics
|
||||
* that appears within <B>...</B> tags or has font-weight:bold applied
|
||||
* via CSS rule. You can activate it by calling
|
||||
*
|
||||
* jsMath.Extension.Require('autobold');
|
||||
*
|
||||
* once jsMath.js has been loaded, or by adding "extensions/autobold.js"
|
||||
* to the loadFiles array in jsMath/easy/load.js.
|
||||
*
|
||||
* Note that you will need to install the cmmib10 and cmbsy10 fonts
|
||||
* that are available from the jsMath extra font page at
|
||||
*
|
||||
* http://www.math.union.edu/locate/jsMath/download/extra-fonts/
|
||||
*
|
||||
* to make this work in image mode. Note that there is no unicode
|
||||
* fallback for these fonts at the moment.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2008 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Extension.Require("boldsymbol");
|
||||
|
||||
jsMath.Translate.OldParse = jsMath.Translate.Parse;
|
||||
jsMath.Translate.Parse = function (style,text,noCache) {
|
||||
if (jsMath.BBoxFor('</SPAN></SPAN><SPAN STYLE="font-family:Times,serif">MMMMMMMMMM</SPAN><SPAN><SPAN>').w >
|
||||
jsMath.BBoxFor('</SPAN></SPAN><SPAN STYLE="font-family:Times,serif; font-weight:normal">MMMMMMMMMM</SPAN><SPAN><SPAN>').w) {
|
||||
text = '\\boldsymbol{' + text + '}';
|
||||
}
|
||||
return jsMath.Translate.OldParse(style,text,noCache);
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* extensions/bbox.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \bbox macro, which creates an HTML 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. 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
|
||||
* \bbox[yellow,2pt,border:1px solid red]{x+y}
|
||||
* % a yellow box with a red border and 2pt space
|
||||
*
|
||||
* This extension is loaded automatically when needed, or you can call
|
||||
* it directly via
|
||||
*
|
||||
* jsMath.Extension.Require('bbox');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Add(jsMath.HTML,{
|
||||
|
||||
/*
|
||||
* Create a colored bbounding box
|
||||
*/
|
||||
BBox: function (w,h,d,c,s) {
|
||||
if (w <= 0) {return ''}
|
||||
if (d == null) {d = 0}
|
||||
var style = (jsMath.Browser.msieInlineBlockFix ? '' : 'overflow:visible;');
|
||||
style += 'width:'+this.Em(w)+'; height:'+this.Em(h+d)+';';
|
||||
if (jsMath.Browser.mozInlineBlockBug) {d = -h}
|
||||
if (jsMath.Browser.msieInlineBlockFix) {d -= jsMath.d}
|
||||
if (d) {style += ' vertical-align:'+this.Em(-d)+';'}
|
||||
if (c) {style += ' background-color:'+c+';'}
|
||||
var html = '<span class="blank" style="'+style+s+'"></span>';
|
||||
return html;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Add(jsMath.mList.prototype.Atomize,{
|
||||
/*
|
||||
* Creates the box HTML
|
||||
*/
|
||||
bbox: function (style,size,mitem,prev,mlist) {
|
||||
var box; var w; var h; var d;
|
||||
var nuc = mitem.nuc = jsMath.Box.Set(mitem.nuc,style,size).Remeasured();
|
||||
if (box == null) {w = nuc.w; h = nuc.h; d = nuc.d} // values before super/subs-cript
|
||||
var nuc = mitem.nuc; nuc.Styled(); var pad = mitem.pad;
|
||||
if (pad) {w += 2*pad; h += pad; d += pad; nuc.w += pad}
|
||||
if (jsMath.Browser.msieCenterBugFix)
|
||||
{nuc.html = '<span style="position:relative">'+nuc.html+'</span>'}
|
||||
nuc.html =
|
||||
jsMath.HTML.BBox(w,h,d,mitem.color,mitem.style) +
|
||||
jsMath.HTML.Spacer(pad-w) +
|
||||
nuc.html;
|
||||
nuc.Remeasured();
|
||||
if (pad && nuc.w < w) {
|
||||
nuc.html += jsMath.HTML.Spacer(w-nuc.w);
|
||||
nuc.w = w;
|
||||
}
|
||||
nuc.h = Math.max(nuc.h,h); nuc.d = Math.max(nuc.d,d);
|
||||
nuc.bh = Math.max(nuc.bh,nuc.h); nuc.bd = Math.max(nuc.bd,nuc.d);
|
||||
mitem.type = 'ord';
|
||||
jsMath.mList.prototype.Atomize.SupSub(style,size,mitem);
|
||||
}
|
||||
});
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {bbox: 'BBox'},
|
||||
|
||||
/*
|
||||
* Implement \bbox[...]{...}
|
||||
*/
|
||||
BBox: function (name) {
|
||||
var extra = this.GetBrackets(this.cmd+name); if (this.error) return;
|
||||
var arg = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
var nuc = this.Process(arg); if (this.error) return;
|
||||
var color; var pad = 0; var style = '';
|
||||
if (extra != '') {
|
||||
var parts = extra.split(/,/);
|
||||
for (var i in parts) {
|
||||
if (parts[i].match(/^\s*([-+]?(\.\d+|\d+(\.\d*)?))(pt|em|ex|mu|px)\s*$/))
|
||||
{pad = this.ParseDimen(parts[i],'',0,1)}
|
||||
else if (parts[i].match(/:/)) {style = parts[i]}
|
||||
else {color = parts[i]}
|
||||
}
|
||||
}
|
||||
var atom = {nuc: nuc, atom: 1, pad: pad, color: color, style: style};
|
||||
this.mlist.Add(new jsMath.mItem('bbox',atom));
|
||||
}
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* extensions/boldsymbol.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \boldsymbol macro. You can activate it
|
||||
* by calling
|
||||
*
|
||||
* jsMath.Extension.Macro('boldsymbol');
|
||||
*
|
||||
* which will cause the extension to be loaded only when it is
|
||||
* needed, or you can force it to be loaded via
|
||||
*
|
||||
* jsMath.Extension.Require('boldsymbol');
|
||||
*
|
||||
* once jsMath.js has been loaded.
|
||||
*
|
||||
* Note that you will need to install the cmmib10 and cmbsy10 fonts
|
||||
* that are available from the jsMath extra font page at
|
||||
*
|
||||
* http://www.math.union.edu/locate/jsMath/download/extra-fonts/
|
||||
*
|
||||
* to make this work in image mode. Note that there is no unicode
|
||||
* fallback for these fonts at the moment.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006-2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {boldsymbol: 'BoldSymbol'},
|
||||
|
||||
/*
|
||||
* Implement \boldsymbol{...}
|
||||
*/
|
||||
BoldSymbol: function (name) {
|
||||
var fam = jsMath.TeX.fam; var restart = 0;
|
||||
var oldfam = [fam[0],fam[1],fam[2]];
|
||||
fam[0] = "cmbx10"; fam[1] = "cmmib10"; fam[2] = "cmbsy10";
|
||||
try{var box = this.ProcessArg(this.cmd+name)}
|
||||
catch (e) {restart = (e == "restart")}
|
||||
fam[0] = oldfam[0]; fam[1] = oldfam[1]; fam[2] = oldfam[2];
|
||||
if (this.error) return; if (restart) {throw "restart"}
|
||||
this.mlist.Add(jsMath.mItem.Atom('ord',box));
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* extensions/double-click.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file allows users to double click on typeset mathematics
|
||||
* to view the TeX source for the given expression. It will be loaded
|
||||
* automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('double-click');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2008 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
if (jsMath.Click && jsMath.Click.styles)
|
||||
{jsMath.Click.oldStyles = jsMath.Click.styles}
|
||||
|
||||
jsMath.Add(jsMath.Click,{
|
||||
|
||||
dragging: 0,
|
||||
|
||||
styles: {
|
||||
// Floating windows for displaying TeX source
|
||||
'#jsMath_float': {
|
||||
position: 'absolute', top: '0px', left: '0px', 'z-index': '101',
|
||||
'max-width': '80%', width: 'auto', height: 'auto',
|
||||
padding: '0px', margin: '0px', 'font-size': '100%'
|
||||
},
|
||||
'#jsMath_float .drag': {
|
||||
'background-color': '#DDDDDD',
|
||||
border: 'outset 1px', padding: '0px', margin: '0px',
|
||||
width: 'auto', height: '12px', 'font-size': '1px'
|
||||
},
|
||||
'#jsMath_float .close': {
|
||||
'background-color': '#E6E6E6',
|
||||
border: 'inset 1px', margin: '1px 2px', padding: '0px',
|
||||
width: '8px', height: '8px'
|
||||
},
|
||||
'#jsMath_float .source': {
|
||||
'background-color': '#E2E2E2',
|
||||
border: 'outset 1px', margin: '0px', padding: '8px 15px',
|
||||
width: 'auto', height: 'auto',
|
||||
'font-family': 'courier, fixed', 'font-size': '90%'
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Create the hidden DIV used for the tex source window
|
||||
*/
|
||||
Init: function () {
|
||||
if (this.oldStyles) {jsMath.Insert(this.styles,this.oldStyles)}
|
||||
jsMath.Setup.Styles(this.styles);
|
||||
this.source = jsMath.Setup.DIV("float",{display:'none'});
|
||||
this.source.innerHTML =
|
||||
'<div class="drag"><div class="close"></div></div>'
|
||||
+ '<div class="source"><span></span></div>';
|
||||
this.drag = this.source.firstChild;
|
||||
this.tex = this.drag.nextSibling.firstChild;
|
||||
this.drag.firstChild.onclick = jsMath.Click.CloseSource;
|
||||
this.drag.onmousedown = jsMath.Click.StartDragging;
|
||||
this.drag.ondragstart = jsMath.Click.False;
|
||||
this.drag.onselectstart = jsMath.Click.False;
|
||||
this.source.onclick = jsMath.Click.CheckClose;
|
||||
},
|
||||
False: function () {return false},
|
||||
|
||||
/*
|
||||
* Handle a double-click on an equation
|
||||
*/
|
||||
DblClick: function (data) {
|
||||
var event = data[0]; var TeX = data[1];
|
||||
var event = jsMath.Click.Event(event);
|
||||
|
||||
var source = jsMath.Click.source
|
||||
var tex = jsMath.Click.tex;
|
||||
|
||||
source.style.visibility = 'hidden';
|
||||
source.style.display = ''; source.style.width = '';
|
||||
source.style.left = ''; source.style.top = '';
|
||||
tex.innerHTML = '';
|
||||
|
||||
TeX = TeX.replace(/^\s+|\s+$/g,'');
|
||||
TeX = TeX.replace(/&/g,'&');
|
||||
TeX = TeX.replace(/</g,'<');
|
||||
TeX = TeX.replace(/>/g,'>');
|
||||
TeX = TeX.replace(/\n/g,'<br/>');
|
||||
tex.innerHTML = TeX;
|
||||
|
||||
var h = source.offsetHeight; var w;
|
||||
if (jsMath.Browser.msieDivWidthBug) {
|
||||
tex.className = 'source'; // Work around MSIE bug where
|
||||
w = tex.offsetWidth + 5; // DIV's don't collapse to
|
||||
tex.className = ''; // their natural widths
|
||||
} else {
|
||||
w = source.offsetWidth;
|
||||
}
|
||||
w = Math.max(50,Math.min(w,.8*event.W,event.W-40));
|
||||
var x = Math.floor(event.x-w/2); var y = Math.floor(event.y-h/2);
|
||||
x = event.X + Math.max(Math.min(x,event.W-w-20),20);
|
||||
y = event.Y + Math.max(Math.min(y,event.H-h-5),5);
|
||||
|
||||
source.style.left = x+'px'; source.style.top = y+'px';
|
||||
source.style.width = w+'px';
|
||||
source.style.visibility = '';
|
||||
jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y;
|
||||
jsMath.Click.w = w; jsMath.Click.h = source.offsetHeight;
|
||||
|
||||
jsMath.Click.DeselectText(x,y);
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* Get window width, height, and offsets plus
|
||||
* position of pointer relative to the window
|
||||
*/
|
||||
Event: function (event) {
|
||||
var W = jsMath.window.innerWidth || jsMath.document.body.clientWidth;
|
||||
var H = jsMath.window.innerHeight || jsMath.document.body.clientHeight;
|
||||
var X = jsMath.window.pageXOffset; var Y = jsMath.window.pageYOffset;
|
||||
if (X == null) {
|
||||
X = jsMath.document.body.clientLeft;
|
||||
Y = jsMath.document.body.clientTop;
|
||||
}
|
||||
var x = event.pageX; var y = event.pageY;
|
||||
if (x == null) {
|
||||
x = event.clientX; y = event.clientY;
|
||||
if (jsMath.browser == 'MSIE' && jsMath.document.compatMode == 'CSS1Compat') {
|
||||
X = jsMath.document.documentElement.scrollLeft;
|
||||
Y = jsMath.document.documentElement.scrollTop;
|
||||
W = jsMath.document.documentElement.clientWidth;
|
||||
H = jsMath.document.documentElement.clientHeight;
|
||||
} else {
|
||||
X = jsMath.document.body.scrollLeft;
|
||||
Y = jsMath.document.body.scrollTop;
|
||||
}
|
||||
} else {x -= X; y -= Y}
|
||||
|
||||
return {x: x, y: y, W: W, H: H, X: X, Y: Y};
|
||||
},
|
||||
|
||||
/*
|
||||
* Unselect whatever text is selected (since double-clicking
|
||||
* usually selects something)
|
||||
*/
|
||||
DeselectText: function (x,y) {
|
||||
if (jsMath.window.getSelection && jsMath.window.getSelection().removeAllRanges)
|
||||
{jsMath.window.getSelection().removeAllRanges()}
|
||||
else if (jsMath.document.getSelection && jsMath.document.getSelection().removeAllRanges)
|
||||
{jsMath.document.getSelection().removeAllRanges()}
|
||||
else if (jsMath.document.selection && jsMath.document.selection.empty)
|
||||
{jsMath.document.selection.empty()}
|
||||
else {
|
||||
/* Hack to deselect the text in Opera and Safari */
|
||||
if (jsMath.browser == 'MSIE') return; // don't try it if MISE on Mac
|
||||
jsMath.hiddenTop.innerHTML =
|
||||
'<textarea style="visibility:hidden" rows="1" cols="1">a</textarea>';
|
||||
jsMath.hiddenTop.firstChild.style.position = 'absolute';
|
||||
jsMath.hiddenTop.firstChild.style.left = x+'px';
|
||||
jsMath.hiddenTop.firstChild.style.top = y+'px';
|
||||
setTimeout(jsMath.Click.SelectHidden,1);
|
||||
}
|
||||
},
|
||||
SelectHidden: function () {
|
||||
jsMath.hiddenTop.firstChild.focus();
|
||||
jsMath.hiddenTop.firstChild.select();
|
||||
jsMath.hiddenTop.innerHTML = '';
|
||||
},
|
||||
|
||||
/*
|
||||
* Close the TeX source window
|
||||
*/
|
||||
CloseSource: function () {
|
||||
jsMath.Click.tex.innerHTML = '';
|
||||
jsMath.Click.source.style.display = 'none';
|
||||
jsMath.Click.source.style.visibility = 'hidden';
|
||||
jsMath.Click.StopDragging();
|
||||
return false;
|
||||
},
|
||||
CheckClose: function (event) {
|
||||
if (!event) {event = jsMath.window.event}
|
||||
if (event.altKey) {jsMath.Click.CloseSource(); return false}
|
||||
},
|
||||
|
||||
/*
|
||||
* Set up for dragging the source panel
|
||||
*/
|
||||
StartDragging: function (event) {
|
||||
if (!event) {event = jsMath.window.event}
|
||||
if (jsMath.Click.dragging) {jsMath.Click.StopDragging(event)}
|
||||
var event = jsMath.Click.Event(event);
|
||||
jsMath.Click.dragging = 1;
|
||||
jsMath.Click.x = event.x + 2*event.X - jsMath.Click.left;
|
||||
jsMath.Click.y = event.y + 2*event.Y - jsMath.Click.top;
|
||||
jsMath.Click.oldonmousemove = jsMath.document.onmousemove;
|
||||
jsMath.Click.oldonmouseup = jsMath.document.onmouseup;
|
||||
jsMath.document.onmousemove = jsMath.Click.DragSource;
|
||||
jsMath.document.onmouseup = jsMath.Click.StopDragging;
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* Stop dragging the source window
|
||||
*/
|
||||
StopDragging: function (event) {
|
||||
if (jsMath.Click.dragging) {
|
||||
jsMath.document.onmousemove = jsMath.Click.oldonmousemove;
|
||||
jsMath.document.onmouseup = jsMath.Click.oldonmouseup;
|
||||
jsMath.Click.oldonmousemove = null;
|
||||
jsMath.Click.oldonmouseup = null;
|
||||
jsMath.Click.dragging = 0;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* Move the source window (but stay within the browser window)
|
||||
*/
|
||||
DragSource: function (event) {
|
||||
if (!event) {event = jsMath.window.event}
|
||||
if (jsMath.Browser.buttonCheck && !event.button) {return jsMath.Click.StopDragging(event)}
|
||||
event = jsMath.Click.Event(event);
|
||||
var x = event.x + event.X - jsMath.Click.x;
|
||||
var y = event.y + event.Y - jsMath.Click.y;
|
||||
x = Math.max(event.X,Math.min(event.W+event.X-jsMath.Click.w,x));
|
||||
y = Math.max(event.Y,Math.min(event.H+event.Y-jsMath.Click.h,y));
|
||||
jsMath.Click.source.style.left = x + 'px';
|
||||
jsMath.Click.source.style.top = y + 'px';
|
||||
jsMath.Click.left = x + event.X; jsMath.Click.top = y + event.Y;
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Click.Init();
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* extensions/eqn-number.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file causes jsMath to add equation numbers to displayed
|
||||
* equations. These are displayed at the right, but the styles can
|
||||
* be controlled through the jsMath.EqnNumber object. Equations
|
||||
* are numbered if they include a \label{xxx} call, and the macro
|
||||
* \ref{xxx} can be used to refer to the equation number elsewhere
|
||||
* in the document (it must appear by itself in a math formula,
|
||||
* e.g., $\ref{xxx}$). The "label-ref" CSS style can be used to
|
||||
* style the references.
|
||||
*
|
||||
* If jsMath.EqnNumber.autonumber is set to 1, then ALL displayed
|
||||
* equations will be numberd. Use the \nolabel macro to prevent
|
||||
* equation numbering on an equation.
|
||||
*
|
||||
* You can activate eqn-numbering by calling
|
||||
*
|
||||
* jsMath.Extension.Require('eqn-number');
|
||||
*
|
||||
* once jsMath.js has been loaded, or by adding "extensions/eqn-number.js"
|
||||
* to the loadFiles array in jsMath/easy/load.js.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2008 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
if (jsMath.EqnNumber) {jsMath.EqnNumber_old = jsMath.EqnNumber}
|
||||
|
||||
jsMath.EqnNumber = {
|
||||
|
||||
styles: {
|
||||
'.jsMath_displayBox, .tex2math_div': {position: 'relative'},
|
||||
'.jsMath_number': {
|
||||
position: 'absolute',
|
||||
right: '2em', top: '50%', 'margin-top': '-.5em',
|
||||
height: 'auto', width: 'auto'
|
||||
},
|
||||
'.jsMath_ref': {'text-decoration': 'none'}
|
||||
},
|
||||
|
||||
autonumber: 0, // set to 1 to have ALL equations numbered
|
||||
|
||||
number: 0,
|
||||
format: function (n) {return n},
|
||||
formatLabel: function (n) {return '<A NAME="eqn-'+n+'">('+n+')</A>'},
|
||||
formatRef: function (n) {return '(<A CLASS="jsMath_ref" HREF="#eqn-'+n+'">'+n+'</A>)'},
|
||||
|
||||
_label: null, // flag set when \label{x} is used
|
||||
_labels: {}, // stores label-name => label-value pairs
|
||||
_refs: {}, // stores elements referring to undefined labels
|
||||
_nolabel: 0, // set by \nolabel
|
||||
|
||||
nextNumber: function () {
|
||||
var ref = this.format(++this.number);
|
||||
if (this._label) {
|
||||
this._labels[this._label] = ref;
|
||||
if (this._refs[this._label]) this.fixRefs(this._label);
|
||||
}
|
||||
return this.formatLabel(ref);
|
||||
},
|
||||
|
||||
isRef: function (element) {
|
||||
var tex = element.innerHTML;
|
||||
var result = tex.match(/^\s*\\ref\s*\{([^\}]+)\}\s*$/);
|
||||
if (!result) {return 0}
|
||||
var ref = result[1];
|
||||
if (this._labels[ref]) {
|
||||
this.setRef(element,ref);
|
||||
} else {
|
||||
if (!this._refs[ref]) {this._refs[ref] = []}
|
||||
this._refs[ref][this._refs[ref].length] = element;
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
|
||||
setRef: function (element,ref) {
|
||||
element.innerHTML = this.formatRef(this._labels[ref]);
|
||||
element.className = "label-ref";
|
||||
},
|
||||
|
||||
fixRefs: function (label) {
|
||||
for (var i = 0; i < this._refs[label].length; i++)
|
||||
{this.setRef(this._refs[label][i],label)}
|
||||
delete this._refs[label];
|
||||
},
|
||||
|
||||
badRefs: function () {
|
||||
for (var label in this._refs) {
|
||||
for (var i = 0; i < this._refs[label].length; i++) {
|
||||
var element = this._refs[label][i];
|
||||
element.className = "typeset";
|
||||
element.innerHTML = "<span class='error'>Reference '"+label+"' is undefined</span>";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
makeDIV: function (element) {
|
||||
var div = document.createElement('div');
|
||||
div.className = 'jsMath_displayBox';
|
||||
div.innerHTML = '<div class="jsMath_number">' + this.nextNumber() + '</div>';
|
||||
element.parentNode.insertBefore(div,element);
|
||||
element.parentNode.removeChild(element);
|
||||
div.appendChild(element);
|
||||
},
|
||||
|
||||
makeSPAN: function (element) {
|
||||
var span = document.createElement('span');
|
||||
span.className = 'jsMath_number';
|
||||
span.style.display = 'inline-block';
|
||||
span.innerHTML = jsMath.EqnNumber.nextNumber();
|
||||
element.parentNode.insertBefore(span,element);
|
||||
},
|
||||
|
||||
ConvertMath: function (style,element,nocache) {
|
||||
var EqnNumber = jsMath.EqnNumber;
|
||||
if (EqnNumber.isRef(element)) return;
|
||||
EqnNumber._label = null; EqnNumber._nolabel = 0;
|
||||
this.ConvertMath_old(style,element,nocache);
|
||||
if (EqnNumber._label || (EqnNumber.autonumber && !EqnNumber._nolabel)) {
|
||||
if (element.tagName.toLowerCase() == 'div') {
|
||||
EqnNumber.makeDIV(element);
|
||||
} else if (element.parentNode.className == 'tex2math_div') {
|
||||
EqnNumber.makeSPAN(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ProcessComplete: function () {
|
||||
jsMath.EqnNumber.badRefs();
|
||||
this.ProcessComplete_old.apply(this,arguments);
|
||||
},
|
||||
|
||||
Init: function () {
|
||||
jsMath.Setup.Styles(this.styles);
|
||||
jsMath.Translate.ConvertMath_old = jsMath.Translate.ConvertMath;
|
||||
jsMath.Translate.ConvertMath = this.ConvertMath;
|
||||
jsMath.Translate.ProcessComplete_old = jsMath.Translate.ProcessComplete;
|
||||
jsMath.Translate.ProcessComplete = this.ProcessComplete;
|
||||
},
|
||||
|
||||
environments: {
|
||||
'equation*': 'Star',
|
||||
'eqnarray*': 'Star',
|
||||
'align*': 'Star',
|
||||
'multline*': 'Star',
|
||||
'gather*': 'Star',
|
||||
align: ['StarExtension','AMSmath'],
|
||||
multline: ['StarExtension','AMSmath'],
|
||||
gather: ['StarExtension','AMSmath']
|
||||
},
|
||||
|
||||
ResetStarEnvironments: function () {
|
||||
var Nenv = jsMath.EqnNumber.environments;
|
||||
var Penv = jsMath.Parser.prototype.environments;
|
||||
for (var name in Nenv) {
|
||||
if (name.match(/\*$/)) {Penv[name] = Nenv[name]}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (jsMath.EqnNumber_old) {
|
||||
jsMath.Insert(jsMath.EqnNumber,jsMath.EqnNumber_old);
|
||||
delete jsMath.EqnNumber_old;
|
||||
}
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
macros: {
|
||||
label: 'Label',
|
||||
nolabel: 'NoLabel',
|
||||
nonumber: 'NoLabel',
|
||||
ref: 'Ref'
|
||||
},
|
||||
|
||||
environments: jsMath.EqnNumber.environments,
|
||||
|
||||
Label: function (name) {
|
||||
var label = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
var EqnNumber = jsMath.EqnNumber;
|
||||
if (!EqnNumber._label) {
|
||||
if (!EqnNumber._labels[label]) {
|
||||
EqnNumber._label = label;
|
||||
EqnNumber._nolabel = 0;
|
||||
} else {
|
||||
this.Error("Label '"+label+"' is already defined");
|
||||
}
|
||||
} else {
|
||||
this.Error(this.cmd+name+' can only be used once in an equation');
|
||||
}
|
||||
},
|
||||
|
||||
NoLabel: function (name) {
|
||||
var EqnNumber = jsMath.EqnNumber;
|
||||
EqnNumber._label = null; EqnNumber._nolabel = 1;
|
||||
},
|
||||
|
||||
Ref: function (name) {
|
||||
this.Error(this.cmd+name+' must be used by itself');
|
||||
},
|
||||
|
||||
Star: function (name) {
|
||||
this.NoLabel();
|
||||
var cmd = this.environments[name.substr(0,name.length-1)];
|
||||
if (typeof(cmd) === 'string') {cmd = [cmd]}
|
||||
this[cmd[0]](name,cmd.slice(1));
|
||||
},
|
||||
|
||||
StarExtension: function (name,data) {
|
||||
try {this.Extension(name,data)} catch (e) {}
|
||||
jsMath.Synchronize(jsMath.EqnNumber.ResetStarEnvironments);
|
||||
throw "restart";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.EqnNumber.Init();
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* extensions/fbox.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \fbox macro. It will be loaded
|
||||
* automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('fbox');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Add(jsMath.HTML,{
|
||||
|
||||
/*
|
||||
* Create a colored frame
|
||||
*/
|
||||
Frame: function (x,y,w,h,c,pos) {
|
||||
|
||||
h -= 2/jsMath.em; // use 2 pixels to compensate for border size
|
||||
w -= 2/jsMath.em;
|
||||
y -= 1/jsMath.em;
|
||||
if (!c) {c = ''} else {c = ' '+c};
|
||||
if (pos) {pos = 'absolute;'} else
|
||||
{pos = 'relative; margin-right: '+this.Em(-(w+2/jsMath.em))+'; '}
|
||||
return '<img src="'+jsMath.blank+'" style="position:' + pos
|
||||
+ 'vertical-align: '+this.Em(y)+'; left: '+this.Em(x)+'; '
|
||||
+ 'width:' +this.Em(w*jsMath.Browser.imgScale)+'; '
|
||||
+ 'height:'+this.Em(h*jsMath.Browser.imgScale)+'; '
|
||||
+ 'border: 1px solid'+c+';" />';
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {fbox: 'FBox'},
|
||||
|
||||
/*
|
||||
* Implement \fbox{...}
|
||||
*/
|
||||
FBox: function (name) {
|
||||
var text = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
var arg = jsMath.Box.InternalMath(text,this.mlist.data.size);
|
||||
var f = 0.25 * jsMath.sizes[this.mlist.data.size]/100;
|
||||
var box = jsMath.Box.Set(arg,this.mlist.data.style,this.mlist.data.size,1).Remeasured();
|
||||
var frame = jsMath.HTML.Frame(-f,-box.d-f,box.w+2*f,box.h+box.d+2*f);
|
||||
box.html = frame + box.html + jsMath.HTML.Spacer(f);
|
||||
box.h += f; box.d += f; box.w +=2*f; box.x += f;
|
||||
box.bh = Math.max(box.bh,box.h); box.bd = Math.max(box.bd,box.d);
|
||||
this.mlist.Add(jsMath.mItem.Atom('ord',box));
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {font: 'Font'},
|
||||
fontCS: {},
|
||||
|
||||
/*
|
||||
* Get a CS name or give an error
|
||||
*/
|
||||
GetCSname: function (cmd) {
|
||||
var c = this.GetNext();
|
||||
if (c != this.cmd) {this.Error(cmd+" must be followed by a control sequence"); return null}
|
||||
var cs = this.trimSpaces(this.GetArgument(cmd)); if (this.error) {return null};
|
||||
return cs.substr(1);
|
||||
},
|
||||
|
||||
/*
|
||||
* Handle the \font command
|
||||
*/
|
||||
Font: function (name) {
|
||||
var cs = this.GetCSname(this.cmd+name); if (this.error) return;
|
||||
while (this.nextIsSpace()) {this.i++}
|
||||
if (this.string.charAt(this.i++) == '=') {
|
||||
while (this.nextIsSpace()) {this.i++}
|
||||
var font = this.string.slice(this.i).match(/^[a-z]+[0-9]+/i);
|
||||
if (font) {
|
||||
this.i += (new String(font)).length;
|
||||
if (jsMath.TeX.famName[font] != null) {
|
||||
this.macros[cs] = ['HandleFont',jsMath.TeX.famName[font]];
|
||||
} else {
|
||||
this.macros[cs] = ['Extension',jsMath.Font.URL(font),"fontCS"];
|
||||
this.fontCS[cs] = 1; // so Extension has something to delete
|
||||
}
|
||||
} else {this.Error("Missing font name")}
|
||||
} else {this.Error("Missing font definition")}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* extensions/leaders.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \overbrace, \underbrace, \overrightarrow
|
||||
* and \overleftarrow macros. It will be loaded automatically when needed,
|
||||
* or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('leaders');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Add(jsMath.Box,{
|
||||
|
||||
/*
|
||||
* Create a horizontally stretchable "delimiter" (like over- and
|
||||
* underbraces).
|
||||
*/
|
||||
//### Add size?
|
||||
Leaders: function (W,leader) {
|
||||
var h; var d; var w; var html; var font;
|
||||
if (leader.lmid) {// braces
|
||||
font = jsMath.TeX.fam[leader.left[0]];
|
||||
var left = this.GetCharCode(leader.left);
|
||||
var right = this.GetCharCode(leader.right);
|
||||
var lmid = this.GetCharCode(leader.lmid);
|
||||
var rmid = this.GetCharCode(leader.rmid);
|
||||
w = (W - left.w - right.w - lmid.w - rmid.w)/2 - .1; h = .4; d = .3;
|
||||
if (w < 0) {w = 0}
|
||||
html = this.AddClass(left.tclass,left.c,left.font)
|
||||
+ jsMath.HTML.Rule(w,left.h)
|
||||
+ this.AddClass(lmid.tclass,lmid.c+rmid.c,lmid.font)
|
||||
+ jsMath.HTML.Rule(w,right.h)
|
||||
+ this.AddClass(right.tclass,right.c,right.font);
|
||||
} else { //arrows
|
||||
font = jsMath.TeX.fam[leader.rep[0]];
|
||||
var left = this.GetCharCode(leader.left? leader.left: leader.rep);
|
||||
var rep = this.GetCharCode(leader.rep);
|
||||
var right = this.GetCharCode(leader.right? leader.right: leader.rep);
|
||||
var n = Math.ceil((W - left.w - right.w + .4)/(rep.w - .3));
|
||||
w = (W - left.w - right.w + .4 - n*(rep.w - .3));
|
||||
if (leader.left) {h = left.h; d = left.d} else {h = right.h; d = right.d}
|
||||
if (d == null) {d = 0}; if (h == null) {h = 0}
|
||||
var html = this.AddClass(left.tclass,left.c,left.font); var m = Math.floor(n/2);
|
||||
var ext = jsMath.HTML.Place(rep.c,-.3,0);
|
||||
var ehtml = ''; for (var i = 0; i < m; i++) {ehtml += ext};
|
||||
html += this.AddClass(rep.tclass,ehtml,rep.font) + jsMath.HTML.Spacer(w);
|
||||
ehtml = ''; for (var i = m; i < n; i++) {ehtml += ext};
|
||||
html += this.AddClass(rep.tclass,ehtml,rep.font);
|
||||
if (jsMath.Browser.msieFontBug) {html += '<span style="display: none">x</span>'}
|
||||
html += jsMath.HTML.Place(this.AddClass(right.tclass,right.c,right.font),-.4,0);
|
||||
}
|
||||
w = jsMath.EmBoxFor(html).w;
|
||||
if (w != W) {
|
||||
w = jsMath.HTML.Spacer((W-w)/2);
|
||||
html = w + html + w;
|
||||
}
|
||||
var box = new jsMath.Box('html',html,W,h,d);
|
||||
box.bh = jsMath.TeX[font].h; box.bd = jsMath.TeX[font].d;
|
||||
return box;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {
|
||||
overbrace: ['HandleLeaders','downbrace',1],
|
||||
underbrace: ['HandleLeaders','upbrace',1,1,-.05],
|
||||
overrightarrow: ['HandleLeaders','rightarrow'],
|
||||
underrightarrow: ['HandleLeaders','rightarrow',null,1,-.2],
|
||||
overleftarrow: ['HandleLeaders','leftarrow'],
|
||||
underleftarrow: ['HandleLeaders','leftarrow',null,1,-.2],
|
||||
overleftrightarrow: ['HandleLeaders','leftrightarrow'],
|
||||
underleftrightarrow: ['HandleLeaders','leftrightarrow',null,1,-.2]
|
||||
},
|
||||
|
||||
/*
|
||||
* The horizontally stretchable delimiters
|
||||
*/
|
||||
leaders: {
|
||||
downbrace: {left: [3,0x7A], lmid: [3,0x7D], rmid: [3,0x7C], right: [3,0x7B]},
|
||||
upbrace: {left: [3,0x7C], lmid: [3,0x7B], rmid: [3,0x7A], right: [3,0x7D]},
|
||||
leftarrow: {left: [2,0x20], rep: [2,0x00]},
|
||||
rightarrow: {rep: [2,0x00], right: [2,0x21]},
|
||||
leftrightarrow: {left: [2,0x20], rep: [2, 0x00], right: [2,0x21]}
|
||||
},
|
||||
|
||||
/*
|
||||
* Implements \overbrace, \underbrace, etc.
|
||||
*/
|
||||
HandleLeaders: function (name,data) {
|
||||
var box = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
box = jsMath.Box.Set(box,'D',this.mlist.data.size).Remeasured();
|
||||
var leader = jsMath.Box.Leaders(box.w,this.leaders[data[0]]);
|
||||
if (data[2]) {leader.y = -leader.h-box.d+(data[3]||0)}
|
||||
else {leader.y = box.h + Math.max(0,leader.d)+(data[3]||0)}
|
||||
box.x = -(leader.w + box.w)/2;
|
||||
var space = jsMath.Box.Space((leader.w-box.w)/2);
|
||||
box = jsMath.mItem.Atom(data[1]? 'op': 'ord',
|
||||
jsMath.Box.SetList([leader,box,space],'T',this.mlist.data.size));
|
||||
box.limits = (data[1]? 1: 0);
|
||||
this.mlist.Add(box);
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* extensions/mathchoice.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the 4-way math choice. It will be loaded
|
||||
* automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('mathchoice');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Add(jsMath.mList.prototype.Atomize,{
|
||||
|
||||
/*
|
||||
* Handle a 4-way choice atom. (Rule 4)
|
||||
*/
|
||||
choice: function (style,mitem,i,mlist) {
|
||||
if (style.charAt(style.length-1) == "'") {style = style.slice(0,style.length-1)}
|
||||
var nlist = []; var M = mitem[style];
|
||||
if (!M) {M = {type: 'mlist', mlist: {mlist: []}}}
|
||||
if (M.type == 'mlist') {
|
||||
M = M.mlist.mlist;
|
||||
for (var k = 0; k < i; k++) {nlist[k] = mlist[k]}
|
||||
for (k = 0; k < M.length; k++) {nlist[i+k] = M[k]}
|
||||
for (k = i+1; k < mlist.length; k++) {nlist[nlist.length] = mlist[k]}
|
||||
return nlist;
|
||||
} else {
|
||||
mlist[i] = jsMath.mItem.Atom('ord',M);
|
||||
return mlist;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {mathchoice: 'MathChoice'},
|
||||
|
||||
/*
|
||||
* Implements \mathchoice{}{}{}{}
|
||||
*/
|
||||
MathChoice: function (name) {
|
||||
var D = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var T = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var S = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var SS = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var box = new jsMath.mItem('choice',{D: D, T: T, S: S, SS: SS});
|
||||
this.mlist.Add(new jsMath.mItem('choice',{D: D, T: T, S: S, SS: SS}));
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* extensions/mimeTeX.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file loads the mimeTeX plugin, and can be called either
|
||||
* by
|
||||
*
|
||||
* jsMath.Extension.Require('mimeTeX');
|
||||
*
|
||||
* or by using
|
||||
*
|
||||
* \require{mimeTeX}
|
||||
*
|
||||
* within a typeset equation.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Setup.Script('plugins/mimeTeX.js');
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* extensions/moreArrows.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements additional arrow macros with under- and
|
||||
* overset labels. It can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('moreArrows');
|
||||
*
|
||||
* or using \require{moreArrows} within a math formula.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Extension.Require('leaders');
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {
|
||||
xrightarrow: ['HandleArrows','rightarrow'],
|
||||
xleftarrow: ['HandleArrows','leftarrow'],
|
||||
xuprightharpoon: ['HandleArrows','uprightharpoon'],
|
||||
xupleftharpoon: ['HandleArrows','upleftharpoon'],
|
||||
xdownrightharpoon: ['HandleArrows','downrightharpoon'],
|
||||
xdownleftharpoon: ['HandleArrows','downleftharpoon']
|
||||
},
|
||||
|
||||
leaders: {
|
||||
upleftharpoon: {left: [1,0x28], rep: [2,0x00]},
|
||||
uprightharpoon: {rep: [2,0x00], right: [1,0x2A]},
|
||||
downleftharpoon: {left: [1,0x29], rep: [2,0x00]},
|
||||
downrightharpoon: {rep: [2,0x00], right: [1,0x2B]}
|
||||
},
|
||||
|
||||
HandleArrows: function (name,data) {
|
||||
var bot = this.GetBrackets(this.cmd+name); if (this.error) return;
|
||||
var top = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var box = jsMath.Box.Set(top,'S',this.mlist.data.size).Remeasured();
|
||||
var w = box.w;
|
||||
if (bot) {
|
||||
bot = this.Process(bot); if (this.error) return;
|
||||
var box = jsMath.Box.Set(bot,'S',this.mlist.data.size).Remeasured();
|
||||
w = Math.max(w,box.w);
|
||||
}
|
||||
var leader = jsMath.Box.Leaders(w+.75,this.leaders[data[0]]);
|
||||
box = jsMath.mItem.Atom('op',jsMath.Box.SetList([leader],'T',this.mlist.data.size));
|
||||
box.limits = 1; box.sup = top; box.sub = bot;
|
||||
this.mlist.Add(box);
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* extensions/newcommand.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \newcommand and \def macros. It will be
|
||||
* loaded automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('newcommand');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2005-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {
|
||||
newcommand: 'NewCommand',
|
||||
newenvironment: 'NewEnvironment',
|
||||
def: 'MacroDef'
|
||||
},
|
||||
|
||||
/*
|
||||
* Implement \newcommand{\name}[n]{...}
|
||||
*/
|
||||
NewCommand: function (name) {
|
||||
var cs = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
var n = this.trimSpaces(this.GetBrackets(this.cmd+name)); if (this.error) return;
|
||||
var def = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (n == '') {n = null}
|
||||
if (cs.charAt(0) == this.cmd) {cs = cs.substr(1)}
|
||||
if (!cs.match(/^(.|[a-z]+)$/i)) {this.Error("Illegal control sequence name for "+this.cmd+name); return}
|
||||
if (n != null && !n.match(/^[0-9]+$/)) {this.Error("Illegal number of parameters specified in "+this.cmd+name); return}
|
||||
jsMath.Parser.prototype.macros[cs] = ['Macro',def,n];
|
||||
},
|
||||
|
||||
/*
|
||||
* Implement \newenvironment{name}[n]{begincmd}{endcmd}
|
||||
*/
|
||||
NewEnvironment: function (name) {
|
||||
var env = this.trimSpaces(this.GetArgument(this.cmd+name)); if (this.error) return;
|
||||
var n = this.trimSpaces(this.GetBrackets(this.cmd+name)); if (this.error) return;
|
||||
var bdef = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
var edef = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (n == '') {n = null}
|
||||
if (n != null && !n.match(/^[0-9]+$/)) {this.Error("Illegal number of parameters specified in "+this.cmd+name); return}
|
||||
jsMath.Parser.prototype.environments[env] = ['Environment',bdef,edef,n];
|
||||
},
|
||||
|
||||
/*
|
||||
* Implement \def command
|
||||
*/
|
||||
MacroDef: function (name) {
|
||||
var cs = this.GetCSname(this.cmd+name); if (this.error) return;
|
||||
var params = this.GetTemplate(this.cmd+name); if (this.error) return;
|
||||
var def = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (typeof(params) == 'number') {
|
||||
jsMath.Parser.prototype.macros[cs] = ['Macro',def,params];
|
||||
} else {
|
||||
jsMath.Parser.prototype.macros[cs] = ['MacroWithTemplate',def,params[0],params[1]];
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Get a CS name or give an error
|
||||
*/
|
||||
GetCSname: function (cmd) {
|
||||
var c = this.GetNext();
|
||||
if (c != this.cmd) {this.Error(cmd+" must be followed by a control sequence"); return null}
|
||||
var cs = this.trimSpaces(this.GetArgument(cmd)); if (this.error) {return null};
|
||||
return cs.substr(1);
|
||||
},
|
||||
|
||||
/*
|
||||
* Get a \def parameter template
|
||||
*/
|
||||
GetTemplate: function (cmd) {
|
||||
var c; var params = []; var 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]/)) {this.Error("Illegal use of # in "+cmd); return null}
|
||||
if (1*c != ++n) {this.Error("Parameters must be numbered sequentially"); return null}
|
||||
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++;
|
||||
}
|
||||
this.Error("Missing replacement string for definition of "+cmd);
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Process a macro with a parameter template
|
||||
*/
|
||||
MacroWithTemplate: function (name,data) {
|
||||
var text = data[0];
|
||||
var n = data[1]; var params = data[2];
|
||||
if (n) {
|
||||
var args = []; var c = this.GetNext();
|
||||
if (params[0] && !this.MatchParam(params[0]))
|
||||
{this.Error("Use of "+this.cmd+name+" doesn't match its definition"); return}
|
||||
for (var i = 0; i < n; i++) {
|
||||
args[args.length] = this.GetParameter(this.cmd+name,params[i+1]);
|
||||
if (this.error) return;
|
||||
}
|
||||
text = this.SubstituteArgs(args,text);
|
||||
}
|
||||
this.string = this.AddArgs(text,this.string.slice(this.i));
|
||||
this.i = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
* Process a user-defined environment
|
||||
*/
|
||||
Environment: function (name,data) {
|
||||
var bdef = data[0]; var edef = data[1]; var n = data[2];
|
||||
if (n) {
|
||||
var args = [];
|
||||
for (var i = 0; i < n; i++) {
|
||||
args[args.length] = this.GetArgument(this.cmd+"begin{"+name+"}"); if (this.error) return;
|
||||
}
|
||||
bdef = this.SubstituteArgs(args,bdef);
|
||||
}
|
||||
var text = this.GetEnd(name); if (this.error) return;
|
||||
text = this.AddArgs(this.AddArgs(bdef,text),edef);
|
||||
this.string = this.AddArgs(text,this.string.slice(this.i));
|
||||
this.i = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
* Find a single parameter delimited by a trailing template
|
||||
*/
|
||||
GetParameter: function (name,param) {
|
||||
if (param == null) {return this.GetArgument(name)}
|
||||
var i = this.i; var j = 0; var 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;
|
||||
}
|
||||
}
|
||||
this.Error("Runaway argument for "+name+"?");
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Check if a template is at the current location.
|
||||
* (The match must be exact, with no spacing differences. TeX is
|
||||
* a little more forgiving 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;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Define a jsMath.Environment() command similar to the
|
||||
* jsMath.Macro() command.
|
||||
*
|
||||
* Usage: jsMath.Environment(name,begin,end[,n])
|
||||
*
|
||||
* where "name" is the name of the environment, "begin" is the
|
||||
* text that replaces the \begin{name} and "end" is the text that
|
||||
* replaces the \end{name}. If "n" is provided, it is the number
|
||||
* of parameters that the \begin{name} accepts, and these are
|
||||
* used to replace #1, #2, etc within the "begin" text.
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath,{
|
||||
Environment: function (name) {
|
||||
var environments = jsMath.Parser.prototype.environments;
|
||||
environments[name] = ['Environment'];
|
||||
for (var i = 1; i < arguments.length; i++)
|
||||
{environments[name][environments[name].length] = arguments[i]}
|
||||
}
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* extensions/underset-overset.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements \underset and \overset macros. It will be loaded
|
||||
* automatically when needed, or can be loaded by
|
||||
*
|
||||
* jsMath.Extension.Require('underset-overset');
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 200-20065 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {
|
||||
overset: 'Overset',
|
||||
underset: 'Underset'
|
||||
},
|
||||
|
||||
Overset: function (name) {
|
||||
var top = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var bot = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var op = jsMath.mItem.Atom('op',bot);
|
||||
op.limits = 1; op.sup = top;
|
||||
this.mlist.Add(op);
|
||||
},
|
||||
|
||||
Underset: function (name) {
|
||||
var bot = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var top = this.ProcessArg(this.cmd+name); if (this.error) return;
|
||||
var op = jsMath.mItem.Atom('op',top);
|
||||
op.limits = 1; op.sub = bot;
|
||||
this.mlist.Add(op);
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* extensions/verb.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file implements the \verb macro. You can activate it
|
||||
* by calling
|
||||
*
|
||||
* jsMath.Extension.Macro('verb');
|
||||
*
|
||||
* which will cause the extension to be loaded only when it is
|
||||
* needed, or you can force it to be loaded via
|
||||
*
|
||||
* jsMath.Extension.Require('verb');
|
||||
*
|
||||
* once jsMath.js has been loaded, or by adding "extensions/verb.js"
|
||||
* to the loadFiles array in the easy/load.js file.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2008 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
macros: {verb: 'Verb'},
|
||||
|
||||
/*
|
||||
* Implement \verb|...|
|
||||
*/
|
||||
Verb: function (name) {
|
||||
var c = this.GetNext(); var start = ++this.i;
|
||||
if (c == "" ) {this.Error(this.cmd+name+" requires an argument"); return}
|
||||
while (this.i < this.string.length && this.string.charAt(this.i) != c) {this.i++}
|
||||
if (this.i == this.string.length)
|
||||
{this.Error("Can't find closing delimiter for "+this.cmd+name); return}
|
||||
var text = this.string.slice(start,this.i); this.i++;
|
||||
text = text.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
||||
text = '<span style="font-family:monospace">'+text+'</span>';
|
||||
var box = jsMath.Box.Text(text,'normal','T',this.mlist.data.size).Styled();
|
||||
box.h = box.bh+box.bd -jsMath.d; box.d = jsMath.d;
|
||||
this.mlist.Add(jsMath.mItem.Typeset(box));
|
||||
}
|
||||
});
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
* jsMath-BaKoMa-fonts.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed to use the BaKoMa fonts and
|
||||
* their encoding.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* The BaKoMa fonts have a different encoding, so change the characters
|
||||
* to correspond to the their encoding.
|
||||
*/
|
||||
|
||||
if (jsMath.browser == "Mozilla" && jsMath.platform != "mac") {
|
||||
|
||||
/*
|
||||
* Mozilla/PC
|
||||
*/
|
||||
jsMath.Update.TeXfontCodes({
|
||||
cmr10: [
|
||||
'Γ', 'Δ', 'Θ', 'Λ',
|
||||
'Ξ', 'Π', 'Σ', 'Υ',
|
||||
'Φ', 'Ψ', 'Ω', 'ff',
|
||||
'fi', 'fl', 'ffi', 'ffl',
|
||||
|
||||
'ı', '', '̀', '́',
|
||||
'̌', '̆', '̅', '̊',
|
||||
'̧', 'ß', 'æ', 'œ',
|
||||
'ø', 'Æ', 'Œ', 'Ø',
|
||||
|
||||
'̷', '!', '”', '#',
|
||||
'$', '%', '&', ''',
|
||||
'(', ')', '*', '+',
|
||||
',', '-', '.', '/',
|
||||
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '¡', '=', '¿', '?',
|
||||
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '“', ']', '̂', '̇',
|
||||
|
||||
'‘', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '–', '—', '̋', '̃', '̈'
|
||||
],
|
||||
|
||||
cmmi10: [
|
||||
'Γ', 'Δ', 'Θ', 'Λ',
|
||||
'Ξ', 'Π', 'Σ', 'Υ',
|
||||
'Φ', 'Ψ', 'Ω', 'α',
|
||||
'β', 'γ', 'δ', 'ε',
|
||||
|
||||
'ζ', 'η', 'θ', 'ι',
|
||||
'κ', 'λ', 'μ', 'ν',
|
||||
'ξ', 'π', 'ρ', 'σ',
|
||||
'τ', 'υ', 'φ', 'χ',
|
||||
|
||||
'ψ', 'ω', 'ɛ', 'ϑ',
|
||||
'ϖ', 'ϱ', 'ς', 'ϕ',
|
||||
'↼', '↽', '⇀', '⇁',
|
||||
'', '', '▹', '◃',
|
||||
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '.', ',', '<', '/', '>', '⋆',
|
||||
|
||||
'∂', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '♭', '♮', '♯', '⌣', '⌢',
|
||||
|
||||
'ℓ', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', 'ı', '', '℘', '⃗', '̑'
|
||||
],
|
||||
|
||||
cmsy10: [
|
||||
'−', '·', '×', '⋆',
|
||||
'÷', '⋄', '±', '∓',
|
||||
'⊕', '⊖', '⊗', '⊘',
|
||||
'⊙', '○', '∘', '∙',
|
||||
|
||||
'≃', '≍', '⊆', '⊇',
|
||||
'≤', '≥', '≼', '≽',
|
||||
'∼', '≅', '⊂', '⊃',
|
||||
'≪', '≫', '≺', '≻',
|
||||
|
||||
'←', '→', '↑', '↓',
|
||||
'↔', '↗', '↘', '≂',
|
||||
'⇐', '⇒', '⇑', '⇓',
|
||||
'⇔', '↖', '↙', '∝',
|
||||
|
||||
'′', '∞', '∈', '∋',
|
||||
'△', '▽', '̸', '',
|
||||
'∀', '∃', '¬', '∅',
|
||||
'ℜ', 'ℑ', '⊤', '⊥',
|
||||
|
||||
'ℵ', '', 'ℬ', '',
|
||||
'', 'ℰ', 'ℱ', '',
|
||||
'ℋ', 'ℐ', '', '',
|
||||
'ℒ', 'ℳ', '', '',
|
||||
|
||||
'', '', 'ℛ', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '∪',
|
||||
'∩', '⊎', '∧', '∨',
|
||||
|
||||
'⊢', '⊣', '⌊', '⌋',
|
||||
'⌈', '⌉', '{', '}',
|
||||
'〈', '〉', '∣', '∥',
|
||||
'↕', '⇕', '∖', '≀',
|
||||
|
||||
'√', '∐', '∇', '∫',
|
||||
'⊔', '⊓', '⊑', '⊒',
|
||||
'§', '†', '‡', '¶',
|
||||
'♣', '♢', '♡', '♠'
|
||||
],
|
||||
|
||||
cmex10: [
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', '',
|
||||
'', '', '', ''
|
||||
]
|
||||
});
|
||||
|
||||
/*
|
||||
* Adjust a few other characters as well
|
||||
*/
|
||||
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {'20': {c: 'ˇ', tclass: 'normal', w: .3}},
|
||||
cmmi10: {
|
||||
'20': {c: '<i>&kappa</i>', tclass: 'normal'},
|
||||
'58': {c: '.', tclass: 'normal'},
|
||||
'59': {c: ',', tclass: 'normal'},
|
||||
'61': {c: '/', tclass: 'cmr10'}
|
||||
},
|
||||
cmsy10: {
|
||||
'3': {c: '*', tclass: 'normal'},
|
||||
'16': {c: '≍'},
|
||||
'17': {c: '≡', tclass: 'normal'},
|
||||
'25': {c: '≈', tclass: 'normal'},
|
||||
'39': {c: '≃'},
|
||||
'20': {c: '≤', tclass: 'normal'}
|
||||
},
|
||||
cmex10: {'20': {c: '<span style="font-size: 80%"></span>'}},
|
||||
cmti10: {'10': {c: '<i>Ω</i>', tclass: 'normal'}},
|
||||
cmbx10: {'10': {c: '<b>Ω</b>', tclass: 'normal'}}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
jsMath.Font.BaKoMa = [
|
||||
'¡', '¢', '£', '¤', '¥', '¦', '§', '¨',
|
||||
'©', 'ª', '­', '®', '¯', '°', '±', '²',
|
||||
|
||||
'³', '´', 'µ', '¶', '∙', '¸', '¹', 'º',
|
||||
'»', '¼', '½', '¾', '¿', 'À', 'Á', 'Â',
|
||||
|
||||
'Ã', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
|
||||
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
|
||||
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '{', '|', '}', '~', 'Ä'
|
||||
];
|
||||
|
||||
jsMath.Update.TeXfontCodes({
|
||||
cmr10: jsMath.Font.BaKoMa,
|
||||
cmmi10: jsMath.Font.BaKoMa,
|
||||
cmsy10: jsMath.Font.BaKoMa,
|
||||
cmex10: jsMath.Font.BaKoMa,
|
||||
cmti10: jsMath.Font.BaKoMa,
|
||||
cmbx10: jsMath.Font.BaKoMa
|
||||
});
|
||||
|
||||
/*
|
||||
* MSIE corrections
|
||||
*/
|
||||
switch (jsMath.browser) {
|
||||
|
||||
case "MSIE":
|
||||
if (jsMath.platform == "pc") {
|
||||
/*
|
||||
* MSIE/PC
|
||||
*/
|
||||
jsMath.Browser.msieFontBug = 1;
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
|
||||
cmmi10: {
|
||||
'10': {c: '<i>Ω</i>', tclass: 'normal'},
|
||||
'126': {c: '~<span style="margin-left:.1em"></span>'}
|
||||
},
|
||||
cmsy10: {
|
||||
'10': {c: '⊗', tclass: 'arial'},
|
||||
'55': {c: '<span style="margin-right:-.54em">7</span>'}
|
||||
},
|
||||
cmex10: {'10': {c: '<span style="font-size: 67%">D</span>'}},
|
||||
cmti10: {'10': {c: '<i>Ω</i>', tclass: 'normal'}},
|
||||
cmbx10: {'10': {c: '<b>Ω</b>', tclass: 'normal'}}
|
||||
});
|
||||
} else {
|
||||
/*
|
||||
* MSIE/Mac
|
||||
*/
|
||||
jsMath.Update.TeXfonts({
|
||||
|
||||
cmr10: {
|
||||
'3': {c: '<font face="Symbol">L</font>', tclass: 'normal'},
|
||||
'5': {c: '<font face="Symbol">P</font>', tclass: 'normal'},
|
||||
'10': {c: '<font face="Symbol">W</font>', tclass: 'normal'},
|
||||
'15': {c: 'ffl', tclass: 'normal'},
|
||||
'16': {c: 'ı', tclass: 'normal'},
|
||||
'20': {c: 'ˇ', tclass: 'normal'},
|
||||
'22': {c: '¯', tclass: 'normal', w: .3},
|
||||
'25': {c: 'ß', tclass: 'normal'},
|
||||
'26': {c: 'æ', tclass: 'normal'},
|
||||
'27': {c: 'œ', tclass: 'normal'}
|
||||
},
|
||||
|
||||
cmmi10: {
|
||||
'3': {c: '<font face="Symbol">L</font>', tclass: 'italic'},
|
||||
'5': {c: '<font face="Symbol">P</font>', tclass: 'italic'},
|
||||
'10': {c: '<font face="Symbol">W</font>', tclass: 'italic'},
|
||||
'15': {c: '<font face="Symbol">e</font>', tclass: 'italic'},
|
||||
'16': {c: '<font face="Symbol">z</font>', tclass: 'italic'},
|
||||
'20': {c: '<font face="Symbol">k</font>', tclass: 'italic'},
|
||||
'22': {c: '<font face="Symbol">m</font>', tclass: 'italic'},
|
||||
'25': {c: '<font face="Symbol">p</font>', tclass: 'italic'},
|
||||
'26': {c: '<font face="Symbol">r</font>', tclass: 'italic'},
|
||||
'27': {c: '<font face="Symbol">s</font>', tclass: 'italic'}
|
||||
},
|
||||
|
||||
cmsy10: {
|
||||
'3': {c: '<span style="vertical-align:-.3em">*</span>', tclass: 'normal'},
|
||||
'5': {c: 'Ή', tclass: 'normal'},
|
||||
'10': {c: '⊗', tclass: 'normal'},
|
||||
'15': {c: '•', tclass: 'normal'},
|
||||
'16': {c: '≍', tclass: 'normal'},
|
||||
'20': {c: '≤', tclass: 'normal'},
|
||||
'22': {c: '≤', tclass: 'normal'},
|
||||
'25': {c: '≈', tclass: 'normal'},
|
||||
'26': {c: '<font face="Symbol">Ì</font>', tclass: 'normal'},
|
||||
'27': {c: '<font face="Symbol">É</font>', tclass: 'normal'}
|
||||
},
|
||||
|
||||
cmex10: {
|
||||
'3': {c: '<span style="font-size: 67%">i</span>'},
|
||||
'5': {c: '<span style="font-size: 67%">k</span>'},
|
||||
'10': {c: '<span style="font-size: 67%">D</span>'},
|
||||
'15': {c: '<span style="font-size: 55%">Â</span>'},
|
||||
'16': {c: '<span style="font-size: 83%">µ</span>'},
|
||||
'20': {c: '<span style="font-size: 83%">"</span>'},
|
||||
'22': {c: '<span style="font-size: 83%">$</span>'},
|
||||
'25': {c: '<span style="font-size: 83%">\'</span>'},
|
||||
'26': {c: '<span style="font-size: 83%">(</span>'},
|
||||
'27': {c: '<span style="font-size: 83%">)</span>'}
|
||||
},
|
||||
|
||||
cmti10: {
|
||||
'3': {c: '<font face="Symbol">L</font>', tclass: 'italic'},
|
||||
'5': {c: '<font face="Symbol">P</font>', tclass: 'italic'},
|
||||
'10': {c: '<font face="Symbol">W</font>', tclass: 'italic'},
|
||||
'16': {c: 'ı', tclass: 'italic'},
|
||||
'20': {c: '­', tclass: 'italic'},
|
||||
'22': {c: '¯', tclass: 'italic', w: .3},
|
||||
'25': {c: 'ß', tclass: 'italic'},
|
||||
'26': {c: 'æ', tclass: 'italic'},
|
||||
'27': {c: 'œ', tclass: 'italic'}
|
||||
},
|
||||
|
||||
cmbx10: {
|
||||
'3': {c: '<font face="Symbol">L</font>', tclass: 'bold'},
|
||||
'5': {c: '<font face="Symbol">P</font>', tclass: 'bold'},
|
||||
'10': {c: '<font face="Symbol">W</font>', tclass: 'bold'},
|
||||
'16': {c: 'ı', tclass: 'bold'},
|
||||
'20': {c: '­', tclass: 'bold'},
|
||||
'22': {c: '¯', tclass: 'bold', w: .3},
|
||||
'25': {c: 'ß', tclass: 'bold'},
|
||||
'26': {c: 'æ', tclass: 'bold'},
|
||||
'27': {c: 'œ', tclass: 'bold'}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "Mozilla":
|
||||
if (jsMath.platform == "mac") {
|
||||
/*
|
||||
* Mozilla/Mac
|
||||
*/
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {'10': {c: 'Ω', tclass: 'normal'}},
|
||||
cmmi10: {'10': {c: '<i>Ω</i>', tclass: 'normal'}},
|
||||
cmsy10: {'10': {c: '⊗', tclass: 'normal'}},
|
||||
cmex10: {'10': {c: '<span style="font-size: 67%">D</span>'}},
|
||||
cmti10: {'10': {c: '<i>Ω</i>', tclass: 'normal'}},
|
||||
cmbx10: {'10': {c: '<b>Ω</b>', tclass: 'normal'}}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "Opera":
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {
|
||||
'10': {c: 'Ω', tclass: 'normal'},
|
||||
'20': {c: 'ˇ', tclass: 'normal'}
|
||||
},
|
||||
cmmi10: {
|
||||
'10': {c: '<i>Ω</i>', tclass: 'normal'},
|
||||
'20': {c: 'κ', tclass: 'normal'}
|
||||
},
|
||||
cmsy10: {
|
||||
'10': {c: '⊗', tclass: 'normal'},
|
||||
'20': {c: '≤', tclass: 'normal'}
|
||||
},
|
||||
cmex10: {
|
||||
'10': {c: '<span style="font-size: 67%">D</span>'},
|
||||
'20': {c: '<span style="font-size: 82%">"</span>'}
|
||||
},
|
||||
cmti10: {
|
||||
'10': {c: '<i>Ω</i>', tclass: 'normal'},
|
||||
'20': {c: '<i>ˇ</i>', tclass: 'normal'}
|
||||
},
|
||||
cmbx10: {
|
||||
'10': {c: '<b>Ω</b>', tclass: 'normal'},
|
||||
'20': {c: '<b>ˇ</b>', tclass: 'normal'}
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case "Konqueror":
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {'20': {c: 'ˇ', tclass: 'normal'}},
|
||||
cmmi10: {'20': {c: 'κ', tclass: 'normal'}},
|
||||
cmsy10: {'20': {c: '≤', tclass: 'normal'}},
|
||||
cmex10: {'20': {c: '<span style="font-size: 84%">"</span>'}},
|
||||
cmti10: {'20': {c: '<i>ˇ</i>', tclass: 'normal'}},
|
||||
cmbx10: {'20': {c: '<b>ˇ</b>', tclass: 'normal'}}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .cmr10': 'font-family: CMR10, serif',
|
||||
'.typeset .cmbx10': 'font-family: CMBX10, CMR10',
|
||||
'.typeset .cmti10': 'font-family: CMTI10, CMR10',
|
||||
'.typeset .cmmi10': 'font-family: CMMI10',
|
||||
'.typeset .cmsy10': 'font-family: CMSY10',
|
||||
'.typeset .cmex10': 'font-family: CMEX10',
|
||||
'.typeset .arial': "font-family: 'Arial unicode MS'"
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-autoload.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file is used for loading jsMath.js and other components
|
||||
| when the "autoload" plugin is used.
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2004-2006 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var isOmniWeb4 = (document.readyState &&
|
||||
document.readyState == 'loading' &&
|
||||
navigator.accentColorName != null &&
|
||||
navigator.omniWebString == null);
|
||||
window.jsMath = window.parent.jsMath;
|
||||
window.jsMathAutoload = 1;
|
||||
if (isOmniWeb4) {
|
||||
if (jsMath.Autoload.Script.url != jsMath.Autoload.Script.prevURL) {
|
||||
jsMath.Autoload.Script.prevURL = jsMath.Autoload.Script.url;
|
||||
document.write('<script src="'+jsMath.Autoload.Script.url+'"><'+'/script>');
|
||||
document.write('<script src="jsMath-loader-omniweb4.js"><'+'/script>');
|
||||
}
|
||||
} else {
|
||||
document.write('<script src="'+jsMath.Autoload.Script.url+'"><'+'/script>');
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (window.jsMath && !isOmniWeb4) {jsMath.Autoload.Script.endLoad()}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,467 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-controls.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file handles the details of the jsMath control panels
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2004-2007 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var showWarning = 0;
|
||||
var domain = document.domain || "";
|
||||
var mustPost = ((domain == "" || domain == "localhost") && window.postMessage);
|
||||
while (!window.jsMath && !showWarning) {
|
||||
try {
|
||||
window.jsMath = window.parent.jsMath;
|
||||
if (!window.jsMath) {throw "no jsMath";}
|
||||
} catch (err) {
|
||||
showWarning = 1; pageDomain = '';
|
||||
try {pageDomain = document.domain} catch (err) {}
|
||||
//
|
||||
// MSIE on Mac can't change document.domain, and 'try' won't
|
||||
// catch the error (Grrr!) so don't even attempt it.
|
||||
//
|
||||
if (pageDomain.match(/\..*\./) &&
|
||||
(navigator.appName != 'Microsoft Internet Explorer' ||
|
||||
!navigator.platform.match(/Mac/) || !navigator.userProfile || !document.all)) {
|
||||
try {
|
||||
document.domain = pageDomain.replace(/^[^.]*\./,'');
|
||||
showWarning = 0;
|
||||
} catch(err) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Warning () {
|
||||
alert(
|
||||
"jsMath can't open the control panel, since jsMath was not " +
|
||||
"obtained from a server that is in the same domain as the " +
|
||||
"page that loaded it."
|
||||
);
|
||||
}
|
||||
|
||||
if (showWarning) {
|
||||
if (!mustPost) setTimeout("Warning()",1);
|
||||
} else {
|
||||
var debug = window.parent.debug;
|
||||
var show = window.parent.show;
|
||||
}
|
||||
</SCRIPT>
|
||||
|
||||
<SCRIPT ID="jsMath_script">
|
||||
if (window.jsMath) {
|
||||
|
||||
jsMath.Add(jsMath.Controls,{
|
||||
|
||||
loaded: 1,
|
||||
|
||||
mainLabels: {
|
||||
print: 'Print', reload: 'Reload', local: 'Go Local', global: 'Go Global',
|
||||
ctrls: 'Controls', opts: 'Options', done: 'Done'
|
||||
},
|
||||
optionLabels: {back: 'Back', done: 'Done'},
|
||||
|
||||
Close: function () {
|
||||
this.panel.style.display = "none";
|
||||
jsMath.Element("button").style.display = (this.cookie.button ? "block" : "none");
|
||||
if (jsMath.document.location.protocol == 'file:' && jsMath.Global.islocal) return;
|
||||
for (var id in {scale:1, scaleImg:1, font:1, print:1, printwarn:1,
|
||||
stayhires:1, autofont:1, alpha:1, tex2math:1, global:1}) {
|
||||
if (this.cookie[id] && this.cookie[id] != this.oldCookie[id] &&
|
||||
this.oldCookie[id] != null) {
|
||||
this.Reload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Main: function () {
|
||||
this.oldCookie = {}; jsMath.Add(this.oldCookie,this.cookie);
|
||||
this.GetPanel("main");
|
||||
|
||||
jsMath.Element("_version").innerHTML = jsMath.version;
|
||||
|
||||
jsMath.Element("_fontType").innerHTML =
|
||||
({tex:"TeX",
|
||||
image:"Image",
|
||||
symbol:"Image symbol",
|
||||
unicode:"Unicode"})[this.cookie.font];
|
||||
|
||||
jsMath.Element("_mailto").href =
|
||||
"mailto:dpvc@union.edu?subject=Bug Report for jsMath "
|
||||
+ jsMath.version + " (using " + jsMath.browser
|
||||
+ " in " + this.cookie.font + " mode)";
|
||||
|
||||
if (this.cookie.print ||
|
||||
(this.cookie.font != 'image' && this.cookie.font != 'symbol'))
|
||||
{jsMath.Element("_resolution").disabled = true}
|
||||
|
||||
if (jsMath.Global.isLocal) {
|
||||
jsMath.Element("_ctrls").disabled = true;
|
||||
} else {
|
||||
this.cookie.hiddenGlobal = jsMath.Global.isHidden;
|
||||
jsMath.Element("_global").style.display = "none";
|
||||
jsMath.Element("_local").style.display = "";
|
||||
if (!jsMath.Global.isHidden || jsMath.noShowGlobal)
|
||||
{jsMath.Element("_ctrls").disabled = true}
|
||||
}
|
||||
if (jsMath.noChangeGlobal) {
|
||||
for (var id in {global:1, local:1, ctrls: 1})
|
||||
{jsMath.Element('_'+id).disabled = true}
|
||||
}
|
||||
if (!window.print) {jsMath.Element("_print").disabled = true}
|
||||
|
||||
if (jsMath.Browser.safariButtonBug) {
|
||||
for (var id in this.mainLabels)
|
||||
{jsMath.Element('_'+id).value = this.mainLabels[id]}
|
||||
}
|
||||
|
||||
this.panel.style.display = "block";
|
||||
this.openMain = 0;
|
||||
},
|
||||
|
||||
Options: function () {
|
||||
this.GetPanel("options");
|
||||
jsMath.Element("_scale").value = this.cookie.scale;
|
||||
jsMath.Element("_keep").value = this.cookie.keep;
|
||||
jsMath.Element("_global").value = this.cookie.global;
|
||||
for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, printwarn: 1,
|
||||
stayhires: 1, button:1, progress:1, asynch:1, blank:1, tex2math:1}) {
|
||||
if (this.cookie[id]) {jsMath.Element('_'+id).checked = true}
|
||||
}
|
||||
var font = jsMath.document.getElementsByName("jsMath__font");
|
||||
for (var i = 0; i < font.length; i++) {
|
||||
if ((font[i].value == 'tex' && jsMath.nofonts) ||
|
||||
((font[i].value == 'symbol' || font[i].value == 'image') &&
|
||||
jsMath.noImgFonts)) {
|
||||
jsMath.Element('_'+font[i].value+"Text").className = "disabled";
|
||||
font[i].disabled = true;
|
||||
}
|
||||
else if (this.cookie.font == font[i].value) {font[i].checked = true}
|
||||
}
|
||||
if (jsMath.noImgFonts) {
|
||||
for (var id in {alpha:1, printwarn:1, stayhires:1}) {
|
||||
var obj = jsMath.Element("_"+id);
|
||||
obj.disabled = true;
|
||||
obj.parentNode.className = "disabled";
|
||||
}
|
||||
} else if (jsMath.Browser.imgScale != 1) {
|
||||
jsMath.Element("_alphaText").className = "disabled";
|
||||
jsMath.Element("_alpha").disabled = true;
|
||||
}
|
||||
if (jsMath.tex2math.Convert) {
|
||||
jsMath.Element("_separator").style.display = '';
|
||||
jsMath.Element("_tex2mathRow").style.display = '';
|
||||
}
|
||||
if (jsMath.noChangeGlobal) {
|
||||
jsMath.Element("_globalText").className = "disabled";
|
||||
jsMath.Element("_global").disabled = true;
|
||||
}
|
||||
if (jsMath.isCHMmode) {
|
||||
jsMath.Element("_asynchText").className = "disabled";
|
||||
jsMath.Element("_asynch").disabled = true;
|
||||
}
|
||||
|
||||
if (jsMath.Browser.safariButtonBug) {
|
||||
for (var id in this.optionLabels)
|
||||
{jsMath.Element('_'+id).value = this.optionLabels[id]}
|
||||
}
|
||||
|
||||
this.panel.style.display = "block";
|
||||
|
||||
if (jsMath.Browser.msieMoveButtonHack) {
|
||||
this.panel.style.left = "0px";
|
||||
this.panel.style.top = "0px";
|
||||
jsMath.Controls.MoveButton();
|
||||
}
|
||||
},
|
||||
|
||||
HTML: {}, // storage for panels for Firefox3 in local mode
|
||||
|
||||
GetPanel: function (name) {
|
||||
this.panel.innerHTML = ""; // for MSIE on the Mac
|
||||
var html = this.HTML[name];
|
||||
if (html == null) {html = document.getElementById("jsMath_"+name).innerHTML}
|
||||
this.panel.innerHTML = html;
|
||||
},
|
||||
|
||||
SaveOptions: function (close) {
|
||||
this.cookie.scale = jsMath.Element("_scale").value;
|
||||
var font = jsMath.document.getElementsByName("jsMath__font");
|
||||
for (var i = 0; i < font.length; i++)
|
||||
{if (font[i].checked) {this.cookie.font = font[i].value}}
|
||||
for (var id in {autofont:1, scaleImg:1, alpha:1, warn:1, printwarn: 1,
|
||||
stayhires: 1, button:1, progress:1, asynch:1, blank:1, tex2math:1}) {
|
||||
if (this.cookie[id] != null) {
|
||||
this.cookie[id] = jsMath.Element('_'+id).checked ? 1: 0;
|
||||
}
|
||||
}
|
||||
this.cookie.keep = jsMath.Element("_keep").value;
|
||||
this.cookie.global = jsMath.Element("_global").value;
|
||||
this.cookie.print = this.cookie.stayhires;
|
||||
this.SetCookie(1);
|
||||
if (close) {this.Close()} else {this.Main()}
|
||||
},
|
||||
|
||||
PrintResolution: function () {
|
||||
this.cookie.print = 1;
|
||||
this.SetCookie(1);
|
||||
this.Close();
|
||||
},
|
||||
|
||||
Print: function () {
|
||||
this.Close();
|
||||
jsMath.window.print();
|
||||
},
|
||||
|
||||
GoGlobal: function () {
|
||||
this.cookie.global = "always";
|
||||
jsMath.Global.GoGlobal(this.SetCookie(2));
|
||||
},
|
||||
GoLocal: function () {jsMath.Global.GoLocal()},
|
||||
|
||||
ShowControls: function () {
|
||||
this.Close();
|
||||
jsMath.Global.Show();
|
||||
},
|
||||
|
||||
NoAuto: function () {jsMath.Element("_autofont").checked = false}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Add(jsMath.Post.Commands,{
|
||||
PAN: function (message) {jsMath.Controls.HTML.main = message},
|
||||
OPT: function (message) {jsMath.Controls.HTML.options = message},
|
||||
|
||||
PST: function (message) {
|
||||
jsMath.Controls.Main();
|
||||
jsMath.Script.endLoad();
|
||||
jsMath.Message.doClear();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<!------------------------------------------------------------>
|
||||
|
||||
<div id="jsMath_main">
|
||||
<div style="text-align:center">
|
||||
<b style="font-size:133%">jsMath v<span ID="jsMath__version"></span></b>
|
||||
(<span id="jsMath__fontType">type</span> fonts)
|
||||
[<a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/main.html">help</a>]
|
||||
<p style="margin-bottom:0px">
|
||||
<table border="0" cellspacing="0" cellpadding="0" style="margin:0px">
|
||||
<tr valign="middle"><td align="center">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/quickstart.html">Quick Start</a></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/fonts.html">Missing Fonts</a></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/printing.html">Printing Issues</a></td></tr>
|
||||
<tr><td height="5"></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath">Home Page</a></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/">Documentation</a></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="https://sourceforge.net/forum/?group_id=172663">User Community</a></td></tr>
|
||||
<tr><td height="5"></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/bugs.html">Known Bugs</a></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a id="jsMath__mailto" href="mailto:dpvc@union.edu?subject=jsMath Bug Report">Report a Bug</a></td></tr>
|
||||
<tr><td height="5"></td></tr>
|
||||
<tr><td class="infoLink" align="left">• <a target="_blank" href="http://www.math.union.edu/locate/jsMath/jsMath/COPYING.txt">License</a></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td style="width:1em"> </td>
|
||||
|
||||
<td align="center">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr><td align="center" colspan="3">
|
||||
<input type="button" id="jsMath__resolution" value="Hi-Res Fonts for Printing"
|
||||
style="width:18em" onclick="jsMath.Controls.PrintResolution()" />
|
||||
</td></tr>
|
||||
|
||||
<tr><td height="8"></td></tr>
|
||||
|
||||
<tr valign="bottom"><td align="left">
|
||||
<input type="button" value="Print" id="jsMath__print" style="width:8em" onclick="jsMath.Controls.Print()" /><br />
|
||||
<input type="button" value="Reload" id="jsMath__reload" style="width:8em" style="width:8em" onclick="jsMath.window.location.reload()" /><br />
|
||||
</td><td>
|
||||
|
||||
</td><td align="right">
|
||||
<input type="button" value="Go Global" id="jsMath__global" style="width:8em" onclick="jsMath.Controls.GoGlobal()"a /><!--
|
||||
--><input type="button" value="Go Local" id="jsMath__local" style="width:8em;display:none" onclick="jsMath.Controls.GoLocal()" /><br />
|
||||
<input type="button" value="Controls" id="jsMath__ctrls" style="width:8em" onclick="jsMath.Controls.ShowControls()" /><br/>
|
||||
</td></tr>
|
||||
|
||||
<tr><td height="8"></td></tr>
|
||||
|
||||
<tr valign="bottom"><td align="left">
|
||||
<input type="button" value="Options" id="jsMath__opts" style="width:8em" onclick="jsMath.Controls.Options()" /><br/>
|
||||
</td><td>
|
||||
|
||||
</td><td align="right">
|
||||
<input type="button" value="Done" id="jsMath__done" style="width:8em" onclick="jsMath.Controls.Close()" />
|
||||
</td></tr>
|
||||
</table></td></tr>
|
||||
|
||||
<tr><td height="10"></td></tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3" align="center" style="width:26em">
|
||||
<i style="font-size:75%">Click the jsMath button or <nobr>ALT-click</nobr>
|
||||
on mathematics to reopen this panel.</i>
|
||||
</td></tr>
|
||||
|
||||
</table></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!------------------------------------------------------------>
|
||||
|
||||
<div id="jsMath_options">
|
||||
<div style="text-align:center">
|
||||
<b style="font-size:133%">jsMath Options</b>
|
||||
[<a target="_blank" href="http://www.math.union.edu/locate/jsMath/users/help.html">help</a>]
|
||||
<p>
|
||||
<form action="javascript:" style="margin:0px">
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr valign="top"><td>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="0" style="text-align:left">
|
||||
|
||||
<tr><td><input type="checkbox" id="jsMath__autofont" value="1" /> Autoselect best font</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__warn" value="1" /> Show font warnings</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__alpha" value="1" /> Use image alpha channels</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__printwarn" value="1" /> Print image-font help</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__stayhires" value="1" /> Always use hi-res fonts</td></tr>
|
||||
|
||||
<tr><td style="height:.8em"></td></tr>
|
||||
|
||||
<tr><td><input type="checkbox" id="jsMath__progress" value="1" /> Show progress messages</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__asynch" value="1" /> <span id="jsMath__asynchText">Force asynchronous processing</span></td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__blank" value="1" /> Don't show page until complete</td></tr>
|
||||
<tr><td><input type="checkbox" id="jsMath__button" value="1" /> Show jsMath button</td></tr>
|
||||
|
||||
<tr id="jsMath__separator" style="display:none"><td style="height:.8em"></td></tr>
|
||||
|
||||
<tr id="jsMath__tex2mathRow" style="display:none"><td><input type="checkbox" id="jsMath__tex2math" value="1" /> Enable <code>tex2math</code> plug-in</td></tr>
|
||||
|
||||
</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
<td style="width:2em"></td>
|
||||
<td>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="0" style="text-align:left">
|
||||
<tr><td>Scale all mathematics to <input type="text" id="jsMath__scale" value="100" size="3" />%</td></tr>
|
||||
|
||||
<tr><td style="height:.5em"></td></tr>
|
||||
|
||||
<tr><td><input type="radio" name="jsMath__font" value="tex" onclick="jsMath.Controls.NoAuto()" />
|
||||
<span id="jsMath__texText">Use native TeX fonts</span>
|
||||
<small>(<a target="_blank" href="http://www.math.union.edu/locate/jsMath/download/jsMath-fonts.html">download</a>)</small>
|
||||
</td></tr>
|
||||
<tr><td><input type="radio" name="jsMath__font" value="image" onclick="jsMath.Controls.NoAuto()" />
|
||||
<span id="jsMath__imageText">Use image fonts
|
||||
<span id="jsMath__scaleImgText">(<input type="checkbox" id="jsMath__scaleImg" value="1" /> scalable)</span></span></td></tr>
|
||||
<tr><td><input type="radio" name="jsMath__font" value="symbol" onclick="jsMath.Controls.NoAuto()" />
|
||||
<span id="jsMath__symbolText">Use images for symbols only</span></td></tr>
|
||||
<tr><td height="2"></td></tr>
|
||||
<tr><td><input type="radio" name="jsMath__font" value="unicode" onclick="jsMath.Controls.NoAuto()" />
|
||||
Use native Unicode fonts</td></tr>
|
||||
|
||||
<tr><td style="height:1em"></td></tr>
|
||||
|
||||
<tr><td align="center"><span id="jsMath__globalText">Use Global mode</span>
|
||||
<select id="jsMath__global">
|
||||
<option value="auto">when requested
|
||||
<option value="always">always
|
||||
<option value="never">never
|
||||
</select>
|
||||
</td></tr>
|
||||
<tr><td height="3"></td></tr>
|
||||
<tr><td>Save settings for
|
||||
<select id="jsMath__keep">
|
||||
<option value="0D">this session only
|
||||
<option value="1D">1 day
|
||||
<option value="2D">2 days
|
||||
<option value="3D">3 days
|
||||
<option value="1W">1 week
|
||||
<option value="2W">2 weeks
|
||||
<option value="1M">1 month
|
||||
<option value="2M">2 months
|
||||
<option value="3M">3 months
|
||||
<option value="6M">6 months
|
||||
<option value="1Y">1 year
|
||||
<option value="5Y">5 years
|
||||
</select>
|
||||
</td></tr>
|
||||
|
||||
<tr><td style="height:1em"></td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<table border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<tr>
|
||||
<td align="left">
|
||||
<input type="button" value="Back" id="jsMath__back" style="width:8em" onclick="jsMath.Controls.SaveOptions(0)" />
|
||||
|
||||
</td>
|
||||
<td align="right">
|
||||
<input type="button" value="Done" id="jsMath__done" style="width:8em" onclick="jsMath.Controls.SaveOptions(1)" />
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<!------------------------------------------------------------>
|
||||
|
||||
<script>
|
||||
if (showWarning) {
|
||||
if (mustPost) {
|
||||
var scr = document.getElementById("jsMath_script");
|
||||
window.parent.postMessage("jsMCP:SCR:"+scr.innerHTML,"*");
|
||||
var main = document.getElementById("jsMath_main");
|
||||
window.parent.postMessage("jsMCP:PAN:"+main.innerHTML,"*");
|
||||
var options = document.getElementById("jsMath_options");
|
||||
window.parent.postMessage("jsMCP:OPT:"+options.innerHTML,"*");
|
||||
window.parent.postMessage("jsMCP:PST:","*");
|
||||
}
|
||||
} else {
|
||||
jsMath.Controls.Main()
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
if (window.jsMath) {
|
||||
jsMath.Script.endLoad();
|
||||
jsMath.Message.doClear();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* jsMath-easy-load.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file is used to load jsMath with one easy <SCRIPT>
|
||||
* command in your HTML file. It is called by the files
|
||||
* in the jsMath/easy/ directory. It expects that the jsMath.Easy
|
||||
* array has been initialized before it is called.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
if (!jsMath.Easy) {jsMath.Easy = {}}
|
||||
if (!jsMath.tex2math) {jsMath.tex2math = {}}
|
||||
|
||||
jsMath.tex2math.doubleDollarsAreInLine = jsMath.Easy.doubleDollarsAreInLine;
|
||||
jsMath.tex2math.allowDisableTag = jsMath.Easy.allowDisableTag;
|
||||
|
||||
jsMath.safeHBoxes = jsMath.Easy.safeHBoxes;
|
||||
|
||||
if (jsMath.Easy.scale) {
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
if (!jsMath.Controls.cookie) {jsMath.Controls.cookie = {}}
|
||||
jsMath.Controls.cookie.scale = jsMath.Easy.scale;
|
||||
}
|
||||
if (!jsMath.Easy.allowDoubleClicks) {
|
||||
if (!jsMath.Click) {jsMath.Click = {}}
|
||||
jsMath.Click.CheckDblClick = function () {};
|
||||
}
|
||||
if (!jsMath.Easy.showFontWarnings) {
|
||||
if (!jsMath.Font) {jsMath.Font = {}}
|
||||
jsMath.Font.Message = function () {};
|
||||
}
|
||||
|
||||
if (!jsMath.Easy.allowGlobal) {
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
if (!jsMath.Controls.cookie) {jsMath.Controls.cookie = {}}
|
||||
jsMath.Controls.cookie.global = 'never';
|
||||
jsMath.noGoGlobal = 1;
|
||||
jsMath.noChangeGlobal = 1;
|
||||
jsMath.noShowGlobal = 1;
|
||||
}
|
||||
|
||||
if (jsMath.Easy.noImageFonts) {
|
||||
jsMath.noImgFonts = 1;
|
||||
if (!jsMath.Font) {jsMath.Font = {}}
|
||||
jsMath.Font.extra_message =
|
||||
'Extra TeX fonts not found: <b><span id="jsMath_ExtraFonts"></span></b><br/>'
|
||||
+ 'Using unicode fonts instead. This may be slow and might not print well.<br/>\n'
|
||||
+ 'Use the jsMath control panel to get additional information.';
|
||||
}
|
||||
|
||||
if (jsMath.Easy.processSingleDollars ||
|
||||
jsMath.Easy.processDoubleDollars ||
|
||||
jsMath.Easy.processSlashParens ||
|
||||
jsMath.Easy.processSlashBrackets ||
|
||||
jsMath.Easy.fixEscapedDollars) {
|
||||
|
||||
jsMath.Easy.findCustomSettings = {
|
||||
processSingleDollars: jsMath.Easy.processSingleDollars,
|
||||
processDoubleDollars: jsMath.Easy.processDoubleDollars,
|
||||
processSlashParens: jsMath.Easy.processSlashParens,
|
||||
processSlashBrackets: jsMath.Easy.processSlashBrackets,
|
||||
processLaTeXenvironments: jsMath.Easy.processLaTeXenvironments,
|
||||
fixEscapedDollars: jsMath.Easy.fixEscapedDollars,
|
||||
custom: 0
|
||||
}
|
||||
}
|
||||
|
||||
if (!jsMath.Autoload) {jsMath.Autoload = {}}
|
||||
jsMath.Autoload.root = jsMath.Easy.root+'/';
|
||||
|
||||
if (jsMath.Easy.autoload) {
|
||||
jsMath.Autoload.findTeXstrings = 0;
|
||||
jsMath.Autoload.findLaTeXstrings = 0;
|
||||
jsMath.Autoload.findCustomStrings = jsMath.Easy.customDelimiters;
|
||||
jsMath.Autoload.findCustomSettings = jsMath.Easy.findCustomSettings;
|
||||
jsMath.Autoload.loadFiles = jsMath.Easy.loadFiles;
|
||||
jsMath.Autoload.loadFonts = jsMath.Easy.loadFonts;
|
||||
jsMath.Autoload.macros = jsMath.Easy.macros;
|
||||
jsMath.Autoload.delayCheck = 1;
|
||||
jsMath.Easy.autoloadCheck = 1;
|
||||
document.write('<script src="'+jsMath.Autoload.root+'plugins/autoload.js"></script>');
|
||||
|
||||
} else {
|
||||
jsMath.Easy.tex2math =
|
||||
(jsMath.Easy.processSingleDollars ||
|
||||
jsMath.Easy.processDoubleDollars ||
|
||||
jsMath.Easy.processSlashParens ||
|
||||
jsMath.Easy.processSlashBrackets ||
|
||||
jsMath.Easy.processLaTeXenvironments ||
|
||||
jsMath.Easy.fixEscapedDollars ||
|
||||
jsMath.Easy.customDelimiters);
|
||||
|
||||
if (!jsMath.Setup) {jsMath.Setup = {}}
|
||||
if (!jsMath.Setup.UserEvent) {jsMath.Setup.UserEvent = {}}
|
||||
jsMath.Setup.UserEvent.onload = function () {
|
||||
var easy = jsMath.Easy;
|
||||
if (easy.tex2math) jsMath.Setup.Script("plugins/tex2math.js");
|
||||
var i;
|
||||
if (easy.loadFiles) {
|
||||
for (i = 0; i < easy.loadFiles.length; i++)
|
||||
jsMath.Setup.Script(easy.loadFiles[i]);
|
||||
}
|
||||
if (easy.loadFonts) {
|
||||
for (i = 0; i < easy.loadFonts.length; i++)
|
||||
jsMath.Font.Load(easy.loadFonts[i]);
|
||||
}
|
||||
if (easy.macros) {
|
||||
for (i in easy.macros) {
|
||||
if (typeof(easy.macros[i]) == 'string') {
|
||||
jsMath.Macro(i,easy.macros[i]);
|
||||
} else {
|
||||
jsMath.Macro(i,easy.macros[i][0],easy.macros[i][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
document.write('<script src="'+jsMath.Easy.root+'/jsMath.js"></script>'+"\n");
|
||||
}
|
||||
|
||||
jsMath.Easy.onload = function () {
|
||||
if (jsMath.Easy.loaded) {return} else {jsMath.Easy.loaded = 1}
|
||||
if (jsMath.Easy.autoloadCheck) jsMath.Autoload.Check();
|
||||
if (jsMath.Easy.tex2math) {
|
||||
jsMath.Synchronize(function () {
|
||||
if (jsMath.Easy.findCustomSettings)
|
||||
jsMath.tex2math.Convert(document,jsMath.Easy.findCustomSettings);
|
||||
if (jsMath.Easy.customDelimiters) {
|
||||
var s = jsMath.Easy.customDelimiters;
|
||||
jsMath.tex2math.CustomSearch(s[0],s[1],s[2],s[3]);
|
||||
jsMath.tex2math.ConvertCustom();
|
||||
}
|
||||
});
|
||||
}
|
||||
(jsMath[jsMath.Easy.method])();
|
||||
}
|
||||
|
||||
if (window.addEventListener) {window.addEventListener("load",jsMath.Easy.onload,false)}
|
||||
else if (window.attachEvent) {window.attachEvent("onload",jsMath.Easy.onload)}
|
||||
else {window.onload = jsMath.Easy.onload}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* jsMath-fallback-mac-mozilla.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed by Mozilla-based browsers on the Mac
|
||||
* for when the TeX fonts are not available.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* Fix the default non-TeX-font characters to work with Mozilla
|
||||
*
|
||||
*/
|
||||
|
||||
jsMath.Update.TeXfonts({
|
||||
cmmi10: {
|
||||
// '41': // leftharpoondown
|
||||
// '43': // rightharpoondown
|
||||
'44': {c: '<span style="position:relative; top:.15em; margin-right:-.1em; margin-left:-.2em">˓</span>'},
|
||||
'45': {c: '<span style="position:relative; top:.15em; margin-right:-.1em; margin-left:-.2em">˒</span>'},
|
||||
'47': {c: '<span style="font-size:60%">◁</span>'},
|
||||
// '92': // natural
|
||||
'126': {c: '<span style="position:relative; left: .3em; top: -.7em; font-size: 50%">→</span>'}
|
||||
},
|
||||
|
||||
cmsy10: {
|
||||
'0': {c: '–', tclass: 'normal'},
|
||||
'11': {c: '<span style="font-size: 70%">◯</span><span style="position:relative; margin-left:-.5em; top:.1em; margin-right:.3em">/</span>', tclass: 'normal'},
|
||||
'42': {c: '⥣'}, '43': {c: '⥥'},
|
||||
'48': {c: '<span style="font-size: 133%; margin-right: -.75em; position: relative; top:.4em">′</span>', tclass: 'normal'},
|
||||
'93': {c: '∪<span style="font-size: 50%; margin-left:-1.3em; position: relative; top:-.3em; margin-right:.6em">+</span>'},
|
||||
'104': {c: '<span style="position:relative; top:.15em; margin-left:-.6em">〈</span>'},
|
||||
'105': {c: '<span style="position:relative; top:.15em; margin-right:-.6em">〉</span>'},
|
||||
'109': {c: '⥣<span style="position:relative; top:.1em; margin-left:-1em">⥥</span>'}
|
||||
//, '116': // sqcup
|
||||
// '117': // sqcap
|
||||
// '118': // sqsubseteq
|
||||
// '119': // sqsupseteq
|
||||
},
|
||||
|
||||
cmex10: {
|
||||
'10': {c: '<span style="position:relative; top:.1em; margin-left:-.6em">〈</span>'},
|
||||
'11': {c: '<span style="position:relative; top:.1em; margin-right:-.6em">〉</span>'},
|
||||
'14': {c: '/'}, '15': {c: '\\'},
|
||||
'28': {c: '<span style="position:relative; top:.1em; margin-left:-.6em">〈</span>'},
|
||||
'29': {c: '<span style="position:relative; top:.1em; margin-right:-.6em">〉</span>'},
|
||||
'30': {c: '/'}, '31': {c: '\\'},
|
||||
'42': {c: '<span style="position:relative; top:.1em; margin-left:-.6em">〈</span>'},
|
||||
'43': {c: '<span style="position:relative; top:.1em; margin-right:-.6em">〉</span>'},
|
||||
'44': {c: '/'}, '45': {c: '\\'},
|
||||
'46': {c: '/'}, '47': {c: '\\'},
|
||||
'68': {c: '<span style="position:relative; top:.1em; margin-left:-.6em">〈</span>'},
|
||||
'69': {c: '<span style="position:relative; top:.1em; margin-right:-.6em">〉</span>'},
|
||||
// '70': // sqcup
|
||||
// '71': // big sqcup
|
||||
'72': {ic: .194}, '73': {ic: .444},
|
||||
'82': {tclass: 'bigop1cx', ic: .15}, '90': {tclass: 'bigop2cx', ic:.6},
|
||||
'85': {c: '∪<span style="font-size: 50%; margin-left:-1.3em; position: relative; top:-.3em; margin-right:.6em">+</span>'},
|
||||
'93': {c: '∪<span style="font-size: 50%; margin-left:-1.3em; position: relative; top:-.3em; margin-right:.6em">+</span>'}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .symbol': "font-family: Osaka",
|
||||
'.typeset .arrow1': "font-family: Osaka; position: relative; top: .125em; margin: -1px",
|
||||
'.typeset .arrow2': "font-family: AppleGothic; font-size: 100%; position:relative; top: .11em; margin:-1px",
|
||||
'.typeset .bigop1': "font-family: AppleGothic; font-size: 110%; position:relative; top: .9em; margin:-.05em",
|
||||
'.typeset .bigop1b': "font-family: Osaka; font-size: 140%; position: relative; top: .8em; margin:-.1em",
|
||||
'.typeset .bigop1c': "font-family: AppleGothic; font-size: 125%; position:relative; top: .85em; margin:-.3em",
|
||||
'.typeset .bigop1cx': "font-family: 'Apple Chancery'; font-size: 125%; position:relative; top: .7em; margin:-.1em",
|
||||
'.typeset .bigop2': "font-family: AppleGothic; font-size: 175%; position:relative; top: .85em; margin:-.1em",
|
||||
'.typeset .bigop2b': "font-family: Osaka; font-size: 200%; position: relative; top: .75em; margin:-.15em",
|
||||
'.typeset .bigop2c': "font-family: AppleGothic; font-size: 300%; position:relative; top: .75em; margin:-.35em",
|
||||
'.typeset .bigop2cx': "font-family: 'Apple Chancery'; font-size: 250%; position:relative; top: .7em; margin-left:-.1em; margin-right:-.2em",
|
||||
'.typeset .delim1b': "font-family: Times; font-size: 150%; position:relative; top:.8em; margin:.01em",
|
||||
'.typeset .delim2b': "font-family: Times; font-size: 210%; position:relative; top:.8em; margin:.01em",
|
||||
'.typeset .delim3b': "font-family: Times; font-size: 300%; position:relative; top:.75em; margin:.01em",
|
||||
'.typeset .delim4b': "font-family: Times; font-size: 400%; position:relative; top:.725em; margin:.01em"
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* replace \not and \joinrel with better dimensions
|
||||
*/
|
||||
|
||||
jsMath.Macro('not','\\mathrel{\\rlap{\\kern 3mu/}}');
|
||||
jsMath.Macro('joinrel','\\mathrel{\\kern-3mu}');
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* jsMath-fallback-mac-msie.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed by Internet Explorer on the Mac
|
||||
* for when the TeX fonts are not available.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* Fix the default non-TeX-font characters to work with MSIE
|
||||
*
|
||||
*/
|
||||
|
||||
jsMath.Update.TeXfonts({
|
||||
cmr10: {
|
||||
'0': {c: 'G', tclass: 'greek'},
|
||||
'1': {c: 'D', tclass: 'greek'},
|
||||
'2': {c: 'Q', tclass: 'greek'},
|
||||
'3': {c: 'L', tclass: 'greek'},
|
||||
'4': {c: 'X', tclass: 'greek'},
|
||||
'5': {c: 'P', tclass: 'greek'},
|
||||
'6': {c: 'S', tclass: 'greek'},
|
||||
'7': {c: '¡', tclass: 'greek'},
|
||||
'8': {c: 'F', tclass: 'greek'},
|
||||
'9': {c: 'Y', tclass: 'greek'},
|
||||
'10': {c: 'W', tclass: 'greek'},
|
||||
'22': {c: '<span style="position:relative; top:.1em">`</span>', tclass: 'symbol3'}
|
||||
},
|
||||
|
||||
cmti10: {
|
||||
'0': {c: 'G', tclass: 'igreek'},
|
||||
'1': {c: 'D', tclass: 'igreek'},
|
||||
'2': {c: 'Q', tclass: 'igreek'},
|
||||
'3': {c: 'L', tclass: 'igreek'},
|
||||
'4': {c: 'X', tclass: 'igreek'},
|
||||
'5': {c: 'P', tclass: 'igreek'},
|
||||
'6': {c: 'S', tclass: 'igreek'},
|
||||
'7': {c: '¡', tclass: 'igreek'},
|
||||
'8': {c: 'F', tclass: 'igreek'},
|
||||
'9': {c: 'Y', tclass: 'igreek'},
|
||||
'10': {c: 'W', tclass: 'igreek'},
|
||||
'22': {c: '<span style="position:relative; top:.1em">`</span>', tclass: 'symbol3'}
|
||||
},
|
||||
|
||||
cmbx10: {
|
||||
'0': {c: 'G', tclass: 'bgreek'},
|
||||
'1': {c: 'D', tclass: 'bgreek'},
|
||||
'2': {c: 'Q', tclass: 'bgreek'},
|
||||
'3': {c: 'L', tclass: 'bgreek'},
|
||||
'4': {c: 'X', tclass: 'bgreek'},
|
||||
'5': {c: 'P', tclass: 'bgreek'},
|
||||
'6': {c: 'S', tclass: 'bgreek'},
|
||||
'7': {c: '¡', tclass: 'bgreek'},
|
||||
'8': {c: 'F', tclass: 'bgreek'},
|
||||
'9': {c: 'Y', tclass: 'bgreek'},
|
||||
'10': {c: 'W', tclass: 'bgreek'},
|
||||
'22': {c: '<span style="position:relative; top:.1em">`</span>', tclass: 'symbol3'}
|
||||
},
|
||||
cmmi10: {
|
||||
'0': {c: 'G', tclass: 'igreek'},
|
||||
'1': {c: 'D', tclass: 'igreek'},
|
||||
'2': {c: 'Q', tclass: 'igreek'},
|
||||
'3': {c: 'L', tclass: 'igreek'},
|
||||
'4': {c: 'X', tclass: 'igreek'},
|
||||
'5': {c: 'P', tclass: 'igreek'},
|
||||
'6': {c: 'S', tclass: 'igreek'},
|
||||
'7': {c: '¡', tclass: 'igreek'},
|
||||
'8': {c: 'F', tclass: 'igreek'},
|
||||
'9': {c: 'Y', tclass: 'igreek'},
|
||||
'10': {c: 'W', tclass: 'igreek'},
|
||||
'11': {c: 'a', tclass: 'greek'},
|
||||
'12': {c: 'b', tclass: 'greek'},
|
||||
'13': {c: 'g', tclass: 'greek'},
|
||||
'14': {c: 'd', tclass: 'greek'},
|
||||
'15': {c: 'e', tclass: 'greek'},
|
||||
'16': {c: 'z', tclass: 'greek'},
|
||||
'17': {c: 'h', tclass: 'greek'},
|
||||
'18': {c: 'q', tclass: 'greek'},
|
||||
'19': {c: 'i', tclass: 'greek'},
|
||||
'20': {c: 'k', tclass: 'greek'},
|
||||
'21': {c: 'l', tclass: 'greek'},
|
||||
'22': {c: 'm', tclass: 'greek'},
|
||||
'23': {c: 'n', tclass: 'greek'},
|
||||
'24': {c: 'x', tclass: 'greek'},
|
||||
'25': {c: 'p', tclass: 'greek'},
|
||||
'26': {c: 'r', tclass: 'greek'},
|
||||
'27': {c: 's', tclass: 'greek'},
|
||||
'28': {c: 't', tclass: 'greek'},
|
||||
'29': {c: 'u', tclass: 'greek'},
|
||||
'30': {c: 'f', tclass: 'greek'},
|
||||
'31': {c: 'c', tclass: 'greek'},
|
||||
'32': {c: 'y', tclass: 'greek'},
|
||||
'33': {c: 'w', tclass: 'greek'},
|
||||
// '41': // leftharpoondown
|
||||
// '43': // rightharpoondown
|
||||
// '44': // hook left
|
||||
// '45': // hook right
|
||||
// '92': // natural
|
||||
'94': {c: '<span style="position:relative; top:.3em">︶</span>'},
|
||||
'95': {c: '<span style="position:relative; top:-.2em">︵</span>'}
|
||||
// '127': // half-circle down accent?
|
||||
},
|
||||
|
||||
cmsy10: {
|
||||
'0': {c: '–', tclass: 'normal'},
|
||||
'11': {c: '<span style="font-size: 70%">◯</span><span style="position:relative; margin-left:-.5em; top:.1em; margin-right:.3em">/</span>', tclass: 'normal'},
|
||||
'16': {c: '<span style="position:relative;top:-.1em; font-size: 67%">︵</span><span style="position:relative;top:.1em;font-size:67%;margin-left:-1em">︶</span>', tclass: 'normal'},
|
||||
'48': {c: '<span style="font-size: 133%; margin-left:-.1em; margin-right: -.6em; position: relative; top:.4em">′</span>'},
|
||||
'93': {c: '∪<span style="font-size: 50%; margin-left:-1.3em; position: relative; top:-.3em; margin-right:.6em">+</span>'},
|
||||
'96': {c: '<span style="font-size:67%; position:relative; top:-.3em;">|</span><span style="position:relative; top:-.15em; margin-left:-.1em">–</span>', tclass: 'normal'},
|
||||
'104': {c: '<span style="position:relative; top:.2em; margin-left:-.6em">〈</span>'},
|
||||
'105': {c: '<span style="position:relative; top:.2em; margin-right:-.6em">〉</span>'},
|
||||
'109': {c: '⇑<span style="position:relative; top:.1em; margin-left:-1em">⇓</span>'},
|
||||
'110': {c: '\\', d:0, tclass: 'normal'}
|
||||
// '111': // wr
|
||||
//, '113': // amalg
|
||||
// '116': // sqcup
|
||||
// '117': // sqcap
|
||||
// '118': // sqsubseteq
|
||||
// '119': // sqsupseteq
|
||||
},
|
||||
|
||||
cmex10: {
|
||||
'10': {c: '<span style="position:relative; top:.1em; margin-left:-.6em">〈</span>'},
|
||||
'11': {c: '<span style="position:relative; top:.1em; margin-right:-.6em">〉</span>'},
|
||||
'14': {c: '/'}, '15': {c: '\\'},
|
||||
'28': {c: '<span style="position:relative; top:.05em; margin-left:-.6em">〈</span>'},
|
||||
'29': {c: '<span style="position:relative; top:.05em; margin-right:-.6em">〉</span>'},
|
||||
'30': {c: '/'}, '31': {c: '\\'},
|
||||
'42': {c: '<span style="margin-left:-.6em">〈</span>'},
|
||||
'43': {c: '<span style="margin-right:-.6em">〉</span>'},
|
||||
'44': {c: '/'}, '45': {c: '\\'},
|
||||
'46': {c: '/'}, '47': {c: '\\'},
|
||||
'68': {c: '<span style="margin-left:-.6em">〈</span>'},
|
||||
'69': {c: '<span style="margin-right:-.6em">〉</span>'},
|
||||
// '70': // sqcup
|
||||
// '71': // big sqcup
|
||||
'72': {ic: 0}, '73': {ic: 0},
|
||||
'82': {tclass: 'bigop1cx', ic: .15}, '90': {tclass: 'bigop2cx', ic:.6},
|
||||
'85': {c: '∪<span style="font-size: 50%; margin-left:-1.25em; position: relative; top:-.3em; margin-right:.6em">+</span>'},
|
||||
'93': {c: '∪<span style="font-size: 50%; margin-left:-1.25em; position: relative; top:-.3em; margin-right:.6em">+</span>'},
|
||||
// '96': // coprod
|
||||
// '97': // big coprod
|
||||
'98': {c: '︿', h: 0.722, w: .58, tclass: 'wide1'},
|
||||
'99': {c: '︿', h: 0.722, w: .58, tclass: 'wide2'},
|
||||
'100': {c: '︿', h: 0.722, w: .58, tclass: 'wide3'},
|
||||
'101': {c: '~', h: 0.722, w: .42, tclass: 'wide1a'},
|
||||
'102': {c: '~', h: 0.8, w: .73, tclass: 'wide2a'},
|
||||
'103': {c: '~', h: 0.8, w: 1.1, tclass: 'wide3a'}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .arrow1': "font-family: Osaka; position: relative; top: .125em; margin: -1px",
|
||||
'.typeset .arrow2': "font-family: Osaka; position: relative; top: .1em; margin:-1px",
|
||||
'.typeset .bigop1': "font-family: Symbol; font-size: 110%; position:relative; top: .8em; margin:-.05em",
|
||||
'.typeset .bigop1b': "font-family: Symbol; font-size: 140%; position: relative; top: .8em; margin:-.1em",
|
||||
'.typeset .bigop1c': "font-family: Osaka; font-size: 125%; position:relative; top: .85em; margin:-.3em",
|
||||
'.typeset .bigop1cx': "font-family: 'Apple Chancery'; font-size: 125%; position:relative; top: .7em; margin:-.1em",
|
||||
'.typeset .bigop2': "font-family: Symbol; font-size: 175%; position:relative; top: .8em; margin:-.07em",
|
||||
'.typeset .bigop2a': "font-family: Baskerville; font-size: 175%; position: relative; top: .65em",
|
||||
'.typeset .bigop2b': "font-family: Symbol; font-size: 175%; position: relative; top: .8em; margin:-.07em",
|
||||
'.typeset .bigop2c': "font-family: Osaka; font-size: 230%; position:relative; top: .85em; margin:-.35em",
|
||||
'.typeset .bigop2cx': "font-family: 'Apple Chancery'; font-size: 250%; position:relative; top: .6em; margin-left:-.1em; margin-right:-.2em",
|
||||
'.typeset .delim1b': "font-family: Times; font-size: 150%; position:relative; top:.8em",
|
||||
'.typeset .delim2b': "font-family: Times; font-size: 210%; position:relative; top:.75em;",
|
||||
'.typeset .delim3b': "font-family: Times; font-size: 300%; position:relative; top:.7em;",
|
||||
'.typeset .delim4b': "font-family: Times; font-size: 400%; position:relative; top:.65em;",
|
||||
'.typeset .symbol3': "font-family: Symbol",
|
||||
'.typeset .wide1': "font-size: 50%; position: relative; top:-1.1em",
|
||||
'.typeset .wide2': "font-size: 80%; position: relative; top:-.7em",
|
||||
'.typeset .wide3': "font-size: 125%; position: relative; top:-.5em",
|
||||
'.typeset .wide1a': "font-size: 75%; position: relative; top:-.5em",
|
||||
'.typeset .wide2a': "font-size: 133%; position: relative; top: -.15em",
|
||||
'.typeset .wide3a': "font-size: 200%; position: relative; top: -.05em",
|
||||
'.typeset .greek': "font-family: Symbol",
|
||||
'.typeset .igreek': "font-family: Symbol; font-style:italic",
|
||||
'.typeset .bgreek': "font-family: Symbol; font-weight:bold"
|
||||
});
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,106 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-global-controls.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file by jsMath-global.html to open a small control panel
|
||||
| at the top of the page. The panel shows the URL and allows the
|
||||
| user to refresh the page, print it, and so on.
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2006 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
<style>
|
||||
body {border:0px; padding:0px; margin:0px}
|
||||
div {padding:0px; background: #CCCCCC; border:1px outset}
|
||||
table {border:0px; padding:0px; margin:0px; width:100%}
|
||||
input {font-size:70%}
|
||||
#url {margin-left:5px; padding:1px 0px 0px 2px}
|
||||
#hide {margin-right:5px}
|
||||
</style>
|
||||
<script>
|
||||
var jsMath;
|
||||
if (window.location.search != '') {document.domain = window.location.search.substr(1)}
|
||||
try {jsMath = parent.jsMath} catch (err) {}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!----------------------------------->
|
||||
<!--
|
||||
| <script src="../../debug/console.js"></script>
|
||||
| <script src="../../debug/show.js"></script>
|
||||
-->
|
||||
<!----------------------------------->
|
||||
<div id="panel">
|
||||
<table border="0">
|
||||
<tr><td width="99%" nowrap>
|
||||
<input type="text" style="width:75%" id="url">
|
||||
<input type="button" value="Go" onclick="jsMath.SetURL()"></td>
|
||||
<td width="1%" nowrap>
|
||||
<!----------------------------------->
|
||||
<!--<input type="button" value="Debug" onclick="debug()">-->
|
||||
<!----------------------------------->
|
||||
<input type="button" value="Print" id="print" onclick="jsMath.Print()">
|
||||
<input type="button" value="Reload" id="reload" onclick="jsMath.Reload()">
|
||||
<input type="button" value="Go Local" id="goLocal" onclick="jsMath.GoLocal()">
|
||||
<input type="button" value="Empty" id="empty" onclick="jsMath.Empty()">
|
||||
<input type="button" value="Hide" id="hide" onclick="setTimeout('jsMath.Hide()',10)"></small></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
if (jsMath) {
|
||||
|
||||
jsMath.url = document.getElementById("url");
|
||||
jsMath.url.onkeypress = function (event) {
|
||||
if (!event) {event = window.event}
|
||||
var code = (event.which != null)? event.which:
|
||||
(event.keyCode != null)? event.keyCode : event.charCode;
|
||||
if (code == 13) {jsMath.SetURL(); return false}
|
||||
return true;
|
||||
};
|
||||
if (jsMath.URL) {jsMath.url.value = jsMath.URL}
|
||||
|
||||
jsMath.print = document.getElementById("print");
|
||||
jsMath.reload = document.getElementById("reload");
|
||||
|
||||
function Show() {
|
||||
var div = document.all.panel;
|
||||
var h = div.clientHeight + 2*div.clientTop;
|
||||
if (h == 0 || h > 200 && attempts++ < 10)
|
||||
{setTimeout("Show()",10*attempts); return}
|
||||
parent.jsMath.SetControls(h+',*');
|
||||
}
|
||||
if (document.body.scrollHeight < 1) {
|
||||
//
|
||||
// MSIE/Mac doesn't get the right scrollHeight until the
|
||||
// frame is fully renderred, which requires the frame
|
||||
// to be visible, and there is no telling when the rendering
|
||||
// is complete (it is AFTER the onload handler fires).
|
||||
//
|
||||
jsMath.print.disabled = true;
|
||||
attempts = 0;
|
||||
parent.document.body.rows = "50,*";
|
||||
setTimeout("Show()",1);
|
||||
} else {
|
||||
parent.jsMath.SetControls(document.body.scrollHeight+',*');
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,414 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-global.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file is used to store persistent data across multiple
|
||||
| documents, for example, the cookie data when files are loaded
|
||||
| locally, or cached typset math data.
|
||||
|
|
||||
| The file opens a frameset with one frame containing the
|
||||
| actual document to view, and stores the global data in the
|
||||
| outer document. That way, when the frame changes documents
|
||||
| the global data is still available.
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2006 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
<title>jsMath Global Frame</title>
|
||||
<style></style>
|
||||
|
||||
<script>
|
||||
var jsMath = {
|
||||
isGlobal: 1, // to pervent FRAME from inheriting this jsMath
|
||||
isOpera: (window.opera != null && window.Packages != null),
|
||||
isSafari: (window.clientInformation && document.implementation.createCSSStyleSheet != null),
|
||||
isMSIEmac: (screen.updateInterval != null && !window.SyntaxError && !window.print),
|
||||
msieDelay: 1000, // MSIE/mac delay time for checking for offsite pages
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
/*
|
||||
* This will be shared with the jsMath in the frameset
|
||||
*/
|
||||
Global: {
|
||||
isHidden: 0,
|
||||
cookie: '',
|
||||
cache: {T: {}, D: {}, R: {}, B: {}},
|
||||
ClearCache: function () {jsMath.Global.cache = {T: {}, D: {}, R: {}, B: {}}},
|
||||
Init: function () {}
|
||||
},
|
||||
|
||||
/*
|
||||
* Called by jsMath to attach to the Global data area.
|
||||
*/
|
||||
Register: function (w) {
|
||||
w.jsMath.Global = jsMath.Global;
|
||||
w.jsMath.Controls.localSetCookie = jsMath.localSetCookie;
|
||||
w.jsMath.Controls.localGetCookie = jsMath.localGetCookie;
|
||||
if (window.location.protocol != 'mk:') {
|
||||
document.title = w.document.title;
|
||||
this.ShowURL(w.location);
|
||||
jsMath.SetUnload();
|
||||
}
|
||||
},
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
/*
|
||||
* Initialize the global data and load the contents of the frame
|
||||
*/
|
||||
Init: function () {
|
||||
if (this.inited) return;
|
||||
this.controls = document.getElementById('jsMath_controls');
|
||||
this.frame = document.getElementById('jsMath_frame');
|
||||
this.window = this.FrameWindow();
|
||||
var URL;
|
||||
if (!this.isOpera) {try {URL = this.window.document.URL} catch (err) {}}
|
||||
if (!URL || URL == "about:blank" || URL.match(/jsMath-global.html$/))
|
||||
{this.frame.src = this.src}
|
||||
|
||||
this.Global.frame = this.frame;
|
||||
this.Global.Show = this.Show;
|
||||
this.Global.GoLocal = this.GoLocal;
|
||||
if (this.hide) {this.Hide()}
|
||||
this.inited = 1;
|
||||
},
|
||||
|
||||
GetURL: function () {
|
||||
var src = unescape(document.location.search.substr(1));
|
||||
if (src == '') {src = unescape(document.location.hash.substr(1))}
|
||||
src = src.replace(/\?(.*)/,'');
|
||||
if (RegExp.$1) {this.Global.cookie = unescape(RegExp.$1)}
|
||||
return src;
|
||||
},
|
||||
|
||||
FrameWindow: function (force) {
|
||||
if (this.window && !force) {return this.window}
|
||||
if (this.frame.contentWindow) {return this.frame.contentWindow}
|
||||
if (document.frames && document.frames.jsMath_frame)
|
||||
{return document.frames.jsMath_frame}
|
||||
return null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Called whenever the FRAME loads a new file.
|
||||
* (Update the title, etc.)
|
||||
*/
|
||||
Loaded: function () {
|
||||
if (!jsMath.inited) {jsMath.Init()}
|
||||
if (!jsMath.window) {jsMath.window = jsMath.FrameWindow()}
|
||||
if (!jsMath.window || window.location.protocol == 'mk:') return;
|
||||
var URL; try {URL = jsMath.frame.src} catch (err) {}
|
||||
var title; try {title = jsMath.window.document.title} catch (err) {}
|
||||
if (URL != null && URL == jsMath.URL) return;
|
||||
if (title != null) {
|
||||
document.title = title;
|
||||
jsMath.ShowURL(jsMath.window.location);
|
||||
jsMath.SetUnload();
|
||||
} else {
|
||||
jsMath.Offsite();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Mark the page as offsite and can't be read
|
||||
*/
|
||||
Offsite: function () {
|
||||
document.title = "jsMath Global: Offsite document -- can't read title";
|
||||
jsMath.ShowURL("(Offsite document -- cant' read URL)");
|
||||
if (jsMath.print && !jsMath.Global.isHidden) {
|
||||
jsMath.print.disabled = true;
|
||||
jsMath.reload.disabled = true;
|
||||
}
|
||||
jsMath.window = null;
|
||||
},
|
||||
|
||||
//
|
||||
// Safari doesn't fire onload for offsite URL's, so use in unload
|
||||
// handler to look for these and mark them.
|
||||
// MSIE/mac doesn't fire onload events at all, so use unload
|
||||
// handler to simulate them.
|
||||
//
|
||||
SetUnload: function () {
|
||||
if (jsMath.isMSIEmac || jsMath.isSafari) {
|
||||
try {jsMath.oldUnload = jsMath.window.unload} catch (err) {}
|
||||
try {jsMath.window.onunload = jsMath.Unload} catch (err) {}
|
||||
}
|
||||
},
|
||||
Unload: function (event) {
|
||||
if (jsMath.oldUnload) {jsMath.oldUnload(event)}
|
||||
try {setTimeout('jsMath.StateChange(0)',1)} catch (err) {}
|
||||
},
|
||||
StateChange: function (i) {
|
||||
jsMath.ShowURL(jsMath.window.location);
|
||||
var state = 'unknown'; try {state = jsMath.window.document.readyState} catch (err) {};
|
||||
if (state == 'unknown' || i++ == 20) {jsMath.Offsite(); return}
|
||||
if (state != 'complete') {setTimeout('jsMath.StateChange('+i+')',50*i); return}
|
||||
document.title = jsMath.window.document.title;
|
||||
jsMath.ShowURL(jsMath.window.location);
|
||||
if (window.location.host == jsMath.window.location.host)
|
||||
{jsMath.SetUnload(); return}
|
||||
if (jsMath.isMSIEmac) {
|
||||
jsMath.oldLocation = jsMath.window.location;
|
||||
setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
|
||||
}
|
||||
},
|
||||
MSIEcheckDocument: function () {
|
||||
if (window.location.host == jsMath.window.location.host) {
|
||||
jsMath.StateChange(0)
|
||||
} else {
|
||||
if (jsMath.oldLocation != jsMath.window.location) {
|
||||
jsMath.ShowURL(jsMath.window.location);
|
||||
document.title = jsMath.window.document.title;
|
||||
}
|
||||
setTimeout('jsMath.MSIEcheckDocument()',jsMath.msieDelay);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Replacements for standard localSetCookie/localGetCookie that
|
||||
* use the global cache for storing the cookie data rather than
|
||||
* the document.location's search field.
|
||||
*/
|
||||
localSetCookie: function (cookie,warn) {
|
||||
if (cookie != "") {cookie = 'jsMath='+cookie}
|
||||
if (cookie == jsMath.Global.cookie) return;
|
||||
jsMath.Global.cookie = cookie;
|
||||
},
|
||||
localGetCookie: function () {return (jsMath.Global.cookie || "")},
|
||||
|
||||
/*
|
||||
* Set the URL in the controls window
|
||||
*/
|
||||
ShowURL: function (URL) {
|
||||
try {
|
||||
jsMath.URL = URL; if (jsMath.url) {jsMath.url.value = URL}
|
||||
if (jsMath.print && !jsMath.Global.isHidden) {
|
||||
jsMath.print.disabled = !window.print;
|
||||
jsMath.reload.disabled = false;
|
||||
}
|
||||
} catch (err) {}
|
||||
},
|
||||
SetURL: function () {this.frame.src = jsMath.url.value},
|
||||
|
||||
/*
|
||||
* Handle actions for the document frame
|
||||
*/
|
||||
Print: function () {if (this.window) {this.window.document.body.focus(); this.window.print()}},
|
||||
Reload: function () {if (this.window) {this.window.location.reload()}},
|
||||
GoLocal: function () {
|
||||
if (jsMath.window) {
|
||||
jsMath.UpdateCookie();
|
||||
if (jsMath.isMSIEmac) {
|
||||
alert("MSIE/Mac has a bug that causes it not to go local properly. "
|
||||
+ "After you press OK below, your browser will appear to hang. "
|
||||
+ "When this happens, press Command-. to cancel the action. "
|
||||
+ "The window should clear and the page location will appear "
|
||||
+ "in the address area at the top of the screen. Press the "
|
||||
+ "REFRESH button to load the page correctly.");
|
||||
}
|
||||
jsMath.location = jsMath.window.location;
|
||||
if (jsMath.window.location.protocol == 'file:' && jsMath.Global.cookie)
|
||||
{jsMath.location += '?' + escape(jsMath.Global.cookie)}
|
||||
setTimeout('window.location = jsMath.location',1);
|
||||
return;
|
||||
}
|
||||
alert("You are viewing a web page from a site other than the "
|
||||
+ "one where you loaded jsMath-Global, so jsMath can't read "
|
||||
+ "its URL to load it locally.\n\n"
|
||||
+ "Check to see if your browser has a contextual menu item to "
|
||||
+ "open the active frame in a separate window.");
|
||||
},
|
||||
|
||||
/*
|
||||
* Read the cookie data, set the hiddenGlobal and global fields
|
||||
* and save the cookie again.
|
||||
*/
|
||||
UpdateCookie: function () {
|
||||
var cookie = []; var cookies = jsMath.window.document.cookie;
|
||||
if (window.location.protocol == 'file:') {cookies = jsMath.Global.cookie}
|
||||
if (cookies.match(/jsMath=([^;]+)/)) {
|
||||
var data = RegExp.$1.split(/,/);
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var x = data[i].match(/(.*):(.*)/);
|
||||
if (x[2].match(/^\d+$/)) {x[2] = 1*x[2]} // convert from string
|
||||
cookie[x[1]] = x[2];
|
||||
}
|
||||
}
|
||||
cookie.hiddenGlobal = jsMath.Global.isHidden;
|
||||
cookie.global = "never"; cookies = [];
|
||||
for (var id in cookie) {cookies[cookies.length] = id + ':' + cookie[id]}
|
||||
cookies = cookies.join(',');
|
||||
if (window.location.protocol == 'file:') {
|
||||
jsMath.Global.cookie = 'jsMath='+cookies;
|
||||
} else {
|
||||
cookies += '; path=/';
|
||||
if (cookie.keep && cookie.keep != '0D') {
|
||||
var ms = {
|
||||
D: 1000*60*60*24,
|
||||
W: 1000*60*60*24*7,
|
||||
M: 1000*60*60*24*30,
|
||||
Y: 1000*60*60*24*365
|
||||
};
|
||||
var exp = new Date;
|
||||
exp.setTime(exp.getTime() +
|
||||
cookie.keep.substr(0,1) * ms[cookie.keep.substr(1,1)]);
|
||||
cookies += '; expires=' + exp.toGMTString();
|
||||
}
|
||||
jsMath.window.document.cookie = 'jsMath='+cookies;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Check if the control panel should be hidden
|
||||
*/
|
||||
SetControls: function (rows) {
|
||||
if (!jsMath.rows) {
|
||||
jsMath.rows = rows;
|
||||
var cookie = document.cookie;
|
||||
if (String(window.location.protocol).match(/^(file|mk):$/))
|
||||
{cookie = jsMath.Global.cookie}
|
||||
if (cookie.match(/jsMath=([^;]+)/)) {cookie = RegExp.$1}
|
||||
if (!cookie.match("hiddenGlobal:0")) {
|
||||
if (this.inited) {setTimeout('jsMath.Hide()',1)} else {jsMath.hide = 1}
|
||||
return;
|
||||
}
|
||||
}
|
||||
document.body.rows = rows;
|
||||
},
|
||||
|
||||
/*
|
||||
* Remove the frame that holds the control panel
|
||||
*/
|
||||
Hide: function () {
|
||||
if (jsMath.Global.isHidden) return;
|
||||
if (this.isMSIEmac) {
|
||||
//
|
||||
// MSIE/Mac can't remove the frame, so hide it (and the drag bar)
|
||||
//
|
||||
document.body.rows = "-6,*";
|
||||
} else if (this.isOpera) {
|
||||
//
|
||||
// Opera can remove it, but it is unstable for that, but
|
||||
// setting the size to -1 seems to remove it as well.
|
||||
//
|
||||
document.body.rows = "-1,*";
|
||||
} else {
|
||||
document.body.removeChild(this.controls);
|
||||
document.body.rows = "*";
|
||||
jsMath.window = jsMath.FrameWindow(1);
|
||||
}
|
||||
this.Global.isHidden = 1;
|
||||
},
|
||||
|
||||
/*
|
||||
* Put back the control-panel frame
|
||||
*/
|
||||
Show: function (bubble) {
|
||||
if (!jsMath.Global.isHidden) {
|
||||
if (bubble && jsMath.window) {jsMath.window.jsMath.Controls.Panel()}
|
||||
return;
|
||||
}
|
||||
if (!jsMath.isMSIEmac) {
|
||||
document.body.insertBefore(jsMath.controls,jsMath.frame);
|
||||
//
|
||||
// Opera doesn't refresh the frames properly, so reload them
|
||||
//
|
||||
if (jsMath.isOpera) {
|
||||
setTimeout(
|
||||
'jsMath.controls.src = "about:blank";\n' +
|
||||
'jsMath.controls.src = jsMath.root+"jsMath-global-controls.html"+jsMath.domain;\n' +
|
||||
'jsMath.frame.src = jsMath.window.location;',1
|
||||
);
|
||||
}
|
||||
}
|
||||
document.body.rows = jsMath.rows;
|
||||
jsMath.window = jsMath.FrameWindow(1);
|
||||
jsMath.Global.isHidden = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
* Empty the cache
|
||||
*/
|
||||
Empty: function () {
|
||||
var OK = confirm('Really empty the equation cache?');
|
||||
if (OK) {jsMath.Global.ClearCache()}
|
||||
},
|
||||
|
||||
/*
|
||||
* Find the largest common domain between the source file
|
||||
* and the location of the jsMath files
|
||||
*/
|
||||
Domain: function () {
|
||||
this.domain = '';
|
||||
// MSIE/Mac can't do domain changes, so don't bother trying
|
||||
if (navigator.appName == 'Microsoft Internet Explorer' &&
|
||||
!navigator.platform.match(/Mac/) && navigator.userProfile != null) return;
|
||||
if (this.src == '') {
|
||||
if (window == parent) return;
|
||||
var oldDomain = document.domain;
|
||||
try {
|
||||
while (true) {
|
||||
try {if (parent.document.title != null) return} catch (err) {}
|
||||
if (!document.domain.match(/\..*\./)) break;
|
||||
document.domain = document.domain.replace(/^[^.]*\./,'');
|
||||
}
|
||||
} catch (err) {}
|
||||
document.domain = oldDomain;
|
||||
} else {
|
||||
if (!this.src.match(new RegExp('^[^:]+:\/\/([^/]+)(:[0-9]+)?\/'))) return;
|
||||
if (document.domain == RegExp.$1) return;
|
||||
var src = RegExp.$1.split(/\./);
|
||||
var loc = String(window.location.host).split(/\./);
|
||||
var si, li; si = src.length-2; li = loc.length-2
|
||||
while (si >= 0 && li >= 0 && src[si] == loc[li]) {li--; si--}
|
||||
document.domain = src.slice(si+1).join('.');
|
||||
this.domain = '?'+document.domain;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Create the document content based on whether this is the initial
|
||||
* call to this file, or the secondary one
|
||||
*/
|
||||
Content: function () {
|
||||
if (this.src != '') {
|
||||
this.root = (!this.isOpera) ? '' :
|
||||
String(window.location).replace(/\/jsMath-global.html\??.*/,'/');
|
||||
document.writeln('<frameset rows="0,*" onload="jsMath.Init()">');
|
||||
document.writeln('<frame src="'+this.root+'jsMath-global-controls.html'+this.domain+'" frameborder="0" scrolling="no" id="jsMath_controls" />');
|
||||
document.writeln('<frame src="'+this.root+'jsMath-global.html" frameborder="0" onload="jsMath.Loaded()" id="jsMath_frame" />');
|
||||
document.writeln('</frameset>');
|
||||
} else {
|
||||
document.writeln('<body><br/></body>');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<script>
|
||||
jsMath.src = jsMath.GetURL();
|
||||
jsMath.Domain();
|
||||
jsMath.Content();
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* jsMath-loader-omniweb4.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file synchronizes the jsMath-loader.html file with
|
||||
* the actual loading of the source javascript file.
|
||||
* OmniWeb 4 has a serious bug where the loader file is run
|
||||
* several times (and out of sequence), which plays havoc
|
||||
* with the Start() and End() calls.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (window.jsMath.Autoload) {
|
||||
jsMath.Autoload.Script.endLoad();
|
||||
} else {
|
||||
if (!window.phase2) {
|
||||
jsMath.Script.Start();
|
||||
window.phase2 = 1;
|
||||
} else {
|
||||
jsMath.Script.End();
|
||||
jsMath.Script.endLoad();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-loader-post.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file is used for loading jsMath components in Firefox3 when
|
||||
| used in a file: url from a directory other than the one containing
|
||||
| jsMath (gets around Firefox3's more restrictive same-origin policy.
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2008 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var isCheck = 0;
|
||||
var url = location.search.substr(1); var ID = "jsMLD";
|
||||
if (url.substr(0,9) == "autoload=") {url = url.substr(9); ID = "jsMAL"}
|
||||
|
||||
if (url == 'http://www.math.union.edu/locate/jsMath/jsMath/jsMath-version-check.js') {
|
||||
//
|
||||
// Handle version check separately
|
||||
//
|
||||
var jsMath = {Controls: {}}; isCheck = 1;
|
||||
document.write('<script src="'+url+'"></'+'script>');
|
||||
} else if (url != "" && url.match(/\.js$/) && !url.match('(^|[/\\?#=])[a-z]+://')) {
|
||||
//
|
||||
// Load the file and pass it to jsMath
|
||||
//
|
||||
var request = new XMLHttpRequest;
|
||||
try {
|
||||
request.open("GET",url,false);
|
||||
request.send(null);
|
||||
window.parent.postMessage(ID+":BGN:","*");
|
||||
window.parent.postMessage(ID+":SCR:"+request.responseText,"*");
|
||||
window.parent.postMessage(ID+":END:1","*");
|
||||
} catch (err) {
|
||||
window.parent.postMessage(ID+":ERR:Can't load "+url+": "+err.message,"*");
|
||||
}
|
||||
} else {
|
||||
window.parent.postMessage(ID+":END:","*");
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
//
|
||||
// If we are loading the version check, pass it to jsMath
|
||||
// and run the check.
|
||||
//
|
||||
if (isCheck) {
|
||||
var fn = jsMath.Controls.TestVersion.toString();
|
||||
window.parent.postMessage(ID+":SCR:" +
|
||||
"jsMath.Controls.TestVersion = "+fn+";" +
|
||||
"jsMath.Message.Clear(); jsMath.Message.doClear();" +
|
||||
"jsMath.Controls.TestVersion()","*"
|
||||
);
|
||||
window.parent.postMessage(ID+":END:","*");
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,92 @@
|
|||
<html>
|
||||
<head>
|
||||
<!--
|
||||
| jsMath-loader.html
|
||||
|
|
||||
| Part of the jsMath package for mathematics on the web.
|
||||
|
|
||||
| This file is used for jsMath components when the browser doesn't
|
||||
| handle the XmlHttpRequest function, or when they must be obtained
|
||||
| from a server other than the one serving the page that is using jsMath.
|
||||
|
|
||||
| ---------------------------------------------------------------------
|
||||
|
|
||||
| Copyright 2004-2006 by Davide P. Cervone
|
||||
|
|
||||
| Licensed under the Apache License, Version 2.0 (the "License");
|
||||
| you may not use this file except in compliance with the License.
|
||||
| You may obtain a copy of the License at
|
||||
|
|
||||
| http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
|
||||
| Unless required by applicable law or agreed to in writing, software
|
||||
| distributed under the License is distributed on an "AS IS" BASIS,
|
||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
| See the License for the specific language governing permissions and
|
||||
| limitations under the License.
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var showWarning = 0;
|
||||
while (!window.jsMath && !showWarning) {
|
||||
try {
|
||||
window.jsMath = window.parent.jsMath;
|
||||
if (!window.jsMath) {throw "no jsMath";}
|
||||
} catch (err) {
|
||||
showWarning = 1; pageDomain = '';
|
||||
try {pageDomain = document.domain} catch (err) {}
|
||||
//
|
||||
// MSIE on Mac can't change document.domain, and 'try' won't
|
||||
// catch the error (Grrr!) so don't even attempt it.
|
||||
//
|
||||
if (pageDomain.match(/\..*\./) &&
|
||||
(navigator.appName != 'Microsoft Internet Explorer' ||
|
||||
!navigator.platform.match(/Mac/) || !navigator.userProfile || !document.all)) {
|
||||
try {
|
||||
document.domain = pageDomain.replace(/^[^.]*\./,'');
|
||||
showWarning = 0;
|
||||
} catch(err) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Warning () {
|
||||
alert(
|
||||
"jsMath can't load one of its required components, because jsMath " +
|
||||
"was not obtained from a server that is in the same domain as the " +
|
||||
"page that loaded it."
|
||||
);
|
||||
}
|
||||
|
||||
isOmniWeb4 = (document.readyState == 'loading' &&
|
||||
navigator.accentColorName != null &&
|
||||
navigator.omniWebString == null);
|
||||
|
||||
if (showWarning) {setTimeout("Warning()",1)} else {
|
||||
debug = window.parent.debug; show = window.parent.show;
|
||||
jsMath.Script.window = window; url = jsMath.Script.url;
|
||||
if (isOmniWeb4) {
|
||||
if (url != jsMath.Script.prevURL) {
|
||||
jsMath.Script.prevURL = url;
|
||||
document.writeln('<script src="'+jsMath.root+'jsMath-loader-omniweb4.js"><'+'/script>');
|
||||
document.writeln('<script src="'+url+'"><'+'/script>');
|
||||
document.writeln('<script src="'+jsMath.root+'jsMath-loader-omniweb4.js"><'+'/script>');
|
||||
}
|
||||
} else {
|
||||
jsMath.Script.Start();
|
||||
document.writeln('<script src="'+url+'"><'+'/script>');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (window.jsMath && !isOmniWeb4) {
|
||||
jsMath.Script.End();
|
||||
jsMath.Script.endLoad();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* jsMath-msie-mac.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed for use with MSIE on the Mac.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* MSIE crashes if it changes the page too quickly, so we add a
|
||||
* delay between processing math entries. Unfortunately, this really
|
||||
* slows down math in MSIE on the mac.
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath,{
|
||||
|
||||
msieProcess: jsMath.Process,
|
||||
msieProcessBeforeShowing: jsMath.ProcessBeforeShowing,
|
||||
|
||||
Process: function () {
|
||||
// we need to delay a bit before starting to process the page
|
||||
// in order to avoid an MSIE display bug
|
||||
jsMath.Message.Set("Processing Math: 0%");
|
||||
setTimeout('jsMath.msieProcess()',jsMath.Browser.delay);
|
||||
},
|
||||
|
||||
ProcessBeforeShowing: function () {
|
||||
// we need to delay a bit before starting to process the page
|
||||
// in order to avoid an MSIE display bug
|
||||
setTimeout('jsMath.msieProcessBeforeShowing()',5*jsMath.Browser.delay);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Browser.delay = 75; // hope this is enough of a delay!
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* jsMath-old-browsers.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed by older versions of some browsers
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath.HTML,{
|
||||
/*
|
||||
* Use the blank GIF image for spacing and rules
|
||||
*/
|
||||
Blank: function (w,h,d,isRule) {
|
||||
var style = '';
|
||||
if (isRule) {
|
||||
if (h*jsMath.em < 1.5) {h = '1px'} else {h = jsMath.HTML.Em(h)}
|
||||
style = 'border-top:'+h+' solid;'; h = 0;
|
||||
}
|
||||
if (d == null) {d = 0}
|
||||
style += 'width:'+this.Em(w)+'; height:'+this.Em(h+d)+';';
|
||||
if (d) {style += 'vertical-align:'+this.Em(-d)}
|
||||
return '<img src="'+jsMath.blank+'" style="'+style+'" />';
|
||||
}
|
||||
});
|
||||
|
||||
if (jsMath.browser == 'Konqueror') {
|
||||
|
||||
jsMath.Package(jsMath.Box,{Remeasured: function() {return this}});
|
||||
|
||||
jsMath.Add(jsMath.HTML,{
|
||||
Spacer: function (w) {
|
||||
if (w == 0) {return ''};
|
||||
return '<span style="margin-left:'+this.Em(w-jsMath.Browser.spaceWidth)+'">'
|
||||
+ ' </span>';
|
||||
}
|
||||
});
|
||||
|
||||
jsMath.Browser.spaceWidth = this.EmBoxFor(' ').w/5;
|
||||
|
||||
}
|
||||
|
||||
jsMath.styles['.typeset .spacer'] = '';
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* local/macros.js
|
||||
*
|
||||
* Use jsMath.Macro() to declare your own local macro definitions here,
|
||||
* and add "local/macros.js" to the loadFiles array in easy/load.js so
|
||||
* that they will be loaded automatically when jsMath is used.
|
||||
*
|
||||
* See http://www.math.union.edu/locate/jsMath/authors/macros.html
|
||||
* for details on defining macros for jsMath.
|
||||
*/
|
||||
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// jsMath.Macro('R','{\\bf R}');
|
||||
// jsMath.Macro('red','\\color{red}{#1}',1);
|
||||
//
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* CHMmode.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes jsMath work with MicroSoft's HTML Help system
|
||||
* from within .chm files (compiled help archives).
|
||||
*
|
||||
* This file should be loaded BEFORE jsMath.js.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006-2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
if (!jsMath.Controls.cookie) {jsMath.Controls.cookie = {}}
|
||||
|
||||
jsMath.isCHMmode = 1;
|
||||
|
||||
jsMath.noChangeGlobal = 1;
|
||||
jsMath.noShowGlobal = 1;
|
||||
jsMath.noImgFonts = 1;
|
||||
jsMath.Controls.cookie.global = 'always';
|
||||
jsMath.Controls.cookie.hiddenGlobal = 1;
|
||||
|
||||
if (window.location.protocol == "mk:") {
|
||||
|
||||
/*
|
||||
* Work around bug in hh.exe that causes it to run at 100% CPU
|
||||
* and not exit if the page is reloaded after an IFRAME is used
|
||||
* to load the controls file, so fake it using XMLHttpRequest.
|
||||
* Load the data into a DIV instead of an IFRAME, and make sure
|
||||
* that the styles are correct for it. Change the GetPanel()
|
||||
* call to hide the other panel and open the correct one.
|
||||
*/
|
||||
|
||||
jsMath.Controls.Init = function () {
|
||||
this.controlPanels = jsMath.Setup.DIV("controlPanels");
|
||||
if (!jsMath.Browser.msieButtonBug) {this.Button()}
|
||||
else {setTimeout("jsMath.Controls.Button()",500)}
|
||||
}
|
||||
|
||||
jsMath.Controls.Panel = function () {
|
||||
jsMath.Translate.Cancel();
|
||||
jsMath.Setup.AddStyleSheet({
|
||||
'#jsMath_options': jsMath.styles['#jsMath_panel'],
|
||||
'#jsMath_options .disabled': jsMath.styles['#jsMath_panel .disabled'],
|
||||
'#jsMath_options .infoLink': jsMath.styles['#jsMath_panel .infoLink']
|
||||
});
|
||||
if (this.loaded) {this.panel = jsMath.Element("panel"); this.Main(); return}
|
||||
var html = jsMath.Script.xmlRequest(jsMath.root+"jsMath-controls.html");
|
||||
var body = (html.match(/<body>([\s\S]*)<\/body>/))[1];
|
||||
this.controlPanels.innerHTML = body;
|
||||
var script = (body.match(/<script>([\s\S]*?)<\/script>/))[1];
|
||||
jsMath.window.eval(script);
|
||||
jsMath.Controls.GetPanel = function (name) {
|
||||
if (this.panel) {this.panel.style.display = "none"}
|
||||
this.panel = jsMath.Element(name);
|
||||
}
|
||||
jsMath.Controls.oldClose = jsMath.Controls.Close;
|
||||
jsMath.Controls.Close = function () {this.oldClose(); this.panel = null}
|
||||
jsMath.Element("options").style.display = "none";
|
||||
jsMath.Controls.Main();
|
||||
if (!jsMath.Browser.IE7 || jsMath.Browser.quirks) {
|
||||
jsMath.window.attachEvent("onscroll",jsMath.Controls.MoveButton);
|
||||
if (jsMath.Browser.IE7) jsMath.window.attachEvent("onresize",jsMath.Controls.MoveButton);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* autoload.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file is a plugin that checks if a page contains any math
|
||||
* that must be processed by jsMath, and only loads jsMath.js
|
||||
* when there is.
|
||||
*
|
||||
* You can control the items to look for via the variables
|
||||
*
|
||||
* jsMath.Autoload.findTeXstrings
|
||||
* jsMath.Autoload.findLaTeXstrings
|
||||
* jsMath.Autoload.findCustomStrings
|
||||
* jsMath.Autoload.findCustomSettings
|
||||
*
|
||||
* which control whether to look for TeX strings that will be converted
|
||||
* by jsMath.ConvertTeX(), or LaTeX strings that will be converted by
|
||||
* jsMath.ConvertLaTeX(). By default, the first is true and the second
|
||||
* and third are false. The findCustomStrings can be used to specify your
|
||||
* own delimiters for in-line and display mathematics, e.g.
|
||||
*
|
||||
* jsMath.Autoload.findCustomStrings = [
|
||||
* '[math],'[/math]', // start and end in-line math
|
||||
* '[display]','[/display]' // start and end display math
|
||||
* ];
|
||||
*
|
||||
* Finally, findCustomSettings can be set to an object reference whose
|
||||
* name:value pairs control the individual search settings for tex2math.
|
||||
* (See the plugins/tex2math.js file for more details).
|
||||
*
|
||||
* If any math strings are found, jsMath.js will be loaded automatically,
|
||||
* but not loaded otherwise. If any of the last four are set and TeX math
|
||||
* strings are found, then plugins/tex2ath.js will be loaded
|
||||
* automatically. jsMath.Autoload.needsJsMath will be set to true or
|
||||
* false depending on whether jsMath needed to be loaded.
|
||||
*
|
||||
* The value of jsMath.Autoload.checkElement controls the element to be
|
||||
* searched by the autoload plug-in. If unset, the complete document will
|
||||
* be searched. If set to a string, the element with that name will be
|
||||
* searched. If set to a DOM object, that object and its children will
|
||||
* be searched.
|
||||
*
|
||||
* Finally, there are two additional parameters that control files to
|
||||
* be loaded after jsMath.js, should it be needed. These are
|
||||
*
|
||||
* jsMath.Autoload.loadFonts
|
||||
* jsMath.Autoload.loadFiles
|
||||
*
|
||||
* If jsMath.js is loaded, the fonts contained in the loadFonts array
|
||||
* will be loaded, and the JavaScript files listed in the loadFiles array
|
||||
* will be run. Relative URL's are loaded based from the URL containing
|
||||
* jsMath.js.
|
||||
*
|
||||
* The autoload plugin can be loaded in the document HEAD or in the BODY.
|
||||
* If it is loaded in the HEAD, you will need to call jsMath.Autoload.Check()
|
||||
* at the end of the BODY (say in the window.onload handler) in order to
|
||||
* get it to check the page for math that needs to be tagged, otherwise load
|
||||
* the file at the bottom of the BODY and it will run the check automatically.
|
||||
*
|
||||
* You can call jsMath.Autoload.Run() after the check has been performed
|
||||
* in order to call the appropriate tex2math routines for the given Autoload
|
||||
* settings. You can call jsMath.Autoload.Run() even when jsMath isn't loaded.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Make sure jsMath.Autoload is available
|
||||
*/
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
if (jsMath.Autoload == null) {jsMath.Autoload = {}}
|
||||
jsMath.Add = function (dst,src) {for (var id in src) {dst[id] = src[id]}};
|
||||
jsMath.document = document; // tex2math needs this
|
||||
|
||||
jsMath.Add(jsMath.Autoload,{
|
||||
|
||||
Script: {
|
||||
|
||||
request: null, // XMLHttpRequest object (if we can get it)
|
||||
iframe: null, // the hidden iframe (if not)
|
||||
operaXMLHttpRequestBug: (window.opera != null), // is Opera browser
|
||||
|
||||
/*
|
||||
* Get XMLHttpRequest object, if possible, and look up the URL root
|
||||
* (MSIE can't use xmlReuest to load local files, so avoid that)
|
||||
*/
|
||||
Init: function () {
|
||||
this.Root();
|
||||
if (window.XMLHttpRequest) {
|
||||
try {this.request = new XMLHttpRequest} catch (err) {}
|
||||
// MSIE and FireFox3 can't use xmlRequest on local files,
|
||||
// but we don't have jsMath.browser yet to tell, so use this check
|
||||
if (this.request && window.location.protocol == "file:") {
|
||||
try {
|
||||
this.request.open("GET",jsMath.Autoload.root+"plugins/autoload.js",false);
|
||||
this.request.send(null);
|
||||
} catch (err) {
|
||||
this.request = null;
|
||||
// Firefox3 has window.postMessage for inter-window communication.
|
||||
// It can be used to handle the new file:// security model,
|
||||
// so set up the listener.
|
||||
if (window.postMessage && window.addEventListener) {
|
||||
this.mustPost = 1;
|
||||
window.addEventListener("message",jsMath.Autoload.Post.Listener,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.request && window.ActiveXObject && !this.mustPost) {
|
||||
var xml = ["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0",
|
||||
"MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
|
||||
for (var i = 0; i < xml.length && !this.request; i++) {
|
||||
try {this.request = new ActiveXObject(xml[i])} catch (err) {}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Load an external JavaScript file
|
||||
*/
|
||||
Load: function (url) {
|
||||
if (this.request && !(this.operaXMLHttpRequestBug && url == 'jsMath.js')) {
|
||||
setTimeout(function () {jsMath.Autoload.Script.xmlLoad(url)},1);
|
||||
} else {
|
||||
this.startLoad(url);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Load an external JavaScript file via XMLHttpRequest
|
||||
*/
|
||||
xmlLoad: function (url) {
|
||||
try {
|
||||
this.request.open("GET",jsMath.Autoload.root+url,false);
|
||||
this.request.send(null);
|
||||
} catch (err) {
|
||||
throw Error("autoload: can't load the file '"+url+"'\n"
|
||||
+ "Message: "+err.message);
|
||||
}
|
||||
if (this.request.status && this.request.status >= 400) {
|
||||
throw Error("autoload: can't load the file '"+url+"'\n"
|
||||
+ "Error status: "+this.request.status);
|
||||
}
|
||||
window.eval(this.request.responseText);
|
||||
this.endLoad();
|
||||
},
|
||||
|
||||
/*
|
||||
* Load an external JavaScript file via jsMath-autoload.html
|
||||
*/
|
||||
startLoad: function (url) {
|
||||
this.iframe = document.createElement('iframe');
|
||||
this.iframe.style.visibility = 'hidden';
|
||||
this.iframe.style.position = 'absolute';
|
||||
this.iframe.style.width = '0px';
|
||||
this.iframe.style.height = '0px';
|
||||
if (document.body.firstChild) {
|
||||
document.body.insertBefore(this.iframe,document.body.firstChild);
|
||||
} else {
|
||||
document.body.appendChild(this.iframe);
|
||||
}
|
||||
this.url = url; setTimeout('jsMath.Autoload.Script.setURL()',100);
|
||||
},
|
||||
endLoad: function () {setTimeout('jsMath.Autoload.Script.AfterLoad()',1)},
|
||||
|
||||
/*
|
||||
* Use location.replace() to avoid browsers placing the file in
|
||||
* the history (and messing up the BACK button action). Not
|
||||
* completely effective in Firefox 1.0.x. Safari won't handle
|
||||
* replace() if the document is local (not sure if that's really
|
||||
* the issue, but that's the only time I see it).
|
||||
*/
|
||||
setURL: function () {
|
||||
if (this.mustPost) {
|
||||
this.iframe.src = jsMath.Autoload.Post.startLoad(this.url,this.iframe);
|
||||
} else {
|
||||
var url = jsMath.Autoload.root+"jsMath-autoload.html";
|
||||
var doc = this.iframe.contentDocument;
|
||||
if (!doc && this.iframe.contentWindow) {doc = this.iframe.contentWindow.document}
|
||||
if (navigator.vendor == "Apple Computer, Inc." &&
|
||||
document.location.protocol == 'file:') {doc = null}
|
||||
if (doc) {doc.location.replace(url)} else {this.iframe.src = url}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Queue items that need to be postponed until jsMath has run
|
||||
*/
|
||||
queue: [],
|
||||
Push: function (name,data) {this.queue[this.queue.length] = [name,data]},
|
||||
RunStack: function () {
|
||||
if (this.tex2math) {jsMath.Autoload.Check2(); return}
|
||||
for (var i = 0; i < this.queue.length; i++) {
|
||||
var name = this.queue[i][0];
|
||||
var data = this.queue[i][1];
|
||||
if (data.length == 1) {jsMath[name](data[0])}
|
||||
else {jsMath[name](data[0],data[1],data[2],data[3])}
|
||||
}
|
||||
this.queue = [];
|
||||
},
|
||||
|
||||
AfterLoad: function () {jsMath.Autoload.Script.RunStack()},
|
||||
|
||||
/*
|
||||
* Look up the jsMath root directory, if it is not already supplied
|
||||
*/
|
||||
Root: function () {
|
||||
if (jsMath.Autoload.root) return;
|
||||
var script = document.getElementsByTagName('script');
|
||||
if (script) {
|
||||
for (var i = 0; i < script.length; i++) {
|
||||
var src = script[i].src;
|
||||
if (src && src.match('(^|/|\\\\)plugins/autoload.js$')) {
|
||||
jsMath.Autoload.root = src.replace(/plugins\/autoload.js$/,'');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
* Handle window.postMessage() events in Firefox3
|
||||
*/
|
||||
Post: {
|
||||
window: null, // iframe we are ing to
|
||||
|
||||
Listener: function (event) {
|
||||
if (event.source != jsMath.Autoload.Post.window) return;
|
||||
var domain = event.origin.replace(/^file:\/\//,'');
|
||||
var ddomain = document.domain.replace(/^file:\/\//,'');
|
||||
if (domain == null || domain == "" || domain == "null") {domain = "localhost"}
|
||||
if (ddomain == null || ddomain == "" || ddomain == "null") {ddomain = "localhost"}
|
||||
if (domain != ddomain || event.data.substr(0,6) != "jsMAL:") return;
|
||||
var type = event.data.substr(6,3).replace(/ /g,'');
|
||||
var message = event.data.substr(10);
|
||||
if (jsMath.Autoload.Post.Commands[type]) (jsMath.Autoload.Post.Commands[type])(message);
|
||||
// cancel event?
|
||||
},
|
||||
|
||||
/*
|
||||
* Commands that can be performed by the listener
|
||||
*/
|
||||
Commands: {
|
||||
SCR: function (message) {window.eval(message)},
|
||||
ERR: function (message) {jsMath.Autoload.Script.endLoad()},
|
||||
END: function (message) {jsMath.Autoload.Script.endLoad()}
|
||||
},
|
||||
|
||||
startLoad: function (url,iframe) {
|
||||
this.window = iframe.contentWindow;
|
||||
return jsMath.Autoload.root+"jsMath-loader-post.html?autoload="+url;
|
||||
},
|
||||
|
||||
endLoad: function () {
|
||||
this.window = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
/*
|
||||
* Load tex2math first (so we can call its search functions
|
||||
* to look to see if anything needs to be turned into math)
|
||||
* if it is needed, otherwise go on to the second check.
|
||||
*/
|
||||
Check: function () {
|
||||
if (this.checked) return; this.checked = 1;
|
||||
if ((this.findTeXstrings || this.findLaTeXstrings ||
|
||||
this.findCustomStrings || this.findCustomSettings) &&
|
||||
(!jsMath.tex2math || !jsMath.tex2math.loaded)) {
|
||||
this.Script.tex2math = 1;
|
||||
this.Script.Load('plugins/tex2math.js');
|
||||
} else {
|
||||
if (!jsMath.tex2math) {jsMath.tex2math = {}}
|
||||
this.Check2();
|
||||
}
|
||||
},
|
||||
ReCheck: function () {
|
||||
if (jsMath.loaded) return;
|
||||
this.InitStubs();
|
||||
this.checked = 0;
|
||||
this.Script.queue = [];
|
||||
this.Check();
|
||||
},
|
||||
|
||||
/*
|
||||
* Once tex2math is loaded, use it to check for math that
|
||||
* needs to be tagged for jsMath, and load jsMath if it is needed
|
||||
*/
|
||||
Check2: function () {
|
||||
this.Script.tex2math = 0; this.needsJsMath = 0;
|
||||
if (this.checkElement == null) {this.checkElement = null}
|
||||
|
||||
if (this.findTeXstrings) {jsMath.tex2math.ConvertTeX(this.checkElement)}
|
||||
if (this.findLaTeXstrings) {jsMath.tex2math.ConvertLaTeX(this.checkElement)}
|
||||
if (this.findCustomSettings) {jsMath.tex2math.Convert(this.checkElement,this.findCustomSettings)}
|
||||
if (this.findCustomStrings) {
|
||||
var s = this.findCustomStrings;
|
||||
jsMath.tex2math.CustomSearch(s[0],s[1],s[2],s[3]);
|
||||
jsMath.tex2math.ConvertCustom(this.checkElement);
|
||||
}
|
||||
|
||||
this.needsJsMath = this.areMathElements(this.checkElement);
|
||||
if (this.needsJsMath) {
|
||||
this.LoadJsMath();
|
||||
} else {
|
||||
jsMath.Process = function () {};
|
||||
jsMath.ProcessBeforeShowing = function () {};
|
||||
jsMath.ProcessElement = function () {};
|
||||
jsMath.ConvertTeX = function () {};
|
||||
jsMath.ConvertTeX2 = function () {};
|
||||
jsMath.ConvertLaTeX = function () {};
|
||||
jsMath.ConvertCustom = function () {};
|
||||
jsMath.CustomSearch = function () {};
|
||||
jsMath.Macro = function () {};
|
||||
jsMath.Synchronize = function (code,data) {
|
||||
if (typeof(code) == 'string') {eval(code)} else {code(data)}
|
||||
};
|
||||
jsMath.Autoload.Script.RunStack(); // perform pending commands
|
||||
jsMath.Autoload.setMessage();
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* A callback used in the tex2math searches to signal that
|
||||
* some math has been found.
|
||||
*/
|
||||
tex2mathCallback: function () {
|
||||
jsMath.Autoload.needsJsMath = 1;
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* jsMath.Autoload.Run() is now longer needed
|
||||
*/
|
||||
Run: function (data) {},
|
||||
|
||||
/*
|
||||
* Look to see if there are SPAN or DIV elements of class "math".
|
||||
*/
|
||||
areMathElements: function (obj) {
|
||||
if (!obj) {obj = document}
|
||||
if (typeof(obj) == 'string') {obj = document.getElementById(obj)}
|
||||
if (!obj.getElementsByTagName) {return false}
|
||||
var math = obj.getElementsByTagName('div');
|
||||
for (var k = 0; k < math.length; k++)
|
||||
{if (math[k].className.match(/(^| )math( |$)/)) {return true}}
|
||||
math = obj.getElementsByTagName('span');
|
||||
for (var k = 0; k < math.length; k++)
|
||||
{if (math[k].className.match(/(^| )math( |$)/)) {return true}}
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* When math tags are found, load the jsMath.js file,
|
||||
* and afterward, load any auxiliary files or fonts,
|
||||
* and then do any pending commands.
|
||||
*/
|
||||
LoadJsMath: function () {
|
||||
if (this.loading) return;
|
||||
if (jsMath.loaded) {this.afterLoad(); return}
|
||||
if (this.root) {
|
||||
this.loading = 1;
|
||||
this.setMessage('Loading jsMath...');
|
||||
this.Script.AfterLoad = this.afterLoad;
|
||||
this.Script.Load('jsMath.js');
|
||||
} else {
|
||||
alert("Can't determine URL for jsMath.js");
|
||||
}
|
||||
},
|
||||
afterLoad: function () {
|
||||
jsMath.Autoload.loading = 0;
|
||||
//
|
||||
// Handle MSIE bug where jsMath.window both is and is not the actual window
|
||||
//
|
||||
if (jsMath.tex2math.window) {jsMath.tex2math.window.jsMath = jsMath}
|
||||
if (jsMath.browser == 'MSIE') {window.onscroll = jsMath.window.onscroll};
|
||||
var fonts = jsMath.Autoload.loadFonts;
|
||||
if (fonts) {
|
||||
if (typeof(fonts) != 'object') {fonts = [fonts]}
|
||||
for (var i = 0; i < fonts.length; i++) {jsMath.Font.Load(fonts[i])}
|
||||
}
|
||||
var files = jsMath.Autoload.loadFiles;
|
||||
if (files) {
|
||||
if (typeof(files) != 'object') {files = [files]}
|
||||
for (var i = 0; i < files.length; i++) {jsMath.Setup.Script(files[i])}
|
||||
}
|
||||
var macros = jsMath.Autoload.macros;
|
||||
if (macros) {
|
||||
for (var id in macros) {
|
||||
if (typeof(macros[id]) == 'string') {
|
||||
jsMath.Macro(id,macros[id]);
|
||||
} else {
|
||||
jsMath.Macro(id,macros[id][0],macros[id][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
jsMath.Synchronize(function () {jsMath.Autoload.Script.RunStack()});
|
||||
jsMath.Autoload.setMessage();
|
||||
},
|
||||
|
||||
/*
|
||||
* Display a message in a small box at the bottom of the screen
|
||||
*/
|
||||
setMessage: function (message) {
|
||||
if (message) {
|
||||
this.div = document.createElement('div');
|
||||
if (!document.body.hasChildNodes) {document.body.appendChild(this.div)}
|
||||
else {document.body.insertBefore(this.div,document.body.firstChild)}
|
||||
var style = {
|
||||
position:'fixed', bottom:'1px', left:'2px',
|
||||
backgroundColor:'#E6E6E6', border:'solid 1px #959595',
|
||||
margin:'0px', padding:'1px 8px', zIndex:102,
|
||||
color:'black', fontSize:'75%', width:'auto'
|
||||
};
|
||||
for (var id in style) {this.div.style[id] = style[id]}
|
||||
this.div.id = "jsMath_message";
|
||||
this.div.appendChild(jsMath.document.createTextNode(message));
|
||||
} else if (this.div) {
|
||||
this.div.firstChild.nodeValue = "";
|
||||
this.div.style.visibility = 'hidden';
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Queue these so we can do them after jsMath has been loaded
|
||||
*/
|
||||
stubs: {
|
||||
Process: function (data) {jsMath.Autoload.Script.Push('Process',[data])},
|
||||
ProcessBeforeShowing: function (data) {jsMath.Autoload.Script.Push('ProcessBeforeShowing',[data])},
|
||||
ProcessElement: function (data) {jsMath.Autoload.Script.Push('ProcessElement',[data])},
|
||||
ConvertTeX: function (data) {jsMath.Autoload.Script.Push('ConvertTeX',[data])},
|
||||
ConvertTeX2: function (data) {jsMath.Autoload.Script.Push('ConvertTeX2',[data])},
|
||||
ConvertLaTeX: function (data) {jsMath.Autoload.Script.Push('ConvertLaTeX',[data])},
|
||||
ConvertCustom: function (data) {jsMath.Autoload.Script.Push('ConvertCustom',[data])},
|
||||
CustomSearch: function (d1,d2,d3,d4) {jsMath.Autoload.Script.Push('CustomSearch',[d1,d2,d3,d4])},
|
||||
Synchronize: function (data) {jsMath.Autoload.Script.Push('Synchronize',[data])},
|
||||
Macro: function (cs,def,params) {jsMath.Autoload.Script.Push('Macro',[cs,def,params])}
|
||||
},
|
||||
|
||||
InitStubs: function () {jsMath.Add(jsMath,jsMath.Autoload.stubs)}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
|
||||
if (jsMath.Autoload.findTeXstrings == null) {jsMath.Autoload.findTeXstrings = 0}
|
||||
if (jsMath.Autoload.findLaTeXstrings == null) {jsMath.Autoload.findLaTeXstrings = 0}
|
||||
|
||||
jsMath.Autoload.Script.Init();
|
||||
jsMath.Autoload.InitStubs();
|
||||
if (document.body && !jsMath.Autoload.delayCheck) {jsMath.Autoload.Check()}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* plugins/global.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file call up the global frame, if it is not already in place.
|
||||
*
|
||||
* This should be called BEFORE loading jsMath.js
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!parent.jsMath || !parent.jsMath.isGlobal) {
|
||||
var cookie = []; var cookies = document.cookies;
|
||||
if (window.location.protocol == 'file:') {cookies = unescape(window.location.search.substr(1))}
|
||||
else if (window.location.protocol == 'mk:') {cookies = unescape(window.location.hash.substr(1))}
|
||||
if (cookies.match(/jsMath=([^;]+)/)) {
|
||||
var data = RegExp.$1.split(/,/);
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var x = data[i].match(/(.*):(.*)/);
|
||||
cookie[x[1]] = x[2];
|
||||
}
|
||||
}
|
||||
if (cookie.global != "never" && !navigator.accentColorName) {
|
||||
var script = document.getElementsByTagName('script');
|
||||
if (script) {
|
||||
for (var i = 0; i < script.length; i++) {
|
||||
src = script[i].src;
|
||||
if (src && src.match('(^|/)plugins/global.js$')) {
|
||||
src = src.replace(/plugins\/global.js$/,'jsMath-global.html');
|
||||
var sep = (window.location.protocol == 'mk:') ? '#' : '?';
|
||||
window.location.replace(src + sep + escape(window.location));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* mimeTeX.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes jsMath more compatible with the mimeTeX program.
|
||||
* It does not make everything work, but it goes a long way.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Treat ~ as space
|
||||
*/
|
||||
jsMath.Parser.prototype.nextIsSpace = function () {
|
||||
return this.string.charAt(this.i) == ' ' ||
|
||||
this.string.charAt(this.i) == '~';
|
||||
}
|
||||
jsMath.Parser.prototype.special['~'] = 'Space';
|
||||
|
||||
/*
|
||||
* Implement \[ ... \], \( ... \), etc.
|
||||
*/
|
||||
jsMath.Macro('[','\\left['); jsMath.Macro(']','\\right]');
|
||||
jsMath.Macro('(','\\left('); jsMath.Macro(')','\\right)');
|
||||
jsMath.Macro('<','\\left<'); jsMath.Macro('>','\\right>');
|
||||
// can't do \. in a reasonable way
|
||||
jsMath.Parser.prototype.macros['|'] = ['HandleLR','|','|'];
|
||||
jsMath.Parser.prototype.macros['='] = ['HandleLR','\\|','\\|'];
|
||||
|
||||
/*
|
||||
* Make non-standard \left{ and \right} work
|
||||
*/
|
||||
jsMath.Parser.prototype.delimiter['}'] = [5,2,0x67,3,0x09];
|
||||
jsMath.Parser.prototype.delimiter['{'] = [4,2,0x66,3,0x08];
|
||||
|
||||
|
||||
/*
|
||||
* Immitate mimeTeX \big... and \Big... ops
|
||||
*/
|
||||
|
||||
// make the normal ones in text mode
|
||||
jsMath.Macro('int','\\intop\\nolimits');
|
||||
jsMath.Macro('oint','\\ointop\\nolimits');
|
||||
jsMath.Macro('sum','\\sumop\\nolimits');
|
||||
jsMath.Macro('prod','\\prodop\\nolimits');
|
||||
jsMath.Macro('coprod','\\coprodop\\nolimits');
|
||||
|
||||
jsMath.Macro('bigint','\\bigintop\\nolimits');
|
||||
jsMath.Macro('bigoint','\\bigointop\\nolimits');
|
||||
jsMath.Macro('bigsum','\\bigsumop\\nolimits');
|
||||
jsMath.Macro('bigprod','\\bigprodop\\nolimits');
|
||||
jsMath.Macro('bigcoprod','\\bigcoprodop\\nolimits');
|
||||
|
||||
jsMath.Macro('Bigint','\\bigintop\\limits');
|
||||
jsMath.Macro('Bigoint','\\bigointop\\limits');
|
||||
jsMath.Macro('Bigsum','\\bigsumop\\limits');
|
||||
jsMath.Macro('Bigprod','\\bigprodop\\limits');
|
||||
jsMath.Macro('Bigcoprod','\\bigcoprod\\limits');
|
||||
|
||||
/*
|
||||
* The characters needed for the macros above
|
||||
*/
|
||||
jsMath.Parser.prototype.mathchardef['coprodop'] = [1,3,0x60];
|
||||
jsMath.Parser.prototype.mathchardef['prodop'] = [1,3,0x51];
|
||||
jsMath.Parser.prototype.mathchardef['sumop'] = [1,3,0x50];
|
||||
|
||||
jsMath.Parser.prototype.mathchardef['bigintop'] = [1,3,0x5A];
|
||||
jsMath.Parser.prototype.mathchardef['bigointop'] = [1,3,0x49];
|
||||
jsMath.Parser.prototype.mathchardef['bigcoprodop'] = [1,3,0x61];
|
||||
jsMath.Parser.prototype.mathchardef['bigprodop'] = [1,3,0x59];
|
||||
jsMath.Parser.prototype.mathchardef['bigsumop'] = [1,3,0x58];
|
||||
|
||||
/*
|
||||
* Unlink the small versions so they don't enlarge in display mode
|
||||
*/
|
||||
jsMath.TeX['cmex10'][0x48].n = null;
|
||||
jsMath.TeX['cmex10'][0x50].n = null;
|
||||
jsMath.TeX['cmex10'][0x51].n = null;
|
||||
jsMath.TeX['cmex10'][0x52].n = null;
|
||||
jsMath.TeX['cmex10'][0x60].n = null;
|
||||
|
||||
|
||||
/*
|
||||
* Some other missing items
|
||||
*/
|
||||
jsMath.Macro('/','{}'); // insert an empty box \/
|
||||
jsMath.Macro('raisebox','\\raise #1px ',1); // convert to \raise
|
||||
jsMath.Macro('hfill','\\quad ',1); // punt
|
||||
jsMath.Macro('fbox','\\oldfbox{$#1$}',1); // do fbox in math mode
|
||||
|
||||
/*
|
||||
* These get new JavaScript routines
|
||||
*/
|
||||
jsMath.Parser.prototype.macros['unitlength'] = 'unitlength';
|
||||
jsMath.Parser.prototype.macros['hspace'] = 'hspace';
|
||||
jsMath.Parser.prototype.macros['fs'] = 'fs';
|
||||
jsMath.Parser.prototype.macros['oldfbox'] = 'FBox';
|
||||
|
||||
/*
|
||||
* Add some JavaScript functions to the parser
|
||||
*/
|
||||
jsMath.Package(jsMath.Parser,{
|
||||
|
||||
/*
|
||||
* Implement \left x ... \right x
|
||||
*/
|
||||
HandleLR: function (name,data) {
|
||||
var arg = this.GetUpto(name,name); if (this.error) return;
|
||||
this.string = '\\left'+data[0]+arg+'\\right'+data[1];
|
||||
this.i = 0;
|
||||
},
|
||||
|
||||
/*
|
||||
* Hold the unit length in mlist.data
|
||||
*/
|
||||
unitlength: function (name) {
|
||||
var n = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (!n.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) {
|
||||
this.Error("Argument for "+this.cmd+name+" must be a number");
|
||||
return;
|
||||
}
|
||||
this.mlist.data['unitlength'] = n;
|
||||
},
|
||||
|
||||
/*
|
||||
* Get the length (converted to ems) and multiply by the unit length
|
||||
*/
|
||||
hspace: function (name) {
|
||||
var w = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (!w.match(/^-?(\d+(\.\d*)?|\.\d+)$/)) {
|
||||
this.Error("Argument for "+this.cmd+name+" must be a number");
|
||||
return;
|
||||
}
|
||||
w /= jsMath.em
|
||||
if (this.mlist.data['unitlength']) {w *= this.mlist.data['unitlength']}
|
||||
this.mlist.Add(jsMath.mItem.Space(w));
|
||||
},
|
||||
|
||||
/*
|
||||
* Implement \fs{...} for font-size changing
|
||||
*/
|
||||
fs: function (name) {
|
||||
var n = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (!n.match(/^[-+]?\d+$/)) {
|
||||
this.Error("Argument for "+this.cmd+name+" must be an integer");
|
||||
return;
|
||||
}
|
||||
if (n.match(/[-+]/)) {n = n - 0; n += this.mlist.data.size}
|
||||
this.mlist.data.size = n = Math.max(0,Math.min(9,n));
|
||||
this.mlist.Add(new jsMath.mItem('size',{size: n}));
|
||||
},
|
||||
|
||||
/*
|
||||
* Repalce the Array function by one that accepts an optional
|
||||
* parameter for the column types, and that handle's mimeTeX's
|
||||
* "preamble" format.
|
||||
*/
|
||||
Array: function (name,delim) {
|
||||
var columns = delim[2]; var cspacing = delim[3];
|
||||
if (!columns && this.GetNext() == '{') {
|
||||
columns = this.GetArgument(this.cmd+'begin{'+name+'}');
|
||||
if (this.error) return;
|
||||
} else {
|
||||
columns = '';
|
||||
}
|
||||
columns = columns.replace(/[^clr]/g,'');
|
||||
columns = columns.split('');
|
||||
var data = this.mlist.data; var style = delim[5] || 'T';
|
||||
var arg = this.GetEnd(name); if (this.error) return;
|
||||
if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); columns = RegExp.$1}
|
||||
var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,style);
|
||||
parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
|
||||
parse.Parse(); if (parse.error) {this.Error(parse); return}
|
||||
parse.HandleRow(name,1); // be sure the last row is recorded
|
||||
var box = jsMath.Box.Layout(data.size,parse.table,columns,cspacing,parse.rspacing,delim[4]||null);
|
||||
// Add parentheses, if needed
|
||||
if (delim[0] && delim[1]) {
|
||||
var left = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
|
||||
var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
|
||||
box = jsMath.Box.SetList([left,box,right],data.style,data.size);
|
||||
}
|
||||
this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
|
||||
},
|
||||
|
||||
/*
|
||||
* Similarly for Matrix (used by \matrix and \array)
|
||||
*/
|
||||
Matrix: function (name,delim) {
|
||||
var data = this.mlist.data;
|
||||
var arg = this.GetArgument(this.cmd+name); if (this.error) return;
|
||||
if (arg.match(/\$/)) {arg = arg.replace(/^([^$]*)\$/,''); delim[2] = RegExp.$1}
|
||||
var parse = new jsMath.Parser(arg+this.cmd+'\\',null,data.size,delim[5] || 'T');
|
||||
parse.matrix = name; parse.row = []; parse.table = []; parse.rspacing = [];
|
||||
parse.Parse(); if (parse.error) {this.Error(parse); return}
|
||||
parse.HandleRow(name,1); // be sure the last row is recorded
|
||||
var box = jsMath.Box.Layout(data.size,parse.table,delim[2]||null,delim[3]||null,parse.rspacing,delim[4]||null);
|
||||
// Add parentheses, if needed
|
||||
if (delim[0] && delim[1]) {
|
||||
var left = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[0]],'T');
|
||||
var right = jsMath.Box.Delimiter(box.h+box.d-jsMath.hd/4,this.delimiter[delim[1]],'T');
|
||||
box = jsMath.Box.SetList([left,box,right],data.style,data.size);
|
||||
}
|
||||
this.mlist.Add(jsMath.mItem.Atom((delim[0]? 'inner': 'ord'),box));
|
||||
}
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* noCache.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file disables the equation cache that jsMath uses to
|
||||
* store the typeset versions of TeX code so that common expressions
|
||||
* won't need to be re-typeset.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath,{
|
||||
|
||||
/*
|
||||
* Get the width and height (in ems) of an HTML string
|
||||
*/
|
||||
EmBoxFor: function (s) {
|
||||
var bbox = this.BBoxFor(s);
|
||||
return {w: bbox.w/this.em, h: bbox.h/this.em};
|
||||
},
|
||||
|
||||
/*
|
||||
* For browsers that don't handle sizes of italics properly (MSIE)
|
||||
*/
|
||||
EmBoxForItalics: function (s) {
|
||||
var bbox = this.BBoxFor(s);
|
||||
if (s.match(/<i>|class=\"(icm|italic|igreek|iaccent)/i)) {
|
||||
bbox.w = this.BBoxFor(s+jsMath.Browser.italicString).w
|
||||
- jsMath.Browser.italicCorrection;
|
||||
}
|
||||
return {w: bbox.w/this.em, h: bbox.h/this.em};
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
jsMath.Add(jsMath.Translate,{
|
||||
|
||||
/*
|
||||
* Typeset a string in \textstyle and return the HTML for it
|
||||
*/
|
||||
TextMode: function (s) {
|
||||
var parse = jsMath.Parse(s,null,null,'T');
|
||||
parse.Atomize();
|
||||
return parse.Typeset();
|
||||
},
|
||||
|
||||
/*
|
||||
* Typeset a string in \displaystyle and return the HTML for it
|
||||
*/
|
||||
DisplayMode: function (s) {
|
||||
var parse = jsMath.Parse(s,null,null,'D');
|
||||
parse.Atomize();
|
||||
return parse.Typeset();
|
||||
}
|
||||
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* noGlobal.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file disables the Go Global button. It should be loaded
|
||||
* BEFORE jsMath.js.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
if (!jsMath.Controls.cookie) {jsMath.Controls.cookie = {}}
|
||||
|
||||
jsMath.noGoGlobal = 1;
|
||||
jsMath.noChangeGlobal = 1;
|
||||
jsMath.noShowGlobal = 1;
|
||||
jsMath.Controls.cookie.global = 'never';
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* noImageFonts.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file indicates that no image fonts are available.
|
||||
* It should be loaded BEFORE jsMath.js is loaded.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
jsMath.noImgFonts = 1;
|
||||
|
||||
if (!jsMath.Font) {jsMath.Font = {}}
|
||||
if (!jsMath.Font.extra_message) {
|
||||
jsMath.Font.extra_message =
|
||||
'Extra TeX fonts not found: <b><span id="jsMath_ExtraFonts"></span></b><br/>'
|
||||
+ 'Using unicode fonts instead. This may be slow and might not print well.<br/>\n'
|
||||
+ 'Use the jsMath control panel to get additional information.';
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* smallFonts.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file changes the sizes of fonts used in subscripts so that they
|
||||
* are larger. This can be helpful if jsMath is used on a page with a
|
||||
* small font size, where the subscripts may tend to disappear.
|
||||
* It should be loaded BEFORE jsMath.js.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
if (!jsMath.styles) {jsMath.styles = {}}
|
||||
if (!jsMath.Img) {jsMath.Img = {}}
|
||||
if (!jsMath.Box) {jsMath.Box = {}}
|
||||
if (!jsMath.Typeset) {jsMath.Typeset = {}}
|
||||
|
||||
/*
|
||||
* Replace the smaller font sizes
|
||||
*/
|
||||
jsMath.sizes = [70, 77, 85, 92, 100, 120, 144, 173, 207, 249];
|
||||
jsMath.Img.fonts = [70, 70, 85, 85, 100, 120, 144, 173, 207, 249, 298, 358, 430];
|
||||
|
||||
jsMath.styles['.typeset .size0']['font-size'] = '70%';
|
||||
jsMath.styles['.typeset .size1']['font-size'] = '77%';
|
||||
jsMath.styles['.typeset .size2']['font-size'] = '85%';
|
||||
jsMath.styles['.typeset .size3']['font-size'] = '92%';
|
||||
|
||||
/*
|
||||
* Fix multiplication factors in these routines
|
||||
*/
|
||||
jsMath.Typeset.StyleValue = function (style,v) {
|
||||
if (style == "S" || style == "S'") {return .85*v}
|
||||
if (style == "SS" || style == "SS'") {return .70*v}
|
||||
return v;
|
||||
};
|
||||
|
||||
jsMath.Box.DelimBestFit = function (H,c,font,style) {
|
||||
if (c == 0 && font == 0) return null;
|
||||
var C; var h; font = jsMath.TeX.fam[font];
|
||||
var isSS = (style.charAt(1) == 'S');
|
||||
var isS = (style.charAt(0) == 'S');
|
||||
while (c != null) {
|
||||
C = jsMath.TeX[font][c];
|
||||
if (C.h == null) {C.h = jsMath.Box.defaultH}; if (C.d == null) {C.d = 0}
|
||||
h = C.h+C.d;
|
||||
if (C.delim) {return [c,font,'',H]}
|
||||
if (isSS && .70*h >= H) {return [c,font,'SS',.7*h]}
|
||||
if (isS && .85*h >= H) {return [c,font,'S',.85*h]}
|
||||
if (h >= H || C.n == null) {return [c,font,'T',h]}
|
||||
c = C.n;
|
||||
}
|
||||
return null;
|
||||
};
|
|
@ -0,0 +1,372 @@
|
|||
/*
|
||||
* plugins/spriteImageFonts.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes jsMath use single files for the image fonts
|
||||
* rather than individual images for each character.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!window.jsMath) {window.jsMath = {}}
|
||||
|
||||
jsMath.spriteImageFonts = {version: "1.1"};
|
||||
|
||||
if (!jsMath.styles) {jsMath.styles = []}
|
||||
|
||||
jsMath.styles['.typeset .img'] = {
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
overflow: 'hidden',
|
||||
'background-repeat': 'no-repeat'
|
||||
};
|
||||
jsMath.styles['.typeset .img .xy'] = {
|
||||
position: 'relative',
|
||||
left: '0px', top: '0px'
|
||||
};
|
||||
|
||||
// for Mozilla
|
||||
jsMath.styles['.typeset .mimg'] = {position: 'relative'};
|
||||
jsMath.styles['.typeset .mimg .size'] = {display: '-moz-inline-box'};
|
||||
jsMath.styles['.typeset .mimg .wh'] = {
|
||||
position: 'absolute',
|
||||
left: '0px', top: '0px',
|
||||
overflow: 'hidden'
|
||||
};
|
||||
jsMath.styles['.typeset .mimg .xy'] = {
|
||||
position: 'relative',
|
||||
left: '0px', top: '0px'
|
||||
};
|
||||
// for MSIE
|
||||
jsMath.styles['.typeset .mimg .h'] = {
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
width: '0px'
|
||||
};
|
||||
|
||||
/*
|
||||
* Replace the TeXIMG function with one that uses the sprite fonts
|
||||
*/
|
||||
if (!jsMath.Box) {jsMath.Box = {}}
|
||||
jsMath.Box.TeXIMG = function (font,C,size) {
|
||||
var c = jsMath.TeX[font][C];
|
||||
if (c.img.reload && jsMath.Img[c.img.reload][font].loaded == 1)
|
||||
{delete c.img.reload; c.img.size = null}
|
||||
if (c.img.size != null && c.img.size == size &&
|
||||
c.img.best != null && c.img.best == jsMath.Img.best) return;
|
||||
var mustScale = (jsMath.Img.scale != 1);
|
||||
var id = jsMath.Img.best + size - 4;
|
||||
if (id < 0) {id = 0; mustScale = 1} else
|
||||
if (id >= jsMath.Img.fonts.length) {id = jsMath.Img.fonts.length-1; mustScale = 1}
|
||||
var imgFont = jsMath.Img[jsMath.Img.fonts[id]][font];
|
||||
if (!imgFont.loaded && jsMath.Browser.waitForImages) {
|
||||
// store information so several fonts can be loaded at once
|
||||
jsMath.Img.mustLoad[jsMath.Img.mustLoad.length] = [font,jsMath.Img.fonts[id]];
|
||||
imgFont.loaded = -1;
|
||||
}
|
||||
var img = imgFont[C];
|
||||
var scale = 1/jsMath.Img.w[jsMath.Img.fonts[id]];
|
||||
if (id != jsMath.Img.best + size - 4) {
|
||||
if (c.w != null) {scale = c.w/img[0]} else {
|
||||
scale *= jsMath.Img.fonts[size]/jsMath.Img.fonts[4]
|
||||
* jsMath.Img.fonts[jsMath.Img.best]/jsMath.Img.fonts[id];
|
||||
}
|
||||
}
|
||||
|
||||
// get the metrics for the character glyph
|
||||
var bScale = jsMath.Browser.imgScale;
|
||||
if (img[3] == null) {img[3] = 0}
|
||||
var w = (img[0]-img[3])*scale; var h = img[1]*scale; var d = -img[2]*scale;
|
||||
var x = img[3]-imgFont.x[C%16]; var y = img[1]-img[2]-imgFont.y[Math.floor(C/16)];
|
||||
var wh; var xy; var v;
|
||||
var ladjust = ""; var resize = ""; var vadjust; var wadjust;
|
||||
|
||||
if ((mustScale || jsMath.Controls.cookie.scaleImg) && !jsMath.Browser.operaImageFonts) {
|
||||
w += 2/jsMath.em; h += 2/jsMath.em; d -= 1/jsMath.em; y += 1; x += 1; // try to adjust for rounding errors
|
||||
resize = "width:"+jsMath.HTML.Em(imgFont.wh[0]*scale*bScale)+";";
|
||||
wh = "width:"+jsMath.HTML.Em(w*bScale)+";height:"+jsMath.HTML.Em(h*bScale)+";";
|
||||
xy = "left:"+jsMath.HTML.Em(x*scale*bScale)+";top:"+jsMath.HTML.Em(y*scale*bScale)+";";
|
||||
vadjust = "vertical-align:"+jsMath.HTML.Em(d*bScale)+";";
|
||||
v = jsMath.HTML.Em(h+d);
|
||||
if (img[3]) {ladjust = "margin-left:"+jsMath.HTML.Em(-img[3]*scale*bScale)+";"}
|
||||
} else {
|
||||
if (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha) {
|
||||
resize = "height:"+(imgFont.wh[1]*jsMath.Browser.imgScale)+"px;"
|
||||
+ "width:"+(imgFont.wh[0]*jsMath.Browser.imgScale)+"px;";
|
||||
}
|
||||
wh = "width:"+img[0]+"px; height:"+img[1]+"px;";
|
||||
xy = "left:"+x+"px; top:"+y+"px;";
|
||||
vadjust = "vertical-align:"+(-img[2])+"px;"; v = (img[1]-img[2])+"px";
|
||||
if (img[3]) {ladjust = "margin-left:"+(-img[3])+"px;"}
|
||||
}
|
||||
|
||||
wadjust = (c.w == null || Math.abs(c.w-w) < .01)? "" : " margin-right:"+jsMath.HTML.Em(c.w-w)+';';
|
||||
if (img[2] == 0 || jsMath.Browser.valignBug) {vadjust = ""}
|
||||
|
||||
// get the image
|
||||
var URL = jsMath.Img.URL(font,jsMath.Img.fonts[id],C); var IMG;
|
||||
if (jsMath.Browser.msieAlphaBug && jsMath.Controls.cookie.alpha) {
|
||||
IMG = '<span class="xy" style="'+xy+'">'
|
||||
+ '<img src="'+jsMath.blank+'" style="' + resize
|
||||
+ 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='
|
||||
+ "'" + URL + "', sizingMethod='scale'" + ');" />'
|
||||
+ '</span>';
|
||||
} else {
|
||||
IMG = '<img src="'+URL+'" class="xy" style="'+xy+resize+'" />';
|
||||
}
|
||||
if (imgFont.loaded == -1) {IMG = ""; c.img.reload = jsMath.Img.fonts[id]}
|
||||
|
||||
// get the HTML for cropping the image
|
||||
c.c = this.IMG(IMG,wh,vadjust,wadjust,ladjust,v,x,y,URL);
|
||||
c.tclass = "normal";
|
||||
c.img.bh = h+d; c.img.bd = -d;
|
||||
c.img.size = size; c.img.best = jsMath.Img.best;
|
||||
};
|
||||
|
||||
/*
|
||||
* Default uses inline-box containing an image
|
||||
*/
|
||||
jsMath.Box.IMG = function (IMG,wh,vadjust,wadjust,ladjust,v,x,y,URL) {
|
||||
return '<span class="img" style="'+wh+vadjust+wadjust+ladjust+'">'
|
||||
+ IMG + '</span>' + jsMath.Browser.msieImgFontBBoxFix;
|
||||
};
|
||||
|
||||
/*
|
||||
* Opera bug in inline-block alignment forces use of background image
|
||||
*/
|
||||
jsMath.Box.IMG_opera = function (IMG,wh,vadjust,wadjust,ladjust,v,x,y,URL) {
|
||||
var html = '<span class="img" style="background-image: url('+URL+');'
|
||||
+ wh + vadjust + 'background-position: '+x+'px '+y+'px"></span>';
|
||||
if (wadjust || ladjust)
|
||||
{html = '<span style="'+wadjust+ladjust+'">' + html + '</span>'}
|
||||
return html;
|
||||
};
|
||||
|
||||
/*
|
||||
* Mozilla's -moz-inline-box has top aligned with baseline, so adjust
|
||||
*/
|
||||
jsMath.Box.IMG_mozilla = function (IMG,wh,vadjust,wadjust,ladjust,v,x,y,URL) {
|
||||
vadjust = "vertical-align:"+v+";";
|
||||
var html = '<span class="mimg" style="'+vadjust+'">'
|
||||
+ '<span class="size" style="'+wh+'"></span>'
|
||||
+ '<span class="wh" style="'+wh+'">' + IMG + '</span>'
|
||||
+ '</span>';
|
||||
if (wadjust || ladjust)
|
||||
{html = '<span style="'+wadjust+ladjust+'">' + html + '</span>'}
|
||||
return html;
|
||||
};
|
||||
|
||||
/*
|
||||
* MSIE screws up vadjust on inline-box elements, so use absolute
|
||||
* positioning and an extra span to set the width and height
|
||||
*/
|
||||
jsMath.Box.IMG_msie = function (IMG,wh,vadjust,wadjust,ladjust,v,x,y,URL) {
|
||||
var html = '<span class="mimg">'
|
||||
+ '<span class="h" style="height:'+v+'">'
|
||||
+ '<span class="wh" style="'+wh+'">' + IMG + '</span>'
|
||||
+ '</span>'
|
||||
+ '<span class="img" style="'+wh+vadjust+'"></span>'
|
||||
+ '</span>';
|
||||
if (wadjust || ladjust) {
|
||||
html = jsMath.Browser.msieSpaceFix
|
||||
+ '<span style="'+wadjust+ladjust+'">' + html + '</span>';
|
||||
}
|
||||
return html;
|
||||
};
|
||||
|
||||
if (!jsMath.Img) {jsMath.Img = {}}
|
||||
|
||||
/*
|
||||
* Called by the extra-font definition files to add an image font
|
||||
* into the mix (save offset data and image size)
|
||||
*/
|
||||
jsMath.Img.AddFont = function (size,def) {
|
||||
if (!jsMath.Img[size]) {jsMath.Img[size] = {}};
|
||||
for (var font in def) {
|
||||
def[font].x = def[font][128]; def[font].y = def[font][129];
|
||||
def[font].wh = def[font][130];
|
||||
delete def[font][128]; delete def[font][129]; delete def[font][130];
|
||||
}
|
||||
jsMath.Add(jsMath.Img[size],def);
|
||||
};
|
||||
|
||||
/*
|
||||
* Get URL to directory for given font and size, based on the
|
||||
* user's alpha/plain setting
|
||||
*/
|
||||
jsMath.Img.URL = function (name,size) {
|
||||
if (size == null) {return this.root+name+'/font.js'}
|
||||
var type = (jsMath.Controls.cookie.alpha) ? '/alpha/': '/plain/';
|
||||
return this.root+name+type+size+'.png';
|
||||
};
|
||||
|
||||
/*
|
||||
* Laod the data for an image font
|
||||
*/
|
||||
jsMath.Img.LoadFont = function (name) {
|
||||
if (jsMath.browser == 'OmniWeb' && !jsMath.Browser.hasInlineBlock) {
|
||||
jsMath.noImgFonts = 1;
|
||||
jsMath.Font.Check();
|
||||
return;
|
||||
}
|
||||
if (!this.loaded) this.Init();
|
||||
jsMath.Setup.Script(this.URL(name));
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup for print mode
|
||||
*/
|
||||
jsMath.Img.Init = function () {
|
||||
if ((jsMath.Controls.cookie.print || jsMath.Controls.cookie.stayhires) && !jsMath.Browser.operaImgFonts) {
|
||||
jsMath.Controls.cookie.print = jsMath.Controls.cookie.stayhires;
|
||||
this.factor *= 3;
|
||||
if (!jsMath.Controls.isLocalCookie || !jsMath.Global.isLocal) {jsMath.Controls.SetCookie(0)}
|
||||
if (jsMath.Browser.alphaPrintBug) {jsMath.Controls.cookie.alpha = 0}
|
||||
}
|
||||
this.loaded = 1;
|
||||
jsMath.Img.root = jsMath.root + "fonts-sprite/";
|
||||
jsMath.version += "-sp" + jsMath.spriteImageFonts.version;
|
||||
};
|
||||
|
||||
|
||||
if (!jsMath.Browser) {jsMath.Browser = {}}
|
||||
/*
|
||||
* Hook into initialization routine
|
||||
*/
|
||||
jsMath.Browser.Init = function () {
|
||||
jsMath.browser = 'unknown';
|
||||
this.TestInlineBlock();
|
||||
this.TestSpanHeight();
|
||||
this.TestRenameOK();
|
||||
this.TestStyleChange();
|
||||
|
||||
this.MSIE();
|
||||
this.Mozilla();
|
||||
this.Opera();
|
||||
this.OmniWeb();
|
||||
this.Safari();
|
||||
this.Konqueror();
|
||||
|
||||
this.ImgFontInit();
|
||||
|
||||
//
|
||||
// Change some routines depending on the browser
|
||||
//
|
||||
if (this.allowAbsoluteDelim) {
|
||||
jsMath.Box.DelimExtend = jsMath.Box.DelimExtendAbsolute;
|
||||
jsMath.Box.Layout = jsMath.Box.LayoutAbsolute;
|
||||
} else {
|
||||
jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
|
||||
jsMath.Box.Layout = jsMath.Box.LayoutRelative;
|
||||
}
|
||||
|
||||
if (this.separateSkips) {
|
||||
jsMath.HTML.Place = jsMath.HTML.PlaceSeparateSkips;
|
||||
jsMath.Typeset.prototype.Place = jsMath.Typeset.prototype.PlaceSeparateSkips;
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* These should be part of the regular browser
|
||||
* test functions
|
||||
*/
|
||||
jsMath.Browser.ImgFontInit = function () {
|
||||
this.msieImgFontBBoxFix = '';
|
||||
if (jsMath.browser == 'Mozilla') {
|
||||
if (!jsMath.Browser.VersionAtLeast("3.0")) {jsMath.Box.IMG = jsMath.Box.IMG_mozilla}
|
||||
} else if (jsMath.browser == 'Opera') {
|
||||
if (!jsMath.Browser.VersionAtLeast("9.50")) {
|
||||
this.operaImageFonts = 1;
|
||||
jsMath.Box.IMG = jsMath.Box.IMG_opera;
|
||||
}
|
||||
} else if (jsMath.browser == 'MSIE') {
|
||||
if (jsMath.platform == 'mac') {
|
||||
this.msieImgFontBBoxFix = '<span style="display:none">x</span>'
|
||||
} else {
|
||||
jsMath.Parser.prototype.oldTypeset = jsMath.Parser.prototype.Typeset;
|
||||
jsMath.Parser.prototype.Typeset = jsMath.Parser.prototype.msieTypeset;
|
||||
jsMath.Img.mustLoad = [];
|
||||
this.msieImageFonts = 1;
|
||||
jsMath.Controls.defaults.alpha = 0;
|
||||
if (!jsMath.Controls.userSet.alpha) {jsMath.Controls.cookie.alpha = 0}
|
||||
jsMath.Box.IMG = jsMath.Box.IMG_msie;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!jsMath.Parser) {jsMath.Parser = {}}
|
||||
if (!jsMath.Parser.prototype) {jsMath.Parser.prototype = {}}
|
||||
/*
|
||||
* Handle loading of image files needed for this equation
|
||||
* (avoids MSIE bug where it will request the image more
|
||||
* than once if it is used more than once before it is
|
||||
* loaded.)
|
||||
*/
|
||||
jsMath.Parser.prototype.msieTypeset = function () {
|
||||
var HTML = this.oldTypeset();
|
||||
if (jsMath.Img.mustLoad.length > 0) {
|
||||
for (var i = 0; i < jsMath.Img.mustLoad.length; i++) {
|
||||
var IMG = jsMath.Img.URL(jsMath.Img.mustLoad[i][0],jsMath.Img.mustLoad[i][1]);
|
||||
jsMath.Script.WaitForImage(IMG);
|
||||
jsMath.Img[jsMath.Img.mustLoad[i][1]][jsMath.Img.mustLoad[i][0]].loaded = 1;
|
||||
}
|
||||
jsMath.Img.mustLoad = [];
|
||||
jsMath.Translate.restart = 1;
|
||||
throw "restart";
|
||||
}
|
||||
return HTML;
|
||||
};
|
||||
|
||||
/*
|
||||
* Override the control panel calls in order to
|
||||
* disable scaling in Opera.
|
||||
*/
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
/*
|
||||
* Add Opera calls to loading of control panel
|
||||
*/
|
||||
jsMath.Controls.Panel = function () {
|
||||
jsMath.Translate.Cancel();
|
||||
if (this.loaded) {
|
||||
this.Main();
|
||||
} else {
|
||||
jsMath.Script.delayedLoad(jsMath.root+"jsMath-controls.html");
|
||||
jsMath.Script.Push(this,"OperaInit");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Disable hi-res fonts and image scaling in Opera
|
||||
*/
|
||||
jsMath.Controls.OperaMain = function (init) {
|
||||
if (!init) {this.OldMain()}
|
||||
jsMath.Element("_resolution").disabled = true;
|
||||
};
|
||||
|
||||
jsMath.Controls.OperaOptions = function () {
|
||||
this.OldOptions();
|
||||
jsMath.Element("_scaleImg").disabled = true;
|
||||
jsMath.Element("_scaleImgText").className = "disabled";
|
||||
};
|
||||
|
||||
jsMath.Controls.OperaInit = function () {
|
||||
if (!jsMath.Browser.operaImageFonts) return;
|
||||
this.OldMain = this.Main; this.Main = this.OperaMain;
|
||||
this.OldOptions = this.Options; this.Options = this.OperaOptions;
|
||||
this.OperaMain(1);
|
||||
};
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* tex2math.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file is a plugin that searches text within a web page
|
||||
* for \(...\), \[...\], $...$ and $$...$$ and converts them to
|
||||
* the appropriate <SPAN CLASS="math">...</SPAN> or
|
||||
* <DIV CLASS="math">...</DIV> tags.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2007 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!jsMath.tex2math) {jsMath.tex2math = {}} // make sure jsMath.tex2math is defined
|
||||
if (!jsMath.tex2math.loaded) { // only load it once
|
||||
|
||||
if (!jsMath.Controls) {jsMath.Controls = {}}
|
||||
if (!jsMath.Controls.cookie) {jsMath.Controls.cookie = {}}
|
||||
|
||||
jsMath.Add(jsMath.tex2math,{
|
||||
|
||||
loaded: 1,
|
||||
window: window,
|
||||
|
||||
/*
|
||||
* Call the main conversion routine with appropriate flags
|
||||
*/
|
||||
|
||||
ConvertTeX: function (element) {
|
||||
this.Convert(element,{
|
||||
processSingleDollars: 1, processDoubleDollars: 1,
|
||||
processSlashParens: 1, processSlashBrackets: 1,
|
||||
processLaTeXenvironments: 0,
|
||||
custom: 0, fixEscapedDollars: 1
|
||||
});
|
||||
},
|
||||
|
||||
ConvertTeX2: function (element) {
|
||||
this.Convert(element,{
|
||||
processSingleDollars: 0, processDoubleDollars: 1,
|
||||
processSlashParens: 1, processSlashBrackets: 1,
|
||||
processLaTeXenvironments: 0,
|
||||
custom: 0, fixEscapedDollars: 0
|
||||
});
|
||||
},
|
||||
|
||||
ConvertLaTeX: function (element) {
|
||||
this.Convert(element,{
|
||||
processSingleDollars: 0, processDoubleDollars: 0,
|
||||
processSlashParens: 1, processSlashBrackets: 1,
|
||||
processLaTeXenvironments: 1,
|
||||
custom: 0, fixEscapedDollars: 0
|
||||
});
|
||||
},
|
||||
|
||||
ConvertCustom: function (element) {
|
||||
this.Convert(element,{custom: 1, fixEscapedDollars: 0});
|
||||
},
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
/*
|
||||
* Define a custom search by indicating the
|
||||
* strings to use for starting and ending
|
||||
* in-line and display mathematics
|
||||
*/
|
||||
CustomSearch: function (iOpen,iClose,dOpen,dClose) {
|
||||
this.inLineOpen = iOpen; this.inLineClose = iClose;
|
||||
this.displayOpen = dOpen; this.displayClose = dClose;
|
||||
this.createPattern('customPattern',new RegExp(
|
||||
'('+this.patternQuote(dOpen)+'|'
|
||||
+this.patternQuote(iOpen)+'|'
|
||||
+this.patternQuote(dClose)+'|'
|
||||
+this.patternQuote(iClose)+'|\\\\.)','g'
|
||||
));
|
||||
},
|
||||
|
||||
patternQuote: function (s) {
|
||||
s = s.replace(/([\^$(){}+*?\-|\[\]\:\\])/g,'\\$1');
|
||||
return s;
|
||||
},
|
||||
|
||||
/*
|
||||
* MSIE on the Mac doesn't handle lastIndex correctly, so
|
||||
* override it and implement it correctly.
|
||||
*/
|
||||
createPattern: function (name,pattern) {
|
||||
jsMath.tex2math[name] = pattern;
|
||||
if (this.fixPatterns) {
|
||||
pattern.oldExec = pattern.exec;
|
||||
pattern.exec = this.msiePatternExec;
|
||||
}
|
||||
},
|
||||
msiePatternExec: function (string) {
|
||||
if (this.lastIndex == null) (this.lastIndex = 0);
|
||||
var match = this.oldExec(string.substr(this.lastIndex));
|
||||
if (match) {this.lastIndex += match.lastIndex}
|
||||
else {this.lastIndex = null}
|
||||
return match;
|
||||
},
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
/*
|
||||
* Set up for the correct type of search, and recursively
|
||||
* convert the mathematics. Disable tex2math if the cookie
|
||||
* isn't set, or of there is an element with ID of 'tex2math_off'.
|
||||
*/
|
||||
Convert: function (element,flags) {
|
||||
this.Init();
|
||||
if (!element) {element = jsMath.document.body}
|
||||
if (typeof(element) == 'string') {element = jsMath.document.getElementById(element)}
|
||||
if (jsMath.Controls.cookie.tex2math &&
|
||||
(!jsMath.tex2math.allowDisableTag || !jsMath.document.getElementById('tex2math_off'))) {
|
||||
this.custom = 0; for (var i in flags) {this[i] = flags[i]}
|
||||
if (this.custom) {
|
||||
this.pattern = this.customPattern;
|
||||
this.ProcessMatch = this.customProcessMatch;
|
||||
} else {
|
||||
this.pattern = this.stdPattern;
|
||||
this.ProcessMatch = this.stdProcessMatch;
|
||||
}
|
||||
if (this.processDoubleDollars || this.processSingleDollars ||
|
||||
this.processSlashParens || this.processSlashBrackets ||
|
||||
this.processLaTeXenvironments || this.custom) this.ScanElement(element);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Recursively look through a document for text nodes that could
|
||||
* contain mathematics.
|
||||
*/
|
||||
ScanElement: function (element,ignore) {
|
||||
if (!element) {element = jsMath.document.body}
|
||||
if (typeof(element) == 'string') {element = jsMath.document.getElementById(element)}
|
||||
while (element) {
|
||||
if (element.nodeName == '#text') {
|
||||
if (!ignore) {element = this.ScanText(element)}
|
||||
} else {
|
||||
if (element.className == null) {element.className = ''}
|
||||
if (element.firstChild && element.className != 'math') {
|
||||
var off = ignore || element.className.match(/(^| )tex2math_ignore( |$)/) ||
|
||||
(element.tagName && element.tagName.match(/^(script|noscript|style|textarea|pre)$/i));
|
||||
off = off && !element.className.match(/(^| )tex2math_process( |$)/);
|
||||
this.ScanElement(element.firstChild,off);
|
||||
}
|
||||
}
|
||||
if (element) {element = element.nextSibling}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Looks through a text element for math delimiters and
|
||||
* process them. If <BR> tags are found in the middle, they
|
||||
* are ignored (this is for BBS systems that have editors
|
||||
* that insert these automatically).
|
||||
*/
|
||||
ScanText: function (element) {
|
||||
if (element.nodeValue.replace(/\s+/,'') == '') {return element}
|
||||
var match; var prev; this.search = {};
|
||||
while (element) {
|
||||
this.pattern.lastIndex = 0;
|
||||
while (element && element.nodeName == '#text' &&
|
||||
(match = this.pattern.exec(element.nodeValue))) {
|
||||
this.pattern.match = match;
|
||||
element = this.ProcessMatch(match[0],match.index,element);
|
||||
}
|
||||
if (this.search.matched) {element = this.EncloseMath(element)}
|
||||
if (!element) {return null}
|
||||
prev = element; element = element.nextSibling;
|
||||
while (element && (element.nodeName.toLowerCase() == 'br' ||
|
||||
element.nodeName.toLowerCase() == "#comment"))
|
||||
{prev = element; element = element.nextSibling}
|
||||
if (!element || element.nodeName != '#text') {return prev}
|
||||
}
|
||||
return element;
|
||||
},
|
||||
|
||||
/*
|
||||
* If a matching end tag has been found, process the mathematics.
|
||||
* Otherwise, update the search data for the given delimiter,
|
||||
* or ignore it, as the item dictates.
|
||||
*/
|
||||
stdProcessMatch: function (match,index,element) {
|
||||
if (match == this.search.end) {
|
||||
this.search.close = element;
|
||||
this.search.cpos = this.pattern.lastIndex;
|
||||
this.search.clength = (match.substr(0,4) == '\\end' ? 0 : match.length);
|
||||
element = this.EncloseMath(element);
|
||||
} else {
|
||||
switch (match) {
|
||||
case '\\(':
|
||||
if ((this.search.end == null ||
|
||||
(this.search.end != '$' && this.search.end != '$$')) &&
|
||||
this.processSlashParens) {
|
||||
this.ScanMark('span',element,'\\)');
|
||||
}
|
||||
break;
|
||||
|
||||
case '\\[':
|
||||
if ((this.search.end == null ||
|
||||
(this.search.end != '$' && this.search.end != '$$')) &&
|
||||
this.processSlashBrackets) {
|
||||
this.ScanMark('div',element,'\\]');
|
||||
}
|
||||
break;
|
||||
|
||||
case '$$':
|
||||
if (this.processDoubleDollars) {
|
||||
var type = (this.doubleDollarsAreInLine? 'span': 'div');
|
||||
this.ScanMark(type,element,'$$');
|
||||
}
|
||||
break;
|
||||
|
||||
case '$':
|
||||
if (this.search.end == null && this.processSingleDollars) {
|
||||
this.ScanMark('span',element,'$');
|
||||
}
|
||||
break;
|
||||
|
||||
case '\\$':
|
||||
if (this.search.end == null && this.fixEscapedDollars) {
|
||||
element.nodeValue = element.nodeValue.substr(0,index)
|
||||
+ element.nodeValue.substr(index+1);
|
||||
this.pattern.lastIndex--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (match.substr(0,6) == '\\begin' && this.search.end == null &&
|
||||
this.processLaTeXenvironments) {
|
||||
this.ScanMark('div',element,'\\end'+match.substr(6));
|
||||
this.search.olength = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return element;
|
||||
},
|
||||
|
||||
/*
|
||||
* If a matching end tag has been found, process the mathematics.
|
||||
* Otherwise, update the search data for the given delimiter,
|
||||
* or ignore it, as the item dictates.
|
||||
*/
|
||||
customProcessMatch: function (match,index,element) {
|
||||
if (match == this.search.end) {
|
||||
this.search.close = element;
|
||||
this.search.clength = match.length;
|
||||
this.search.cpos = this.pattern.lastIndex;
|
||||
if (match == this.inLineOpen || match == this.displayOpen) {
|
||||
element = this.EncloseMath(element);
|
||||
} else {this.search.matched = 1}
|
||||
} else if (match == this.inLineOpen) {
|
||||
if (this.search.matched) {element = this.EncloseMath(element)}
|
||||
this.ScanMark('span',element,this.inLineClose);
|
||||
} else if (match == this.displayOpen) {
|
||||
if (this.search.matched) {element = this.EncloseMath(element)}
|
||||
this.ScanMark('div',element,this.displayClose);
|
||||
}
|
||||
return element;
|
||||
},
|
||||
|
||||
/*
|
||||
* Return a structure that records the starting location
|
||||
* for the math element, and the end delimiter we want to find.
|
||||
*/
|
||||
ScanMark: function (type,element,end) {
|
||||
var len = this.pattern.match[1].length;
|
||||
this.search = {
|
||||
type: type, end: end, open: element, olength: len,
|
||||
pos: this.pattern.lastIndex - len
|
||||
};
|
||||
},
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
/*
|
||||
* Surround the mathematics by an appropriate
|
||||
* SPAN or DIV element marked as CLASS="math".
|
||||
*/
|
||||
EncloseMath: function (element) {
|
||||
var search = this.search; search.end = null;
|
||||
var close = search.close;
|
||||
if (search.cpos == close.length) {close = close.nextSibling}
|
||||
else {close = close.splitText(search.cpos)}
|
||||
if (!close) {close = jsMath.document.createTextNode("")}
|
||||
if (element == search.close) {element = close}
|
||||
var math = search.open.splitText(search.pos);
|
||||
while (math.nextSibling && math.nextSibling != close) {
|
||||
if (math.nextSibling.nodeValue !== null) {
|
||||
if (math.nextSibling.nodeName.toLowerCase() === "#comment") {
|
||||
math.nodeValue += math.nextSibling.nodeValue.replace(/^\[CDATA\[(.*)\]\]$/,"$1");
|
||||
} else {
|
||||
math.nodeValue += math.nextSibling.nodeValue;
|
||||
}
|
||||
} else {
|
||||
math.nodeValue += ' ';
|
||||
}
|
||||
math.parentNode.removeChild(math.nextSibling);
|
||||
}
|
||||
var TeX = math.nodeValue.substr(search.olength,
|
||||
math.nodeValue.length-search.olength-search.clength);
|
||||
math.parentNode.removeChild(math);
|
||||
math = this.createMathTag(search.type,TeX);
|
||||
//
|
||||
// This is where older, buggy browsers can fail under unpredicatble
|
||||
// circumstances, so we trap errors and at least get to continue
|
||||
// with the rest of the math. (## should add error message ##)
|
||||
//
|
||||
try {
|
||||
if (close && close.parentNode) {
|
||||
close.parentNode.insertBefore(math,close);
|
||||
} else if (search.open.nextSibling) {
|
||||
search.open.parentNode.insertBefore(math,search.open.nextSibling);
|
||||
} else {
|
||||
search.open.parentNode.appendChild(math);
|
||||
}
|
||||
} catch (err) {}
|
||||
this.search = {}; this.pattern.lastIndex = 0;
|
||||
return math;
|
||||
},
|
||||
|
||||
/*
|
||||
* Create an element for the mathematics
|
||||
*/
|
||||
createMathTag: function (type,text) {
|
||||
var tag = jsMath.document.createElement(type); tag.className = "math";
|
||||
var math = jsMath.document.createTextNode(text);
|
||||
tag.appendChild(math);
|
||||
return tag;
|
||||
},
|
||||
|
||||
//
|
||||
// MSIE won't let you insert a DIV within tags that are supposed to
|
||||
// contain in-line data (like <P> or <SPAN>), so we have to fake it
|
||||
// using SPAN tags that force the formatting to work like DIV. We
|
||||
// use a separate SPAN that is the full width of the containing
|
||||
// item, and that has the margins and centering from the div.typeset
|
||||
// style.
|
||||
//
|
||||
MSIEcreateMathTag: function (type,text) {
|
||||
var tag = jsMath.document.createElement("span");
|
||||
tag.className = "math";
|
||||
text = text.replace(/</g,'<').replace(/>/g,'>');
|
||||
if (type == 'div') {
|
||||
tag.className = "tex2math_div";
|
||||
text = '<span class="math">\\displaystyle{'+text+'}</span>';
|
||||
}
|
||||
tag.innerHTML = text;
|
||||
return tag;
|
||||
},
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
Init: function () {
|
||||
if (!jsMath.browser && document.all && !window.opera) {
|
||||
jsMath.browser = 'MSIE';
|
||||
jsMath.platform = (navigator.platform.match(/Mac/) ? "mac" :
|
||||
navigator.platform.match(/Win/) ? "pc" : "unix");
|
||||
}
|
||||
if (this.inited || !jsMath.browser) return;
|
||||
/*
|
||||
* MSIE can't handle the DIV's properly, so we need to do it by
|
||||
* hand. Use an extra SPAN that uses CSS to act like a DIV.
|
||||
*/
|
||||
if (jsMath.browser == 'MSIE' && jsMath.platform == 'pc')
|
||||
{this.createMathTag = this.MSIEcreateMathTag}
|
||||
this.inited = 1;
|
||||
},
|
||||
|
||||
/*
|
||||
* Test to see if we need to override the pattern exec() call
|
||||
* (for MSIE on the Mac).
|
||||
*/
|
||||
TestPatterns: function () {
|
||||
var pattern = /a/g;
|
||||
var match = pattern.exec("xax");
|
||||
this.fixPatterns = (pattern.lastIndex != 2 && match.lastIndex == 2);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Initialize
|
||||
*/
|
||||
if (jsMath.Controls.cookie.tex2math == null) {jsMath.Controls.cookie.tex2math = 1}
|
||||
if (jsMath.tex2math.allowDisableTag == null) {jsMath.tex2math.allowDisableTag = 1}
|
||||
jsMath.tex2math.TestPatterns();
|
||||
jsMath.tex2math.createPattern('stdPattern',/(\\[\(\)\[\]$]|\$\$|\$|\\(begin|end)\{[^}]+\})/g);
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>jsMath (Test): jsMath Image Mode Test Page</TITLE>
|
||||
<!-- Copyright (c) 2007 by Davide P. Cervone. All rights reserved. -->
|
||||
<!-- *Document-Format: jsMath -->
|
||||
<!-- *Navigation-Data:-->
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- *Navigation-links -->
|
||||
<TABLE WIDTH="100%" BORDER="1" CELLPADDING="2" CELLSPACING="1">
|
||||
<TR><TD BGCOLOR="#B8B8B8"><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
|
||||
<TR><TD WIDTH="20%" ALIGN="LEFT" NOWRAP></TD>
|
||||
<TD ALIGN="CENTER" WIDTH="60%"><!
|
||||
><NOBR><B><SMALL><A HREF="../welcome.html">jsMath</A> (Test)</SMALL></B></NOBR><!
|
||||
></TD>
|
||||
<TD ALIGN="RIGHT" WIDTH="20%" HEIGHT="25" NOWRAP><!
|
||||
></TD></TR></TABLE>
|
||||
</TD></TR></TABLE>
|
||||
<p>
|
||||
<!BR>
|
||||
|
||||
<!-- *Begin-Document-Body -->
|
||||
|
||||
<SCRIPT>
|
||||
jsMath = {
|
||||
Controls: {cookie: {scale: 133, font:'image', autofont:0}},
|
||||
Parser: {prototype: {
|
||||
macros: {warning: ["Macro","\\color{##00CC00}{\\rm jsMath\\ image\\ mode\\ appears\\ to\\ be\\ working!}",1]}
|
||||
}}
|
||||
}
|
||||
</SCRIPT>
|
||||
<SCRIPT SRC="../jsMath.js"></SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<DIV STYLE="color:#CC0000; text-align:center">
|
||||
<B>Warning: <A HREF="http://www.math.union.edu/locate/jsMath">jsMath</A>
|
||||
requires JavaScript to process the mathematics on this page.<BR>
|
||||
If your browser supports JavaScript, be sure it is enabled.<B>
|
||||
</DIV>
|
||||
<HR>
|
||||
</NOSCRIPT>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<H1>jsMath Image Mode Test Page</H1>
|
||||
|
||||
If you see typeset mathematics below, then jsMath Image Mode is working. If you see
|
||||
TeX code instead, jsMath Image Mode is not working for you.
|
||||
<p>
|
||||
<!------------------------------------------------------------------------>
|
||||
<HR>
|
||||
|
||||
|
||||
<DIV CLASS="math">
|
||||
\left(\, \sum_{k=1}^n a_k b_k \right)^2 \le
|
||||
\left(\, \sum_{k=1}^n a_k^2 \right) \left(\, \sum_{k=1}^n b_k^2 \right)
|
||||
</DIV>
|
||||
<p>
|
||||
|
||||
<DIV CLASS="math" STYLE="color:red">
|
||||
\warning{ jsMath image mode is not working! }
|
||||
</DIV>
|
||||
|
||||
<!------------------------------------------------------------------------>
|
||||
<HR>
|
||||
<p>
|
||||
If the mathematics does not show up properly, you may not have not
|
||||
installed the <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/download/jsMath.html">jsMath
|
||||
image fonts</A> file correctly. Follow the instructions on the linked
|
||||
page.
|
||||
<p>
|
||||
|
||||
Once you have jsMath working, go on to the <A HREF="sample.html">sample
|
||||
page</A> to see if <CODE>easy/load.js</CODE> is configured properly.
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<SCRIPT>
|
||||
jsMath.Controls.cookie.autofont = 0;
|
||||
jsMath.Controls.cookie.font = "image";
|
||||
jsMath.Process(document);
|
||||
</SCRIPT>
|
||||
|
||||
<!-- *End-Document-Body -->
|
||||
|
||||
<!-- *jsMath-Common-Footer -->
|
||||
<!BR><p>
|
||||
<HR SIZE="3">
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="98%" ALIGN="CENTER">
|
||||
<TR VALIGN="MIDDLE"><TD BGCOLOR="#B8B8B8" WIDTH="50%">
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="8" ALIGN="CENTER">
|
||||
<TR VALIGN="MIDDLE">
|
||||
|
||||
<TD><IMG SRC="jsMath40.jpg" ALT="[HOME]" BORDER="1" WIDTH="40" HEIGHT="40" HSPACE="5"></TD>
|
||||
<TD><SMALL>jsMath web pages<BR>
|
||||
Created: 14 Feb 2007<BR>
|
||||
<!-- hhmts start -->
|
||||
Last modified: Jun 16, 2007 8:56:17 AM
|
||||
<!-- hhmts end -->
|
||||
<BR>
|
||||
Comments to: <A HREF="mailto:dpvc@union.edu"><CODE>dpvc@union.edu</CODE></A><BR>
|
||||
</SMALL></TD>
|
||||
|
||||
</TR></TABLE></TD>
|
||||
<TD WIDTH="100%" BGCOLOR="#B8B8B8"> </TD>
|
||||
</TR></TABLE>
|
||||
<HR SIZE="3">
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,114 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>jsMath (Test): jsMath Test Page</TITLE>
|
||||
<!-- Copyright (c) 2007 by Davide P. Cervone. All rights reserved. -->
|
||||
<!-- *Document-Format: jsMath -->
|
||||
<!-- *Navigation-Data:-->
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- *Navigation-links -->
|
||||
<TABLE WIDTH="100%" BORDER="1" CELLPADDING="2" CELLSPACING="1">
|
||||
<TR><TD BGCOLOR="#B8B8B8"><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
|
||||
<TR><TD WIDTH="20%" ALIGN="LEFT" NOWRAP></TD>
|
||||
<TD ALIGN="CENTER" WIDTH="60%"><!
|
||||
><NOBR><B><SMALL><A HREF="../welcome.html">jsMath</A> (Test)</SMALL></B></NOBR><!
|
||||
></TD>
|
||||
<TD ALIGN="RIGHT" WIDTH="20%" HEIGHT="25" NOWRAP><!
|
||||
></TD></TR></TABLE>
|
||||
</TD></TR></TABLE>
|
||||
<p>
|
||||
<!BR>
|
||||
|
||||
<!-- *Begin-Document-Body -->
|
||||
|
||||
<SCRIPT>
|
||||
jsMath = {
|
||||
Controls: {
|
||||
cookie: {scale: 133},
|
||||
CheckVersion: function () {
|
||||
jsMath.Script.delayedLoad('http://www.math.union.edu/locate/jsMath/jsMath/jsMath-version-check.js');
|
||||
}
|
||||
},
|
||||
Parser: {prototype: {
|
||||
macros: {warning: ["Macro","\\color{##00CC00}{\\rm jsMath\\ appears\\ to\\ be\\ working!}",1]}
|
||||
}}
|
||||
}
|
||||
</SCRIPT>
|
||||
<SCRIPT SRC="../plugins/noImageFonts.js"></SCRIPT>
|
||||
<SCRIPT SRC="../jsMath.js"></SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<DIV STYLE="color:#CC0000; text-align:center">
|
||||
<B>Warning: <A HREF="http://www.math.union.edu/locate/jsMath">jsMath</A>
|
||||
requires JavaScript to process the mathematics on this page.<BR>
|
||||
If your browser supports JavaScript, be sure it is enabled.<B>
|
||||
</DIV>
|
||||
<HR>
|
||||
</NOSCRIPT>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<DIV STYLE="float:right; width:auto; margin-top:.5em">
|
||||
<INPUT TYPE="button" VALUE="Check for Updates" ONCLICK="jsMath.Controls.CheckVersion()">
|
||||
</DIV>
|
||||
|
||||
<H1>jsMath Test Page</H1>
|
||||
|
||||
If you see typeset mathematics below, then jsMath is working. If you see
|
||||
TeX code instead, jsMath is not working for you.
|
||||
<p>
|
||||
<!------------------------------------------------------------------------>
|
||||
<HR>
|
||||
|
||||
|
||||
<DIV CLASS="math">
|
||||
\left(\, \sum_{k=1}^n a_k b_k \right)^2 \le
|
||||
\left(\, \sum_{k=1}^n a_k^2 \right) \left(\, \sum_{k=1}^n b_k^2 \right)
|
||||
</DIV>
|
||||
<p>
|
||||
|
||||
<DIV CLASS="math" STYLE="color:red">
|
||||
\warning{ jsMath is not working! }
|
||||
</DIV>
|
||||
|
||||
<!------------------------------------------------------------------------>
|
||||
<HR>
|
||||
<p>
|
||||
|
||||
Once you have jsMath working properly, view the <A
|
||||
HREF="index-images.html">image mode test page</A> to make sure that the
|
||||
image fallback mode is working as well.
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<SCRIPT>
|
||||
jsMath.Process(document);
|
||||
</SCRIPT>
|
||||
|
||||
<!-- *End-Document-Body -->
|
||||
|
||||
<!-- *jsMath-Common-Footer -->
|
||||
<!BR><p>
|
||||
<HR SIZE="3">
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="98%" ALIGN="CENTER">
|
||||
<TR VALIGN="MIDDLE"><TD BGCOLOR="#B8B8B8" WIDTH="50%">
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="8" ALIGN="CENTER">
|
||||
<TR VALIGN="MIDDLE">
|
||||
|
||||
<TD><IMG SRC="jsMath40.jpg" ALT="[HOME]" BORDER="1" WIDTH="40" HEIGHT="40" HSPACE="5"></TD>
|
||||
<TD><SMALL>jsMath web pages<BR>
|
||||
Created: 14 Feb 2007<BR>
|
||||
<!-- hhmts start -->
|
||||
Last modified: Feb 12, 2009 6:14:47 PM
|
||||
<!-- hhmts end -->
|
||||
<BR>
|
||||
Comments to: <A HREF="mailto:dpvc@union.edu"><CODE>dpvc@union.edu</CODE></A><BR>
|
||||
</SMALL></TD>
|
||||
|
||||
</TR></TABLE></TD>
|
||||
<TD WIDTH="100%" BGCOLOR="#B8B8B8"> </TD>
|
||||
</TR></TABLE>
|
||||
<HR SIZE="3">
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,165 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>jsMath (Test): jsMath Sample Page</TITLE>
|
||||
<!-- Copyright (c) 2007 by Davide P. Cervone. All rights reserved. -->
|
||||
<!--
|
||||
| -----------------------------------------------------------
|
||||
| The following line loads and initializes jsMath.
|
||||
| You may need to edit the load.js file to set the
|
||||
| root URL for your site before this file will
|
||||
| display properly
|
||||
| -----------------------------------------------------------
|
||||
-->
|
||||
<SCRIPT SRC="../easy/load.js"></SCRIPT>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!--
|
||||
| -----------------------------------------------------------
|
||||
| Include this NOSCRIPT block to inform users that JavaScript
|
||||
| is required if they don't have it enabled.
|
||||
| -----------------------------------------------------------
|
||||
-->
|
||||
<NOSCRIPT>
|
||||
<DIV STYLE="color:#CC0000; text-align:center">
|
||||
<B>Warning: <A HREF="http://www.math.union.edu/locate/jsMath">jsMath</A>
|
||||
requires JavaScript to process the mathematics on this page.<BR>
|
||||
If your browser supports JavaScript, be sure it is enabled.<B>
|
||||
</DIV>
|
||||
<HR>
|
||||
</NOSCRIPT>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
|
||||
<H1>jsMath Sample Page</H1>
|
||||
|
||||
This is a sample file showing you how to use jsMath to display mathematics
|
||||
in your web pages. Be sure you have followed the <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/authors/installation.html">installation
|
||||
instructions</A> before loading this file. Also, you may need to edit the
|
||||
<CODE>jsMath/easy/load.js</CODE> file to set the root URL for where jsMath
|
||||
can be found on your web site. The rest of this document gives examples of
|
||||
how to enter mathematics in your pages. Depending on the settings in
|
||||
<CODE>jsMath/easy/load.js</CODE>, not all of the mathematics below will be
|
||||
processed by jsMath. Experiment with the settings in that file to see how
|
||||
they work.
|
||||
<p>
|
||||
|
||||
<HR>
|
||||
<p>
|
||||
|
||||
<H2>Some mathematics using <CODE>tex2math</CODE></H2>
|
||||
|
||||
The easiest way to enter mathematics is to use jsMath's <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/authors/tex2math.html">tex2math</A>
|
||||
plugin to identify the mathematics in your document by looking for <SPAN
|
||||
class="math">\rm\TeX</SPAN>-like math delimiters. Here are some math
|
||||
equations using those markers. Some inline math: $\sqrt{1-x^2}$ or \(ax^2+bx+c\),
|
||||
and some displayed math:
|
||||
$$\int {1\over x}\,dx = \ln(x)+C$$
|
||||
and
|
||||
\[\sum_{i=1}^n i = {n(n+1)\over 2}.\]
|
||||
Note that the first of these will not be processed unless you have enabled
|
||||
<CODE>processSingleDollars</CODE> in <CODE>jsMath/easy/load.js</CODE>,
|
||||
which is disabled by default. That is because a single dollar sign can
|
||||
appear in normal text (as in "That will cost from <SPAN>$</SPAN>3.50 to
|
||||
<SPAN>$</SPAN>5.00 to repair"), and you don't want jsMath to try to typeset
|
||||
the "3.50 to " as mathematics.
|
||||
<p>
|
||||
|
||||
If you enable <CODE>processSingleDollars</CODE>, you might also want to
|
||||
enable <CODE>fixEscapedDollars</CODE>, so that it is possible to enter
|
||||
dollar signs by preceding them with a backslash. Here's one that you can
|
||||
use to see the results of these settings: \$ (an escaped dollar) and $x+1$
|
||||
(not escaped).
|
||||
<p>
|
||||
|
||||
It is also possible to use your own custom delimiters for marking the
|
||||
mathematics within your pages. If you uncomment the <CODE>customDelimiters</CODE>
|
||||
array in <CODE>jsMath/easy/load.js</CODE>, then the following math will be
|
||||
typeset by jsMath: some inline math [math]\sin(2\pi x)[/math] and some
|
||||
display math [display]x={-b\pm \sqrt{b^2-4ac}\over 2a}.[/display]
|
||||
You may change the delimiters to nearly anything you want, but they can not
|
||||
look like HTML tags, since some browsers will eliminate unknown tags, and
|
||||
jsMath doesn't get to look for the custom delimiters until <I>after</I> the
|
||||
browser has interpreted the page.
|
||||
<p>
|
||||
|
||||
<DIV CLASS="tex2math_ignore">
|
||||
You can prevent the <CODE>tex2math</CODE> plugin from processing a portion
|
||||
of a page by enclosing it in a tag that is of
|
||||
<CODE>CLASS="tex2math_ignore"</CODE>. Often, that tag will be a
|
||||
<CODE>DIV</CODE> or <CODE>SPAN</CODE>, but it can be anything. This
|
||||
paragraph is wrapped in a DIV tag with
|
||||
<CODE>CLASS="tex2math_ignore"</CODE>, and so no math delimiters will be
|
||||
processed: $f\colon X\to Y$, \(x^2 \gt 5\), $$1\over 1+x^2$$ and
|
||||
\[\matrix{a& b\cr c& d}.\]
|
||||
Note that this includes the processing of escaped dollars (\$) and
|
||||
custom delimiters ([math]a \mapsto a^2[/math]) as well.
|
||||
This makes it possible to produce examples of how to enter mathematics on
|
||||
your site, for instance.
|
||||
</DIV>
|
||||
<P>
|
||||
JsMath will automatically ignore the text within
|
||||
<CODE>PRE</CODE> tags, so you can easily enter examples that way as well:
|
||||
<PRE>
|
||||
$f\colon X\to Y$, \(x^2 \gt 5\),
|
||||
$$1\over 1+x^2$$ and \[\matrix{a& b\cr c& d}.\]
|
||||
</PRE>
|
||||
<P>
|
||||
|
||||
Note that since the < and > symbols are used to denote HTML tags,
|
||||
these can be hard to incorporate into your <SPAN CLASS="math">\rm\TeX</SPAN>
|
||||
code. Often, putting spaces around the < or > will make it work, but
|
||||
it is probably better to use <CODE>\lt</CODE> and <CODE>\gt</CODE> instead.
|
||||
Also note that the <CODE>tex2math</CODE> plugin does not allow any HTML
|
||||
tags to be within the math delimiters, with the exception of
|
||||
<CODE><BR></CODE>, which is ignored.
|
||||
<p>
|
||||
|
||||
See the <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/authors/tex2math.html">tex2math
|
||||
documentation</A> for more information.
|
||||
<p>
|
||||
|
||||
<HR>
|
||||
<p>
|
||||
|
||||
<H2>Mathematics without <CODE>tex2math</CODE></H2>
|
||||
<p>
|
||||
|
||||
If you are not using <CODE>tex2math</CODE>, then you will need to enclose
|
||||
your mathematics within <CODE>SPAN</CODE> or <CODE>DIV</CODE> tags that
|
||||
are of <CODE>CLASS="math"</CODE>. Use a <CODE>SPAN</CODE> for in-line math
|
||||
and a <CODE>DIV</CODE> for displayed math. For instance, <SPAN
|
||||
CLASS="math">P = (x_1,\ldots,x_n)</SPAN> and
|
||||
<DIV CLASS="math">
|
||||
A = \left\lgroup\matrix{a_{11}& \cdots& a_{1m}\cr
|
||||
\vdots& \ddots& \vdots\cr
|
||||
a_{n1}& \cdots& a_{nm}\cr}\right\rgroup.
|
||||
</DIV>
|
||||
<p>
|
||||
<HR>
|
||||
<P>
|
||||
<H2>More information</H2>
|
||||
<p>
|
||||
|
||||
See the <A HREF="http://www.math.union.edu/locate/jsMath/examples">jsMath
|
||||
example files</A> for more examples of using jsMath. There are several <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/examples/extensions.html">extensions</A>
|
||||
to <SPAN CLASS="math">\rm\TeX</SPAN> that allow jsMath to interact better
|
||||
with HTML. These provide features such as colored text, tagging mathematics
|
||||
with CSS styles, and so on.
|
||||
<p>
|
||||
|
||||
More information is available from the <A
|
||||
HREF="http://www.math.union.edu/locate/jsMath/authors">jsMath author's
|
||||
documentation</A> site. JsMath also has a <A
|
||||
HREF="http://sourceforge.net/projects/jsmath/">home page at
|
||||
SourceForge</A>, and that includes <A
|
||||
HREF="http://sourceforge.net/forum/?group_id=172663">public forums</A>
|
||||
for jsMath where you can ask the jsMath user community for help.
|
||||
</BLOCKQUOTE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,977 @@
|
|||
/*
|
||||
* jsMath-fallback-pc.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed for when the TeX fonts are not available
|
||||
* with a browser on the PC.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* Here we replace the TeX character mappings by equivalent unicode
|
||||
* points when possible, and adjust the character dimensions
|
||||
* based on the fonts we hope we get them from (the styles are set
|
||||
* to try to use the best characters available in the standard
|
||||
* fonts).
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath.TeX,{
|
||||
|
||||
cmr10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', tclass: 'greek'},
|
||||
{c: 'Δ', tclass: 'greek'},
|
||||
{c: 'Θ', tclass: 'greek'},
|
||||
{c: 'Λ', tclass: 'greek'},
|
||||
{c: 'Ξ', tclass: 'greek'},
|
||||
{c: 'Π', tclass: 'greek'},
|
||||
{c: 'Σ', tclass: 'greek'},
|
||||
{c: 'Υ', tclass: 'greek'},
|
||||
{c: 'Φ', tclass: 'greek'},
|
||||
{c: 'Ψ', tclass: 'greek'},
|
||||
{c: 'Ω', tclass: 'greek'},
|
||||
{c: 'ff', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}, tclass: 'normal'},
|
||||
{c: 'fi', tclass: 'normal'},
|
||||
{c: 'fl', tclass: 'normal'},
|
||||
{c: 'ffi', tclass: 'normal'},
|
||||
{c: 'ffl', tclass: 'normal'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, tclass: 'normal'},
|
||||
{c: 'j', d:.2, tclass: 'normal'},
|
||||
{c: 'ˋ', tclass: 'accent'},
|
||||
{c: 'ˊ', tclass: 'accent'},
|
||||
{c: 'ˇ', tclass: 'accent'},
|
||||
{c: '˘', tclass: 'accent'},
|
||||
{c: 'ˉ', tclass: 'accent'},
|
||||
{c: '˚', tclass: 'accent'},
|
||||
{c: '̧', tclass: 'normal'},
|
||||
{c: 'ß', tclass: 'normal'},
|
||||
{c: 'æ', a:0, tclass: 'normal'},
|
||||
{c: 'œ', a:0, tclass: 'normal'},
|
||||
{c: 'ø', tclass: 'normal'},
|
||||
{c: 'Æ', tclass: 'normal'},
|
||||
{c: 'Œ', tclass: 'normal'},
|
||||
{c: 'Ø', tclass: 'normal'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.278, '76': -0.319}, tclass: 'normal'},
|
||||
{c: '!', lig: {'96': 60}, tclass: 'normal'},
|
||||
{c: '”', tclass: 'normal'},
|
||||
{c: '#', tclass: 'normal'},
|
||||
{c: '$', tclass: 'normal'},
|
||||
{c: '%', tclass: 'normal'},
|
||||
{c: '&', tclass: 'normal'},
|
||||
{c: '’', krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}, tclass: 'normal'},
|
||||
{c: '(', d:.2, tclass: 'normal'},
|
||||
{c: ')', d:.2, tclass: 'normal'},
|
||||
{c: '*', tclass: 'normal'},
|
||||
{c: '+', a:.1, tclass: 'normal'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'normal'},
|
||||
{c: '-', a:0, lig: {'45': 123}, tclass: 'normal'},
|
||||
{c: '.', a:-.25, tclass: 'normal'},
|
||||
{c: '/', tclass: 'normal'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'normal'},
|
||||
{c: '1', tclass: 'normal'},
|
||||
{c: '2', tclass: 'normal'},
|
||||
{c: '3', tclass: 'normal'},
|
||||
{c: '4', tclass: 'normal'},
|
||||
{c: '5', tclass: 'normal'},
|
||||
{c: '6', tclass: 'normal'},
|
||||
{c: '7', tclass: 'normal'},
|
||||
{c: '8', tclass: 'normal'},
|
||||
{c: '9', tclass: 'normal'},
|
||||
{c: ':', tclass: 'normal'},
|
||||
{c: ';', tclass: 'normal'},
|
||||
{c: '¡', tclass: 'normal'},
|
||||
{c: '=', a:0, d:-.1, tclass: 'normal'},
|
||||
{c: '¿', tclass: 'normal'},
|
||||
{c: '?', lig: {'96': 62}, tclass: 'normal'},
|
||||
// 40 - 4F
|
||||
{c: '@', tclass: 'normal'},
|
||||
{c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'B', tclass: 'normal'},
|
||||
{c: 'C', tclass: 'normal'},
|
||||
{c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'normal'},
|
||||
{c: 'E', tclass: 'normal'},
|
||||
{c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'G', tclass: 'normal'},
|
||||
{c: 'H', tclass: 'normal'},
|
||||
{c: 'I', krn: {'73': 0.0278}, tclass: 'normal'},
|
||||
{c: 'J', tclass: 'normal'},
|
||||
{c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'M', tclass: 'normal'},
|
||||
{c: 'N', tclass: 'normal'},
|
||||
{c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'normal'},
|
||||
// 50 - 5F
|
||||
{c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'normal'},
|
||||
{c: 'Q', d:.2, tclass: 'normal'},
|
||||
{c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'S', tclass: 'normal'},
|
||||
{c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'normal'},
|
||||
{c: 'U', tclass: 'normal'},
|
||||
{c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'normal'},
|
||||
{c: 'Z', tclass: 'normal'},
|
||||
{c: '[', d:.1, tclass: 'normal'},
|
||||
{c: '“', tclass: 'normal'},
|
||||
{c: ']', d:.1, tclass: 'normal'},
|
||||
{c: 'ˆ', tclass: 'accent'},
|
||||
{c: '˙', tclass: 'accent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', lig: {'96': 92}, tclass: 'normal'},
|
||||
{c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}, tclass: 'normal'},
|
||||
{c: 'd', tclass: 'normal'},
|
||||
{c: 'e', a:0, tclass: 'normal'},
|
||||
{c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'normal'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}, tclass: 'normal'},
|
||||
{c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'i', tclass: 'normal'},
|
||||
{c: 'j', d:.2, tclass: 'normal'},
|
||||
{c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'l', tclass: 'normal'},
|
||||
{c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'q', a:0, d:.2, tclass: 'normal'},
|
||||
{c: 'r', a:0, tclass: 'normal'},
|
||||
{c: 's', a:0, tclass: 'normal'},
|
||||
{c: 't', krn: {'121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'u', a:0, krn: {'119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'x', a:0, tclass: 'normal'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'normal'},
|
||||
{c: 'z', a:0, tclass: 'normal'},
|
||||
{c: '–', a:.1, ic: 0.0278, lig: {'45': 124}, tclass: 'normal'},
|
||||
{c: '—', a:.1, ic: 0.0278, tclass: 'normal'},
|
||||
{c: '˝', tclass: 'accent'},
|
||||
{c: '˜', tclass: 'accent'},
|
||||
{c: '¨', tclass: 'accent'}
|
||||
],
|
||||
|
||||
cmmi10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Δ', krn: {'127': 0.167}, tclass: 'igreek'},
|
||||
{c: 'Θ', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Λ', krn: {'127': 0.167}, tclass: 'igreek'},
|
||||
{c: 'Ξ', ic: 0.0757, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Π', ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Σ', ic: 0.0576, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Υ', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Φ', krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Ψ', ic: 0.11, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Ω', ic: 0.0502, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'α', a:0, ic: 0.0037, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'β', d:.2, ic: 0.0528, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'γ', a:0, d:.2, ic: 0.0556, tclass: 'greek'},
|
||||
{c: 'δ', ic: 0.0378, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'ε', a:0, krn: {'127': 0.0556}, tclass: 'lucida'},
|
||||
// 10 - 1F
|
||||
{c: 'ζ', d:.2, ic: 0.0738, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'η', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'θ', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'ι', a:0, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'κ', a:0, tclass: 'greek'},
|
||||
{c: 'λ', tclass: 'greek'},
|
||||
{c: 'μ', a:0, d:.2, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'ν', a:0, ic: 0.0637, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'ξ', d:.2, ic: 0.046, krn: {'127': 0.111}, tclass: 'greek'},
|
||||
{c: 'π', a:0, ic: 0.0359, tclass: 'greek'},
|
||||
{c: 'ρ', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'σ', a:0, ic: 0.0359, krn: {'59': -0.0556, '58': -0.0556}, tclass: 'greek'},
|
||||
{c: 'τ', a:0, ic: 0.113, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'υ', a:0, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'φ', a:.1, d:.2, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'χ', a:0, d:.2, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
// 20 - 2F
|
||||
{c: 'ψ', a:.1, d:.2, ic: 0.0359, krn: {'127': 0.111}, tclass: 'greek'},
|
||||
{c: 'ω', a:0, ic: 0.0359, tclass: 'greek'},
|
||||
{c: 'ε', a:0, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'ϑ', krn: {'127': 0.0833}, tclass: 'lucida'},
|
||||
{c: 'ϖ', a:0, ic: 0.0278, tclass: 'lucida'},
|
||||
{c: 'ϱ', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'lucida'},
|
||||
{c: 'ς', a:0, d:.2, ic: 0.0799, krn: {'127': 0.0833}, tclass: 'lucida'},
|
||||
{c: 'ϕ', a:.1, d:.2, krn: {'127': 0.0833}, tclass: 'lucida'},
|
||||
{c: '↼', a:0, d:-.2, tclass: 'arrows'},
|
||||
{c: '↽', a:0, d:-.1, tclass: 'arrows'},
|
||||
{c: '⇀', a:0, d:-.2, tclass: 'arrows'},
|
||||
{c: '⇁', a:0, d:-.1, tclass: 'arrows'},
|
||||
{c: '<span style="position:relative; top:-.1em">˓</span>', a:.1, tclass: 'symbol'},
|
||||
{c: '<span style="position:relative; top:-.1em">˒</span>', a:.1, tclass: 'symbol'},
|
||||
{c: '▹', tclass: 'symbol'},
|
||||
{c: '◃', tclass: 'symbol'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'normal'},
|
||||
{c: '1', tclass: 'normal'},
|
||||
{c: '2', tclass: 'normal'},
|
||||
{c: '3', tclass: 'normal'},
|
||||
{c: '4', tclass: 'normal'},
|
||||
{c: '5', tclass: 'normal'},
|
||||
{c: '6', tclass: 'normal'},
|
||||
{c: '7', tclass: 'normal'},
|
||||
{c: '8', tclass: 'normal'},
|
||||
{c: '9', tclass: 'normal'},
|
||||
{c: '.', a:-.3, tclass: 'normal'},
|
||||
{c: ',', a:-.3, d:.2, tclass: 'normal'},
|
||||
{c: '<', a:.1, tclass: 'normal'},
|
||||
{c: '<span style="font-size:133%; position:relative; top:.1em">/</span>', d:.1, krn: {'1': -0.0556, '65': -0.0556, '77': -0.0556, '78': -0.0556, '89': 0.0556, '90': -0.0556}, tclass: 'normal'},
|
||||
{c: '>', a:.1, tclass: 'normal'},
|
||||
{c: '⋆', a:0, tclass: 'arial'},
|
||||
// 40 - 4F
|
||||
{c: '∂', ic: 0.0556, krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: 'A', krn: {'127': 0.139}, tclass: 'italic'},
|
||||
{c: 'B', ic: 0.0502, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'C', ic: 0.0715, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'D', ic: 0.0278, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'E', ic: 0.0576, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'F', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'G', krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'H', ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'I', ic: 0.0785, krn: {'127': 0.111}, tclass: 'italic'},
|
||||
{c: 'J', ic: 0.0962, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'K', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'L', krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'M', ic: 0.109, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'N', ic: 0.109, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'O', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'Q', d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'R', ic: 0.00773, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'S', ic: 0.0576, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'T', ic: 0.139, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'U', ic: 0.109, krn: {'59': -0.111, '58': -0.111, '61': -0.0556, '127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'V', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'W', ic: 0.139, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'X', ic: 0.0785, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'Y', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'Z', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: '♭', tclass: 'symbol'},
|
||||
{c: '♮', tclass: 'symbol'},
|
||||
{c: '♯', tclass: 'symbol'},
|
||||
{c: '<span style="position: relative; top:-.3em; font-size:75%">‿</span>', a:0, d:-.1, tclass: 'arial'},
|
||||
{c: '<span style="position: relative; top:.4em; font-size:75%">⁀</span>', a:0, d:-.1, tclass: 'arial'},
|
||||
// 60 - 6F
|
||||
{c: 'ℓ', krn: {'127': 0.111}, tclass: 'italic'},
|
||||
{c: 'a', a:0, tclass: 'italic'},
|
||||
{c: 'b', tclass: 'italic'},
|
||||
{c: 'c', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'd', krn: {'89': 0.0556, '90': -0.0556, '106': -0.111, '102': -0.167, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'e', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'f', d:.2, ic: 0.108, krn: {'59': -0.0556, '58': -0.0556, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'h', krn: {'127': -0.0278}, tclass: 'italic'},
|
||||
{c: 'i', tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.0572, krn: {'59': -0.0556, '58': -0.0556}, tclass: 'italic'},
|
||||
{c: 'k', ic: 0.0315, tclass: 'italic'},
|
||||
{c: 'l', ic: 0.0197, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'm', a:0, tclass: 'italic'},
|
||||
{c: 'n', a:0, tclass: 'italic'},
|
||||
{c: 'o', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'q', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'r', a:0, ic: 0.0278, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 's', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 't', krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'u', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'v', a:0, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'w', a:0, ic: 0.0269, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'x', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'z', a:0, ic: 0.044, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'ı', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'j', d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: '℘', a:0, d:.2, krn: {'127': 0.111}, tclass: 'arial'},
|
||||
{c: '<span style="position:relative; left: .3em; top: -.65em; font-size: 67%">→</span>', ic: 0.154, tclass: 'symbol'},
|
||||
{c: '̑', ic: 0.399, tclass: 'normal'}
|
||||
],
|
||||
|
||||
cmsy10: [
|
||||
// 00 - 0F
|
||||
{c: '<span style="position:relative; top:.1em">−</span>', a:.1, tclass: 'symbol'},
|
||||
{c: '·', a:0, d:-.2, tclass: 'normal'},
|
||||
{c: '×', a:0, tclass: 'normal'},
|
||||
{c: '<span style="position:relative; top:.3em">*</span>', a:0, tclass: 'normal'},
|
||||
{c: '÷', a:0, tclass: 'normal'},
|
||||
{c: '◊', tclass: 'symbol'},
|
||||
{c: '±', a:.1, tclass: 'normal'},
|
||||
{c: '∓', tclass: 'symbol'},
|
||||
{c: '⊕', tclass: 'symbol'},
|
||||
{c: '⊖', tclass: 'symbol'},
|
||||
{c: '⊗', tclass: 'symbol'},
|
||||
{c: '⊘', tclass: 'symbol'},
|
||||
{c: '⊙', tclass: 'symbol'},
|
||||
{c: '◯', tclass: 'arial'},
|
||||
{c: '∘', a:0, d:-.1, tclass: 'symbol2'},
|
||||
{c: '•', a:0, d:-.2, tclass: 'symbol'},
|
||||
// 10 - 1F
|
||||
{c: '≍', a:.1, tclass: 'symbol2'},
|
||||
{c: '≡', a:.1, tclass: 'symbol2'},
|
||||
{c: '⊆', tclass: 'symbol'},
|
||||
{c: '⊇', tclass: 'symbol'},
|
||||
{c: '≤', tclass: 'symbol'},
|
||||
{c: '≥', tclass: 'symbol'},
|
||||
{c: '≼', tclass: 'symbol'},
|
||||
{c: '≽', tclass: 'symbol'},
|
||||
{c: '~', a:0, d: -.2, tclass: 'normal'},
|
||||
{c: '≈', a:.1, d:-.1, tclass: 'symbol'},
|
||||
{c: '⊂', tclass: 'symbol'},
|
||||
{c: '⊃', tclass: 'symbol'},
|
||||
{c: '≪', tclass: 'symbol'},
|
||||
{c: '≫', tclass: 'symbol'},
|
||||
{c: '≺', tclass: 'symbol'},
|
||||
{c: '≻', tclass: 'symbol'},
|
||||
// 20 - 2F
|
||||
{c: '←', a:-.1, tclass: 'arrow1'},
|
||||
{c: '→', a:-.1, tclass: 'arrow1'},
|
||||
{c: '↑', a:.2, d:0, tclass: 'arrow1a'},
|
||||
{c: '↓', a:.2, d:0, tclass: 'arrow1a'},
|
||||
{c: '↔', a:-.1, tclass: 'arrow1'},
|
||||
{c: '↗', a:.1, tclass: 'arrows'},
|
||||
{c: '↘', a:.1, tclass: 'arrows'},
|
||||
{c: '≃', a: .1, tclass: 'symbol2'},
|
||||
{c: '⇐', a:-.1, tclass: 'arrow2'},
|
||||
{c: '⇒', a:-.1, tclass: 'arrow2'},
|
||||
{c: '⇑', a:.2, d:.1, tclass: 'arrow1a'},
|
||||
{c: '⇓', a:.2, d:.1, tclass: 'arrow1a'},
|
||||
{c: '⇔', a:-.1, tclass: 'arrow2'},
|
||||
{c: '↖', a:.1, tclass: 'arrows'},
|
||||
{c: '↙', a:.1, tclass: 'arrows'},
|
||||
{c: '∝', a:.1, tclass: 'normal'},
|
||||
// 30 - 3F
|
||||
{c: '<span style="font-size: 133%; margin-right: -.1em; position: relative; top:.4em">′</span>', a: 0, tclass: 'lucida'},
|
||||
{c: '∞', a:.1, tclass: 'symbol'},
|
||||
{c: '∈', tclass: 'symbol'},
|
||||
{c: '∋', tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 150%; position:relative; top:.2em">△</span>', tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 150%; position:relative; top:.2em">▽</span>', tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 133%; position:relative; top:.2em">/</span>', d:.2, tclass: 'normal'},
|
||||
{c: '<span style="font-size: 67%; position: relative; top:-.15em; margin-right:-.3em">⊢</span>', tclass: 'symbol'},
|
||||
{c: '∀', tclass: 'symbol'},
|
||||
{c: '∃', tclass: 'symbol'},
|
||||
{c: '¬', a:0, d:-.1, tclass: 'symbol'},
|
||||
{c: '∅', tclass: 'symbol'},
|
||||
{c: 'ℜ', tclass: 'symbol'},
|
||||
{c: 'ℑ', tclass: 'symbol'},
|
||||
{c: '⊤', tclass: 'symbol'},
|
||||
{c: '⊥', tclass: 'symbol'},
|
||||
// 40 - 4F
|
||||
{c: 'ℵ', tclass: 'symbol'},
|
||||
{c: 'A', krn: {'48': 0.194}, tclass: 'cal'},
|
||||
{c: 'B', ic: 0.0304, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'C', ic: 0.0583, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'D', ic: 0.0278, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'E', ic: 0.0894, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'F', ic: 0.0993, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'G', d:.2, ic: 0.0593, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'H', ic: 0.00965, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'I', ic: 0.0738, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'J', d:.2, ic: 0.185, krn: {'48': 0.167}, tclass: 'cal'},
|
||||
{c: 'K', ic: 0.0144, krn: {'48': 0.0556}, tclass: 'cal'},
|
||||
{c: 'L', krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'M', krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'N', ic: 0.147, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'O', ic: 0.0278, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'Q', d:.2, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'R', krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'S', ic: 0.075, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'T', ic: 0.254, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'U', ic: 0.0993, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'V', ic: 0.0822, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'W', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'X', ic: 0.146, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'Y', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'Z', ic: 0.0794, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: '⋃', tclass: 'symbol'},
|
||||
{c: '⋂', tclass: 'symbol'},
|
||||
{c: '⊎', tclass: 'symbol'},
|
||||
{c: '⋀', tclass: 'symbol'},
|
||||
{c: '⋁', tclass: 'symbol'},
|
||||
// 60 - 6F
|
||||
{c: '⊢', tclass: 'symbol'},
|
||||
{c: '⊣', tclass: 'symbol'},
|
||||
{c: '⌊', a:.3, d:.2, tclass: 'arial'},
|
||||
{c: '⌋', a:.3, d:.2, tclass: 'arial'},
|
||||
{c: '⌈', a:.3, d:.2, tclass: 'arial'},
|
||||
{c: '⌉', a:.3, d:.2, tclass: 'arial'},
|
||||
{c: '{', d:.2, tclass: 'normal'},
|
||||
{c: '}', d:.2, tclass: 'normal'},
|
||||
{c: '〈', a:.3, d:.2, tclass: 'symbol'},
|
||||
{c: '〉', a:.3, d:.2, tclass: 'symbol'},
|
||||
{c: '∣', d:.1, tclass: 'symbol'},
|
||||
{c: '∥', d:.1, tclass: 'symbol'},
|
||||
{c: '↕', a:.2, d:0, tclass: 'arrow1a'},
|
||||
{c: '⇕', a:.3, d:0, tclass: 'arrow1a'},
|
||||
{c: '∖', a:.3, d:.1, tclass: 'symbol'},
|
||||
{c: '≀', tclass: 'symbol'},
|
||||
// 70 - 7F
|
||||
{c: '<span style="position:relative; top: .8em">√</span>', h:.04, d:.8, tclass: 'symbol'},
|
||||
{c: '∐', a:.4, tclass: 'symbol'},
|
||||
{c: '∇', tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 85%; left:-.1em; margin-right:-.2em">∫</span>', a:.4, d:.1, ic: 0.111, tclass: 'lucida'},
|
||||
{c: '⊔', tclass: 'symbol'},
|
||||
{c: '⊓', tclass: 'symbol'},
|
||||
{c: '⊑', tclass: 'symbol'},
|
||||
{c: '⊒', tclass: 'symbol'},
|
||||
{c: '§', d:.1, tclass: 'normal'},
|
||||
{c: '†', d:.1, tclass: 'normal'},
|
||||
{c: '‡', d:.1, tclass: 'normal'},
|
||||
{c: '¶', a:.3, d:.1, tclass: 'lucida'},
|
||||
{c: '♣', tclass: 'arial'},
|
||||
{c: '♢', tclass: 'arial'},
|
||||
{c: '♡', tclass: 'arial'},
|
||||
{c: '♠', tclass: 'arial'}
|
||||
],
|
||||
|
||||
cmex10: [
|
||||
// 00 - 0F
|
||||
{c: '(', h: 0.04, d: 1.16, n: 16, tclass: 'delim1'},
|
||||
{c: ')', h: 0.04, d: 1.16, n: 17, tclass: 'delim1'},
|
||||
{c: '[', h: 0.04, d: 1.16, n: 104, tclass: 'delim1'},
|
||||
{c: ']', h: 0.04, d: 1.16, n: 105, tclass: 'delim1'},
|
||||
{c: '⌈', h: 0.04, d: 1.16, n: 106, tclass: 'delim1a'},
|
||||
{c: '⌉', h: 0.04, d: 1.16, n: 107, tclass: 'delim1a'},
|
||||
{c: '⌊', h: 0.04, d: 1.16, n: 108, tclass: 'delim1a'},
|
||||
{c: '⌋', h: 0.04, d: 1.16, n: 109, tclass: 'delim1a'},
|
||||
{c: '<span style="margin-left:-.1em">{</span>', h: 0.04, d: 1.16, n: 110, tclass: 'delim1'},
|
||||
{c: '<span style="margin-right:-.1em">}</span>', h: 0.04, d: 1.16, n: 111, tclass: 'delim1'},
|
||||
{c: '〈', h: 0.04, d: 1.16, n: 68, tclass: 'delim1b'},
|
||||
{c: '〉', h: 0.04, d: 1.16, n: 69, tclass: 'delim1b'},
|
||||
{c: '∣', h:.7, d:.1, delim: {rep: 12}, tclass: 'symbol'},
|
||||
{c: '∥', h:.7, d:.1, delim: {rep: 13}, tclass: 'symbol'},
|
||||
{c: '/', h: 0.04, d: 1.16, n: 46, tclass: 'delim1a'},
|
||||
{c: '∖', h: 0.04, d: 1.16, n: 47, tclass: 'delim1a'},
|
||||
// 10 - 1F
|
||||
{c: '(', h: 0.04, d: 1.76, n: 18, tclass: 'delim2'},
|
||||
{c: ')', h: 0.04, d: 1.76, n: 19, tclass: 'delim2'},
|
||||
{c: '(', h: 0.04, d: 2.36, n: 32, tclass: 'delim3'},
|
||||
{c: ')', h: 0.04, d: 2.36, n: 33, tclass: 'delim3'},
|
||||
{c: '[', h: 0.04, d: 2.36, n: 34, tclass: 'delim3'},
|
||||
{c: ']', h: 0.04, d: 2.36, n: 35, tclass: 'delim3'},
|
||||
{c: '⌈', h: 0.04, d: 2.36, n: 36, tclass: 'delim3a'},
|
||||
{c: '⌉', h: 0.04, d: 2.36, n: 37, tclass: 'delim3a'},
|
||||
{c: '⌊', h: 0.04, d: 2.36, n: 38, tclass: 'delim3a'},
|
||||
{c: '⌋', h: 0.04, d: 2.36, n: 39, tclass: 'delim3a'},
|
||||
{c: '<span style="position:relative; left:-.1em; margin-right:-.1em">{</span>', h: 0.04, d: 2.36, n: 40, tclass: 'delim3'},
|
||||
{c: '<span style="position:relative; left:-.05em; margin-right:-.1em">}</span>', h: 0.04, d: 2.36, n: 41, tclass: 'delim3'},
|
||||
{c: '〈', h: 0.04, d: 2.36, n: 42, tclass: 'delim3b'},
|
||||
{c: '〉', h: 0.04, d: 2.36, n: 43, tclass: 'delim3b'},
|
||||
{c: '/', h: 0.04, d: 2.36, n: 44, tclass: 'delim3a'},
|
||||
{c: '∖', h: 0.04, d: 2.36, n: 45, tclass: 'delim3a'},
|
||||
// 20 - 2F
|
||||
{c: '(', h: 0.04, d: 2.96, n: 48, tclass: 'delim4'},
|
||||
{c: ')', h: 0.04, d: 2.96, n: 49, tclass: 'delim4'},
|
||||
{c: '[', h: 0.04, d: 2.96, n: 50, tclass: 'delim4'},
|
||||
{c: ']', h: 0.04, d: 2.96, n: 51, tclass: 'delim4'},
|
||||
{c: '⌈', h: 0.04, d: 2.96, n: 52, tclass: 'delim4a'},
|
||||
{c: '⌉', h: 0.04, d: 2.96, n: 53, tclass: 'delim4a'},
|
||||
{c: '⌊', h: 0.04, d: 2.96, n: 54, tclass: 'delim4a'},
|
||||
{c: '⌋', h: 0.04, d: 2.96, n: 55, tclass: 'delim4a'},
|
||||
{c: '<span style="position:relative; left:-.1em; margin-right:-.1em">{</span>', h: 0.04, d: 2.96, n: 56, tclass: 'delim4'},
|
||||
{c: '<span style="position:relative; left:-.1em; margin-right:-.1em">}</span>', h: 0.04, d: 2.96, n: 57, tclass: 'delim4'},
|
||||
{c: '〈', h: 0.04, d: 2.96, tclass: 'delim4b'},
|
||||
{c: '〉', h: 0.04, d: 2.96, tclass: 'delim4b'},
|
||||
{c: '/', h: 0.04, d: 2.96, tclass: 'delim4a'},
|
||||
{c: '∖', h: 0.04, d: 2.96, tclass: 'delim4a'},
|
||||
{c: '/', h: 0.04, d: 1.76, n: 30, tclass: 'delim2a'},
|
||||
{c: '∖', h: 0.04, d: 1.76, n: 31, tclass: 'delim2a'},
|
||||
// 30 - 3F
|
||||
{c: 'æ', h: .8, d: .2, delim: {top: 48, bot: 64, rep: 66}, tclass: 'delimx'},
|
||||
{c: 'ö', h: .8, d: .2, delim: {top: 49, bot: 65, rep: 67}, tclass: 'delimx'},
|
||||
{c: 'é', h: .8, d: .2, delim: {top: 50, bot: 52, rep: 54}, tclass: 'delimx'},
|
||||
{c: 'ù', h: .8, d: .2, delim: {top: 51, bot: 53, rep: 55}, tclass: 'delimx'},
|
||||
{c: 'ë', h: .8, d: .2, delim: {bot: 52, rep: 54}, tclass: 'delimx'},
|
||||
{c: 'û', h: .8, d: .2, delim: {bot: 53, rep: 55}, tclass: 'delimx'},
|
||||
{c: 'ê', h: .8, d: .2, delim: {top: 50, rep: 54}, tclass: 'delimx'},
|
||||
{c: 'ú', h: .8, d: .2, delim: {top: 51, rep: 55}, tclass: 'delimx'},
|
||||
{c: 'ì', h: .8, d: .2, delim: {top: 56, mid: 60, bot: 58, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'ü', h: .8, d: .2, delim: {top: 57, mid: 61, bot: 59, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'î', h: .8, d: .2, delim: {top: 56, bot: 58, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'þ', h: .8, d: .2, delim: {top: 57, bot: 59, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'í', h: .8, d: .2, delim: {rep: 63}, tclass: 'delimx'},
|
||||
{c: 'ý', h: .8, d: .2, delim: {rep: 119}, tclass: 'delimx'},
|
||||
{c: 'ï', h: .8, d: .2, delim: {rep: 62}, tclass: 'delimx'},
|
||||
{c: '<span style="margin:.125em">|</span>', h: .8, d: 0, delim: {top: 120, bot: 121, rep: 63}, tclass: 'normal'},
|
||||
// 40 - 4F
|
||||
{c: 'è', h: .8, d: .2, delim: {top: 56, bot: 59, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'ø', h: .8, d: .2, delim: {top: 57, bot: 58, rep: 62}, tclass: 'delimx'},
|
||||
{c: 'ç', h: .8, d: .2, delim: {rep: 66}, tclass: 'delimx'},
|
||||
{c: '÷', h: .8, d: .2, delim: {rep: 67}, tclass: 'delimx'},
|
||||
{c: '〈', h: 0.04, d: 1.76, n: 28, tclass: 'delim2b'},
|
||||
{c: '〉', h: 0.04, d: 1.76, n: 29, tclass: 'delim2b'},
|
||||
{c: '⊔', h: 0, d: 1, n: 71, tclass: 'bigop1'},
|
||||
{c: '⊔', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '∮', h: 0, d: 1.11, ic: 0.095, n: 73, tclass: 'bigop1c'},
|
||||
{c: '∮', h: 0, d: 2.22, ic: 0.222, tclass: 'bigop2c'},
|
||||
{c: '⊙', h: 0, d: 1, n: 75, tclass: 'bigop1'},
|
||||
{c: '⊙', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '⊕', h: 0, d: 1, n: 77, tclass: 'bigop1'},
|
||||
{c: '⊕', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '⊗', h: 0, d: 1, n: 79, tclass: 'bigop1'},
|
||||
{c: '⊗', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
// 50 - 5F
|
||||
{c: '∑', h: 0, d: 1, n: 88, tclass: 'bigop1a'},
|
||||
{c: '∏', h: 0, d: 1, n: 89, tclass: 'bigop1a'},
|
||||
{c: '∫', h: 0, d: 1.11, ic: 0.095, n: 90, tclass: 'bigop1c'},
|
||||
{c: '∪', h: 0, d: 1, n: 91, tclass: 'bigop1b'},
|
||||
{c: '∩', h: 0, d: 1, n: 92, tclass: 'bigop1b'},
|
||||
{c: '⊎', h: 0, d: 1, n: 93, tclass: 'bigop1b'},
|
||||
{c: '⋀', h: 0, d: 1, n: 94, tclass: 'bigop1'},
|
||||
{c: '⋁', h: 0, d: 1, n: 95, tclass: 'bigop1'},
|
||||
{c: '∑', h: 0.1, d: 1.6, tclass: 'bigop2a'},
|
||||
{c: '∏', h: 0.1, d: 1.5, tclass: 'bigop2a'},
|
||||
{c: '∫', h: 0, d: 2.22, ic: 0.222, tclass: 'bigop2c'},
|
||||
{c: '∪', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '∩', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '⊎', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '⋀', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '⋁', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
// 60 - 6F
|
||||
{c: '∐', h: 0, d: 1, n: 97, tclass: 'bigop1a'},
|
||||
{c: '∐', h: 0.1, d: 1.5, tclass: 'bigop2a'},
|
||||
{c: '︿', h: 0.722, w: .65, n: 99, tclass: 'wide1'},
|
||||
{c: '︿', h: 0.85, w: 1.1, n: 100, tclass: 'wide2'},
|
||||
{c: '︿', h: 0.99, w: 1.65, tclass: 'wide3'},
|
||||
{c: '~', h: 0.722, w: .5, n: 102, tclass: 'wide1a'},
|
||||
{c: '~', h: 0.8, w: .8, n: 103, tclass: 'wide2a'},
|
||||
{c: '~', h: 0.99, w: 1.3, tclass: 'wide3a'},
|
||||
{c: '[', h: 0.04, d: 1.76, n: 20, tclass: 'delim2'},
|
||||
{c: ']', h: 0.04, d: 1.76, n: 21, tclass: 'delim2'},
|
||||
{c: '⌈', h: 0.04, d: 1.76, n: 22, tclass: 'delim2a'},
|
||||
{c: '⌉', h: 0.04, d: 1.76, n: 23, tclass: 'delim2a'},
|
||||
{c: '⌊', h: 0.04, d: 1.76, n: 24, tclass: 'delim2a'},
|
||||
{c: '⌋', h: 0.04, d: 1.76, n: 25, tclass: 'delim2a'},
|
||||
{c: '<span style="position:relative; left:-.1em; margin-right:-.1em">{</span>', h: 0.04, d: 1.76, n: 26, tclass: 'delim2'},
|
||||
{c: '<span style="position:relative; margin-right:-.1em; left:-.05em">}</span>', h: 0.04, d: 1.76, n: 27, tclass: 'delim2'},
|
||||
// 70 - 7F
|
||||
{c: '<span style="font-size: 150%; position:relative; top:.8em">√</span>', h: 0.04, d: 1.16, n: 113, tclass: 'root'},
|
||||
{c: '<span style="font-size: 220%; position:relative; top:.8em">√</span>', h: 0.04, d: 1.76, n: 114, tclass: 'root'},
|
||||
{c: '<span style="font-size: 310%; position:relative; top:.8em; margin-right:-.01em">√</span>', h: 0.06, d: 2.36, n: 115, tclass: 'root'},
|
||||
{c: '<span style="font-size: 400%; position:relative; top:.8em; margin-right:-.025em">√</span>', h: 0.08, d: 2.96, n: 116, tclass: 'root'},
|
||||
{c: '<span style="font-size: 490%; position:relative; top:.8em; margin-right:-.03em">√</span>', h: 0.1, d: 3.75, n: 117, tclass: 'root'},
|
||||
{c: '<span style="font-size: 580%; position:relative; top:.775em; margin-right:-.04em">√</span>', h: .12, d: 4.5, n: 118, tclass: 'root'},
|
||||
{c: '<span style="font-size: 750%; position:relative; top:.775em;margin-right:-.04em">√</span>', h: .14, d: 5.7, tclass: 'root'},
|
||||
{c: '<span style="margin-left:.02em">|</span><span style="margin-left:.08em; margin-right:.125em">|</span>', h:.8, d:0, delim: {top: 126, bot: 127, rep: 119}, tclass: 'normal'},
|
||||
{c: '↑', h:.7, d:0, delim: {top: 120, rep: 63}, tclass: 'arrow1a'},
|
||||
{c: '↓', h:.65, d:0, delim: {bot: 121, rep: 63}, tclass: 'arrow1a'},
|
||||
{c: '<span style="margin-left:-.1em"></span><span style="position:relative; top:.55em; margin-right:-.3em">◜</span>', h: 0.05, tclass: 'symbol'},
|
||||
{c: '<span style="margin-left:-.3em"></span><span style="position:relative; top:.55em; margin-right:-.1em">◝</span>', h: 0.05, tclass: 'symbol'},
|
||||
{c: '<span style="margin-left:-.1em"></span><span style="position:relative; top:.15em; margin-right:-.3em">◟</span>', h: 0.05, tclass: 'symbol'},
|
||||
{c: '<span style="margin-left:-.3em"></span><span style="position:relative; top:.15em; margin-right:-.1em">◞</span>', h: 0.05, tclass: 'symbol'},
|
||||
{c: '⇑', h: .7, d:0, delim: {top: 126, rep: 119}, tclass: 'arrow1a'},
|
||||
{c: '⇓', h: .7, d:0, delim: {bot: 127, rep: 119}, tclass: 'arrow1a'}
|
||||
],
|
||||
|
||||
cmti10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', ic: 0.133, tclass: 'igreek'},
|
||||
{c: 'Δ', tclass: 'igreek'},
|
||||
{c: 'Θ', ic: 0.094, tclass: 'igreek'},
|
||||
{c: 'Λ', tclass: 'igreek'},
|
||||
{c: 'Ξ', ic: 0.153, tclass: 'igreek'},
|
||||
{c: 'Π', ic: 0.164, tclass: 'igreek'},
|
||||
{c: 'Σ', ic: 0.12, tclass: 'igreek'},
|
||||
{c: 'Υ', ic: 0.111, tclass: 'igreek'},
|
||||
{c: 'Φ', ic: 0.0599, tclass: 'igreek'},
|
||||
{c: 'Ψ', ic: 0.111, tclass: 'igreek'},
|
||||
{c: 'Ω', ic: 0.103, tclass: 'igreek'},
|
||||
{c: 'ff', ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 14, '108': 15}, tclass: 'italic'},
|
||||
{c: 'fi', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'fl', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'ffi', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'ffl', ic: 0.103, tclass: 'italic'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.0374, tclass: 'italic'},
|
||||
{c: 'ˋ', tclass: 'iaccent'},
|
||||
{c: 'ˊ', ic: 0.0969, tclass: 'iaccent'},
|
||||
{c: 'ˇ', ic: 0.083, tclass: 'iaccent'},
|
||||
{c: '˘', ic: 0.108, tclass: 'iaccent'},
|
||||
{c: 'ˉ', ic: 0.103, tclass: 'iaccent'},
|
||||
{c: '˚', tclass: 'iaccent'},
|
||||
{c: '?', d: 0.17, w: 0.46, tclass: 'italic'},
|
||||
{c: 'ß', ic: 0.105, tclass: 'italic'},
|
||||
{c: 'æ', a:0, ic: 0.0751, tclass: 'italic'},
|
||||
{c: 'œ', a:0, ic: 0.0751, tclass: 'italic'},
|
||||
{c: 'ø', ic: 0.0919, tclass: 'italic'},
|
||||
{c: 'Æ', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'Œ', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'Ø', ic: 0.094, tclass: 'italic'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.256, '76': -0.321}, tclass: 'italic'},
|
||||
{c: '!', ic: 0.124, lig: {'96': 60}, tclass: 'italic'},
|
||||
{c: '”', ic: 0.0696, tclass: 'italic'},
|
||||
{c: '#', ic: 0.0662, tclass: 'italic'},
|
||||
{c: '$', tclass: 'italic'},
|
||||
{c: '%', ic: 0.136, tclass: 'italic'},
|
||||
{c: '&', ic: 0.0969, tclass: 'italic'},
|
||||
{c: '’', ic: 0.124, krn: {'63': 0.102, '33': 0.102}, lig: {'39': 34}, tclass: 'italic'},
|
||||
{c: '(', d:.2, ic: 0.162, tclass: 'italic'},
|
||||
{c: ')', d:.2, ic: 0.0369, tclass: 'italic'},
|
||||
{c: '*', ic: 0.149, tclass: 'italic'},
|
||||
{c: '+', a:.1, ic: 0.0369, tclass: 'italic'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'italic'},
|
||||
{c: '-', a:0, ic: 0.0283, lig: {'45': 123}, tclass: 'italic'},
|
||||
{c: '.', a:-.25, tclass: 'italic'},
|
||||
{c: '/', ic: 0.162, tclass: 'italic'},
|
||||
// 30 - 3F
|
||||
{c: '0', ic: 0.136, tclass: 'italic'},
|
||||
{c: '1', ic: 0.136, tclass: 'italic'},
|
||||
{c: '2', ic: 0.136, tclass: 'italic'},
|
||||
{c: '3', ic: 0.136, tclass: 'italic'},
|
||||
{c: '4', ic: 0.136, tclass: 'italic'},
|
||||
{c: '5', ic: 0.136, tclass: 'italic'},
|
||||
{c: '6', ic: 0.136, tclass: 'italic'},
|
||||
{c: '7', ic: 0.136, tclass: 'italic'},
|
||||
{c: '8', ic: 0.136, tclass: 'italic'},
|
||||
{c: '9', ic: 0.136, tclass: 'italic'},
|
||||
{c: ':', ic: 0.0582, tclass: 'italic'},
|
||||
{c: ';', ic: 0.0582, tclass: 'italic'},
|
||||
{c: '¡', ic: 0.0756, tclass: 'italic'},
|
||||
{c: '=', a:0, d:-.1, ic: 0.0662, tclass: 'italic'},
|
||||
{c: '¿', tclass: 'italic'},
|
||||
{c: '?', ic: 0.122, lig: {'96': 62}, tclass: 'italic'},
|
||||
// 40 - 4F
|
||||
{c: '@', ic: 0.096, tclass: 'italic'},
|
||||
{c: 'A', krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'B', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'C', ic: 0.145, tclass: 'italic'},
|
||||
{c: 'D', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}, tclass: 'italic'},
|
||||
{c: 'E', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'F', ic: 0.133, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'G', ic: 0.0872, tclass: 'italic'},
|
||||
{c: 'H', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'I', ic: 0.158, tclass: 'italic'},
|
||||
{c: 'J', ic: 0.14, tclass: 'italic'},
|
||||
{c: 'K', ic: 0.145, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'L', krn: {'84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'M', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'N', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'O', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}, tclass: 'italic'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.103, krn: {'65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'Q', d:.2, ic: 0.094, tclass: 'italic'},
|
||||
{c: 'R', ic: 0.0387, krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'S', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'T', ic: 0.133, krn: {'121': -0.0767, '101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'U', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'V', ic: 0.184, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'W', ic: 0.184, krn: {'65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'X', ic: 0.158, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'Y', ic: 0.194, krn: {'101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'Z', ic: 0.145, tclass: 'italic'},
|
||||
{c: '[', d:.1, ic: 0.188, tclass: 'italic'},
|
||||
{c: '“', ic: 0.169, tclass: 'italic'},
|
||||
{c: ']', d:.1, ic: 0.105, tclass: 'italic'},
|
||||
{c: 'ˆ', ic: 0.0665, tclass: 'iaccent'},
|
||||
{c: '˙', ic: 0.118, tclass: 'iaccent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', ic: 0.124, lig: {'96': 92}, tclass: 'italic'},
|
||||
{c: 'a', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'b', ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'c', a:0, ic: 0.0565, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'd', ic: 0.103, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'e', a:0, ic: 0.0751, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'f', ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'italic'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'h', ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'i', ic: 0.102, tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.145, tclass: 'italic'},
|
||||
{c: 'k', ic: 0.108, tclass: 'italic'},
|
||||
{c: 'l', ic: 0.103, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'm', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'n', a:0, ic: 0.0767, krn: {'39': -0.102}, tclass: 'italic'},
|
||||
{c: 'o', a:0, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'q', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'r', a:0, ic: 0.108, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 's', a:0, ic: 0.0821, tclass: 'italic'},
|
||||
{c: 't', ic: 0.0949, tclass: 'italic'},
|
||||
{c: 'u', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'v', a:0, ic: 0.108, tclass: 'italic'},
|
||||
{c: 'w', a:0, ic: 0.108, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'x', a:0, ic: 0.12, tclass: 'italic'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'z', a:0, ic: 0.123, tclass: 'italic'},
|
||||
{c: '–', a:.1, ic: 0.0921, lig: {'45': 124}, tclass: 'italic'},
|
||||
{c: '—', a:.1, ic: 0.0921, tclass: 'italic'},
|
||||
{c: '˝', ic: 0.122, tclass: 'iaccent'},
|
||||
{c: '˜', ic: 0.116, tclass: 'iaccent'},
|
||||
{c: '¨', tclass: 'iaccent'}
|
||||
],
|
||||
|
||||
cmbx10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', tclass: 'bgreek'},
|
||||
{c: 'Δ', tclass: 'bgreek'},
|
||||
{c: 'Θ', tclass: 'bgreek'},
|
||||
{c: 'Λ', tclass: 'bgreek'},
|
||||
{c: 'Ξ', tclass: 'bgreek'},
|
||||
{c: 'Π', tclass: 'bgreek'},
|
||||
{c: 'Σ', tclass: 'bgreek'},
|
||||
{c: 'Υ', tclass: 'bgreek'},
|
||||
{c: 'Φ', tclass: 'bgreek'},
|
||||
{c: 'Ψ', tclass: 'bgreek'},
|
||||
{c: 'Ω', tclass: 'bgreek'},
|
||||
{c: 'ff', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}, tclass: 'bold'},
|
||||
{c: 'fi', tclass: 'bold'},
|
||||
{c: 'fl', tclass: 'bold'},
|
||||
{c: 'ffi', tclass: 'bold'},
|
||||
{c: 'ffl', tclass: 'bold'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, tclass: 'bold'},
|
||||
{c: 'j', d:.2, tclass: 'bold'},
|
||||
{c: 'ˋ', tclass: 'baccent'},
|
||||
{c: 'ˊ', tclass: 'baccent'},
|
||||
{c: 'ˇ', tclass: 'baccent'},
|
||||
{c: '˘', tclass: 'baccent'},
|
||||
{c: 'ˉ', tclass: 'baccent'},
|
||||
{c: '˚', tclass: 'baccent'},
|
||||
{c: '?', tclass: 'bold'},
|
||||
{c: 'ß', tclass: 'bold'},
|
||||
{c: 'æ', a:0, tclass: 'bold'},
|
||||
{c: 'œ', a:0, tclass: 'bold'},
|
||||
{c: 'ø', tclass: 'bold'},
|
||||
{c: 'Æ', tclass: 'bold'},
|
||||
{c: 'Œ', tclass: 'bold'},
|
||||
{c: 'Ø', tclass: 'bold'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.278, '76': -0.319}, tclass: 'bold'},
|
||||
{c: '!', lig: {'96': 60}, tclass: 'bold'},
|
||||
{c: '”', tclass: 'bold'},
|
||||
{c: '#', tclass: 'bold'},
|
||||
{c: '$', tclass: 'bold'},
|
||||
{c: '%', tclass: 'bold'},
|
||||
{c: '&', tclass: 'bold'},
|
||||
{c: '’', krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}, tclass: 'bold'},
|
||||
{c: '(', d:.2, tclass: 'bold'},
|
||||
{c: ')', d:.2, tclass: 'bold'},
|
||||
{c: '*', tclass: 'bold'},
|
||||
{c: '+', a:.1, tclass: 'bold'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'bold'},
|
||||
{c: '-', a:0, lig: {'45': 123}, tclass: 'bold'},
|
||||
{c: '.', a:-.25, tclass: 'bold'},
|
||||
{c: '/', tclass: 'bold'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'bold'},
|
||||
{c: '1', tclass: 'bold'},
|
||||
{c: '2', tclass: 'bold'},
|
||||
{c: '3', tclass: 'bold'},
|
||||
{c: '4', tclass: 'bold'},
|
||||
{c: '5', tclass: 'bold'},
|
||||
{c: '6', tclass: 'bold'},
|
||||
{c: '7', tclass: 'bold'},
|
||||
{c: '8', tclass: 'bold'},
|
||||
{c: '9', tclass: 'bold'},
|
||||
{c: ':', tclass: 'bold'},
|
||||
{c: ';', tclass: 'bold'},
|
||||
{c: '¡', tclass: 'bold'},
|
||||
{c: '=', a:0, d:-.1, tclass: 'bold'},
|
||||
{c: '¿', tclass: 'bold'},
|
||||
{c: '?', lig: {'96': 62}, tclass: 'bold'},
|
||||
// 40 - 4F
|
||||
{c: '@', tclass: 'bold'},
|
||||
{c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'B', tclass: 'bold'},
|
||||
{c: 'C', tclass: 'bold'},
|
||||
{c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'bold'},
|
||||
{c: 'E', tclass: 'bold'},
|
||||
{c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'G', tclass: 'bold'},
|
||||
{c: 'H', tclass: 'bold'},
|
||||
{c: 'I', krn: {'73': 0.0278}, tclass: 'bold'},
|
||||
{c: 'J', tclass: 'bold'},
|
||||
{c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'M', tclass: 'bold'},
|
||||
{c: 'N', tclass: 'bold'},
|
||||
{c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'bold'},
|
||||
// 50 - 5F
|
||||
{c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'bold'},
|
||||
{c: 'Q', d:.2, tclass: 'bold'},
|
||||
{c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'S', tclass: 'bold'},
|
||||
{c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'bold'},
|
||||
{c: 'U', tclass: 'bold'},
|
||||
{c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'bold'},
|
||||
{c: 'Z', tclass: 'bold'},
|
||||
{c: '[', d:.1, tclass: 'bold'},
|
||||
{c: '“', tclass: 'bold'},
|
||||
{c: ']', d:.1, tclass: 'bold'},
|
||||
{c: 'ˆ', tclass: 'baccent'},
|
||||
{c: '˙', tclass: 'baccent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', lig: {'96': 92}, tclass: 'bold'},
|
||||
{c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}, tclass: 'bold'},
|
||||
{c: 'd', tclass: 'bold'},
|
||||
{c: 'e', a:0, tclass: 'bold'},
|
||||
{c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'bold'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}, tclass: 'bold'},
|
||||
{c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'i', tclass: 'bold'},
|
||||
{c: 'j', d:.2, tclass: 'bold'},
|
||||
{c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'l', tclass: 'bold'},
|
||||
{c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'q', a:0, d:.2, tclass: 'bold'},
|
||||
{c: 'r', a:0, tclass: 'bold'},
|
||||
{c: 's', a:0, tclass: 'bold'},
|
||||
{c: 't', krn: {'121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'u', a:0, krn: {'119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'x', a:0, tclass: 'bold'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'bold'},
|
||||
{c: 'z', a:0, tclass: 'bold'},
|
||||
{c: '–', a:.1, ic: 0.0278, lig: {'45': 124}, tclass: 'bold'},
|
||||
{c: '—', a:.1, ic: 0.0278, tclass: 'bold'},
|
||||
{c: '˝', tclass: 'baccent'},
|
||||
{c: '˜', tclass: 'baccent'},
|
||||
{c: '¨', tclass: 'baccent'}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .cmr10': "font-family: serif",
|
||||
'.typeset .italic': "font-style: italic",
|
||||
'.typeset .bold': "font-weight: bold",
|
||||
'.typeset .lucida': "font-family: 'lucida sans unicode'",
|
||||
'.typeset .arial': "font-family: 'Arial unicode MS'",
|
||||
'.typeset .cal': "font-family: 'Script MT', 'Script MT Bold', cursive",
|
||||
'.typeset .arrows': "font-family: 'Arial unicode MS'",
|
||||
'.typeset .arrow1': "font-family: 'Arial unicode MS'",
|
||||
'.typeset .arrow1a': "font-family: 'Arial unicode MS'; position:relative; top:.05em;left:-.15em; margin-right:-.15em",
|
||||
'.typeset .arrow2': "font-family: 'Arial unicode MS'; position:relative; top:-.1em;",
|
||||
'.typeset .arrow3': "font-family: 'Arial unicode MS'; margin:.1em",
|
||||
'.typeset .symbol': "font-family: 'Arial unicode MS'",
|
||||
'.typeset .symbol2': "font-family: 'Arial unicode MS'",
|
||||
'.typeset .delim1': "font-family: 'Times New Roman'; font-size: 133%; position:relative; top:.7em",
|
||||
'.typeset .delim1a': "font-family: 'Lucida sans unicode'; font-size: 133%; position:relative; top:.8em",
|
||||
'.typeset .delim1b': "font-family: 'Arial unicode MS'; font-size: 133%; position:relative; top:.8em",
|
||||
'.typeset .delim2': "font-family: 'Times New Roman'; font-size: 180%; position:relative; top:.75em",
|
||||
'.typeset .delim2a': "font-family: 'Lucida sans unicode'; font-size: 180%; position:relative; top:.8em",
|
||||
'.typeset .delim2b': "font-family: 'Arial unicode MS'; font-size: 180%; position:relative; top:.8em",
|
||||
'.typeset .delim3': "font-family: 'Times New Roman'; font-size: 250%; position:relative; top:.725em",
|
||||
'.typeset .delim3a': "font-family: 'Lucida sans unicode'; font-size: 250%; position:relative; top:.775em",
|
||||
'.typeset .delim3b': "font-family: 'Arial unicode MS'; font-size: 250%; position:relative; top:.8em",
|
||||
'.typeset .delim4': "font-family: 'Times New Roman'; font-size: 325%; position:relative; top:.7em",
|
||||
'.typeset .delim4a': "font-family: 'Lucida sans unicode'; font-size: 325%; position:relative; top:.775em",
|
||||
'.typeset .delim4b': "font-family: 'Arial unicode MS'; font-size: 325%; position:relative; top:.8em",
|
||||
'.typeset .delimx': "font-family: Symbol; position:relative; top:.2em",
|
||||
'.typeset .greek': "font-family: 'Times New Roman'",
|
||||
'.typeset .igreek': "font-family: 'Times New Roman'; font-style:italic",
|
||||
'.typeset .bgreek': "font-family: 'Times New Roman'; font-weight:bold",
|
||||
'.typeset .bigop1': "font-family: 'Arial unicode MS'; font-size: 130%; position: relative; top: .7em; margin:-.05em",
|
||||
'.typeset .bigop1a': "font-family: 'Arial unicode MS'; font-size: 110%; position: relative; top: .85em;",
|
||||
'.typeset .bigop1b': "font-family: 'Arial unicode MS'; font-size: 180%; position: relative; top: .6em",
|
||||
'.typeset .bigop1c': "font-family: 'Arial unicode MS'; font-size: 85%; position: relative; top: 1em",
|
||||
'.typeset .bigop2': "font-family: 'Arial unicode MS'; font-size: 230%; position: relative; top: .6em; margin:-.05em",
|
||||
'.typeset .bigop2a': "font-family: 'Arial unicode MS'; font-size: 185%; position: relative; top: .75em",
|
||||
'.typeset .bigop2b': "font-family: 'Arial unicode MS'; font-size: 275%; position: relative; top: .55em",
|
||||
'.typeset .bigop2c': "font-family: 'Arial unicode MS'; font-size: 185%; position: relative; top: 1em; margin-right:-.1em",
|
||||
'.typeset .wide1': "font-size: 67%; position: relative; top:-.5em;",
|
||||
'.typeset .wide2': "font-size: 110%; position: relative; top:-.2em;",
|
||||
'.typeset .wide3': "font-size: 175%;",
|
||||
'.typeset .wide1a': "font-family: 'Times New Roman'; font-size: 75%; position: relative; top:-.5em",
|
||||
'.typeset .wide2a': "font-family: 'Times New Roman'; font-size: 133%; position: relative; top:-.2em",
|
||||
'.typeset .wide3a': "font-family: 'Times New Roman'; font-size: 200%; position: relative; top:-.1em",
|
||||
'.typeset .root': "font-family: 'Arial unicode MS'; margin-right:-.075em",
|
||||
'.typeset .accent': "font-family: 'Arial unicode MS'; position:relative; top:.05em; left:.15em",
|
||||
'.typeset .iaccent': "font-family: 'Arial unicode MS'; position:relative; top:.05em; left:.15em; font-style:italic",
|
||||
'.typeset .baccent': "font-family: 'Arial unicode MS'; position:relative; top:.05em; left:.15em; font-weight:bold"
|
||||
});
|
||||
|
||||
//
|
||||
// adjust for Mozilla
|
||||
//
|
||||
if (jsMath.browser == 'Mozilla') {
|
||||
jsMath.Update.TeXfonts({
|
||||
cmex10: {
|
||||
'48': {c: ''},
|
||||
'49': {c: ''},
|
||||
'50': {c: ''},
|
||||
'51': {c: ''},
|
||||
'52': {c: ''},
|
||||
'53': {c: ''},
|
||||
'54': {c: ''},
|
||||
'55': {c: ''},
|
||||
'56': {c: ''},
|
||||
'57': {c: ''},
|
||||
'58': {c: ''},
|
||||
'59': {c: ''},
|
||||
'60': {c: ''},
|
||||
'61': {c: ''},
|
||||
'62': {c: ''},
|
||||
'64': {c: ''},
|
||||
'65': {c: ''},
|
||||
'66': {c: ''},
|
||||
'67': {c: ''}
|
||||
}
|
||||
});
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .accent': 'font-family: Arial unicode MS; position:relative; top:.05em; left:.05em'
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// adjust for MSIE
|
||||
//
|
||||
if (jsMath.browser == "MSIE") {
|
||||
jsMath.Browser.msieFontBug = 1;
|
||||
jsMath.Update.TeXfonts({
|
||||
cmex10: {
|
||||
'63': {c: '<span style="position:relative; left:.125em; margin-right:.125em">|</span>'},
|
||||
'119': {c: '<span style="position:relative; left:.02em; margin-right=.08em">|</span><span style="margin-right:.125em">|</span>'}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* No access to TeX "not" character, so fake this
|
||||
* Also ajust the bowtie spacing
|
||||
*/
|
||||
jsMath.Macro('not','\\mathrel{\\rlap{\\kern 3mu/}}');
|
||||
jsMath.Macro('bowtie','\\mathrel\\triangleright\\kern-6mu\\mathrel\\triangleleft');
|
||||
|
||||
jsMath.Box.defaultH = 0.8;
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* jsMath-fallback-symbols.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed to use image fonts for symbols
|
||||
* but standard native fonts for letters and numbers.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath.Img,{
|
||||
UpdateTeXFonts: function (change) {
|
||||
for (var font in change) {
|
||||
for (var code in change[font]) {
|
||||
jsMath.TeX[font][code] = change[font][code];
|
||||
jsMath.TeX[font][code].tclass = 'i' + font;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
jsMath.Img.UpdateTeXFonts({
|
||||
cmr10: {
|
||||
'33': {c: '!', lig: {'96': 60}},
|
||||
'35': {c: '#'},
|
||||
'36': {c: '$'},
|
||||
'37': {c: '%'},
|
||||
'38': {c: '&'},
|
||||
'40': {c: '(', d:.2},
|
||||
'41': {c: ')', d:.2},
|
||||
'42': {c: '*', d:-.3},
|
||||
'43': {c: '+', a:.1},
|
||||
'44': {c: ',', a:-.3},
|
||||
'45': {c: '-', a:0, lig: {'45': 123}},
|
||||
'46': {c: '.', a:-.25},
|
||||
'47': {c: '/'},
|
||||
'48': {c: '0'},
|
||||
'49': {c: '1'},
|
||||
'50': {c: '2'},
|
||||
'51': {c: '3'},
|
||||
'52': {c: '4'},
|
||||
'53': {c: '5'},
|
||||
'54': {c: '6'},
|
||||
'55': {c: '7'},
|
||||
'56': {c: '8'},
|
||||
'57': {c: '9'},
|
||||
'58': {c: ':'},
|
||||
'59': {c: ';'},
|
||||
'61': {c: '=', a:0, d:-.1},
|
||||
'63': {c: '?', lig: {'96': 62}},
|
||||
'64': {c: '@'},
|
||||
'65': {c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'66': {c: 'B'},
|
||||
'67': {c: 'C'},
|
||||
'68': {c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
|
||||
'69': {c: 'E'},
|
||||
'70': {c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'71': {c: 'G'},
|
||||
'72': {c: 'H'},
|
||||
'73': {c: 'I', krn: {'73': 0.0278}},
|
||||
'74': {c: 'J'},
|
||||
'75': {c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'76': {c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'77': {c: 'M'},
|
||||
'78': {c: 'N'},
|
||||
'79': {c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
|
||||
'80': {c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
|
||||
'81': {c: 'Q', d: 1},
|
||||
'82': {c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'83': {c: 'S'},
|
||||
'84': {c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
|
||||
'85': {c: 'U'},
|
||||
'86': {c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'87': {c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'88': {c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'89': {c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
|
||||
'90': {c: 'Z'},
|
||||
'91': {c: '[', d:.1},
|
||||
'93': {c: ']', d:.1},
|
||||
'97': {c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'98': {c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'99': {c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}},
|
||||
'100': {c: 'd'},
|
||||
'101': {c: 'e', a:0},
|
||||
'102': {c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}},
|
||||
'103': {c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}},
|
||||
'104': {c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'105': {c: 'i'},
|
||||
'106': {c: 'j', d:1},
|
||||
'107': {c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'108': {c: 'l'},
|
||||
'109': {c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'110': {c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'111': {c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'112': {c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'113': {c: 'q', a:0, d:1},
|
||||
'114': {c: 'r', a:0},
|
||||
'115': {c: 's', a:0},
|
||||
'116': {c: 't', krn: {'121': -0.0278, '119': -0.0278}},
|
||||
'117': {c: 'u', a:0, krn: {'119': -0.0278}},
|
||||
'118': {c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'119': {c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'120': {c: 'x', a:0},
|
||||
'121': {c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
|
||||
'122': {c: 'z', a:0}
|
||||
},
|
||||
cmmi10: {
|
||||
'65': {c: 'A', krn: {'127': 0.139}},
|
||||
'66': {c: 'B', ic: 0.0502, krn: {'127': 0.0833}},
|
||||
'67': {c: 'C', ic: 0.0715, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'68': {c: 'D', ic: 0.0278, krn: {'127': 0.0556}},
|
||||
'69': {c: 'E', ic: 0.0576, krn: {'127': 0.0833}},
|
||||
'70': {c: 'F', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}},
|
||||
'71': {c: 'G', krn: {'127': 0.0833}},
|
||||
'72': {c: 'H', ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
|
||||
'73': {c: 'I', ic: 0.0785, krn: {'127': 0.111}},
|
||||
'74': {c: 'J', ic: 0.0962, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.167}},
|
||||
'75': {c: 'K', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}},
|
||||
'76': {c: 'L', krn: {'127': 0.0278}},
|
||||
'77': {c: 'M', ic: 0.109, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'78': {c: 'N', ic: 0.109, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'79': {c: 'O', ic: 0.0278, krn: {'127': 0.0833}},
|
||||
'80': {c: 'P', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}},
|
||||
'81': {c: 'Q', d:.2, krn: {'127': 0.0833}},
|
||||
'82': {c: 'R', ic: 0.00773, krn: {'127': 0.0833}},
|
||||
'83': {c: 'S', ic: 0.0576, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'84': {c: 'T', ic: 0.139, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'85': {c: 'U', ic: 0.109, krn: {'59': -0.111, '58': -0.111, '61': -0.0556, '127': 0.0278}},
|
||||
'86': {c: 'V', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
|
||||
'87': {c: 'W', ic: 0.139, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
|
||||
'88': {c: 'X', ic: 0.0785, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'89': {c: 'Y', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}},
|
||||
'90': {c: 'Z', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}},
|
||||
'97': {c: 'a', a:0},
|
||||
'98': {c: 'b'},
|
||||
'99': {c: 'c', a:0, krn: {'127': 0.0556}},
|
||||
'100': {c: 'd', krn: {'89': 0.0556, '90': -0.0556, '106': -0.111, '102': -0.167, '127': 0.167}},
|
||||
'101': {c: 'e', a:0, krn: {'127': 0.0556}},
|
||||
'102': {c: 'f', d:.2, ic: 0.108, krn: {'59': -0.0556, '58': -0.0556, '127': 0.167}},
|
||||
'103': {c: 'g', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0278}},
|
||||
'104': {c: 'h', krn: {'127': -0.0278}},
|
||||
'105': {c: 'i'},
|
||||
'106': {c: 'j', d:.2, ic: 0.0572, krn: {'59': -0.0556, '58': -0.0556}},
|
||||
'107': {c: 'k', ic: 0.0315},
|
||||
'108': {c: 'l', ic: 0.0197, krn: {'127': 0.0833}},
|
||||
'109': {c: 'm', a:0},
|
||||
'110': {c: 'n', a:0},
|
||||
'111': {c: 'o', a:0, krn: {'127': 0.0556}},
|
||||
'112': {c: 'p', a:0, d:.2, krn: {'127': 0.0833}},
|
||||
'113': {c: 'q', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0833}},
|
||||
'114': {c: 'r', a:0, ic: 0.0278, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}},
|
||||
'115': {c: 's', a:0, krn: {'127': 0.0556}},
|
||||
'116': {c: 't', krn: {'127': 0.0833}},
|
||||
'117': {c: 'u', a:0, krn: {'127': 0.0278}},
|
||||
'118': {c: 'v', a:0, ic: 0.0359, krn: {'127': 0.0278}},
|
||||
'119': {c: 'w', a:0, ic: 0.0269, krn: {'127': 0.0833}},
|
||||
'120': {c: 'x', a:0, krn: {'127': 0.0278}},
|
||||
'121': {c: 'y', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0556}},
|
||||
'122': {c: 'z', a:0, ic: 0.044, krn: {'127': 0.0556}}
|
||||
},
|
||||
cmsy10: {
|
||||
'0': {c:'−', a:.1}
|
||||
},
|
||||
cmti10: {
|
||||
'33': {c: '!', lig: {'96': 60}},
|
||||
'35': {c: '#', ic: 0.0662},
|
||||
'37': {c: '%', ic: 0.136},
|
||||
'38': {c: '&', ic: 0.0969},
|
||||
'40': {c: '(', d:.2, ic: 0.162},
|
||||
'41': {c: ')', d:.2, ic: 0.0369},
|
||||
'42': {c: '*', ic: 0.149},
|
||||
'43': {c: '+', a:.1, ic: 0.0369},
|
||||
'44': {c: ',', a:-.3, d:.2, w: 0.278},
|
||||
'45': {c: '-', a:0, ic: 0.0283, lig: {'45': 123}},
|
||||
'46': {c: '.', a:-.25},
|
||||
'47': {c: '/', ic: 0.162},
|
||||
'48': {c: '0', ic: 0.136},
|
||||
'49': {c: '1', ic: 0.136},
|
||||
'50': {c: '2', ic: 0.136},
|
||||
'51': {c: '3', ic: 0.136},
|
||||
'52': {c: '4', ic: 0.136},
|
||||
'53': {c: '5', ic: 0.136},
|
||||
'54': {c: '6', ic: 0.136},
|
||||
'55': {c: '7', ic: 0.136},
|
||||
'56': {c: '8', ic: 0.136},
|
||||
'57': {c: '9', ic: 0.136},
|
||||
'58': {c: ':', ic: 0.0582},
|
||||
'59': {c: ';', ic: 0.0582},
|
||||
'61': {c: '=', a:0, d:-.1, ic: 0.0662},
|
||||
'63': {c: '?', ic: 0.122, lig: {'96': 62}},
|
||||
'64': {c: '@', ic: 0.096},
|
||||
'65': {c: 'A', krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'66': {c: 'B', ic: 0.103},
|
||||
'67': {c: 'C', ic: 0.145},
|
||||
'68': {c: 'D', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}},
|
||||
'69': {c: 'E', ic: 0.12},
|
||||
'70': {c: 'F', ic: 0.133, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
|
||||
'71': {c: 'G', ic: 0.0872},
|
||||
'72': {c: 'H', ic: 0.164},
|
||||
'73': {c: 'I', ic: 0.158},
|
||||
'74': {c: 'J', ic: 0.14},
|
||||
'75': {c: 'K', ic: 0.145, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
|
||||
'76': {c: 'L', krn: {'84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'77': {c: 'M', ic: 0.164},
|
||||
'78': {c: 'N', ic: 0.164},
|
||||
'79': {c: 'O', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}},
|
||||
'80': {c: 'P', ic: 0.103, krn: {'65': -0.0767}},
|
||||
'81': {c: 'Q', d:.2, ic: 0.094},
|
||||
'82': {c: 'R', ic: 0.0387, krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'83': {c: 'S', ic: 0.12},
|
||||
'84': {c: 'T', ic: 0.133, krn: {'121': -0.0767, '101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}},
|
||||
'85': {c: 'U', ic: 0.164},
|
||||
'86': {c: 'V', ic: 0.184, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
|
||||
'87': {c: 'W', ic: 0.184, krn: {'65': -0.0767}},
|
||||
'88': {c: 'X', ic: 0.158, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}},
|
||||
'89': {c: 'Y', ic: 0.194, krn: {'101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}},
|
||||
'90': {c: 'Z', ic: 0.145},
|
||||
'91': {c: '[', d:.1, ic: 0.188},
|
||||
'93': {c: ']', d:.1, ic: 0.105},
|
||||
'97': {c: 'a', a:0, ic: 0.0767},
|
||||
'98': {c: 'b', ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'99': {c: 'c', a:0, ic: 0.0565, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'100': {c: 'd', ic: 0.103, krn: {'108': 0.0511}},
|
||||
'101': {c: 'e', a:0, ic: 0.0751, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'102': {c: 'f', ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 12, '102': 11, '108': 13}},
|
||||
'103': {c: 'g', a:0, d:.2, ic: 0.0885},
|
||||
'104': {c: 'h', ic: 0.0767},
|
||||
'105': {c: 'i', ic: 0.102},
|
||||
'106': {c: 'j', d:.2, ic: 0.145},
|
||||
'107': {c: 'k', ic: 0.108},
|
||||
'108': {c: 'l', ic: 0.103, krn: {'108': 0.0511}},
|
||||
'109': {c: 'm', a:0, ic: 0.0767},
|
||||
'110': {c: 'n', a:0, ic: 0.0767, krn: {'39': -0.102}},
|
||||
'111': {c: 'o', a:0, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'112': {c: 'p', a:0, d:.2, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'113': {c: 'q', a:0, d:.2, ic: 0.0885},
|
||||
'114': {c: 'r', a:0, ic: 0.108, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}},
|
||||
'115': {c: 's', a:0, ic: 0.0821},
|
||||
'116': {c: 't', ic: 0.0949},
|
||||
'117': {c: 'u', a:0, ic: 0.0767},
|
||||
'118': {c: 'v', a:0, ic: 0.108},
|
||||
'119': {c: 'w', a:0, ic: 0.108, krn: {'108': 0.0511}},
|
||||
'120': {c: 'x', a:0, ic: 0.12},
|
||||
'121': {c: 'y', a:0, d:.2, ic: 0.0885},
|
||||
'122': {c: 'z', a:0, ic: 0.123}
|
||||
},
|
||||
cmbx10: {
|
||||
'33': {c: '!', lig: {'96': 60}},
|
||||
'35': {c: '#'},
|
||||
'36': {c: '$'},
|
||||
'37': {c: '%'},
|
||||
'38': {c: '&'},
|
||||
'40': {c: '(', d:.2},
|
||||
'41': {c: ')', d:.2},
|
||||
'42': {c: '*'},
|
||||
'43': {c: '+', a:.1},
|
||||
'44': {c: ',', a:-.3, d:.2, w: 0.278},
|
||||
'45': {c: '-', a:0, lig: {'45': 123}},
|
||||
'46': {c: '.', a:-.25},
|
||||
'47': {c: '/'},
|
||||
'48': {c: '0'},
|
||||
'49': {c: '1'},
|
||||
'50': {c: '2'},
|
||||
'51': {c: '3'},
|
||||
'52': {c: '4'},
|
||||
'53': {c: '5'},
|
||||
'54': {c: '6'},
|
||||
'55': {c: '7'},
|
||||
'56': {c: '8'},
|
||||
'57': {c: '9'},
|
||||
'58': {c: ':'},
|
||||
'59': {c: ';'},
|
||||
'61': {c: '=', a:0, d:-.1},
|
||||
'63': {c: '?', lig: {'96': 62}},
|
||||
'64': {c: '@'},
|
||||
'65': {c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'66': {c: 'B'},
|
||||
'67': {c: 'C'},
|
||||
'68': {c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
|
||||
'69': {c: 'E'},
|
||||
'70': {c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'71': {c: 'G'},
|
||||
'72': {c: 'H'},
|
||||
'73': {c: 'I', krn: {'73': 0.0278}},
|
||||
'74': {c: 'J'},
|
||||
'75': {c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'76': {c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'77': {c: 'M'},
|
||||
'78': {c: 'N'},
|
||||
'79': {c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}},
|
||||
'80': {c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
|
||||
'81': {c: 'Q', d: 1},
|
||||
'82': {c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}},
|
||||
'83': {c: 'S'},
|
||||
'84': {c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
|
||||
'85': {c: 'U'},
|
||||
'86': {c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'87': {c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'88': {c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}},
|
||||
'89': {c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}},
|
||||
'90': {c: 'Z'},
|
||||
'91': {c: '[', d:.1},
|
||||
'93': {c: ']', d:.1},
|
||||
'97': {c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'98': {c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'99': {c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}},
|
||||
'100': {c: 'd'},
|
||||
'101': {c: 'e', a:0},
|
||||
'102': {c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}},
|
||||
'103': {c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}},
|
||||
'104': {c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'105': {c: 'i'},
|
||||
'106': {c: 'j', d:1},
|
||||
'107': {c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'108': {c: 'l'},
|
||||
'109': {c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'110': {c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}},
|
||||
'111': {c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'112': {c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}},
|
||||
'113': {c: 'q', a:0, d:1},
|
||||
'114': {c: 'r', a:0},
|
||||
'115': {c: 's', a:0},
|
||||
'116': {c: 't', krn: {'121': -0.0278, '119': -0.0278}},
|
||||
'117': {c: 'u', a:0, krn: {'119': -0.0278}},
|
||||
'118': {c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'119': {c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}},
|
||||
'120': {c: 'x', a:0},
|
||||
'121': {c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}},
|
||||
'122': {c: 'z', a:0}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (jsMath.browser == 'MSIE' && jsMath.platform == 'mac') {
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .math': 'font-style: normal',
|
||||
'.typeset .typeset': 'font-style: normal',
|
||||
'.typeset .icmr10': 'font-family: Times',
|
||||
'.typeset .icmmi10': 'font-family: Times; font-style: italic',
|
||||
'.typeset .icmbx10': 'font-family: Times; font-weight: bold',
|
||||
'.typeset .icmti10': 'font-family: Times; font-style: italic'
|
||||
});
|
||||
} else {
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .math': 'font-style: normal',
|
||||
'.typeset .typeset': 'font-style: normal',
|
||||
'.typeset .icmr10': 'font-family: serif',
|
||||
'.typeset .icmmi10': 'font-family: serif; font-style: italic',
|
||||
'.typeset .icmbx10': 'font-family: serif; font-weight: bold',
|
||||
'.typeset .icmti10': 'font-family: serif; font-style: italic'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
jsMath.Add(jsMath.Img,{
|
||||
symbols: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 34, 39,
|
||||
60, 62,
|
||||
|
||||
92, 94, 95,
|
||||
96,
|
||||
123,124,125,126,127
|
||||
]
|
||||
});
|
||||
|
||||
/*
|
||||
* for now, use images for everything
|
||||
*/
|
||||
jsMath.Img.SetFont({
|
||||
cmr10: jsMath.Img.symbols,
|
||||
cmmi10: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
91, 92, 93, 94, 95,
|
||||
96,
|
||||
123,124,125,126,127
|
||||
],
|
||||
cmsy10: [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127
|
||||
],
|
||||
cmex10: ['all'],
|
||||
cmti10: jsMath.Img.symbols.concat(36),
|
||||
cmbx10: jsMath.Img.symbols
|
||||
});
|
||||
|
||||
jsMath.Img.LoadFont('cm-fonts');
|
||||
|
|
@ -0,0 +1,935 @@
|
|||
/*
|
||||
* jsMath-fallback-mac.js
|
||||
*
|
||||
* Part of the jsMath package for mathematics on the web.
|
||||
*
|
||||
* This file makes changes needed for when the TeX fonts are not available
|
||||
* with a browser on the Mac.
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright 2004-2006 by Davide P. Cervone
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* Here we replace the TeX character mappings by equivalent unicode
|
||||
* points when possible, and adjust the character dimensions
|
||||
* based on the fonts we hope we get them from (the styles are set
|
||||
* to try to use the best characters available in the standard
|
||||
* fonts).
|
||||
*/
|
||||
|
||||
jsMath.Add(jsMath.TeX,{
|
||||
|
||||
cmr10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', tclass: 'greek'},
|
||||
{c: 'Δ', tclass: 'greek'},
|
||||
{c: 'Θ', tclass: 'greek'},
|
||||
{c: 'Λ', tclass: 'greek'},
|
||||
{c: 'Ξ', tclass: 'greek'},
|
||||
{c: 'Π', tclass: 'greek'},
|
||||
{c: 'Σ', tclass: 'greek'},
|
||||
{c: 'Υ', tclass: 'greek'},
|
||||
{c: 'Φ', tclass: 'greek'},
|
||||
{c: 'Ψ', tclass: 'greek'},
|
||||
{c: 'Ω', tclass: 'greek'},
|
||||
{c: 'ff', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}, tclass: 'normal'},
|
||||
{c: 'fi', tclass: 'normal'},
|
||||
{c: 'fl', tclass: 'normal'},
|
||||
{c: 'ffi', tclass: 'normal'},
|
||||
{c: 'ffl', tclass: 'normal'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, tclass: 'normal'},
|
||||
{c: 'j', d:.2, tclass: 'normal'},
|
||||
{c: '`', tclass: 'accent'},
|
||||
{c: '´', tclass: 'accent'},
|
||||
{c: 'ˇ', tclass: 'accent'},
|
||||
{c: '˘', tclass: 'accent'},
|
||||
{c: '<span style="position:relative; top:.1em">ˉ</span>', tclass: 'accent'},
|
||||
{c: '˚', tclass: 'accent'},
|
||||
{c: '̧', tclass: 'normal'},
|
||||
{c: 'ß', tclass: 'normal'},
|
||||
{c: 'æ', a:0, tclass: 'normal'},
|
||||
{c: 'œ', a:0, tclass: 'normal'},
|
||||
{c: 'ø', tclass: 'normal'},
|
||||
{c: 'Æ', tclass: 'normal'},
|
||||
{c: 'Œ', tclass: 'normal'},
|
||||
{c: 'Ø', tclass: 'normal'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.278, '76': -0.319}, tclass: 'normal'},
|
||||
{c: '!', lig: {'96': 60}, tclass: 'normal'},
|
||||
{c: '”', tclass: 'normal'},
|
||||
{c: '#', tclass: 'normal'},
|
||||
{c: '$', tclass: 'normal'},
|
||||
{c: '%', tclass: 'normal'},
|
||||
{c: '&', tclass: 'normal'},
|
||||
{c: '’', krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}, tclass: 'normal'},
|
||||
{c: '(', d:.2, tclass: 'normal'},
|
||||
{c: ')', d:.2, tclass: 'normal'},
|
||||
{c: '*', tclass: 'normal'},
|
||||
{c: '+', a:.1, tclass: 'normal'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'normal'},
|
||||
{c: '-', a:0, lig: {'45': 123}, tclass: 'normal'},
|
||||
{c: '.', a:-.25, tclass: 'normal'},
|
||||
{c: '/', tclass: 'normal'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'normal'},
|
||||
{c: '1', tclass: 'normal'},
|
||||
{c: '2', tclass: 'normal'},
|
||||
{c: '3', tclass: 'normal'},
|
||||
{c: '4', tclass: 'normal'},
|
||||
{c: '5', tclass: 'normal'},
|
||||
{c: '6', tclass: 'normal'},
|
||||
{c: '7', tclass: 'normal'},
|
||||
{c: '8', tclass: 'normal'},
|
||||
{c: '9', tclass: 'normal'},
|
||||
{c: ':', tclass: 'normal'},
|
||||
{c: ';', tclass: 'normal'},
|
||||
{c: '¡', tclass: 'normal'},
|
||||
{c: '=', a:0, d:-.1, tclass: 'normal'},
|
||||
{c: '¿', tclass: 'normal'},
|
||||
{c: '?', lig: {'96': 62}, tclass: 'normal'},
|
||||
// 40 - 4F
|
||||
{c: '@', tclass: 'normal'},
|
||||
{c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'B', tclass: 'normal'},
|
||||
{c: 'C', tclass: 'normal'},
|
||||
{c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'normal'},
|
||||
{c: 'E', tclass: 'normal'},
|
||||
{c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'G', tclass: 'normal'},
|
||||
{c: 'H', tclass: 'normal'},
|
||||
{c: 'I', krn: {'73': 0.0278}, tclass: 'normal'},
|
||||
{c: 'J', tclass: 'normal'},
|
||||
{c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'M', tclass: 'normal'},
|
||||
{c: 'N', tclass: 'normal'},
|
||||
{c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'normal'},
|
||||
// 50 - 5F
|
||||
{c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'normal'},
|
||||
{c: 'Q', d: 1, tclass: 'normal'},
|
||||
{c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'normal'},
|
||||
{c: 'S', tclass: 'normal'},
|
||||
{c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'normal'},
|
||||
{c: 'U', tclass: 'normal'},
|
||||
{c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'normal'},
|
||||
{c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'normal'},
|
||||
{c: 'Z', tclass: 'normal'},
|
||||
{c: '[', d:.1, tclass: 'normal'},
|
||||
{c: '“', tclass: 'normal'},
|
||||
{c: ']', d:.1, tclass: 'normal'},
|
||||
{c: 'ˆ', tclass: 'accent'},
|
||||
{c: '˙', tclass: 'accent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', lig: {'96': 92}, tclass: 'normal'},
|
||||
{c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}, tclass: 'normal'},
|
||||
{c: 'd', tclass: 'normal'},
|
||||
{c: 'e', a:0, tclass: 'normal'},
|
||||
{c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'normal'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}, tclass: 'normal'},
|
||||
{c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'i', tclass: 'normal'},
|
||||
{c: 'j', d:.2, tclass: 'normal'},
|
||||
{c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'l', tclass: 'normal'},
|
||||
{c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'q', a:0, d:.2, tclass: 'normal'},
|
||||
{c: 'r', a:0, tclass: 'normal'},
|
||||
{c: 's', a:0, tclass: 'normal'},
|
||||
{c: 't', krn: {'121': -0.0278, '119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'u', a:0, krn: {'119': -0.0278}, tclass: 'normal'},
|
||||
{c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'normal'},
|
||||
{c: 'x', a:0, tclass: 'normal'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'normal'},
|
||||
{c: 'z', a:0, tclass: 'normal'},
|
||||
{c: '–', a:.1, ic: 0.0278, lig: {'45': 124}, tclass: 'normal'},
|
||||
{c: '—', a:.1, ic: 0.0278, tclass: 'normal'},
|
||||
{c: '˝', tclass: 'accent'},
|
||||
{c: '˜', tclass: 'accent'},
|
||||
{c: '¨', tclass: 'accent'}
|
||||
],
|
||||
|
||||
cmmi10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Δ', krn: {'127': 0.167}, tclass: 'igreek'},
|
||||
{c: 'Θ', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Λ', krn: {'127': 0.167}, tclass: 'igreek'},
|
||||
{c: 'Ξ', ic: 0.0757, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Π', ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Σ', ic: 0.0576, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Υ', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Φ', krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'Ψ', ic: 0.11, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'igreek'},
|
||||
{c: 'Ω', ic: 0.0502, krn: {'127': 0.0833}, tclass: 'igreek'},
|
||||
{c: 'α', a:0, ic: 0.0037, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'β', d:.2, ic: 0.0528, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'γ', a:0, d:.2, ic: 0.0556, tclass: 'greek'},
|
||||
{c: 'δ', ic: 0.0378, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'ε', a:0, krn: {'127': 0.0556}, tclass: 'symbol'},
|
||||
// 10 - 1F
|
||||
{c: 'ζ', d:.2, ic: 0.0738, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'η', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'θ', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'ι', a:0, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
{c: 'κ', a:0, tclass: 'greek'},
|
||||
{c: 'λ', tclass: 'greek'},
|
||||
{c: 'μ', a:0, d:.2, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'ν', a:0, ic: 0.0637, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'ξ', d:.2, ic: 0.046, krn: {'127': 0.111}, tclass: 'greek'},
|
||||
{c: 'π', a:0, ic: 0.0359, tclass: 'greek'},
|
||||
{c: 'ρ', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'σ', a:0, ic: 0.0359, krn: {'59': -0.0556, '58': -0.0556}, tclass: 'greek'},
|
||||
{c: 'τ', a:0, ic: 0.113, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'υ', a:0, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'greek'},
|
||||
{c: 'φ', a:.1, d:.2, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'χ', a:0, d:.2, krn: {'127': 0.0556}, tclass: 'greek'},
|
||||
// 20 - 2F
|
||||
{c: 'ψ', a:.1, d:.2, ic: 0.0359, krn: {'127': 0.111}, tclass: 'greek'},
|
||||
{c: 'ω', a:0, ic: 0.0359, tclass: 'greek'},
|
||||
{c: 'ε', a:0, krn: {'127': 0.0833}, tclass: 'greek'},
|
||||
{c: 'ϑ', krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: 'ϖ', a:0, ic: 0.0278, tclass: 'normal'},
|
||||
{c: 'ϱ', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: 'ς', a:0, d:.2, ic: 0.0799, krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: 'ϕ', a:.1, d:.2, krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: '↼', a:0, d:-.2, tclass: 'harpoon'},
|
||||
{c: '↽', a:0, d:-.1, tclass: 'harpoon'},
|
||||
{c: '⇀', a:0, d:-.2, tclass: 'harpoon'},
|
||||
{c: '⇁', a:0, d:-.1, tclass: 'harpoon'},
|
||||
{c: '<span style="font-size: 133%; position:relative; top:-.1em; margin:-.2em; left:-.05em">˓</span>', a:.1, tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 133%; position:relative; top:-.1em; margin:-.2em; left:-.05em">˒</span>', a:.1, tclass: 'symbol'},
|
||||
{c: '<span style="font-size:50%">▷</span>', tclass: 'symbol'},
|
||||
{c: '<span style="font-size:50%">◁</span>', tclass: 'symbol'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'normal'},
|
||||
{c: '1', tclass: 'normal'},
|
||||
{c: '2', tclass: 'normal'},
|
||||
{c: '3', tclass: 'normal'},
|
||||
{c: '4', tclass: 'normal'},
|
||||
{c: '5', tclass: 'normal'},
|
||||
{c: '6', tclass: 'normal'},
|
||||
{c: '7', tclass: 'normal'},
|
||||
{c: '8', tclass: 'normal'},
|
||||
{c: '9', tclass: 'normal'},
|
||||
{c: '.', a:-.3, tclass: 'normal'},
|
||||
{c: ',', a:-.3, d:.2, tclass: 'normal'},
|
||||
{c: '<', a:.1, tclass: 'normal'},
|
||||
{c: '/', krn: {'1': -0.0556, '65': -0.0556, '77': -0.0556, '78': -0.0556, '89': 0.0556, '90': -0.0556}, tclass: 'normal'},
|
||||
{c: '>', a:.1, tclass: 'normal'},
|
||||
{c: '<span style="font-size:50%">★</span>', a:0, tclass: 'symbol'},
|
||||
// 40 - 4F
|
||||
{c: '∂', ic: 0.0556, krn: {'127': 0.0833}, tclass: 'normal'},
|
||||
{c: 'A', krn: {'127': 0.139}, tclass: 'italic'},
|
||||
{c: 'B', ic: 0.0502, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'C', ic: 0.0715, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'D', ic: 0.0278, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'E', ic: 0.0576, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'F', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'G', krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'H', ic: 0.0812, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'I', ic: 0.0785, krn: {'127': 0.111}, tclass: 'italic'},
|
||||
{c: 'J', ic: 0.0962, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'K', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'L', krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'M', ic: 0.109, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'N', ic: 0.109, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'O', ic: 0.0278, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.139, krn: {'61': -0.0556, '59': -0.111, '58': -0.111, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'Q', d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'R', ic: 0.00773, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'S', ic: 0.0576, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'T', ic: 0.139, krn: {'61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'U', ic: 0.109, krn: {'59': -0.111, '58': -0.111, '61': -0.0556, '127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'V', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'W', ic: 0.139, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'X', ic: 0.0785, krn: {'61': -0.0833, '61': -0.0278, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'Y', ic: 0.222, krn: {'59': -0.167, '58': -0.167, '61': -0.111}, tclass: 'italic'},
|
||||
{c: 'Z', ic: 0.0715, krn: {'61': -0.0556, '59': -0.0556, '58': -0.0556, '127': 0.0833}, tclass: 'italic'},
|
||||
{c: '♭', tclass: 'symbol2'},
|
||||
{c: '♮', tclass: 'symbol2'},
|
||||
{c: '♯', tclass: 'symbol2'},
|
||||
{c: '⌣', a:0, d:-.1, tclass: 'normal'},
|
||||
{c: '⌢', a:0, d:-.1, tclass: 'normal'},
|
||||
// 60 - 6F
|
||||
{c: 'ℓ', krn: {'127': 0.111}, tclass: 'symbol'},
|
||||
{c: 'a', a:0, tclass: 'italic'},
|
||||
{c: 'b', tclass: 'italic'},
|
||||
{c: 'c', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'd', krn: {'89': 0.0556, '90': -0.0556, '106': -0.111, '102': -0.167, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'e', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'f', d:.2, ic: 0.108, krn: {'59': -0.0556, '58': -0.0556, '127': 0.167}, tclass: 'italic'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'h', krn: {'127': -0.0278}, tclass: 'italic'},
|
||||
{c: 'i', tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.0572, krn: {'59': -0.0556, '58': -0.0556}, tclass: 'italic'},
|
||||
{c: 'k', ic: 0.0315, tclass: 'italic'},
|
||||
{c: 'l', ic: 0.0197, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'm', a:0, tclass: 'italic'},
|
||||
{c: 'n', a:0, tclass: 'italic'},
|
||||
{c: 'o', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'q', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'r', a:0, ic: 0.0278, krn: {'59': -0.0556, '58': -0.0556, '127': 0.0556}, tclass: 'italic'},
|
||||
{c: 's', a:0, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 't', krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'u', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'v', a:0, ic: 0.0359, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'w', a:0, ic: 0.0269, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: 'x', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0359, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'z', a:0, ic: 0.044, krn: {'127': 0.0556}, tclass: 'italic'},
|
||||
{c: 'ı', a:0, krn: {'127': 0.0278}, tclass: 'italic'},
|
||||
{c: 'j', d:.2, krn: {'127': 0.0833}, tclass: 'italic'},
|
||||
{c: '℘', a:0, d:.2, krn: {'127': 0.111}, tclass: 'normal'},
|
||||
{c: '<span style="position:relative; left: .4em; top: -.8em; font-size: 50%">→</span>', ic: 0.154, tclass: 'symbol'},
|
||||
{c: '̑', ic: 0.399, tclass: 'normal'}
|
||||
],
|
||||
|
||||
cmsy10: [
|
||||
// 00 - 0F
|
||||
{c: '−', a:.1, tclass: 'symbol'},
|
||||
{c: '·', a:0, d:-.2, tclass: 'symbol'},
|
||||
{c: '×', a:0, tclass: 'symbol'},
|
||||
{c: '<span style="position:relative; top:.2em">*</span>', a:0, tclass: 'symbol'},
|
||||
{c: '÷', a:0, tclass: 'symbol'},
|
||||
{c: '◊', tclass: 'symbol'},
|
||||
{c: '±', a:.1, tclass: 'symbol'},
|
||||
{c: '∓', tclass: 'symbol'},
|
||||
{c: '⊕', tclass: 'symbol'},
|
||||
{c: '⊖', tclass: 'symbol'},
|
||||
{c: '⊗', tclass: 'symbol'},
|
||||
{c: '⊘', tclass: 'symbol'},
|
||||
{c: '⊙', tclass: 'symbol'},
|
||||
{c: '◯', tclass: 'symbol'},
|
||||
{c: '<span style="position:relative; top:.25em;">°</span>', a:0, d:-.1, tclass: 'symbol'},
|
||||
{c: '•', a:0, d:-.2, tclass: 'symbol'},
|
||||
// 10 - 1F
|
||||
{c: '≍', a:.1, tclass: 'symbol'},
|
||||
{c: '≡', a:.1, tclass: 'symbol'},
|
||||
{c: '⊆', tclass: 'symbol'},
|
||||
{c: '⊇', tclass: 'symbol'},
|
||||
{c: '≤', tclass: 'symbol'},
|
||||
{c: '≥', tclass: 'symbol'},
|
||||
{c: '≼', tclass: 'symbol'},
|
||||
{c: '≽', tclass: 'symbol'},
|
||||
{c: '~', a:0, d: -.2, tclass: 'normal'},
|
||||
{c: '≈', a:.1, d:-.1, tclass: 'symbol'},
|
||||
{c: '⊂', tclass: 'symbol'},
|
||||
{c: '⊃', tclass: 'symbol'},
|
||||
{c: '≪', tclass: 'symbol'},
|
||||
{c: '≫', tclass: 'symbol'},
|
||||
{c: '≺', tclass: 'symbol'},
|
||||
{c: '≻', tclass: 'symbol'},
|
||||
// 20 - 2F
|
||||
{c: '←', a:0, d:-.15, tclass: 'arrows'},
|
||||
{c: '→', a:0, d:-.15, tclass: 'arrows'},
|
||||
{c: '↑', h:1, tclass: 'arrows'},
|
||||
{c: '↓', h:1, tclass: 'arrows'},
|
||||
{c: '↔', a:0, tclass: 'arrows'},
|
||||
{c: '↗', h:1, tclass: 'arrows'},
|
||||
{c: '↘', h:1, tclass: 'arrows'},
|
||||
{c: '≃', a: .1, tclass: 'symbol'},
|
||||
{c: '⇐', a:.1, tclass: 'arrows'},
|
||||
{c: '⇒', a:.1, tclass: 'arrows'},
|
||||
{c: '⇑', h:.9, d:.1, tclass: 'arrows'},
|
||||
{c: '⇓', h:.9, d:.1, tclass: 'arrows'},
|
||||
{c: '⇔', a:.1, tclass: 'arrows'},
|
||||
{c: '↖', h:1, tclass: 'arrows'},
|
||||
{c: '↙', h:1, tclass: 'arrows'},
|
||||
{c: '∝', a:.1, tclass: 'symbol'},
|
||||
// 30 - 3F
|
||||
{c: '<span style="font-size: 133%; margin-right: -.1em; position: relative; top:.4em">′</span>', a: 0, tclass: 'symbol'},
|
||||
{c: '∞', a:.1, tclass: 'symbol'},
|
||||
{c: '∈', tclass: 'symbol'},
|
||||
{c: '∋', tclass: 'symbol'},
|
||||
{c: '△', tclass: 'symbol'},
|
||||
{c: '▽', tclass: 'symbol'},
|
||||
{c: '/', tclass: 'symbol'},
|
||||
{c: '<span style="font-size:50%; position:relative; top:-.3em; margin-right:-.2em">|</span>', a:0, tclass: 'normal'},
|
||||
{c: '∀', tclass: 'symbol'},
|
||||
{c: '∃', tclass: 'symbol'},
|
||||
{c: '¬', a:0, d:-.1, tclass: 'symbol1'},
|
||||
{c: '∅', tclass: 'symbol'},
|
||||
{c: 'ℜ', tclass: 'symbol'},
|
||||
{c: 'ℑ', tclass: 'symbol'},
|
||||
{c: '⊤', tclass: 'symbol'},
|
||||
{c: '⊥', tclass: 'symbol'},
|
||||
// 40 - 4F
|
||||
{c: 'ℵ', tclass: 'symbol'},
|
||||
{c: 'A', krn: {'48': 0.194}, tclass: 'cal'},
|
||||
{c: 'B', ic: 0.0304, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'C', ic: 0.0583, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'D', ic: 0.0278, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'E', ic: 0.0894, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'F', ic: 0.0993, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'G', d:.2, ic: 0.0593, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'H', ic: 0.00965, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'I', ic: 0.0738, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'J', d:.2, ic: 0.185, krn: {'48': 0.167}, tclass: 'cal'},
|
||||
{c: 'K', ic: 0.0144, krn: {'48': 0.0556}, tclass: 'cal'},
|
||||
{c: 'L', krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'M', krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'N', ic: 0.147, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'O', ic: 0.0278, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'Q', d:.2, krn: {'48': 0.111}, tclass: 'cal'},
|
||||
{c: 'R', krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'S', ic: 0.075, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'T', ic: 0.254, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'U', ic: 0.0993, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'V', ic: 0.0822, krn: {'48': 0.0278}, tclass: 'cal'},
|
||||
{c: 'W', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'X', ic: 0.146, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: 'Y', ic: 0.0822, krn: {'48': 0.0833}, tclass: 'cal'},
|
||||
{c: 'Z', ic: 0.0794, krn: {'48': 0.139}, tclass: 'cal'},
|
||||
{c: '⋃', tclass: 'symbol'},
|
||||
{c: '⋂', tclass: 'symbol'},
|
||||
{c: '⊎', tclass: 'symbol'},
|
||||
{c: '⋀', tclass: 'symbol'},
|
||||
{c: '⋁', tclass: 'symbol'},
|
||||
// 60 - 6F
|
||||
{c: '⊢', tclass: 'symbol'},
|
||||
{c: '⊣', tclass: 'symbol2'},
|
||||
{c: '', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '{', d:.2, tclass: 'normal'},
|
||||
{c: '}', d:.2, tclass: 'normal'},
|
||||
{c: '〈', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '〉', a:.3, d:.2, tclass: 'normal'},
|
||||
{c: '|', d:.1, tclass: 'vertical'},
|
||||
{c: '||', d:0, tclass: 'vertical'},
|
||||
{c: '↕', h:1, d:.15, tclass: 'arrows'},
|
||||
{c: '⇕', a:.2, d:.1, tclass: 'arrows'},
|
||||
{c: '∖', a:.3, d:.1, tclass: 'normal'},
|
||||
{c: '≀', tclass: 'symbol'},
|
||||
// 70 - 7F
|
||||
{c: '<span style="position:relative; top: .8em">√</span>', h:.04, d:.9, tclass: 'normal'},
|
||||
{c: '∐', a:.4, tclass: 'symbol'},
|
||||
{c: '∇', tclass: 'symbol'},
|
||||
{c: '∫', h:1, d:.1, ic: 0.111, tclass: 'root'},
|
||||
{c: '⊔', tclass: 'symbol'},
|
||||
{c: '⊓', tclass: 'symbol'},
|
||||
{c: '⊑', tclass: 'symbol'},
|
||||
{c: '⊒', tclass: 'symbol'},
|
||||
{c: '§', d:.1, tclass: 'normal'},
|
||||
{c: '†', d:.1, tclass: 'normal'},
|
||||
{c: '‡', d:.1, tclass: 'normal'},
|
||||
{c: '¶', a:.3, d:.1, tclass: 'normal'},
|
||||
{c: '♣', tclass: 'symbol'},
|
||||
{c: '♦', tclass: 'symbol'},
|
||||
{c: '♥', tclass: 'symbol'},
|
||||
{c: '♠', tclass: 'symbol'}
|
||||
],
|
||||
|
||||
cmex10: [
|
||||
// 00 - 0F
|
||||
{c: '(', h: 0.04, d: 1.16, n: 16, tclass: 'delim1'},
|
||||
{c: ')', h: 0.04, d: 1.16, n: 17, tclass: 'delim1'},
|
||||
{c: '[', h: 0.04, d: 1.16, n: 104, tclass: 'delim1'},
|
||||
{c: ']', h: 0.04, d: 1.16, n: 105, tclass: 'delim1'},
|
||||
{c: '', h: 0.04, d: 1.16, n: 106, tclass: 'delim1'},
|
||||
{c: '', h: 0.04, d: 1.16, n: 107, tclass: 'delim1'},
|
||||
{c: '', h: 0.04, d: 1.16, n: 108, tclass: 'delim1'},
|
||||
{c: '', h: 0.04, d: 1.16, n: 109, tclass: 'delim1'},
|
||||
{c: '{', h: 0.04, d: 1.16, n: 110, tclass: 'delim1'},
|
||||
{c: '}', h: 0.04, d: 1.16, n: 111, tclass: 'delim1'},
|
||||
{c: '〈', h: 0.04, d: 1.16, n: 68, tclass: 'delim1c'},
|
||||
{c: '〉', h: 0.04, d: 1.16, n: 69, tclass: 'delim1c'},
|
||||
{c: '|', h:.7, d:0, delim: {rep: 12}, tclass: 'vertical'},
|
||||
{c: '||', h:.7, d:0, delim: {rep: 13}, tclass: 'vertical'},
|
||||
{c: '/', h: 0.04, d: 1.16, n: 46, tclass: 'delim1b'},
|
||||
{c: '∖', h: 0.04, d: 1.16, n: 47, tclass: 'delim1b'},
|
||||
// 10 - 1F
|
||||
{c: '(', h: 0.04, d: 1.76, n: 18, tclass: 'delim2'},
|
||||
{c: ')', h: 0.04, d: 1.76, n: 19, tclass: 'delim2'},
|
||||
{c: '(', h: 0.04, d: 2.36, n: 32, tclass: 'delim3'},
|
||||
{c: ')', h: 0.04, d: 2.36, n: 33, tclass: 'delim3'},
|
||||
{c: '[', h: 0.04, d: 2.36, n: 34, tclass: 'delim3'},
|
||||
{c: ']', h: 0.04, d: 2.36, n: 35, tclass: 'delim3'},
|
||||
{c: '', h: 0.04, d: 2.36, n: 36, tclass: 'delim3'},
|
||||
{c: '', h: 0.04, d: 2.36, n: 37, tclass: 'delim3'},
|
||||
{c: '', h: 0.04, d: 2.36, n: 38, tclass: 'delim3'},
|
||||
{c: '', h: 0.04, d: 2.36, n: 39, tclass: 'delim3'},
|
||||
{c: '{', h: 0.04, d: 2.36, n: 40, tclass: 'delim3'},
|
||||
{c: '}', h: 0.04, d: 2.36, n: 41, tclass: 'delim3'},
|
||||
{c: '〈', h: 0.04, d: 2.36, n: 42, tclass: 'delim3c'},
|
||||
{c: '〉', h: 0.04, d: 2.36, n: 43, tclass: 'delim3c'},
|
||||
{c: '/', h: 0.04, d: 2.36, n: 44, tclass: 'delim3b'},
|
||||
{c: '∖', h: 0.04, d: 2.36, n: 45, tclass: 'delim3b'},
|
||||
// 20 - 2F
|
||||
{c: '(', h: 0.04, d: 2.96, n: 48, tclass: 'delim4'},
|
||||
{c: ')', h: 0.04, d: 2.96, n: 49, tclass: 'delim4'},
|
||||
{c: '[', h: 0.04, d: 2.96, n: 50, tclass: 'delim4'},
|
||||
{c: ']', h: 0.04, d: 2.96, n: 51, tclass: 'delim4'},
|
||||
{c: '', h: 0.04, d: 2.96, n: 52, tclass: 'delim4'},
|
||||
{c: '', h: 0.04, d: 2.96, n: 53, tclass: 'delim4'},
|
||||
{c: '', h: 0.04, d: 2.96, n: 54, tclass: 'delim4'},
|
||||
{c: '', h: 0.04, d: 2.96, n: 55, tclass: 'delim4'},
|
||||
{c: '{', h: 0.04, d: 2.96, n: 56, tclass: 'delim4'},
|
||||
{c: '}', h: 0.04, d: 2.96, n: 57, tclass: 'delim4'},
|
||||
{c: '〈', h: 0.04, d: 2.96, tclass: 'delim4c'},
|
||||
{c: '〉', h: 0.04, d: 2.96, tclass: 'delim4c'},
|
||||
{c: '/', h: 0.04, d: 2.96, tclass: 'delim4b'},
|
||||
{c: '∖', h: 0.04, d: 2.96, tclass: 'delim4b'},
|
||||
{c: '/', h: 0.04, d: 1.76, n: 30, tclass: 'delim2b'},
|
||||
{c: '∖', h: 0.04, d: 1.76, n: 31, tclass: 'delim2b'},
|
||||
// 30 - 3F
|
||||
{c: '', h: .8, d: .15, delim: {top: 48, bot: 64, rep: 66}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 49, bot: 65, rep: 67}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 50, bot: 52, rep: 54}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 51, bot: 53, rep: 55}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {bot: 52, rep: 54}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {bot: 53, rep: 55}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 50, rep: 54}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 51, rep: 55}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 56, mid: 60, bot: 58, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 57, mid: 61, bot: 59, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 56, bot: 58, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 57, bot: 59, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {rep: 63}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {rep: 119}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {rep: 62}, tclass: 'delim'},
|
||||
{c: '|', h: .65, d: 0, delim: {top: 120, bot: 121, rep: 63}, tclass: 'vertical'},
|
||||
// 40 - 4F
|
||||
{c: '', h: .8, d: .15, delim: {top: 56, bot: 59, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {top: 57, bot: 58, rep: 62}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {rep: 66}, tclass: 'delim'},
|
||||
{c: '', h: .8, d: .15, delim: {rep: 67}, tclass: 'delim'},
|
||||
{c: '〈', h: 0.04, d: 1.76, n: 28, tclass: 'delim2c'},
|
||||
{c: '〉', h: 0.04, d: 1.76, n: 29, tclass: 'delim2c'},
|
||||
{c: '⊔', h: 0, d: 1, n: 71, tclass: 'bigop1'},
|
||||
{c: '⊔', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '∮', h: 0, d: 1.11, ic: 0.095, n: 73, tclass: 'bigop1c'},
|
||||
{c: '∮', h: 0, d: 2.22, ic: 0.222, tclass: 'bigop2c'},
|
||||
{c: '⊙', h: 0, d: 1, n: 75, tclass: 'bigop1'},
|
||||
{c: '⊙', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '⊕', h: 0, d: 1, n: 77, tclass: 'bigop1'},
|
||||
{c: '⊕', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '⊗', h: 0, d: 1, n: 79, tclass: 'bigop1'},
|
||||
{c: '⊗', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
// 50 - 5F
|
||||
{c: '∑', h: 0, d: 1, n: 88, tclass: 'bigop1a'},
|
||||
{c: '∏', h: 0, d: 1, n: 89, tclass: 'bigop1a'},
|
||||
{c: '∫', h: 0, d: 1.11, ic: 0.095, n: 90, tclass: 'bigop1c'},
|
||||
{c: '∪', h: 0, d: 1, n: 91, tclass: 'bigop1b'},
|
||||
{c: '∩', h: 0, d: 1, n: 92, tclass: 'bigop1b'},
|
||||
{c: '⊎', h: 0, d: 1, n: 93, tclass: 'bigop1b'},
|
||||
{c: '∧', h: 0, d: 1, n: 94, tclass: 'bigop1'},
|
||||
{c: '∨', h: 0, d: 1, n: 95, tclass: 'bigop1'},
|
||||
{c: '∑', h: 0.1, d: 1.6, tclass: 'bigop2a'},
|
||||
{c: '∏', h: 0.1, d: 1.5, tclass: 'bigop2a'},
|
||||
{c: '∫', h: 0, d: 2.22, ic: 0.222, tclass: 'bigop2c'},
|
||||
{c: '∪', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '∩', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '⊎', h: 0.1, d: 1.5, tclass: 'bigop2b'},
|
||||
{c: '∧', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
{c: '∨', h: 0.1, d: 1.5, tclass: 'bigop2'},
|
||||
// 60 - 6F
|
||||
{c: '∐', h: 0, d: 1, n: 97, tclass: 'bigop1a'},
|
||||
{c: '∐', h: 0.1, d: 1.5, tclass: 'bigop2a'},
|
||||
{c: '︿', h: 0.722, w: .65, n: 99, tclass: 'wide1'},
|
||||
{c: '︿', h: 0.85, w: 1.1, n: 100, tclass: 'wide2'},
|
||||
{c: '︿', h: 0.99, w: 1.65, tclass: 'wide3'},
|
||||
{c: '⁓', h: 0.722, w: .75, n: 102, tclass: 'wide1a'},
|
||||
{c: '⁓', h: 0.8, w: 1.35, n: 103, tclass: 'wide2a'},
|
||||
{c: '⁓', h: 0.99, w: 2, tclass: 'wide3a'},
|
||||
{c: '[', h: 0.04, d: 1.76, n: 20, tclass: 'delim2'},
|
||||
{c: ']', h: 0.04, d: 1.76, n: 21, tclass: 'delim2'},
|
||||
{c: '', h: 0.04, d: 1.76, n: 22, tclass: 'delim2'},
|
||||
{c: '', h: 0.04, d: 1.76, n: 23, tclass: 'delim2'},
|
||||
{c: '', h: 0.04, d: 1.76, n: 24, tclass: 'delim2'},
|
||||
{c: '', h: 0.04, d: 1.76, n: 25, tclass: 'delim2'},
|
||||
{c: '{', h: 0.04, d: 1.76, n: 26, tclass: 'delim2'},
|
||||
{c: '}', h: 0.04, d: 1.76, n: 27, tclass: 'delim2'},
|
||||
// 70 - 7F
|
||||
{c: '<span style="font-size: 125%; position:relative; top:.95em">√</span>', h: 0.04, d: 1.16, n: 113, tclass: 'root'},
|
||||
{c: '<span style="font-size: 190%; position:relative; top:.925em">√</span>', h: 0.04, d: 1.76, n: 114, tclass: 'root'},
|
||||
{c: '<span style="font-size: 250%; position:relative; top:.925em">√</span>', h: 0.06, d: 2.36, n: 115, tclass: 'root'},
|
||||
{c: '<span style="font-size: 320%; position:relative; top:.92em">√</span>', h: 0.08, d: 2.96, n: 116, tclass: 'root'},
|
||||
{c: '<span style="font-size: 400%; position:relative; top:.92em">√</span>', h: 0.1, d: 3.75, n: 117, tclass: 'root'},
|
||||
{c: '<span style="font-size: 500%; position:relative; top:.9em">√</span>', h: .12, d: 4.5, n: 118, tclass: 'root'},
|
||||
{c: '<span style="font-size: 625%; position:relative; top:.9em">√</span>', h: .14, d: 5.7, tclass: 'root'},
|
||||
{c: '<span style="margin:.001em">||</span>', h:.65, d:0, delim: {top: 126, bot: 127, rep: 119}, tclass: 'vertical'},
|
||||
{c: '▵', h:.45, delim: {top: 120, rep: 63}, tclass: 'arrow1'},
|
||||
{c: '▿', h:.45, delim: {bot: 121, rep: 63}, tclass: 'arrow1'},
|
||||
{c: '<span style="font-size: 67%; position:relative; top:.35em; margin-left:-.5em">╭</span>', h:.1, tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 67%; position:relative; top:.35em; margin-right:-.5em">╮</span>', h:.1, tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 67%; position:relative; top:.35em; margin-left:-.5em">╰</span>', h:.1, tclass: 'symbol'},
|
||||
{c: '<span style="font-size: 67%; position:relative; top:.35em; margin-right:-.5em">╯</span>', h:.1, tclass: 'symbol'},
|
||||
{c: '▵', h:.5, delim: {top: 126, rep: 119}, tclass: 'arrow2'},
|
||||
{c: '▿', h:.5, delim: {bot: 127, rep: 119}, tclass: 'arrow2'}
|
||||
],
|
||||
|
||||
cmti10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', ic: 0.133, tclass: 'igreek'},
|
||||
{c: 'Δ', tclass: 'igreek'},
|
||||
{c: 'Θ', ic: 0.094, tclass: 'igreek'},
|
||||
{c: 'Λ', tclass: 'igreek'},
|
||||
{c: 'Ξ', ic: 0.153, tclass: 'igreek'},
|
||||
{c: 'Π', ic: 0.164, tclass: 'igreek'},
|
||||
{c: 'Σ', ic: 0.12, tclass: 'igreek'},
|
||||
{c: 'Υ', ic: 0.111, tclass: 'igreek'},
|
||||
{c: 'Φ', ic: 0.0599, tclass: 'igreek'},
|
||||
{c: 'Ψ', ic: 0.111, tclass: 'igreek'},
|
||||
{c: 'Ω', ic: 0.103, tclass: 'igreek'},
|
||||
{c: 'ff', ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 14, '108': 15}, tclass: 'italic'},
|
||||
{c: 'fi', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'fl', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'ffi', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'ffl', ic: 0.103, tclass: 'italic'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.0374, tclass: 'italic'},
|
||||
{c: '`', tclass: 'iaccent'},
|
||||
{c: '´', ic: 0.0969, tclass: 'iaccent'},
|
||||
{c: 'ˇ', ic: 0.083, tclass: 'iaccent'},
|
||||
{c: '˘', ic: 0.108, tclass: 'iaccent'},
|
||||
{c: 'ˉ', ic: 0.103, tclass: 'iaccent'},
|
||||
{c: '˚', tclass: 'iaccent'},
|
||||
{c: '?', d: 0.17, w: 0.46, tclass: 'italic'},
|
||||
{c: 'ß', ic: 0.105, tclass: 'italic'},
|
||||
{c: 'æ', a:0, ic: 0.0751, tclass: 'italic'},
|
||||
{c: 'œ', a:0, ic: 0.0751, tclass: 'italic'},
|
||||
{c: 'ø', ic: 0.0919, tclass: 'italic'},
|
||||
{c: 'Æ', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'Œ', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'Ø', ic: 0.094, tclass: 'italic'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.256, '76': -0.321}, tclass: 'italic'},
|
||||
{c: '!', ic: 0.124, lig: {'96': 60}, tclass: 'italic'},
|
||||
{c: '”', ic: 0.0696, tclass: 'italic'},
|
||||
{c: '#', ic: 0.0662, tclass: 'italic'},
|
||||
{c: '$', tclass: 'italic'},
|
||||
{c: '%', ic: 0.136, tclass: 'italic'},
|
||||
{c: '&', ic: 0.0969, tclass: 'italic'},
|
||||
{c: '’', ic: 0.124, krn: {'63': 0.102, '33': 0.102}, lig: {'39': 34}, tclass: 'italic'},
|
||||
{c: '(', d:.2, ic: 0.162, tclass: 'italic'},
|
||||
{c: ')', d:.2, ic: 0.0369, tclass: 'italic'},
|
||||
{c: '*', ic: 0.149, tclass: 'italic'},
|
||||
{c: '+', a:.1, ic: 0.0369, tclass: 'italic'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'italic'},
|
||||
{c: '-', a:0, ic: 0.0283, lig: {'45': 123}, tclass: 'italic'},
|
||||
{c: '.', a:-.25, tclass: 'italic'},
|
||||
{c: '/', ic: 0.162, tclass: 'italic'},
|
||||
// 30 - 3F
|
||||
{c: '0', ic: 0.136, tclass: 'italic'},
|
||||
{c: '1', ic: 0.136, tclass: 'italic'},
|
||||
{c: '2', ic: 0.136, tclass: 'italic'},
|
||||
{c: '3', ic: 0.136, tclass: 'italic'},
|
||||
{c: '4', ic: 0.136, tclass: 'italic'},
|
||||
{c: '5', ic: 0.136, tclass: 'italic'},
|
||||
{c: '6', ic: 0.136, tclass: 'italic'},
|
||||
{c: '7', ic: 0.136, tclass: 'italic'},
|
||||
{c: '8', ic: 0.136, tclass: 'italic'},
|
||||
{c: '9', ic: 0.136, tclass: 'italic'},
|
||||
{c: ':', ic: 0.0582, tclass: 'italic'},
|
||||
{c: ';', ic: 0.0582, tclass: 'italic'},
|
||||
{c: '¡', ic: 0.0756, tclass: 'italic'},
|
||||
{c: '=', a:0, d:-.1, ic: 0.0662, tclass: 'italic'},
|
||||
{c: '¿', tclass: 'italic'},
|
||||
{c: '?', ic: 0.122, lig: {'96': 62}, tclass: 'italic'},
|
||||
// 40 - 4F
|
||||
{c: '@', ic: 0.096, tclass: 'italic'},
|
||||
{c: 'A', krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'B', ic: 0.103, tclass: 'italic'},
|
||||
{c: 'C', ic: 0.145, tclass: 'italic'},
|
||||
{c: 'D', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}, tclass: 'italic'},
|
||||
{c: 'E', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'F', ic: 0.133, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'G', ic: 0.0872, tclass: 'italic'},
|
||||
{c: 'H', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'I', ic: 0.158, tclass: 'italic'},
|
||||
{c: 'J', ic: 0.14, tclass: 'italic'},
|
||||
{c: 'K', ic: 0.145, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'L', krn: {'84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'M', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'N', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'O', ic: 0.094, krn: {'88': -0.0256, '87': -0.0256, '65': -0.0256, '86': -0.0256, '89': -0.0256}, tclass: 'italic'},
|
||||
// 50 - 5F
|
||||
{c: 'P', ic: 0.103, krn: {'65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'Q', d: 1, ic: 0.094, tclass: 'italic'},
|
||||
{c: 'R', ic: 0.0387, krn: {'110': -0.0256, '108': -0.0256, '114': -0.0256, '117': -0.0256, '109': -0.0256, '116': -0.0256, '105': -0.0256, '67': -0.0256, '79': -0.0256, '71': -0.0256, '104': -0.0256, '98': -0.0256, '85': -0.0256, '107': -0.0256, '118': -0.0256, '119': -0.0256, '81': -0.0256, '84': -0.0767, '89': -0.0767, '86': -0.102, '87': -0.102, '101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'S', ic: 0.12, tclass: 'italic'},
|
||||
{c: 'T', ic: 0.133, krn: {'121': -0.0767, '101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'U', ic: 0.164, tclass: 'italic'},
|
||||
{c: 'V', ic: 0.184, krn: {'111': -0.0767, '101': -0.0767, '117': -0.0767, '114': -0.0767, '97': -0.0767, '65': -0.102, '79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'W', ic: 0.184, krn: {'65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'X', ic: 0.158, krn: {'79': -0.0256, '67': -0.0256, '71': -0.0256, '81': -0.0256}, tclass: 'italic'},
|
||||
{c: 'Y', ic: 0.194, krn: {'101': -0.0767, '111': -0.0767, '114': -0.0767, '97': -0.0767, '117': -0.0767, '65': -0.0767}, tclass: 'italic'},
|
||||
{c: 'Z', ic: 0.145, tclass: 'italic'},
|
||||
{c: '[', d:.1, ic: 0.188, tclass: 'italic'},
|
||||
{c: '“', ic: 0.169, tclass: 'italic'},
|
||||
{c: ']', d:.1, ic: 0.105, tclass: 'italic'},
|
||||
{c: 'ˆ', ic: 0.0665, tclass: 'iaccent'},
|
||||
{c: '˙', ic: 0.118, tclass: 'iaccent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', ic: 0.124, lig: {'96': 92}, tclass: 'italic'},
|
||||
{c: 'a', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'b', ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'c', a:0, ic: 0.0565, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'd', ic: 0.103, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'e', a:0, ic: 0.0751, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'f', ic: 0.212, krn: {'39': 0.104, '63': 0.104, '33': 0.104, '41': 0.104, '93': 0.104}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'italic'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'h', ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'i', ic: 0.102, tclass: 'italic'},
|
||||
{c: 'j', d:.2, ic: 0.145, tclass: 'italic'},
|
||||
{c: 'k', ic: 0.108, tclass: 'italic'},
|
||||
{c: 'l', ic: 0.103, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'm', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'n', a:0, ic: 0.0767, krn: {'39': -0.102}, tclass: 'italic'},
|
||||
{c: 'o', a:0, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, ic: 0.0631, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 'q', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'r', a:0, ic: 0.108, krn: {'101': -0.0511, '97': -0.0511, '111': -0.0511, '100': -0.0511, '99': -0.0511, '103': -0.0511, '113': -0.0511}, tclass: 'italic'},
|
||||
{c: 's', a:0, ic: 0.0821, tclass: 'italic'},
|
||||
{c: 't', ic: 0.0949, tclass: 'italic'},
|
||||
{c: 'u', a:0, ic: 0.0767, tclass: 'italic'},
|
||||
{c: 'v', a:0, ic: 0.108, tclass: 'italic'},
|
||||
{c: 'w', a:0, ic: 0.108, krn: {'108': 0.0511}, tclass: 'italic'},
|
||||
{c: 'x', a:0, ic: 0.12, tclass: 'italic'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0885, tclass: 'italic'},
|
||||
{c: 'z', a:0, ic: 0.123, tclass: 'italic'},
|
||||
{c: '–', a:.1, ic: 0.0921, lig: {'45': 124}, tclass: 'italic'},
|
||||
{c: '—', a:.1, ic: 0.0921, tclass: 'italic'},
|
||||
{c: '˝', ic: 0.122, tclass: 'iaccent'},
|
||||
{c: '˜', ic: 0.116, tclass: 'iaccent'},
|
||||
{c: '¨', tclass: 'iaccent'}
|
||||
],
|
||||
|
||||
cmbx10: [
|
||||
// 00 - 0F
|
||||
{c: 'Γ', tclass: 'bgreek'},
|
||||
{c: 'Δ', tclass: 'bgreek'},
|
||||
{c: 'Θ', tclass: 'bgreek'},
|
||||
{c: 'Λ', tclass: 'bgreek'},
|
||||
{c: 'Ξ', tclass: 'bgreek'},
|
||||
{c: 'Π', tclass: 'bgreek'},
|
||||
{c: 'Σ', tclass: 'bgreek'},
|
||||
{c: 'Υ', tclass: 'bgreek'},
|
||||
{c: 'Φ', tclass: 'bgreek'},
|
||||
{c: 'Ψ', tclass: 'bgreek'},
|
||||
{c: 'Ω', tclass: 'bgreek'},
|
||||
{c: 'ff', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 14, '108': 15}, tclass: 'bold'},
|
||||
{c: 'fi', tclass: 'bold'},
|
||||
{c: 'fl', tclass: 'bold'},
|
||||
{c: 'ffi', tclass: 'bold'},
|
||||
{c: 'ffl', tclass: 'bold'},
|
||||
// 10 - 1F
|
||||
{c: 'ı', a:0, tclass: 'bold'},
|
||||
{c: 'j', d:.2, tclass: 'bold'},
|
||||
{c: '`', tclass: 'baccent'},
|
||||
{c: '´', tclass: 'baccent'},
|
||||
{c: 'ˇ', tclass: 'baccent'},
|
||||
{c: '˘', tclass: 'baccent'},
|
||||
{c: 'ˉ', tclass: 'baccent'},
|
||||
{c: '˚', tclass: 'baccent'},
|
||||
{c: '?', tclass: 'bold'},
|
||||
{c: 'ß', tclass: 'bold'},
|
||||
{c: 'æ', a:0, tclass: 'bold'},
|
||||
{c: 'œ', a:0, tclass: 'bold'},
|
||||
{c: 'ø', tclass: 'bold'},
|
||||
{c: 'Æ', tclass: 'bold'},
|
||||
{c: 'Œ', tclass: 'bold'},
|
||||
{c: 'Ø', tclass: 'bold'},
|
||||
// 20 - 2F
|
||||
{c: '?', krn: {'108': -0.278, '76': -0.319}, tclass: 'bold'},
|
||||
{c: '!', lig: {'96': 60}, tclass: 'bold'},
|
||||
{c: '”', tclass: 'bold'},
|
||||
{c: '#', tclass: 'bold'},
|
||||
{c: '$', tclass: 'bold'},
|
||||
{c: '%', tclass: 'bold'},
|
||||
{c: '&', tclass: 'bold'},
|
||||
{c: '’', krn: {'63': 0.111, '33': 0.111}, lig: {'39': 34}, tclass: 'bold'},
|
||||
{c: '(', d:.2, tclass: 'bold'},
|
||||
{c: ')', d:.2, tclass: 'bold'},
|
||||
{c: '*', tclass: 'bold'},
|
||||
{c: '+', a:.1, tclass: 'bold'},
|
||||
{c: ',', a:-.3, d:.2, w: 0.278, tclass: 'bold'},
|
||||
{c: '-', a:0, lig: {'45': 123}, tclass: 'bold'},
|
||||
{c: '.', a:-.25, tclass: 'bold'},
|
||||
{c: '/', tclass: 'bold'},
|
||||
// 30 - 3F
|
||||
{c: '0', tclass: 'bold'},
|
||||
{c: '1', tclass: 'bold'},
|
||||
{c: '2', tclass: 'bold'},
|
||||
{c: '3', tclass: 'bold'},
|
||||
{c: '4', tclass: 'bold'},
|
||||
{c: '5', tclass: 'bold'},
|
||||
{c: '6', tclass: 'bold'},
|
||||
{c: '7', tclass: 'bold'},
|
||||
{c: '8', tclass: 'bold'},
|
||||
{c: '9', tclass: 'bold'},
|
||||
{c: ':', tclass: 'bold'},
|
||||
{c: ';', tclass: 'bold'},
|
||||
{c: '¡', tclass: 'bold'},
|
||||
{c: '=', a:0, d:-.1, tclass: 'bold'},
|
||||
{c: '¿', tclass: 'bold'},
|
||||
{c: '?', lig: {'96': 62}, tclass: 'bold'},
|
||||
// 40 - 4F
|
||||
{c: '@', tclass: 'bold'},
|
||||
{c: 'A', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'B', tclass: 'bold'},
|
||||
{c: 'C', tclass: 'bold'},
|
||||
{c: 'D', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'bold'},
|
||||
{c: 'E', tclass: 'bold'},
|
||||
{c: 'F', krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'G', tclass: 'bold'},
|
||||
{c: 'H', tclass: 'bold'},
|
||||
{c: 'I', krn: {'73': 0.0278}, tclass: 'bold'},
|
||||
{c: 'J', tclass: 'bold'},
|
||||
{c: 'K', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'L', krn: {'84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'M', tclass: 'bold'},
|
||||
{c: 'N', tclass: 'bold'},
|
||||
{c: 'O', krn: {'88': -0.0278, '87': -0.0278, '65': -0.0278, '86': -0.0278, '89': -0.0278}, tclass: 'bold'},
|
||||
// 50 - 5F
|
||||
{c: 'P', krn: {'65': -0.0833, '111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'bold'},
|
||||
{c: 'Q', d: 1, tclass: 'bold'},
|
||||
{c: 'R', krn: {'116': -0.0278, '67': -0.0278, '79': -0.0278, '71': -0.0278, '85': -0.0278, '81': -0.0278, '84': -0.0833, '89': -0.0833, '86': -0.111, '87': -0.111}, tclass: 'bold'},
|
||||
{c: 'S', tclass: 'bold'},
|
||||
{c: 'T', krn: {'121': -0.0278, '101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'bold'},
|
||||
{c: 'U', tclass: 'bold'},
|
||||
{c: 'V', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'W', ic: 0.0139, krn: {'111': -0.0833, '101': -0.0833, '117': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.111, '79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'X', krn: {'79': -0.0278, '67': -0.0278, '71': -0.0278, '81': -0.0278}, tclass: 'bold'},
|
||||
{c: 'Y', ic: 0.025, krn: {'101': -0.0833, '111': -0.0833, '114': -0.0833, '97': -0.0833, '65': -0.0833, '117': -0.0833}, tclass: 'bold'},
|
||||
{c: 'Z', tclass: 'bold'},
|
||||
{c: '[', d:.1, tclass: 'bold'},
|
||||
{c: '“', tclass: 'bold'},
|
||||
{c: ']', d:.1, tclass: 'bold'},
|
||||
{c: 'ˆ', tclass: 'baccent'},
|
||||
{c: '˙', tclass: 'baccent'},
|
||||
// 60 - 6F
|
||||
{c: '‘', lig: {'96': 92}, tclass: 'bold'},
|
||||
{c: 'a', a:0, krn: {'118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'b', krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'c', a:0, krn: {'104': -0.0278, '107': -0.0278}, tclass: 'bold'},
|
||||
{c: 'd', tclass: 'bold'},
|
||||
{c: 'e', a:0, tclass: 'bold'},
|
||||
{c: 'f', ic: 0.0778, krn: {'39': 0.0778, '63': 0.0778, '33': 0.0778, '41': 0.0778, '93': 0.0778}, lig: {'105': 12, '102': 11, '108': 13}, tclass: 'bold'},
|
||||
{c: 'g', a:0, d:.2, ic: 0.0139, krn: {'106': 0.0278}, tclass: 'bold'},
|
||||
{c: 'h', krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'i', tclass: 'bold'},
|
||||
{c: 'j', d:.2, tclass: 'bold'},
|
||||
{c: 'k', krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'l', tclass: 'bold'},
|
||||
{c: 'm', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'n', a:0, krn: {'116': -0.0278, '117': -0.0278, '98': -0.0278, '121': -0.0278, '118': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'o', a:0, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
// 70 - 7F
|
||||
{c: 'p', a:0, d:.2, krn: {'101': 0.0278, '111': 0.0278, '120': -0.0278, '100': 0.0278, '99': 0.0278, '113': 0.0278, '118': -0.0278, '106': 0.0556, '121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'q', a:0, d:.2, tclass: 'bold'},
|
||||
{c: 'r', a:0, tclass: 'bold'},
|
||||
{c: 's', a:0, tclass: 'bold'},
|
||||
{c: 't', krn: {'121': -0.0278, '119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'u', a:0, krn: {'119': -0.0278}, tclass: 'bold'},
|
||||
{c: 'v', a:0, ic: 0.0139, krn: {'97': -0.0556, '101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'w', a:0, ic: 0.0139, krn: {'101': -0.0278, '97': -0.0278, '111': -0.0278, '99': -0.0278}, tclass: 'bold'},
|
||||
{c: 'x', a:0, tclass: 'bold'},
|
||||
{c: 'y', a:0, d:.2, ic: 0.0139, krn: {'111': -0.0278, '101': -0.0278, '97': -0.0278, '46': -0.0833, '44': -0.0833}, tclass: 'bold'},
|
||||
{c: 'z', a:0, tclass: 'bold'},
|
||||
{c: '–', a:.1, ic: 0.0278, lig: {'45': 124}, tclass: 'bold'},
|
||||
{c: '—', a:.1, ic: 0.0278, tclass: 'bold'},
|
||||
{c: '˝', tclass: 'baccent'},
|
||||
{c: '˜', tclass: 'baccent'},
|
||||
{c: '¨', tclass: 'baccent'}
|
||||
]
|
||||
});
|
||||
|
||||
jsMath.Setup.Styles({
|
||||
'.typeset .math': 'font-style: normal',
|
||||
'.typeset .italic': 'font-style: italic',
|
||||
'.typeset .bold': 'font-weight: bold',
|
||||
'.typeset .cmr10': 'font-family: serif',
|
||||
'.typeset .cal': 'font-family: cursive',
|
||||
'.typeset .arrows': '',
|
||||
'.typeset .arrow1': '',
|
||||
'.typeset .arrow2': '',
|
||||
'.typeset .harpoon': 'font-size: 125%',
|
||||
'.typeset .symbol': '',
|
||||
'.typeset .symbol2': '',
|
||||
'.typeset .delim1': 'font-size: 133%; position:relative; top:.75em',
|
||||
'.typeset .delim1b': 'font-size: 133%; position:relative; top:.8em; margin: -.1em',
|
||||
'.typeset .delim1c': 'font-size: 120%; position:relative; top:.8em;',
|
||||
'.typeset .delim2': 'font-size: 180%; position:relative; top:.75em',
|
||||
'.typeset .delim2b': 'font-size: 190%; position:relative; top:.8em; margin: -.1em',
|
||||
'.typeset .delim2c': 'font-size: 167%; position:relative; top:.8em;',
|
||||
'.typeset .delim3': 'font-size: 250%; position:relative; top:.725em',
|
||||
'.typeset .delim3b': 'font-size: 250%; position:relative; top:.8em; margin: -.1em',
|
||||
'.typeset .delim3c': 'font-size: 240%; position:relative; top:.775em;',
|
||||
'.typeset .delim4': 'font-size: 325%; position:relative; top:.7em',
|
||||
'.typeset .delim4b': 'font-size: 325%; position:relative; top:.8em; margin: -.1em',
|
||||
'.typeset .delim4c': 'font-size: 300%; position:relative; top:.8em;',
|
||||
'.typeset .delim': '',
|
||||
'.typeset .vertical': '',
|
||||
'.typeset .greek': '',
|
||||
'.typeset .igreek': 'font-style: italic',
|
||||
'.typeset .bgreek': 'font-weight: bold',
|
||||
'.typeset .bigop1': 'font-size: 133%; position: relative; top: .85em; margin:-.05em',
|
||||
'.typeset .bigop1a': 'font-size: 100%; position: relative; top: .775em;',
|
||||
'.typeset .bigop1b': 'font-size: 160%; position: relative; top: .7em; margin:-.1em',
|
||||
'.typeset .bigop1c': 'font-size: 125%; position: relative; top: .75em; margin:-.1em;',
|
||||
'.typeset .bigop2': 'font-size: 200%; position: relative; top: .8em; margin:-.07em',
|
||||
'.typeset .bigop2a': 'font-size: 175%; position: relative; top: .7em;',
|
||||
'.typeset .bigop2b': 'font-size: 270%; position: relative; top: .62em; margin:-.1em',
|
||||
'.typeset .bigop2c': 'font-size: 250%; position: relative; top: .7em; margin:-.17em;',
|
||||
'.typeset .wide1': 'font-size: 67%; position: relative; top:-.8em',
|
||||
'.typeset .wide2': 'font-size: 110%; position: relative; top:-.5em',
|
||||
'.typeset .wide3': 'font-size: 175%; position: relative; top:-.32em',
|
||||
'.typeset .wide1a': 'font-size: 75%; position: relative; top:-.5em',
|
||||
'.typeset .wide2a': 'font-size: 133%; position: relative; top: -.15em',
|
||||
'.typeset .wide3a': 'font-size: 200%; position: relative; top: -.05em',
|
||||
'.typeset .root': '',
|
||||
'.typeset .accent': 'position: relative; top: .02em',
|
||||
'.typeset .iaccent': 'position: relative; top: .02em; font-style: italic',
|
||||
'.typeset .baccent': 'position: relative; top: .02em; font-weight: bold'
|
||||
});
|
||||
|
||||
|
||||
jsMath.Setup.Styles();
|
||||
|
||||
/*
|
||||
* No access to TeX "not" character, so fake this
|
||||
*/
|
||||
jsMath.Macro('not','\\mathrel{\\rlap{\\kern 4mu/}}');
|
||||
jsMath.Macro('joinrel','\\mathrel{\\kern-2mu}');
|
||||
|
||||
|
||||
jsMath.Box.DelimExtend = jsMath.Box.DelimExtendRelative;
|
||||
|
||||
jsMath.Box.defaultH = 0.8;
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 210 KiB |
|
@ -0,0 +1,54 @@
|
|||
About
|
||||
**********
|
||||
|
||||
madIS is a extensible relational database system build upon the SQLite database and with extensions written in Python.
|
||||
|
||||
It was designed and created by a small team of developers at the MaDgIK lab of the National and Kapodistrian University of Athens, under the surpevising of professor Yannis Ioannidis.
|
||||
|
||||
The extensibility permits quick experimentation concerning data analysis tasks, rapid development of data processing workflows and serves in general as a simple and easy environment to test database related ideas without much effort.
|
||||
madIS' query language is SQL with some syntactic "extensions" aiming to simplify query composition.
|
||||
|
||||
|
||||
madIS main design goals are:
|
||||
|
||||
- To be easy, and versatile
|
||||
|
||||
- To be extremely productive for data analysis and data processing tasks
|
||||
|
||||
- Maximum reusability of extensions
|
||||
|
||||
In practice madIS has proved to be extremely easy when adding new functionalities to it, very fast in developing new workflows and most of all the majority of the external functions written for madIS, have proven to be reusable in new tasks for which they were not designed for.
|
||||
|
||||
madIS is suitable for
|
||||
=======================
|
||||
|
||||
Complex data analysis tasks
|
||||
----------------------------
|
||||
|
||||
In madIS it is very easy to create additional relational functions, or join against external files without first importing them into the database.
|
||||
|
||||
Additionally madIS offers a very fast multidimensional index, greatly speeding up multi-constraint joins, even when joining against external sources.
|
||||
|
||||
Data transformations
|
||||
---------------------
|
||||
|
||||
madIS can already use the file system or network sources as tables. In addition, with a little Python knowledge, complex data transformation functions can be created and be used inside the database. All these can be done even without importing anything inside the database.
|
||||
|
||||
In addition madIS offers a very easy, to work with, workflow engine to automate the data transformation steps.
|
||||
|
||||
Database research
|
||||
-------------------
|
||||
|
||||
If you wish to develop and test a new indexing structure, it can easily be developed in madIS. madIS uses Python for its extensions and already has plenty of code to start from.
|
||||
|
||||
|
||||
.. note::
|
||||
Due to madIS' SQLite core, the database format of madIS is exactly the same as SQLite's one.
|
||||
This means that all SQLite databases are directly usable with madIS.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* `SQLite <http://www.sqlite.org>`_
|
||||
* `Python <http://www.python.org>`_
|
||||
* `APSW <http://code.google.com/p/apsw/>`_
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# madIS documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Nov 26 16:25:19 2009.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.append(os.path.abspath('.'))
|
||||
sys.path.append(os.path.abspath(os.path.dirname(__file__)+'../../../'))
|
||||
import functions
|
||||
|
||||
#sys.path.append(os.path.abspath(os.path.dirname(__file__)+'\\..\\..\\'))
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.jsmath', 'sphinx.ext.ifconfig']
|
||||
|
||||
# JSMath extension option
|
||||
jsmath_path='jsMath/easy/load.js'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.txt'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8'
|
||||
|
||||
def process_signature(app, what, name, obj, opts, sig, ann):
|
||||
if what == 'function':
|
||||
return ""
|
||||
|
||||
def setup(app):
|
||||
app.connect('autodoc-process-signature', process_signature)
|
||||
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'madIS'
|
||||
copyright = u'2009-2010, L. Stamatogiannakis, M. Triantafyllidi, M. Vayanou, M. Kyriakidi'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = functions.VERSION
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directory, that shouldn't be searched
|
||||
# for source files.
|
||||
exclude_trees = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = False
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
html_theme_options = {} #{'stickysidebar': True}
|
||||
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = 'madislog.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_use_modindex = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
html_split_index = True
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'madisdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'madis.tex', u'madIS Documentation',
|
||||
u'mlmlml', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
|
@ -0,0 +1,192 @@
|
|||
Examples
|
||||
********
|
||||
|
||||
.. _pivoting:
|
||||
|
||||
.. highlight:: mysql
|
||||
|
||||
Pivot
|
||||
=====
|
||||
|
||||
First import data from a tsv file (Tab Separated Values) with :func:`~functions.vtable.file.file` virtual table function.
|
||||
:download:`sales.tsv <../../functions/row/testing/sales.tsv>`
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> sql("""create table sales as
|
||||
... select Product,Region,Month,cast(Sales as int) as Sales
|
||||
... from
|
||||
... (file 'testing/sales.tsv' 'dialect:tsv' header:t)""")
|
||||
>>> sql("select * from sales")
|
||||
Product | Region | Month | Sales
|
||||
----------------------------------
|
||||
Cars | Athens | 2010-01 | 200
|
||||
Cars | Athens | 2010-02 | 130
|
||||
Bikes | NY | 2010-01 | 10
|
||||
Bikes | NY | 2010-02 | 30
|
||||
Cars | NY | 2010-01 | 100
|
||||
Cars | NY | 2010-02 | 160
|
||||
Cars | Paris | 2010-01 | 70
|
||||
Cars | Paris | 2010-02 | 20
|
||||
Bikes | Paris | 2010-01 | 100
|
||||
Bikes | Paris | 2010-02 | 20
|
||||
Boats | Paris | 2010-01 | 200
|
||||
|
||||
Let's say we want the result to be a table with columns:
|
||||
|
||||
- Product
|
||||
- NY: the total sales in NY for this product
|
||||
- Paris: the total sales in Paris for this product
|
||||
- Athens: the total sales in Athens for this product
|
||||
|
||||
We will perform the aggregate function *sum* over *Sales* column, grouping by *Product* and *Region* columns.
|
||||
Then :func:`~functions.aggregate.packing.vecpack` must be performed over *Region* and *Sales* sums, grouping on *Product*.
|
||||
|
||||
To use :func:`~functions.aggregate.packing.vecpack` the first argument must be a pack of the dimensions. This is the
|
||||
result of packing the distinct *Region* values, grouping over all the table.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> sql("""select Product,unpackcol(vpck)
|
||||
... from
|
||||
... (select Product,vecpack(rpk,Region,salessum) as vpck
|
||||
... from
|
||||
... (select pack(distinct Region) as rpk from sales),
|
||||
... (select Product,Region,sum(sales) as salessum
|
||||
... from sales group by Product,Region)
|
||||
... group by Product)""")
|
||||
Product | Paris | NY | Athens
|
||||
------------------------------
|
||||
Bikes | 120 | 40 | 0
|
||||
Boats | 200 | 0 | 0
|
||||
Cars | 90 | 260 | 330
|
||||
|
||||
|
||||
.. _applexample:
|
||||
|
||||
|
||||
Application scenario
|
||||
====================
|
||||
|
||||
|
||||
In this example we implement a simple application for query recommendation based on user's country of origin. The input data come from a web portal's logs.
|
||||
|
||||
The query mining workflow includes the following five main steps:
|
||||
|
||||
1. Import the portal log files into a relational table
|
||||
2. Use time-heuristics so as to identify coherent query sessions.
|
||||
Assign and store a new, reconstructed session id for each record in the logs
|
||||
3. Preprocess and clean logged queries text
|
||||
4. Retrieve IP-to-country information from the web and combine this with the IP information from portal log files
|
||||
so as to assign a country code to each one of the logged sessions
|
||||
5. Apply an `Apriori-based <http://en.wikipedia.org/wiki/Apriori_algorithm>`_ technique for extracting frequent term sets per country.
|
||||
|
||||
A sample from the log file used is presented below:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
36506 guest X.X.X.134 p93t9q5eqaa0u0p8isd9skp1n6 en ("paradis riedinger") search_sim 2010-01-01 00:28:23
|
||||
36507 guest X.X.X.134 p93t9q5eqaa0u0p8isd9skp1n6 en ("paradis riedinger") view_brief 2010-01-01 00:28:34
|
||||
36508 guest X.X.X.134 p93t9q5eqaa0u0p8isd9skp1n6 en ("paradis riedinger") view_brief 2010-01-01 00:28:34
|
||||
36509 guest X.X.X.134 p93t9q5eqaa0u0p8isd9skp1n6 en ("paradis riedinger") view_full 2010-01-01 00:28:42
|
||||
36510 guest X.X.X.55 a9qo379qnl5hbbria6tj6nlp95 de (creator all "frank leonhard") search_adv 2010-01-01 00:28:44
|
||||
36511 guest X.X.X.55 a9qo379qnl5hbbria6tj6nlp95 de (creator all "frank leonhard") view_brief 2010-01-01 00:29:10
|
||||
36512 guest X.X.X.55 a9qo379qnl5hbbria6tj6nlp95 de (creator all "frank leonhard") search_res 2010-01-01 00:29:18
|
||||
|
||||
|
||||
**Step 1**
|
||||
|
||||
Initially, log files which are available in the Tab Separated Value format, are imported into a relational table.
|
||||
The import process is easily implemented in madIS using the :func:`~functions.vtable.file.file` function,
|
||||
by selecting the appropriate columns from the ".tsv" file.
|
||||
|
||||
::
|
||||
|
||||
create table logs as
|
||||
select C1 as id, C2 as userid, C3 as userip, C4 as sesid, C6 as query, c7 as action, C8 as date
|
||||
from file('raw_logs.tsv','delimiter:\t','quoting:QUOTE_NONE');
|
||||
|
||||
**Step 2**
|
||||
|
||||
Thereafter, session reconstruction, a common task in web usage mining, is performed.
|
||||
In this example it uses a predefined inactivity thresholds to break in-coming sessions.
|
||||
Such functionality is performed in madIS through the :func:`~functions.aggregate.subgroup.datediffbreak` function,
|
||||
which takes as an argument the inactivity threshold (as well as some additional parameters) and returns the new session ids.
|
||||
In the following madSQL segment, where the efficient employment of the described function is presented,
|
||||
the inactivity threshold has been set to 30 minutes (provided in milliseconds).
|
||||
|
||||
::
|
||||
|
||||
alter table logs add sesidnew text;
|
||||
update logs
|
||||
set sesidnew=
|
||||
(select bgroupid
|
||||
from
|
||||
( cache select datediffbreak(sesid,id,date,30*60*1000,'order',date,id)
|
||||
from logs
|
||||
where sesid not null group by sesid)
|
||||
where C1=id )
|
||||
where sesid is not null;
|
||||
|
||||
**Step 3**
|
||||
|
||||
Then, focusing on issued queries, the distinct queries per session are retrieved from the logs
|
||||
and a variety of query text processing steps take place.
|
||||
However, a great amount of malformed queries has been observed, so it is only queries of valid text in utf8 encoding that are selected.
|
||||
This filtering step is performed using the :func:`~functions.row.text.isvalidutf8` function in the where clause of the corresponding madSQL fragment.
|
||||
|
||||
Thereafter, stop word removal is performed over the selected queries through the corresponding function.
|
||||
Moreover, since queries are issued and logged using the Common Query Language (CQL) syntax, an additional filtering step is executed for removing *CQL* constructs,
|
||||
through the madIS function :func:`~functions.row.text.cqlkeywords`. The processed queries are then stored in table *QueriesPerSession*.
|
||||
One of the advantages offered by madIS framework, is that all the powerful Python capabilities and
|
||||
open source libraries for text processing can be exploited for the rapid implementation of customized functions,
|
||||
hence significantly easing the “flow-level programming”, in madSQL.
|
||||
|
||||
::
|
||||
|
||||
create table QueriesPerSession as
|
||||
select filterstopwords(cqlkeywords(query)) as cleanquery , sesidnew, userid
|
||||
from logs
|
||||
where action like 'search%' and cleanquery!='' and isvalidutf8(query)
|
||||
group by query, sesidnew;
|
||||
|
||||
**Step 4**
|
||||
|
||||
Aiming towards the extraction of term associations per country, an external data source is fetched from the web,
|
||||
containing the mapping between IP ranges and countries.
|
||||
Again, the :func:`~functions.vtable.file.file` function is employed for fetching the URL resource and importing the corresponding data in a main memory
|
||||
indexed table using the :func:`~functions.vtable.cache.cache` function of madIS. The fetched data source specifies the IP ranges in IP long number format,
|
||||
so the logged IPs have to be converted to the same format by using :func:`~functions.row.iptools.ip2long` function, and then to be subsequently matched
|
||||
to the imported ranges. However, since each session may contain requests from multiple IPs (due to dynamic IPs, etc.),
|
||||
it is only the first encountered IP that is considered for each session.
|
||||
The first IP for each session is obtained using the :func:`~functions.aggregate.selection.minrow` function, comparing the corresponding records’ ids.
|
||||
The generated mapping from each session to a country code is stored in table Session2Country.
|
||||
|
||||
::
|
||||
|
||||
create temporary table Session2Country as
|
||||
select sesidnew, CountryCode
|
||||
from
|
||||
(select ip2long(minrow(id,userip)) as iplong, sesidnew
|
||||
from logs
|
||||
group by sesidnew),
|
||||
(cache select cast(C3 as integer) as ipfrom, cast(C4 as integer) as ipto, C5 as CountryCode
|
||||
from file('http://.../GeoIPCountryCSV.zip','dialect:csv','compression:t'))
|
||||
where iplong>=ipfrom and iplong <= ipto;
|
||||
|
||||
**Step 5**
|
||||
|
||||
Then information regarding text of queries, and session to country mappings is jointly used so as to extract term associations,
|
||||
with an `apriori-like <http://en.wikipedia.org/wiki/Apriori_algorithm>`_ technique, using the aggregate function :func:`~functions.aggregate.mining.freqitemsets`.
|
||||
Frequent query term sets are computed over each one of the country codes that occur in Session2Country table.
|
||||
|
||||
::
|
||||
|
||||
create table FrequentItemsets as
|
||||
select 'nat', CountryCode,
|
||||
freqitemsets(cleanquery,'threshold:2','maxlen:5')
|
||||
from QueriesPerSession as qs, Session2Country as sc
|
||||
where qs.sesidnew = sc.sesidnew
|
||||
group by CountryCode;
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
Where to create functions
|
||||
-------------------------
|
||||
|
||||
Row functions HOWTO
|
||||
-------------------
|
||||
|
||||
Aggregate functions HOWTO
|
||||
-------------------------
|
||||
|
||||
|
||||
Virtual table functions HOWTO
|
||||
-----------------------------
|
||||
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
|
||||
Global settings
|
||||
---------------
|
|
@ -0,0 +1,49 @@
|
|||
.. madIS documentation master file, created by
|
||||
sphinx-quickstart on Thu Nov 26 16:25:19 2009.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
madIS documentation
|
||||
===================
|
||||
|
||||
+--------------------------------------------------------------+
|
||||
| |
|
||||
|" Making the simple complicated is commonplace; |
|
||||
| making the complicated simple, awesomely simple... |
|
||||
| that's creativity. " |
|
||||
| |
|
||||
+--------------------------------------------------------------+
|
||||
|
||||
.. centered:: madIS |version|
|
||||
|
||||
madIS is a extensible relational database system build upon the SQLite database and with extensions written in Python.
|
||||
|
||||
The extensibility permits quick experimentation concerning data analysis tasks, rapid development of data processing workflows and serves in general as a simple and easy environment to test database related ideas without much effort.
|
||||
madIS' query language is SQL with some syntactic "extensions" aiming to simplify query composition.
|
||||
|
||||
madIS is hosted at http://code.google.com/p/madis/
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
install
|
||||
about
|
||||
manual
|
||||
usefulnotes
|
||||
examples
|
||||
row
|
||||
aggregate
|
||||
vtable
|
||||
people
|
||||
license
|
||||
thanks
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Installing madIS
|
||||
================
|
||||
|
||||
The requirements for using madIS are:
|
||||
|
||||
1. **Python 2.6.x** or **2.7.x**: You can download a windows distribution of Python from
|
||||
http://www.python.org/download/releases/ .You need to download the latest
|
||||
Python in the 2.6 or 2.7 series. madIS doesn't currently work with Python 3.0.
|
||||
|
||||
.. note::
|
||||
Most Linux distributions come with Python 2.6 or Python 2.7 preinstalled.
|
||||
|
||||
2. **APSW**:
|
||||
|
||||
Windows:
|
||||
|
||||
Download the windows distribution of `APSW` from http://code.google.com/p/apsw/downloads/list .
|
||||
|
||||
Linux:
|
||||
|
||||
Most Linux distributions contain in their repositories a sufficiently recent version of `APSW`.
|
||||
If you use Ubuntu 10.04 and later, install the `python-apsw` package::
|
||||
|
||||
sudo apt-get install python-apsw
|
||||
|
||||
In case `APSW` is not provided with your Linux distribution of choise, `APSW` should be build from source.
|
||||
The detailed instructions for building `APSW` can be found at:
|
||||
|
||||
http://apidoc.apsw.googlecode.com/hg/build.html#recommended
|
||||
|
||||
A quick command line to build and install `APSW` is::
|
||||
|
||||
sudo python setup.py fetch --all --missing-checksum-ok build install
|
||||
|
||||
If you are using Ubuntu and wish to build `APSW` from source, you also need the packages::
|
||||
|
||||
build-essential libreadline5-dev zlib1g-dev python-dev
|
||||
|
||||
MacOS:
|
||||
|
||||
On *MacOS 10.6* install `APSW` and `readline` via `easy_install`::
|
||||
|
||||
easy_install apsw
|
||||
easy_install readline
|
||||
|
||||
On *MacOS 10.7* you have to build `APSW` from source (as showed above), for which you'll
|
||||
also need *Xcode*.
|
||||
|
||||
After building `APSW`, install `readline` via `easy_install`::
|
||||
|
||||
sudo easy_install readline
|
||||
|
||||
3. Download the madIS archive (.zip) from:
|
||||
|
||||
http://code.google.com/p/madis/downloads/list
|
||||
|
||||
4. Uncompress above zip file
|
||||
|
||||
5. Use madis by entering into the new "madis/" path and executing "python mterm.py"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Copyright and License
|
||||
=====================
|
||||
|
||||
Copyright (C) 2009-2013 Lefteris Stamatogiannakis, Mei Li Triantafyllidi,
|
||||
Ioannis Foufoulas, Maria Vayanou, Marialena Kyriakidi.
|
||||
|
||||
The external libraries used throughout the madIS project are copyright
|
||||
of their respective authors.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
* The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
* Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
* This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
|
||||
Alternatively you may strike the license above and use it under any
|
||||
OSI approved open source license such as those listed at
|
||||
http://opensource.org/licenses/alphabetical
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,564 @@
|
|||
.. highlight:: sql
|
||||
|
||||
Manual
|
||||
#########
|
||||
|
||||
Functions
|
||||
*********
|
||||
|
||||
Functions are the main mechanism with which extensions are implemented.
|
||||
The are three kinds of functions:
|
||||
|
||||
- Row functions
|
||||
|
||||
- Aggregate functions
|
||||
|
||||
- Virtual tables
|
||||
|
||||
madIS also provides syntactic extensions, in its supported SQL, that simplify the use of above functions.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`row-functions-list`
|
||||
* :ref:`aggregate-functions-list`
|
||||
* :ref:`vtable-functions-list`
|
||||
|
||||
Row functions
|
||||
|
||||
Programmable row functions work in a similar way as standard SQL row functions such as *abs()*, *lower()* and *upper()*.
|
||||
Their implementation is done in Python, and they are able to use all Python facilities and libraries.
|
||||
|
||||
An example of an SQL statement using an external row function is::
|
||||
|
||||
mterm> select detectlang('Il en est des livres comme du feu de nos foyers');
|
||||
french
|
||||
|
||||
Above statement executes the *detectlang* function, which tries to detect the language of a snippet of text by analysing its statistical properties.
|
||||
On the above example the snippet is a Voltaire quote, and the correct answer from *detectlang* is that it is in french.
|
||||
|
||||
If we wished to do the same for multiple quotes then we could use the following SQL statement (assuming the existence of a *quotes_table* which contains the column *quote*)::
|
||||
|
||||
mterm> select detectlang(quote) from quotes_table;
|
||||
french
|
||||
english
|
||||
...
|
||||
|
||||
In general external row functions can be used in exactly the same way as SQLite's internal row functions.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`row-functions-list`
|
||||
* :func:`~functions.row.langtools.detectlang`
|
||||
|
||||
Creating and using a simple row function
|
||||
----------------------------------------
|
||||
|
||||
Python files that implement row functions live in "/src/functions/row". A single python file can contain many row functions.
|
||||
Now lets create a simple "hello world" row function.
|
||||
|
||||
Go to the "src/functions/row/" path of madIS, and create "hello.py". Then write the following code in it:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
def hello(*args):
|
||||
return "hello "+args[0]
|
||||
|
||||
hello.registered=True
|
||||
|
||||
The code above, looks like and indeed is, a simple python function that takes multiple arguments.
|
||||
The only peculiarity is the "hello.registered=True" line.
|
||||
What this line does, is to instruct madIS to register this function with the SQLite core.
|
||||
This way, Python functions that we don't wish to become SQLite row functions, can simply be used without any change to them.
|
||||
|
||||
To execute the above row function we start madIS and execute an SQL query which uses the new *hello* row function::
|
||||
|
||||
% python mterm.py
|
||||
mterm> select hello("world");
|
||||
hello world
|
||||
|
||||
|
||||
The SQL query above, shows the results of calling *hello* function with "world" as a parameter.
|
||||
As happens very often in SQL queries, parameter values are retrieved from tables.
|
||||
Below we show such an example::
|
||||
|
||||
mterm> select "world" as a UNION select "all" as a;
|
||||
all
|
||||
world
|
||||
Query executed in 0 min. 0 sec 3 msec
|
||||
mterm> select hello(a) from (select "world" as a UNION select "all" as a);
|
||||
hello all
|
||||
hello world
|
||||
Query executed in 0 min. 0 sec 7 msec
|
||||
|
||||
When developing custom row functions it is very useful to browse through the already developed row functions, in the "functions/row" path of madIS.
|
||||
Most of the time a custom function can be based on an already existing one.
|
||||
|
||||
.. note::
|
||||
If a developer wishes to add a row function that in essence is a part of a pre-existing Python library.
|
||||
The madIS convention is to put the library files in the "src/lib/" path of madIS and then create a row function in the "row" path of madIS which imports and calls the necessary methods of the actual library in "lib" path.
|
||||
For an example of this see *detectlang.*
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`row-functions-list`
|
||||
|
||||
Aggregate functions
|
||||
|
||||
Programmable aggregate functions work in a similar way as standard SQL aggregate functions such as *sum()*, *min()* and *max()*.
|
||||
Their implementation is done in Python, and as is also the case for row functions, all Python facilities and libraries are available.
|
||||
|
||||
An example of an SQL statement using an external aggregate function is::
|
||||
|
||||
mterm> select "term1+term2" as a UNION select "term2 term3" as a;
|
||||
term1+term2
|
||||
term2 term3
|
||||
mterm> select concatterms(a)
|
||||
from (select "term1+term2" as a UNION select "term2 term3" as a);
|
||||
term1+term2 term2 term3
|
||||
|
||||
The statement above, executes the :func:`~functions.aggregate.text.concatterms` function, which concatenates strings of terms together, while keeping the terms disjoint.
|
||||
|
||||
Using the aggregate function above, together with a row function is also possible.
|
||||
To concatenate together only the input string keywords we could execute the following SQL::
|
||||
|
||||
mterm> select concatterms(keywords(a))
|
||||
from (select "term1+term2" as a UNION select "term2 term3" as a);
|
||||
term1 term2 term2 term3
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`aggregate-functions-list`
|
||||
* :func:`~functions.aggregate.text.concatterms`
|
||||
* :func:`~functions.row.keywords.keywords`
|
||||
|
||||
|
||||
Creating and using a simple aggregate function
|
||||
----------------------------------------------
|
||||
|
||||
Python files that implement aggregate functions live in
|
||||
"/src/functions/aggregate". A single python file can contain many aggregate functions.
|
||||
Now, lets create a simple aggregate function.
|
||||
|
||||
Go to the "src/functions/aggregate/" path of madIS, and create "myconcat.py". Then write the following code in it:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
class quotedconcatterms:
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.result=[]
|
||||
|
||||
def step(self, *args):
|
||||
if len(args[0])!=0:
|
||||
self.result.append("'"+args[0]+"'")
|
||||
|
||||
def final(self):
|
||||
return ' '.join(self.result)
|
||||
|
||||
What the aggregate function above does, is to concatenate strings of terms together while inserting single quotes around each string.
|
||||
|
||||
In the "__init__" method of class *quotedconcatterms* we initialize all needed variables (self.result).
|
||||
The "step" method, is called by SQLite's engine for every tuple of the group which is fed into the aggregate function.
|
||||
At the end of the group, the "final" method is called to return the final result.
|
||||
|
||||
The "registered=True" line above, as in row functions, instructs madIS to load the class into the SQLite engine as an aggregate function.
|
||||
|
||||
To execute the above aggregate function we start madIS and execute an SQL query which uses the new *quotedconcatterms*
|
||||
aggregate function (notice the single quotes around each input string in the results)::
|
||||
|
||||
% python mterm.py
|
||||
mterm> select quotedconcatterms(keywords(a)) from (select "term1+term2" as a UNION select "term2 term3" as a);
|
||||
'term1 term2' 'term2 term3'
|
||||
|
||||
As is the case with aggregate functions it is very useful to browse through the
|
||||
already developed aggregate functions, in the "functions/aggregate" path of
|
||||
madIS, to find snippets of code implementing wished for, functionality.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`aggregate-functions-list`
|
||||
|
||||
Virtual tables
|
||||
|
||||
Virtual tables are actually functions that take parameters and output table like data. They can be used in the SQL syntax wherever
|
||||
a regular table would be placed.
|
||||
|
||||
Virtual tables are one of the most powerful function classes in madIS. They can function in a regular table fashion,
|
||||
where the output data is finite in number, or in a streaming fashion, where the output stream can be infinite.
|
||||
|
||||
This, together with the SQL syntax extensions of madIS, creates a very powerful environment with which a variety
|
||||
of standard madIS features have been developed, such as the *multisets*, *workflow engine*,
|
||||
*direct data load from filesystem or network*, etc.
|
||||
|
||||
|
||||
Typical examples of virtual tables sources are files, SQL query resulsets, or even external programs output.
|
||||
|
||||
In addition to the above, virtual tables can also function as programmable indexes on the input data,
|
||||
negotiating with the database engine about which constraints or ordering they'll be able to answer/produce quickly.
|
||||
The only madIS virtual table that implements and works as an index is :ref:`cache <tutcache>`, which offers, a created on the fly,
|
||||
multidimensional index.
|
||||
|
||||
Using virtual tables can be done in a variety of ways.
|
||||
The first is **parametric table**::
|
||||
|
||||
% python mterm.py
|
||||
mterm> select * from file('./demo/continents.tsv') limit 2;
|
||||
Asia|AF
|
||||
Europe|AL
|
||||
|
||||
What the example above does, is to read the tab separated "continents.tsv" filesystem file as a table.
|
||||
Using the standard *limit* SQL directive, the output is limited to only 2 rows.
|
||||
|
||||
An example showing the streaming nature of virtual tables is::
|
||||
|
||||
mterm> select output from pipe('query:date');
|
||||
Fri Feb 1 12:34:55 EET 2000
|
||||
""
|
||||
mterm> select strsplit(output,'delimiter: ') from pipe('query:date');
|
||||
Mon|Feb||1|12:34:56|EET|2000
|
||||
|
||||
The first of the above examples executes system's "date" command through the use of the :mod:`~functions.vtable.pipe` virtual table.
|
||||
Notice that the :mod:`~functions.vtable.pipe` virtual table has a default returned schema, having one column named *output.*
|
||||
|
||||
The second of the above examples does the same as the previous one, however it also splits :mod:`~functions.vtable.pipe`'s output,
|
||||
using space as a delimiter, into multiple columns through :func:`~functions.row.formating.strsplit` row function.
|
||||
|
||||
At this point, we should skip a little ahead, and mention two peculiarities on the queries above.
|
||||
The first one is the "query:date" parameter of :mod:`~functions.vtable.pipe`.
|
||||
This in madIS is called a *named parameter*, where the part before the ":" is a parameter's name and the second part is a parameter's value.
|
||||
|
||||
The second peculiarity is the that the row function :func:`~functions.row.formating.strsplit` returns multiple columns.
|
||||
This is a :ref:`multiset <tutmultiset>` function, able to return as many columns and rows as it wishes.
|
||||
To see the column names and column types of second query above, we can execute::
|
||||
|
||||
mterm> coltypes select strsplit(output,'delimiter: ') from pipe('query:date');
|
||||
C1|text
|
||||
C2|text
|
||||
C3|text
|
||||
C4|text
|
||||
C5|text
|
||||
C6|text
|
||||
C7|text
|
||||
|
||||
|
||||
The "coltypes" in the above query may look like a special function of the terminal but in essence it is also
|
||||
a virtual table that takes as input a query and returns a table having as first column the column names
|
||||
of the inside query and as second column the column types of the inside query.
|
||||
|
||||
|
||||
.. note::
|
||||
- :mod:`~functions.vtable.coltypes` is able to be used in front of a query because it is in its :ref:`inverted form <inversion>`.
|
||||
We'll discuss madIS SQL extensions in the following section.
|
||||
- We won't present a simple virtual table implementation as they are too complex to be presented here.
|
||||
For more see the already existing tables in the "/src/functions/vtable" path of madIS, and the
|
||||
`APSW documentation <http://apidoc.apsw.googlecode.com/hg/vtable.html>`_ concerning virtual tables.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`vtable-functions-list`
|
||||
* :mod:`~functions.vtable.file`
|
||||
* :mod:`~functions.vtable.pipe`
|
||||
* :func:`~functions.row.formating.strsplit`
|
||||
* :mod:`~functions.vtable.coltypes`
|
||||
|
||||
.. _inversion:
|
||||
|
||||
madIS SQL extensions
|
||||
********************
|
||||
|
||||
While developing madIS, we realized that some simple ideas like virtual table chaining, were too difficult to be written in plain SQL.
|
||||
In addition using a virtual table was more difficult than it needed to be, due to having to "create" a virtual table before using it.
|
||||
|
||||
To solve the problems above, we've extended SQL with the following features:
|
||||
|
||||
- Parametric virtual tables are automatically created and deleted
|
||||
|
||||
- Syntax inversion
|
||||
|
||||
The first of above features, is quite apparent. The user doesn't have to manage virtual tables,
|
||||
madIS does everything it is needed automatically in the background, creating a virtual table just before a query using it, is executed, and
|
||||
deleting it after the query's execution completes. This is why we could directly
|
||||
read from the file system, with the *file* virtual table, in the previous section.
|
||||
|
||||
Inversions are slightly more complex.
|
||||
So lets start with a simple virtual table chaining example and invert it::
|
||||
|
||||
mterm> select * from output('d.txt', "query:select * from pipe('query:date')");
|
||||
1
|
||||
|
||||
What the query above does, is to call system's "date" command, through the *pipe* virtual table, and write the output back to the file system (in the file named "d.txt").
|
||||
The *output* virtual table returns back if it succeeded or not (1 or 0).
|
||||
|
||||
Because chaining virtual tables on the manner shown above, proved to require a lot of effort and in addition was error prone, syntax inversion was added to madIS' accepted SQL syntax.
|
||||
The inversion syntax is::
|
||||
|
||||
VTname 'param1' 'param2'... namedparam1:valueofnamedparam1 ... SQL_query
|
||||
|
||||
|
||||
Whenever madIS' SQL preprocessor "sees" above syntax it turns it into::
|
||||
|
||||
select * from Vtname('param1', 'param2' ..., 'namedparam1:valueofnamedparam1' ... , 'query:SQL_query')
|
||||
|
||||
So lets use the inverted syntax, to reissue the query above::
|
||||
|
||||
mterm> output 'd.txt' pipe date;
|
||||
1
|
||||
|
||||
In practice a wide range of functionalities has been possible with inversions.
|
||||
The *coltypes* example shown in the previous section "feels" like special functionality that is implemented execution engine in other DB systems.
|
||||
In madIS, most of the special commands are in essence virtual tables (or row functions) in their inverted form.
|
||||
|
||||
The same inverted syntax is also offered by madIS, for row functions.
|
||||
So instead of::
|
||||
|
||||
mterm> select detectlang('Il en est des livres comme du feu de nos foyers');
|
||||
french
|
||||
|
||||
We could have written it as such::
|
||||
|
||||
mterm> detectlang 'Il en est des livres comme du feu de nos foyers';
|
||||
french
|
||||
|
||||
A problem arises with row inversions.
|
||||
How to distinguish between the case of passing the actual query to a row function, and passing the **results** of the query to the row function.
|
||||
|
||||
madIS has the *var* row function, which sets and retrieves a madIS variable.
|
||||
Some examples of its usage::
|
||||
|
||||
mterm> var 'demo' 'time'; -- This puts value 'time' to the variable named 'demo'
|
||||
time
|
||||
mterm> var 'demo'; -- This retrieves the value of variable 'demo'
|
||||
time
|
||||
mterm> select var('demo','time');--The same queries in their not inverted forms
|
||||
time
|
||||
mterm> select var('demo');
|
||||
time
|
||||
|
||||
What would happen if instead of the value "time" we had a plain query?::
|
||||
|
||||
mterm> var 'demo2' select var('demo');
|
||||
select var('demo')
|
||||
mterm> var 'demo2';
|
||||
select var('demo')
|
||||
|
||||
We see above, that instead of putting the result of the query "select var('demo')" into "demo2", it put the query's text in it.
|
||||
This makes it complex to pass values between variables, forcing us to do::
|
||||
|
||||
mterm> select var('demo2', (select var('demo'))); --Non inverted syntax
|
||||
time
|
||||
mterm> var 'demo2';
|
||||
time
|
||||
|
||||
Due to this, a directive which forces the use of the results of the embedded query has been created, to ease use cases such as above::
|
||||
|
||||
mterm> var 'demo2' 'essence of';
|
||||
essence of
|
||||
mterm> var 'demo' 'time';
|
||||
time
|
||||
mterm> var 'demo2' FROM var 'demo';
|
||||
time
|
||||
mterm> var 'demo2';
|
||||
time
|
||||
|
||||
Notice the "FROM" keyword after the "var 'demo2'" part of the query.
|
||||
What "FROM" does is to transform the query in its non inverted syntax shown above.
|
||||
|
||||
.. note::
|
||||
Both "FROM" and "OF" are accepted as synonyms, when specifying the use of embedded query results.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :mod:`~functions.vtable.output`
|
||||
* :mod:`~functions.vtable.pipe`
|
||||
* :func:`~functions.row.langtools.detectlang`
|
||||
* :func:`~functions.row.variables.var`
|
||||
|
||||
|
||||
.. _tutmultiset:
|
||||
|
||||
Multisets
|
||||
*********
|
||||
|
||||
Early in the development of madIS, the need to return multiple rows and columns from row and aggregate functions, arose.
|
||||
This need was satisfied through the use of *expand* virtual table and an accompanying Python API (*CompBuffer*) to create multisets.
|
||||
|
||||
Virtual table *expand* works by looking into the results of a SQL query, and if
|
||||
it finds a specially formatted tuple (in *CompBuffer's* format), it decompresses it,
|
||||
looks for schema information, and then starts returning one by one the compressed data to the outside query.
|
||||
If more than one *CompBuffers* are found, then their schemata are consolidated into one.
|
||||
|
||||
CompBuffer tries to avoid writing on the hard disk, by compressing in memory, the data fed
|
||||
into it and only after a threshold of 10 Mb of compressed data is reached, spilling over into the hard disk.
|
||||
|
||||
To make multiset usage transparent to the user, madIS' SQL preprocessor, inserts automatically
|
||||
the *expand* virtual table whenever a multiset producing function is met.
|
||||
To flag a row or aggregate function as a multiset one, the programmer has to set the function's attribute
|
||||
"multiset" to "True". This is done in the same way as for the "registered" function's attribute.
|
||||
|
||||
|
||||
An example of a multiset row function which produces multiple columns is::
|
||||
|
||||
mterm> select strsplit("one,two,three");
|
||||
one|two|three
|
||||
|
||||
And one which produces multiple rows is::
|
||||
|
||||
mterm> select strsplitv("one,two,three");
|
||||
one
|
||||
two
|
||||
three
|
||||
|
||||
Both of the functions above, break their input on "comma" by default.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :func:`~functions.row.formating.strsplit`
|
||||
* :func:`~functions.row.formating.strsplitv`
|
||||
|
||||
|
||||
.. _tutcache:
|
||||
|
||||
On the fly multidimensional indexing (the *cache* virtual table)
|
||||
****************************************************************
|
||||
|
||||
Working with external sources directly, has the major problem of not being able to put acceleration structures on them (indexing), unless materializing them in the form of a database table.
|
||||
Joins with external sources, in particular, are very slow, forcing the SQLite core to do multiple sequential passes on the virtual tables tied to the external sources.
|
||||
|
||||
To solve the problems above, the *cache* virtual table was created.
|
||||
The way it works is this:
|
||||
|
||||
- At the beginning it does one pass over the results of the input query, and keeps them in memory
|
||||
|
||||
- Then it negotiates with SQLite's core about what constraints and order bys, the core would like to have answered as fast as possible
|
||||
|
||||
- It builds a very fast multidimensional index based on the negotiations above
|
||||
|
||||
- It waits until the core starts sending queries on the above constraints, and returns the results using the just build multidimensional index
|
||||
|
||||
- At the end of the query it throws away the cached query's data and the multidimensional index
|
||||
|
||||
The multidimensional index is based on kd-trees and is implemented in Python, using the virtual table indexing API.
|
||||
It is a very fast to be build index, and extremely fast on answering queries involving many constraints.
|
||||
The multidimensional index is also designed to be memory efficient, needing O(number_of_dataset_rows) memory no matter the number of indexed dimensions.
|
||||
|
||||
In practice, it has been up to 10 times faster on interval joins compared to SQLite's native indexing, and as the dimensions grow in number its speed advantage becomes bigger.
|
||||
|
||||
An example of *cache* use is::
|
||||
|
||||
% cd demo
|
||||
% python mterm.py
|
||||
mterm> select country.c2, continent.c1
|
||||
from file('countries.tsv') as country,
|
||||
file('continents.tsv') as continent
|
||||
where country.c1=continent.c2;
|
||||
Aruba|Americas
|
||||
Antigua and Barbuda|Americas
|
||||
United Arab Emirates|Asia
|
||||
Afghanistan|Asia
|
||||
. . . . . . . . .
|
||||
Query executed in 0 min 2 sec 40 msec
|
||||
mterm> select country.c2, continent.c1
|
||||
from file('countries.tsv') as country,
|
||||
(CACHE file 'continents.tsv') as continent
|
||||
where country.c1=continent.c2;
|
||||
Aruba|Americas
|
||||
Antigua and Barbuda|Americas
|
||||
United Arab Emirates|Asia
|
||||
Afghanistan|Asia
|
||||
. . . . . . . . .
|
||||
Query executed in 0 min 0 sec 71 msec
|
||||
|
||||
The queries above, do a direct join on the filesystem's files "countries.tsv" and "continents.tsv" (in the "demo" path of madIS).
|
||||
The first query doesn't do any caching at all, so it is forced to do multiple sequential reads of the "continents" file, to execute the join.
|
||||
The second query, using the inverted syntax, caches the "continents" file and creates the required indexes to execute the join quickly.
|
||||
|
||||
The speed difference between the two queries is quite significant (cached version of query is 28x faster).
|
||||
For bigger datasets and more constraints the speed advantage could be even greater.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :mod:`~functions.vtable.cache`
|
||||
* :mod:`~functions.vtable.file`
|
||||
|
||||
Workflows
|
||||
*********
|
||||
|
||||
From the beginning madIS was designed for building complete data processing systems with it.
|
||||
In madIS, workflows are viewed as a series of queries to be executed sequentially.
|
||||
|
||||
The main function that implements madIS' workflow engine is :mod:`~functions.vtable.exec` virtual table::
|
||||
|
||||
mterm> select 'select 5';
|
||||
select 5
|
||||
mterm> exec select 'select 5';
|
||||
1
|
||||
|
||||
Virtual table :mod:`~functions.vtable.exec`, takes as input an SQL query, executes it and then operates on the **results** of the input query, executing them sequentially and returning "1" if all the queries executed successfully, or throwing an error if any queries failed to execute correctly.
|
||||
|
||||
This peculiar design (its a meta-meta function), enables :mod:`~functions.vtable.exec` to work in tandem with other virtual tables that feed to it the workflows to be executed.
|
||||
The most frequent combination is::
|
||||
|
||||
mterm> exec flow file 'workflow.sql';
|
||||
|
||||
What the query above does, is to open and read the "workflow.sql" filesystem file via
|
||||
the *file* virtual table, then feed its results into the *flow* virtual table
|
||||
which collects in one line the "broken into multiple lines" queries, and finally
|
||||
to feed the resulting queries to :mod:`~functions.vtable.exec` virtual table which will execute them.
|
||||
|
||||
The above combination of virtual tables presents, one the most powerful aspects of madIS.
|
||||
Namely the ability to create complex functionality (in this instance a workflow engine), by quickly combining simple entities.
|
||||
|
||||
.. note::
|
||||
Another benefit of using (or abusing) a relational database to implement a workflow engine, is that all ACID properties
|
||||
of the database are still present during the workflow processing. Unfortunately due to limitations of the SQLite core,
|
||||
transactional execution of madIS workflows isn't fully working yet (see :ref:`tutlimitations`).
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :mod:`~functions.vtable.exec`
|
||||
* :mod:`~functions.vtable.flow`
|
||||
* :mod:`~functions.vtable.file`
|
||||
|
||||
Designing and building a data processing system with madIS
|
||||
**********************************************************
|
||||
|
||||
Concerning the design of a data processing system.
|
||||
The required steps that have to be made when **designing** a data processing system with madIS are:
|
||||
|
||||
1. Define the problem you are trying to solve
|
||||
|
||||
2. Break the problem into workflows
|
||||
|
||||
3. Break the workflows into queries
|
||||
|
||||
4. Find the functions that the queries will need
|
||||
|
||||
5. Find the Python libraries that the functions will need
|
||||
|
||||
The steps above, are mostly self evident, and should be made in the order that they are presented.
|
||||
|
||||
To **build** the data processing system, the above steps have to be followed, finding/building the required entities (functions, queries), for each step, **going from bottom to top** (Step 5 to Step 2),
|
||||
|
||||
In practice we have found that there is always some overlap between the designing and building stages and between steps.
|
||||
Great care should be given, when designing, on the most difficult and time consuming step, which is step 1. When step 1 is successfully executed, the speed with which the rest of the steps are designed and following that, building them from bottom to top, is extremely fast in our experience.
|
||||
|
||||
.. note::
|
||||
|
||||
An example of a madIS workflow can be found in the :ref:`examples section <applexample>`.
|
||||
|
||||
.. _tutlimitations:
|
||||
|
||||
Limitations of madIS
|
||||
********************
|
||||
|
||||
The limitations of madIS are:
|
||||
|
||||
- Due to SQLite's inability to simultaneously use multiple CPUs to execute a query, madIS' query execution is done by only one CPU.
|
||||
This will be partially solved in the future through the use of the *map* virtual table, which will be able to execute a row function on multiple data rows in parallel.
|
||||
For more heavy processing concurrency, functions and virtual tables enabling madIS to be used on clusters are in the planning stage
|
||||
|
||||
- Due to SQLite's locking semantics, workflows inside a parent workflow, aren't in their own transactions.
|
||||
So when a child workflow fails, the whole parent transaction rolls back.
|
||||
This will be solved whenever SQLite fixes the problem where the database's system schema table is locked whenever a table is deleted
|
|
@ -0,0 +1,14 @@
|
|||
Project Documentation
|
||||
=====================
|
||||
|
||||
This page contains the Project Modules documentation.
|
||||
|
||||
Modules
|
||||
-------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
row
|
||||
aggregate
|
||||
vtable
|
|
@ -0,0 +1,12 @@
|
|||
People
|
||||
======
|
||||
|
||||
Core developers
|
||||
---------------
|
||||
- Lefteris Stamatogiannakis
|
||||
- Mei Li Triantafyllidi
|
||||
|
||||
Extensions developers
|
||||
---------------------
|
||||
- Maria Vayanou
|
||||
- Marialena Kyriakidi
|
|
@ -0,0 +1,18 @@
|
|||
Thanks
|
||||
======
|
||||
madIS project wouldn't exist without the amazing work of several other people, and the
|
||||
Open Source spirit.
|
||||
|
||||
Specifically we would like to thank:
|
||||
|
||||
- APSW's Roger Binns
|
||||
- SQLite's authors
|
||||
|
||||
In both of above projects, the work ethic and quality of their code are of an
|
||||
extremely high level. Nearly every line of their code is extensively tested.
|
||||
|
||||
In madIS we stressed the code of both of above projects as much as we could, and
|
||||
they handled it beautifully.
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
Useful notes
|
||||
*************
|
||||
|
||||
This section contains useful tips to help with understanding function usage, ease
|
||||
shell interaction and introduce some basic characteristics of the dynamic virtual tables.
|
||||
|
||||
.. _unotesexamples:
|
||||
|
||||
Understanding function examples
|
||||
===============================
|
||||
|
||||
While reading each function's description, you will notice examples like this:
|
||||
|
||||
>>> sql("select ifthenelse(1>0,'yes','no') as answer")
|
||||
answer
|
||||
------
|
||||
yes
|
||||
|
||||
Because examples also serve as tests for madIS's functions, they are coded and displayed as actual Python code. The string inside Python function "sql()" is
|
||||
an SQL query, having its results displayed in the lines following it. Query results in examples also include the column names for clarity.
|
||||
However in the interactive shell column names are not shown. In the interactive shell, the same as above example, would look like the following::
|
||||
|
||||
mterm> select ifthenelse(1>0,'yes','no') as answer;
|
||||
yes
|
||||
Query executed in 0 min. 0 sec 33 msec
|
||||
|
||||
|
||||
.. _unotesparameters:
|
||||
|
||||
Understanding function parameters
|
||||
=================================
|
||||
|
||||
**Named parameters**
|
||||
|
||||
All types of functions (row, aggregate and virtual table) can take simple or named parameters.
|
||||
For simple parameters, ordering is important and should follow function's definition. Named
|
||||
parameters can be placed anywhere in the parameters lists, with few exceptions that are clearly stated.
|
||||
Named parameters are strings (so they must be placed inside quotes) using the format *paramname:paramvalue*.
|
||||
|
||||
For example :mod:`~functions.vtable.file` function is declared as::
|
||||
|
||||
file(location[, formatting options])
|
||||
|
||||
where *location* is a simple parameter containing the file name or network resource to read from,
|
||||
and *formatting options* is a list of named parameters (eg. parameter *dialect* which accepts one of values *tsv* or *csv*).
|
||||
So using this function to import a csv file would look like this::
|
||||
|
||||
select * from file('myfile','dialect:csv');
|
||||
|
||||
By using inverted syntax (see :ref:`SQL extensions <inversion>`), the query would look like this::
|
||||
|
||||
select * from (file 'myfile' dialect:csv);
|
||||
|
||||
Notice that non named parameters must be quoted. However named parameters quoting is optional. Also parameters are separated with spaces instead of commas.
|
||||
If a space character appears in a named parameter's value field, quoting should be used.
|
||||
So importing a file that uses spaces as value delimiters, would look like following (using inverted syntax)::
|
||||
|
||||
select * from (file 'myfile' 'delimiter: ');
|
||||
|
||||
An example of a function definition which contains named parameters is :mod:`~functions.vtable.output`::
|
||||
|
||||
output(query:None, file[, formatting options])
|
||||
|
||||
The definition above states, that the function output receives the named parameter *query* which has no default value (the value following the ":" character
|
||||
of a named parameter in a functions' definition, represents the default value).
|
||||
|
||||
.. _unoteqparameter:
|
||||
|
||||
**The query parameter**
|
||||
|
||||
Named parameter *query* shown in the definition above, defines which SQL query the function *output* will execute
|
||||
and then write the query's results in the given *file*.
|
||||
When using, in inverted syntax, a function that takes a *query* parameter (see :ref:`SQL extensions <inversion>`) the *query* keyword should be omitted.
|
||||
Instead the actual query should be placed at the end of the statement. For example to output, in inverted syntax, some query's result, the following could be used::
|
||||
|
||||
output 'outfile' dialect:tsv select * from table1;
|
||||
|
||||
In non inverted syntax, this is equivalent to::
|
||||
|
||||
select * from output('query:select * from table1','outfile','dialect:tsv');
|
||||
|
||||
Inverting queries that include the *query* parameter, permits "pipelining" of many virtual table functions, while using an easy to read syntax.
|
||||
So to re-order a file and add line numbers you can do::
|
||||
|
||||
output 'outfile.csv' rowidvt select * from (file 'infile.csv') order by C2;
|
||||
|
||||
Let's look at the details of this query. :mod:`~functions.vtable.file` function reads *infile.csv* and returns the data as a table.
|
||||
Returned data are then ordered by column C2.
|
||||
The result of the query, *select \* from (file 'infile.csv') order by C2* is the *query* parameter for :mod:`~functions.vtable.rowidvt` function.
|
||||
This function adds a *rowid* column to the query result that indicates the order of the row in the result (and not in the initial table).
|
||||
The result of :mod:`~functions.vtable.rowidvt` function is forwarded into :mod:`~functions.vtable.output` which writes the result in the *outfile.csv* file.
|
||||
|
||||
|
||||
.. _unotesreturntypes:
|
||||
|
||||
Understanding function return types
|
||||
===================================
|
||||
|
||||
To understand how function return types works, make sure you understand how `SQLite types <http://www.sqlite.org/datatype3.html>`_ work.
|
||||
The return type of the row and aggregate madIS functions refers to the storage class typically returned by the function.
|
||||
Virtual table functions return a table having a static (or dynamic) schema with column names and `types affinity <http://www.sqlite.org/datatype3.html#affinity>`_.
|
||||
To clarify the difference of the returned types of row/aggregate functions and virtual table functions consider the following example::
|
||||
|
||||
mterm> select * from (select kwnum('lol') as a) where a=='1';
|
||||
Query executed in 0 min. 0 sec 17 msec
|
||||
|
||||
Here :func:`~functions.row.text.kwnum` function returns the number of keywords of the 'lol' string which is an integer.
|
||||
Although the first returned column (named *a*) is of integer type, the literal text '1' in the *where* part is not converted to an integer,
|
||||
so the condition fails. In the following example, by using the built in SQLite function *cast*, an integer type affinity
|
||||
is suggested so the text literal '1' is automatically converted to an integer and the condition is evaluated to true.
|
||||
|
||||
::
|
||||
|
||||
mterm> select * from (select cast(kwnum('lol') as int) as a) where a=='1';
|
||||
1
|
||||
Query executed in 0 min. 0 sec 21 msec
|
||||
|
||||
In conclusion, the returned values from row and aggregate functions, even :ref:`multisets <tutmultiset>` do not also imply data affinity.
|
||||
|
||||
.. note::
|
||||
|
||||
The same result could be reached using the virtual table functions, eg. :mod:`~functions.vtable.typing` or :mod:`~functions.vtable.setschema`.
|
||||
|
||||
.. _unotesshell:
|
||||
|
||||
Shell interaction
|
||||
=================
|
||||
|
||||
In madIS's interactive shell mode some helpful shell commands and functions helping with complex query composition are supported.
|
||||
These can be listed in the terminal with the *.help* command.
|
||||
|
||||
**Names function**
|
||||
|
||||
Function :mod:`~functions.vtable.names` is a virtual table function that operates over a query (See :ref:`unotesparameters`)
|
||||
and returns the column names of the query result.
|
||||
|
||||
::
|
||||
|
||||
mterm> names select * from file('test.csv','header:t') ;
|
||||
City|Region|Country|Population
|
||||
Query executed in 0 min. 0 sec 24 msec
|
||||
|
||||
Function :mod:`~functions.vtable.coltypes`, has similar functionality, additionally presenting the column's
|
||||
`type affinity <http://www.sqlite.org/datatype3.html#affinity>`_ when this information is contained in its input.
|
||||
|
||||
::
|
||||
|
||||
mterm> coltypes select * from file('/home/meili/Desktop/test.csv','header:t') ;
|
||||
City|text
|
||||
Region|text
|
||||
Country|text
|
||||
Population|text
|
||||
|
||||
|
||||
.. _unotesemptyschema:
|
||||
|
||||
Empty schema exception
|
||||
======================
|
||||
|
||||
A price to pay for using virtual tables having dynamic schema creation, is that if no data are provided, for example an empty file
|
||||
to the :mod:`~functions.vtable.file` function or
|
||||
a query that returns no rows to virtual tables that accept input *queries* (eg. :mod:`~functions.vtable.cache` function), is an exception as a result::
|
||||
|
||||
mterm> select * from (cache select 5 as a where a!=5);
|
||||
Madis SQLError: operator cache: Cannot initialise dynamic schema virtual table without data
|
||||
|
||||
To avoid this issue, especially in automatic flow execution where a flow crash is undesirable, the :mod:`~functions.vtable.setschema` function can be used.
|
||||
*Setschema* is virtual table function that enforces a given schema. In the case of non empty resultsets, it can be used to project,
|
||||
rename and typecast inner query columns, while in case of an empty resultset, it works as a static schema definition.
|
||||
::
|
||||
|
||||
mterm> select * from (setschema 'a' cache select 5 as a where a!=5);
|
||||
Query executed in 0 min. 0 sec 62 msec
|
||||
|
||||
In the example above, *cache* function has a possibility of producing an empty schema exception. Applying the *setschema* function with the desirable schema
|
||||
(column a with NONE type) this problem is avoided.
|
||||
|
||||
Other possible causes of empty schema exceptions are also :ref:`multiset <tutmultiset>` functions which are actually implemented
|
||||
through the :mod:`~functions.vtable.expand` virtual table function.
|
||||
|
||||
.. _unotesefficiencyvt:
|
||||
|
||||
Efficiency in streaming virtual tables
|
||||
======================================
|
||||
|
||||
Virtual table functions that work as streams do not need to materialise the whole input/output data streams before returning them, they can produce them on demand.
|
||||
So executing, for example a *join*, between streaming virtual tables for a huge volume of data is not a good idea, as the data will have to be re-produced
|
||||
over and over again. Using :ref:`cache <tutcache>` virtual table function on one of the *streaming* queries will significantly increase performance.
|
||||
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
Virtual table concept in madIS
|
||||
==============================
|
||||
|
||||
Virtual table can be any piece of code that returns its results as list of lists. It will be used in madSQL in the FROM part of a query.
|
||||
|
||||
Example::
|
||||
|
||||
select * from file('data.tsv');
|
||||
|
||||
In this case data are produced from external sources. Many madis virtual tables take a query as an input, execute it and returns its results transformed.
|
||||
(See :ref:`Query parameter <unoteqparameter>`). In that case the vtable "call" could be inverted in the query. (see :ref:`SQL extensions <inversion>`).
|
||||
|
||||
Example::
|
||||
|
||||
rowidvt select * from table1 limit 3;
|
||||
|
||||
|
||||
Creating a virtual table function
|
||||
----------------------------------------
|
||||
|
||||
Virtual table fuctions are the most advanced operator in madIS. Existing virtual table functions can be organized by increasing implementation complexity in three categories:
|
||||
|
||||
- Single boolean output vt functions with query input: Virtual table functions that take an input, do sth and return 1 or 0. Example table fuctions are :mod:`~functions.vtable.exec`
|
||||
|
||||
- Iterative output: Vts that take input and returns many data (iterator of list).
|
||||
Its call of the iterator retuns a list with each row data. In this category falls :mod:`~functions.vtable.file` operator, as well as :mod:`~functions.vtable.expand`, :mod:`~functions.vtable.rowidvt`, etc.
|
||||
|
||||
- Advanced: Advanced vt's that need the index capability of virtual tables. In this category falls only :mod:`~functions.vtable.cache` functions. These functions must implement virtual tables from scratch as described in
|
||||
`APSW documentation <http://apidoc.apsw.googlecode.com/hg/vtable.html>`_.
|
||||
|
||||
|
||||
All virtual table functions are created in XXXX folder. Every virtual table function must be single module.
|
||||
Detailed documentation of virtual table API could be found in `APSW documentation <http://apidoc.apsw.googlecode.com/hg/vtable.html>`_.
|
||||
In madIS there are used mostly two specific types of Virtual table functions, that helper libraries have been implemented to simplify
|
||||
their implementation.
|
||||
So implementing a virtual table function, is feasible either by following the `APSW API <http://apidoc.apsw.googlecode.com/hg/vtable.html>`_
|
||||
and adding the flags for madIS, either by using the helper libraries, as explained below.
|
||||
To continue reading, have a look to the Virtual table function API in APSW and play with toggle function and a virtual table call.
|
||||
Example::
|
||||
|
||||
mterm> toggle tracing;
|
||||
tracing is now: True
|
||||
Query executed in 0 min. 0 sec 4 msec
|
||||
|
||||
mterm> select * from (file 'data.csv');
|
||||
executetrace(u"create virtual table temp.vt_144176563 using file('data.csv','automatic_vtable:1')")
|
||||
executetrace(u'select * from (SELECT * FROM vt_144176563 );',None)
|
||||
...
|
||||
executetrace(u'drop table temp.vt_144176563;')
|
||||
Query executed in 0 min. 0 sec 14 msec
|
||||
|
||||
mterm> toggle vtdebug;
|
||||
executetrace(u"SELECT toggle('vtdebug');",None)
|
||||
vtdebug is now: True
|
||||
Query executed in 0 min. 0 sec 4 msec
|
||||
|
||||
mterm> select * from (file 'data.csv');
|
||||
....
|
||||
|
||||
Toggle is a row function that toggles the value of :ref:`madIS global settings<>`
|
||||
|
||||
Important flags for madIS VT functions
|
||||
--------------------------------------
|
||||
|
||||
registered=True # set this flag to register in madis the function, if set to false the module is not loaded.
|
||||
|
||||
external_stream=True # Set this flag if no query parameter can be used.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Impementing single boolean output virtual table function
|
||||
--------------------------------------------------------
|
||||
|
||||
The
|
||||
|
||||
def function()
|
||||
from madis.vtout import SourceNtoOne
|
||||
|
||||
class SourceNtoOne:
|
||||
def __init__(self,func,boolargs=None,nonstringargs=None,needsescape=None,notsplit=None,connectionhandler=False,retalways=False):
|
||||
|
||||
|
||||
To create iterative VT's the madIS vtiterable could be used that hide some of the implementation details, or it can be build from scratch as in APSW, documentation. (http://apsw.googlecode.com/svn/publish/vtable.html) If vtiterable is not used, no standard parameter parsing will be available.
|
||||
|
||||
MUST BE SET TO USE VT in madis:
|
||||
One VT - one file in vtable folder
|
||||
registered=True ( as in all operators)
|
||||
external_stream=True (if the operator does not accept query parameter)
|
||||
|
||||
Source function must be implemented!!
|
||||
|
||||
|
||||
|
||||
::
|
||||
|
||||
#Cursor Iterator
|
||||
|
||||
class TableCursor: # INTERFACE
|
||||
def __init__(self): # when called for first time, it must probably identify the schema, if it is not dynamic
|
||||
pass
|
||||
def __iter__(self):
|
||||
pass
|
||||
def next(self):
|
||||
pass
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
::
|
||||
|
||||
|
||||
class TableVT: #INTERFACE
|
||||
|
||||
def __init__(self,envdict,largs,dictargs): #DO NOT DO ANYTHING HEAVY it, will be called before querying the table
|
||||
pass
|
||||
|
||||
def getdescription(self):
|
||||
"""
|
||||
must return a list of tuples (column name, columntype), if type not available leave it empty or None eg.(col,)
|
||||
example:
|
||||
[('column1','int'),('column2',),('column3','text')]
|
||||
"""
|
||||
return schemalist
|
||||
|
||||
def open(self):
|
||||
"""
|
||||
After the first time it is called getdescription function must return table instance schema
|
||||
Must returns VT cursor
|
||||
"""
|
||||
return TableCursor()
|
||||
|
||||
def destroy(self): # Called when Table instance is destroyed (on drop statement), OPTIONAL
|
||||
pass
|
||||
|
||||
.. function:: TableVT.__init__(self,envdict,largs,dictargs)
|
||||
|
||||
Parameters:
|
||||
|
||||
:envdict:
|
||||
Dictionary with enviromental variables (correspond to APSW parameters of VTModule.Create)
|
||||
:tablename: name of the table that will be created.
|
||||
:db: instance of the connection to the database
|
||||
:dbname: database name
|
||||
:modulename: The string name under which the module was registered???????
|
||||
|
||||
:largs: table function list arguments
|
||||
|
||||
:dictargs: dictionary table function named arguments eg. type:int -> dictargs['type']='int'
|
||||
|
||||
|
||||
|
||||
def Source():
|
||||
return SourceVT(TableVT,boolargs,nonstringargs,needsescape,notsplit)
|
||||
|
||||
class SourceVT:
|
||||
def __init__(self,table,boolargs=None,nonstringargs=None,needsescape=None,staticschema=False,notsplit=None):
|
||||
|
||||
.. params:
|
||||
|
||||
Parameters
|
||||
|
||||
:table: Class implementing TableVT interface
|
||||
:boolargs: List of parameter names that will be chnged to True/False if they are accordingly t/f
|
||||
:nonstringargs: Dictionary of parameter names that will be tranformed according to their value , eg. string input to dialect object {'dialect':{'line':line(),'tsv':tsv(),'csv':defaultcsv()}}
|
||||
:needsescape: List of parameter names that that include escape sequences eg. \n, \t etc.
|
||||
:staticschema: True if TableVT.open does not need to be executed before getdescription can be called
|
||||
:notsplit: List of parameter names that should not be splitted in named parameters eg. ['http'] for do not splitting http://server.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
executing madSQL workflow
|
||||
|
||||
logging on workflows
|
||||
flowname
|
||||
|
||||
variables in workflows
|
||||
|
||||
passing variable in new workflow execution
|
||||
|
||||
Transcactions in workflows
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
-- This is a simple example of bulk harvesting an OAI-PMH service. The data are then converted from XML to a single relational table.
|
||||
-- Due to the extreme slowness and unreliability of OAI-PMH protocol, we first fetch all data into a plain text file. If the transmission breaks, you should continue the transfer on a different file (e.g. 'rawdata1.txt'), so as to no overwrite previously fetched data.
|
||||
|
||||
output 'rawdata.txt' select * from (oaiget metadataPrefix:oai_dc 'http://citeseerx.ist.psu.edu/oai2');
|
||||
|
||||
-- After fetching all of the above 'rawdataX' files, concatenate them into a single one ('rawdata.txt').
|
||||
|
||||
|
||||
-- We then want to find out which XML keys the 'rawdata' file contains. We restrict our key search to keys under "record".
|
||||
|
||||
select jgroupunion(jdictkeys(c1)) from (xmlparse root:record fast:1 file 'rawdata.txt.gz');
|
||||
|
||||
-- ["record/header/identifier","record/header/datestamp","record/metadata/dc/@/schemalocation","record/metadata/dc/title","record/metadata/dc/creator","record/metadata/dc/subject","record/metadata/dc/description","record/metadata/dc/contributor","record/metadata/dc/publisher","record/metadata/dc/date","record/metadata/dc/format","record/metadata/dc/type","record/metadata/dc/identifier","record/metadata/dc/source","record/metadata/dc/language","record/metadata/dc/relation","record/metadata/dc/rights"]
|
||||
|
||||
|
||||
-- Finally we create the "article" table using the keys from above that interest us
|
||||
|
||||
create table article as
|
||||
select regexpr(':([^:]*)$', header_identifier) as header_identifier, header_datestamp, metadata_dc_schemalocation, metadata_dc_title, metadata_dc_creator, metadata_dc_subject, metadata_dc_description, metadata_dc_contributor, metadata_dc_publisher, metadata_dc_date, metadata_dc_format, metadata_dc_type, metadata_dc_identifier, metadata_dc_source, metadata_dc_language, metadata_dc_relation, metadata_dc_rights
|
||||
from (
|
||||
xmlparse strict:0 '["record/header/identifier","record/header/datestamp","record/metadata/dc/@/schemalocation","record/metadata/dc/title","record/metadata/dc/creator","record/metadata/dc/subject","record/metadata/dc/description","record/metadata/dc/contributor","record/metadata/dc/publisher","record/metadata/dc/date","record/metadata/dc/format","record/metadata/dc/type","record/metadata/dc/identifier","record/metadata/dc/source","record/metadata/dc/language","record/metadata/dc/relation","record/metadata/dc/rights"]'
|
||||
file 'rawdata.txt' );
|
|
@ -0,0 +1,85 @@
|
|||
-- First of all download http://dblp.uni-trier.de/xml/dblp.xml.gz
|
||||
|
||||
-- To find the XML keys inside above XML and under the "article" tag, execute.
|
||||
|
||||
select jgroupunion(jdictkeys(c1)) from (xmlparse root:article fast:1 file 'dblp.xml.gz');
|
||||
|
||||
-- ["article/@/mdate","article/@/key","article/author","article/title/*","article/journal","article/volume","article/month","article/year","article/cdrom","article/ee","article/url","article/@/publtype","article/editor","article/publisher","article/pages","article/number","article/cite","article/cite/@/label","article/crossref","article/booktitle","article/note","article/@/rating","article/@/reviewid"]
|
||||
|
||||
-- We do the same for "www" and "inproceedings" tags.
|
||||
|
||||
select jgroupunion(jdictkeys(c1)) from (xmlparse root:www fast:1 file 'dblp.gz');
|
||||
|
||||
--["www/@/mdate","www/@/key","www/author","www/title","www/year","www/url","www/editor","www/booktitle","www/note","www/crossref","www/cite","www/ee","www/note/@/type","www/author/@/bibtex"]
|
||||
|
||||
select jgroupunion(jdictkeys(c1)) from (xmlparse root:inproceedings fast:1 file 'dblp.xml.gz');
|
||||
|
||||
--["inproceedings/@/mdate","inproceedings/@/key","inproceedings/author","inproceedings/title/*","inproceedings/pages","inproceedings/year","inproceedings/booktitle","inproceedings/month","inproceedings/url","inproceedings/note","inproceedings/cdrom","inproceedings/ee","inproceedings/crossref","inproceedings/cite","inproceedings/editor","inproceedings/cite/@/label","inproceedings/@/publtype","inproceedings/number"]
|
||||
|
||||
-- We create the article, www and inproceedings tables.
|
||||
|
||||
create table article as
|
||||
select * from (
|
||||
xmlparse '["article/@/mdate","article/@/key","article/author","article/title/*","article/journal","article/volume","article/month","article/year","article/cdrom","article/ee","article/url","article/@/publtype","article/editor","article/publisher","article/pages","article/number","article/cite","article/cite/@/label","article/crossref","article/booktitle","article/note","article/@/rating","article/@/reviewid"]' fast:1 file 'dblp.xml.gz' );
|
||||
|
||||
create table www as select * from (xmlparse '["www/@/mdate","www/@/key","www/author","www/title","www/year","www/url","www/editor","www/booktitle","www/note","www/crossref","www/cite","www/ee","www/note/@/type","www/author/@/bibtex"]' fast:1 file 'dblp.xml.gz');
|
||||
|
||||
create table inproceedings as select * from (xmlparse '["inproceedings/@/mdate","inproceedings/@/key","inproceedings/author","inproceedings/title/*","inproceedings/pages","inproceedings/year","inproceedings/booktitle","inproceedings/month","inproceedings/url","inproceedings/note","inproceedings/cdrom","inproceedings/ee","inproceedings/crossref","inproceedings/cite","inproceedings/editor","inproceedings/cite/@/label","inproceedings/@/publtype","inproceedings/number"]' fast:1 file 'dblp.xml.gz');
|
||||
|
||||
-- Lets say that we want to find the author tenure dates from the data. We'll do it by using a heuristic method, where the "oldest" author among a paper's author list is considered to be the "professor". Please NOTE that the used heuristic is very unreliable.
|
||||
|
||||
-- We start by creating a table that will contain author and his publication years.
|
||||
|
||||
create table authorpubyear as select jsplitv(t2j(author)) as author, year from article;
|
||||
|
||||
-- From author's publications we find the oldest one.
|
||||
|
||||
create table authorminyear as select author,min(year) as year from authorpubyear group by author;
|
||||
|
||||
create index idxauthorminyear on authorminyear(author);
|
||||
|
||||
-- For articles that have multiple authors (XMLPARSE uses TAB for multiple values on the same key, this is why we use "like '%TAB%'" below), find their minyear and select the author having the minimum minyear among them.
|
||||
|
||||
create table professors as
|
||||
select minrow(myear,author) as pauthor,pyear from (
|
||||
select
|
||||
key,
|
||||
author,
|
||||
(select authorminyear.year from authorminyear where authorminyear.author=a.author) as myear,
|
||||
pyear
|
||||
from
|
||||
(select key,jsplitv(t2j(author)) as author,year as pyear from article where author like '% %') as a
|
||||
) group by key;
|
||||
|
||||
-- We assume that the first time that an author appeared as a professor in a paper, is his tenure year.
|
||||
|
||||
create table tenures as select pauthor,min(pyear) as tyear from professors group by pauthor;
|
||||
|
||||
-- Now, lets calculate some other statistics.
|
||||
|
||||
-- Number of per author publications before tenure
|
||||
select pauthor,count(year) from authorpubyear, tenures where authorpubyear.author=tenures.pauthor and authorpubyear.year<tenures.tyear group by pauthor;
|
||||
|
||||
-- Distribution of number of publications before tenure
|
||||
select btyear,count(btyear) from (select pauthor,count(year) as btyear from authorpubyear, tenures where authorpubyear.author=tenures.pauthor and authorpubyear.year<tenures.tyear group by pauthor) group by btyear;
|
||||
|
||||
-- Top 100 number of coauthors per author
|
||||
select author1, coauths from (select author1, count(distinct author2) as coauths from (select jpermutations(t2j(author),2) as author from article where author like '% %') group by author1) order by coauths desc limit 100;
|
||||
|
||||
|
||||
-- And run 5 steps of the PageRank algorithm on the graph created from author paper collaborations.
|
||||
|
||||
--Authorank
|
||||
create table authorlinks as select distinct * from (select jpermutations(t2j(author),2) as author from article where author like '% %');
|
||||
create index idxauthor1 on authorlinks(author1);
|
||||
|
||||
create table authorank as select author, 1.0 as rank,(select count(author1) from authorlinks where author1=author) as linkcount from (select distinct(author1) as author from authorlinks);
|
||||
create index idxauthorank on authorank(author);
|
||||
|
||||
update authorank set rank=1.0;
|
||||
update authorank set rank=0.15+0.85*(select sum(rank/linkcount) from authorlinks al,authorank ar where al.author2=ar.author and al.author1=authorank.author);
|
||||
update authorank set rank=0.15+0.85*(select sum(rank/linkcount) from authorlinks al,authorank ar where al.author2=ar.author and al.author1=authorank.author);
|
||||
update authorank set rank=0.15+0.85*(select sum(rank/linkcount) from authorlinks al,authorank ar where al.author2=ar.author and al.author1=authorank.author);
|
||||
update authorank set rank=0.15+0.85*(select sum(rank/linkcount) from authorlinks al,authorank ar where al.author2=ar.author and al.author1=authorank.author);
|
||||
update authorank set rank=0.15+0.85*(select sum(rank/linkcount) from authorlinks al,authorank ar where al.author2=ar.author and al.author1=authorank.author);
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
-- This is a simple example of harvesting Greek government decisions data from http://opendata.diavgeia.gov.gr/
|
||||
|
||||
-- First of all put file diavgeiaget.py in functionslocal/vtable/
|
||||
|
||||
-- Following query fetches the data
|
||||
|
||||
output 'rawdata.txt' select * from (diavgeiaget);
|
||||
|
||||
-- If the transmission breaks (it happens very often) then continue by using
|
||||
-- output 'rawdataY.txt' select * from (diavgeiaget datefrom:DD-MM-YYYY);
|
||||
-- where Y is an increasing number (so as to not overwrite previously fetched data), and you can get DD-MM-YYYY from the last <ns3:submissionTimestamp>YYYY-MM-DD....</ns3:submissionTimestamp> field in the data you've recieved
|
||||
|
||||
-- After fetching all of the above 'rawdataY' files, concatenate them into a single one ('rawdata.txt').
|
||||
|
||||
|
||||
-- We then want to find out which XML keys the 'rawdata' file contains. We restrict our key search to keys under "decisionexpanded".
|
||||
|
||||
select jgroupunion(jdictkeys(c1)) from (xmlparse root:decisionexpanded select utf8clean(c1) from (file 'rawdata.txt'));
|
||||
|
||||
-- ["decisions/decisionexpanded/ada","decisions/decisionexpanded/submissiontimestamp","decisions/decisionexpanded/metadata/protocolnumber","decisions/decisionexpanded/metadata/date","decisions/decisionexpanded/metadata/subject","decisions/decisionexpanded/metadata/organization/@/uid","decisions/decisionexpanded/metadata/organization/label","decisions/decisionexpanded/metadata/organization/latinname","decisions/decisionexpanded/metadata/organizationunit/@/uid","decisions/decisionexpanded/metadata/organizationunit/label","decisions/decisionexpanded/metadata/decisiontype/@/uid","decisions/decisionexpanded/metadata/decisiontype/label","decisions/decisionexpanded/metadata/tags/tag/@/uid","decisions/decisionexpanded/metadata/tags/tag/label","decisions/decisionexpanded/metadata/relativefek/issue","decisions/decisionexpanded/metadata/relativefek/year","decisions/decisionexpanded/url","decisions/decisionexpanded/documenturl","decisions/decisionexpanded/metadata/relativefek/feknumber","decisions/decisionexpanded/metadata/extrafields/extrafield/@/name","decisions/decisionexpanded/metadata/extrafields/extrafield/label","decisions/decisionexpanded/metadata/extrafields/extrafield/value","decisions/decisionexpanded/metadata/tags/tag/@/nil","decisions/decisionexpanded/metadata/iscorrectedbyada","decisions/decisionexpanded/metadata/relativeada","decisions/decisionexpanded/metadata/organization/units/unit/@/uid","decisions/decisionexpanded/metadata/organization/units/unit/label","decisions/decisionexpanded/metadata/iscorrectionofada"]
|
||||
|
||||
|
||||
-- We then create the "decisions" table using the keys from above that interest us
|
||||
|
||||
create table decisions as
|
||||
select * from (
|
||||
xmlparse '["decisionexpanded/ada","decisionexpanded/submissiontimestamp","decisionexpanded/metadata/protocolnumber","decisionexpanded/metadata/date","decisionexpanded/metadata/subject","decisionexpanded/metadata/organization/@/uid","decisionexpanded/metadata/organization/label","decisionexpanded/metadata/organization/latinname","decisionexpanded/metadata/organizationunit/@/uid","decisionexpanded/metadata/organizationunit/label","decisionexpanded/metadata/decisiontype/@/uid","decisionexpanded/metadata/decisiontype/label","decisionexpanded/metadata/tags/tag/@/uid","decisionexpanded/metadata/tags/tag/label","decisionexpanded/metadata/relativefek/issue","decisionexpanded/metadata/relativefek/year","decisionexpanded/url","decisionexpanded/documenturl","decisionexpanded/metadata/relativefek/feknumber","decisionexpanded/metadata/extrafields/extrafield/@/name","decisionexpanded/metadata/extrafields/extrafield/label","decisionexpanded/metadata/extrafields/extrafield/value","decisionexpanded/metadata/tags/tag/@/nil","decisionexpanded/metadata/iscorrectedbyada","decisionexpanded/metadata/relativeada","decisionexpanded/metadata/organization/units/unit/@/uid","decisionexpanded/metadata/organization/units/unit/label","decisionexpanded/metadata/iscorrectionofada"]'
|
||||
select utf8clean(c1) from
|
||||
(file 'rawdata.txt')
|
||||
);
|
||||
|
||||
|
||||
-- Finally we delete the duplicate ada (decision ids)
|
||||
|
||||
delete from decisions where rowid not in (
|
||||
select rowid from decisions group by ada
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
"""
|
||||
.. function:: diavgeiaget(url, verb, metadataPrefix,...)
|
||||
|
||||
Fetches data from an OAIPMH service, using resumption tokens to fetch large datasets.
|
||||
|
||||
- If no *verb* is provided then *verb* is assumed to be 'ListRecords'.
|
||||
- If no *metadataPrefix* is provided then *verb* is assumed to be 'ListMetadataFormats', which will list
|
||||
all metadata formats.
|
||||
|
||||
:Returned table schema:
|
||||
Column C1 as text
|
||||
|
||||
Examples:
|
||||
|
||||
>>> sql("select * from diavgeiaget('verb:ListRecords', 'metadataPrefix:ctxo')") # doctest:+ELLIPSIS +NORMALIZE_WHITESPACE
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
OperatorError: Madis SQLError:
|
||||
Operator OAIGET: An OAIPMH URL should be provided
|
||||
|
||||
>>> sql("select * from (diavgeiaget verb:ListRecords metadataPrefix:ctxo 'http://oaiurl' )") # doctest:+ELLIPSIS +NORMALIZE_WHITESPACE
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
OperatorError: Madis SQLError:
|
||||
Operator OAIGET: <urlopen error [Errno -2] Name or service not known>
|
||||
|
||||
"""
|
||||
from functions.vtable import vtbase
|
||||
import functions
|
||||
import time
|
||||
|
||||
registered=True
|
||||
external_stream=True
|
||||
|
||||
class diavgeiaget(vtbase.VT):
|
||||
def VTiter(self, *parsedArgs, **envars):
|
||||
|
||||
def buildURL(baseurl, opts):
|
||||
return '?'.join([ baseurl, '&'.join([x+'='+unicode(y) for x,y in opts if y!=None]) ])
|
||||
|
||||
import urllib2
|
||||
import re
|
||||
|
||||
opts= self.full_parse(parsedArgs)[1]
|
||||
|
||||
yield ('c1', 'text')
|
||||
|
||||
if 'datefrom' not in opts:
|
||||
opts['datefrom']='01-01-1000'
|
||||
if 'output' not in opts:
|
||||
opts['output']='full'
|
||||
if 'order' not in opts:
|
||||
opts['order']='asc'
|
||||
if 'http' not in opts:
|
||||
opts['http']='//opendata.diavgeia.gov.gr/api/decisions'
|
||||
|
||||
baseurl='http:'+opts['http']
|
||||
|
||||
findcount=re.compile(r"""<count>[^\d]*?(\d+)[^\d]*?</count>""", re.DOTALL| re.UNICODE)
|
||||
findtotal=re.compile(r"""<total>[^\d]*?(\d+)[^\d]*?</total>""", re.DOTALL| re.UNICODE)
|
||||
findfrom=re.compile(r"""<from>[^\d]*?(\d+)[^\d]*?</from>""", re.DOTALL| re.UNICODE)
|
||||
|
||||
count=total=fromv=lastfromv=None
|
||||
firsttime=True
|
||||
|
||||
del(opts['http'])
|
||||
opts=list(opts.iteritems())
|
||||
url=buildURL(baseurl, opts)
|
||||
|
||||
def buildopener():
|
||||
o = urllib2.build_opener()
|
||||
o.addheaders = [
|
||||
('Accept', '*/*'),
|
||||
('Connection', 'Keep-Alive'),
|
||||
('Content-type', 'text/xml')
|
||||
]
|
||||
return o
|
||||
|
||||
opener=buildopener()
|
||||
|
||||
errorcount=0
|
||||
while True:
|
||||
try:
|
||||
for i in opener.open( url, timeout=1200 ):
|
||||
if count==None:
|
||||
t=findcount.search(i)
|
||||
if t:
|
||||
count=int(t.groups()[0])
|
||||
if total==None:
|
||||
t=findtotal.search(i)
|
||||
if t:
|
||||
errorcount=0
|
||||
total=int(t.groups()[0])
|
||||
if fromv==None:
|
||||
t=findfrom.search(i)
|
||||
if t:
|
||||
errorcount=0
|
||||
fromv=int(t.groups()[0])
|
||||
yield (unicode(i.rstrip("\n"), 'utf-8'),)
|
||||
if count==None or total==None or fromv==None:
|
||||
break
|
||||
fromv=fromv+count
|
||||
if fromv>total:
|
||||
break
|
||||
url=buildURL(baseurl, opts+[('from', fromv)])
|
||||
lastfromv=fromv
|
||||
count=total=fromv=None
|
||||
firsttime=False
|
||||
except Exception,e:
|
||||
if errorcount<10 and not firsttime:
|
||||
time.sleep(2**errorcount)
|
||||
errorcount+=1
|
||||
else:
|
||||
if lastfromv==None:
|
||||
raise functions.OperatorError(__name__.rsplit('.')[-1], e)
|
||||
else:
|
||||
raise functions.OperatorError(__name__.rsplit('.')[-1], str(e)+'\n'+'To continue, use the following "from" parameter:\n'+str(lastfromv))
|
||||
|
||||
def Source():
|
||||
return vtbase.VTGenerator(diavgeiaget)
|
||||
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
Inside the subdirectories you'll find madIS' usage examples.
|
||||
|
||||
To execute the examples you'll need to enter inside a subdirectory and start
|
||||
mterm with a database name argument:
|
||||
|
||||
> cd dblp
|
||||
> mterm dblp.db
|
||||
|
||||
You can execute the entirety of a particular SQL flow by using:
|
||||
|
||||
exec flow file 'dblp.sql';
|
||||
|
||||
Or by opening "dblp.sql" in a text editor and copy pasting one by one the
|
||||
SQL commands, from text editor's window into mterm's window.
|
||||
|
||||
To optimize the resulting database, it is best to execute (inside mterm) the
|
||||
following SQLite pragmas as soon as you open mterm, and before executing any
|
||||
other SQL query:
|
||||
|
||||
pragma page_size = 16384;
|
||||
pragma default_cache_size = 10000;
|
||||
pragma journal_mode = PERSIST;
|
||||
pragma journal_size_limit = 10000000;
|
||||
pragma legacy_file_format = false;
|
||||
pragma synchronous = 1;
|
||||
pragma auto_vacuum = 2;
|
||||
|
||||
Above pragmas optimize SQLite's default options for analytic (bulk/OLAP) SQL queries.
|
||||
|
|
@ -0,0 +1,612 @@
|
|||
"""functions
|
||||
"""
|
||||
VERSION = "1.9"
|
||||
|
||||
import setpath
|
||||
import os.path
|
||||
import os
|
||||
import apsw
|
||||
import sqltransform
|
||||
import traceback
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
import copy
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
# Python 2.6
|
||||
from lib.collections26 import OrderedDict
|
||||
|
||||
try:
|
||||
from inspect import isgeneratorfunction
|
||||
except ImportError:
|
||||
# Python < 2.6
|
||||
def isgeneratorfunction(obj):
|
||||
return bool((inspect.isfunction(object) or inspect.ismethod(object)) and
|
||||
obj.func_code.co_flags & CO_GENERATOR)
|
||||
|
||||
sys.setcheckinterval(1000)
|
||||
|
||||
sqlite_version = apsw.sqlitelibversion()
|
||||
apsw_version = apsw.apswversion()
|
||||
|
||||
VTCREATE = 'create virtual table temp.'
|
||||
SQLITEAFTER3711 = False
|
||||
SQLITEAFTER380 = False
|
||||
sqlite_version_split = [int(x) for x in sqlite_version.split('.')]
|
||||
|
||||
if sqlite_version_split[0:3] >= [3,8,0]:
|
||||
SQLITEAFTER380 = True
|
||||
|
||||
try:
|
||||
if sqlite_version_split[0:3] >= [3,7,11]:
|
||||
VTCREATE = 'create virtual table if not exists temp.'
|
||||
SQLITEAFTER3711 = True
|
||||
except Exception, e:
|
||||
VTCREATE = 'create virtual table if not exists temp.'
|
||||
SQLITEAFTER3711 = True
|
||||
|
||||
firstimport=True
|
||||
test_connection = None
|
||||
|
||||
settings={
|
||||
'tracing':False,
|
||||
'vtdebug':False,
|
||||
'logging':False,
|
||||
'syspath':str(os.path.abspath(os.path.expandvars(os.path.expanduser(os.path.normcase(sys.path[0])))))
|
||||
}
|
||||
|
||||
functions = {'row': {}, 'aggregate': {}, 'vtable': {}}
|
||||
multiset_functions = {}
|
||||
iterheader = 'ITER'+chr(30)
|
||||
|
||||
variables = lambda _: _
|
||||
variables.flowname = ''
|
||||
variables.execdb = None
|
||||
variables.filename = ''
|
||||
|
||||
privatevars=lambda _: _
|
||||
|
||||
rowfuncs=lambda _: _
|
||||
|
||||
oldexecdb=-1
|
||||
|
||||
ExecutionCompleteError = apsw.ExecutionCompleteError
|
||||
|
||||
def getvar(name):
|
||||
return variables.__dict__[name]
|
||||
|
||||
def setvar(name, value):
|
||||
variables.__dict__[name] = value
|
||||
|
||||
def mstr(s):
|
||||
if s==None:
|
||||
return None
|
||||
|
||||
try:
|
||||
return unicode(s, 'utf-8', errors='replace')
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
# Parse exceptions that cannot be converted by unicode above
|
||||
try:
|
||||
return str(s)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
pass
|
||||
|
||||
o=repr(s)
|
||||
if (o[0:2]=="u'" and o[-1]=="'") or (o[0:2]=='u"' and o[-1]=='"'):
|
||||
o=o[2:-1]
|
||||
elif (o[0]=="'" and o[-1]=="'") or (o[0]=='"' and o[-1]=='"'):
|
||||
o=o[1:-1]
|
||||
o=o.replace('''\\n''','\n')
|
||||
o=o.replace('''\\t''','\t')
|
||||
return o
|
||||
|
||||
class MadisError(Exception):
|
||||
def __init__(self,msg):
|
||||
self.msg=mstr(msg)
|
||||
def __str__(self):
|
||||
merrormsg="Madis SQLError: \n"
|
||||
if self.msg.startswith(merrormsg):
|
||||
return self.msg
|
||||
else:
|
||||
return merrormsg+self.msg
|
||||
|
||||
class OperatorError(MadisError):
|
||||
def __init__(self,opname,msg):
|
||||
self.msg="Operator %s: %s" %(mstr(opname.upper()),mstr(msg))
|
||||
|
||||
class DynamicSchemaWithEmptyResultError(MadisError):
|
||||
def __init__(self,opname):
|
||||
self.msg="Operator %s: Cannot initialize dynamic schema virtual table without data" %(mstr(opname.upper()))
|
||||
|
||||
def echofunctionmember(func):
|
||||
def wrapper(*args, **kw):
|
||||
if settings['tracing']:
|
||||
if settings['logging']:
|
||||
try:
|
||||
lg = logging.LoggerAdapter(logging.getLogger(__name__),{ "flowname" : variables.flowname })
|
||||
if hasattr(lg.logger.parent.handlers[0],'baseFilename'):
|
||||
lg.info("%s(%s)" %(func.__name__,','.join(list([repr(el) for el in args[1:]])+["%s=%s" %(k,repr(v)) for k,v in kw.items()])))
|
||||
except Exception:
|
||||
pass
|
||||
print "%s(%s)" %(func.__name__,','.join(list([repr(el)[:200]+('' if len(repr(el))<=200 else '...') for el in args[1:]])+["%s=%s" %(k,repr(v)) for k,v in kw.items()]))
|
||||
return func(*args, **kw)
|
||||
return wrapper
|
||||
|
||||
def iterwrapper(con, func, *args):
|
||||
global iterheader
|
||||
i=func(*args)
|
||||
si=iterheader+str(i)
|
||||
con.openiters[si]=i
|
||||
return buffer(si)
|
||||
|
||||
def iterwrapperaggr(con, func, self):
|
||||
global iterheader
|
||||
i=func(self)
|
||||
si=iterheader+str(i)
|
||||
con.openiters[si]=i
|
||||
return buffer(si)
|
||||
|
||||
class Cursor(object):
|
||||
def __init__(self,w):
|
||||
self.__wrapped=w
|
||||
self.__vtables=[]
|
||||
self.__permanentvtables=OrderedDict()
|
||||
self.__query = ''
|
||||
self.__initialised=True #this should be last in init
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if self.__dict__.has_key(attr):
|
||||
return self.__dict__[attr]
|
||||
return getattr(self.__wrapped, attr)
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
if self.__dict__.has_key(attr):
|
||||
return object.__setattr__(self, attr, value)
|
||||
if not self.__dict__.has_key('_Cursor__initialised'): # this test allows attributes to be set in the __init__ method
|
||||
return object.__setattr__(self, attr, value)
|
||||
return setattr(self.__wrapped, attr, value)
|
||||
|
||||
@echofunctionmember
|
||||
def executetrace(self,statements,bindings=None):
|
||||
try:
|
||||
return self.__wrapped.execute(statements,bindings)
|
||||
except Exception, e:
|
||||
try: # avoid masking exception in recover statements
|
||||
raise e, None, sys.exc_info()[2]
|
||||
finally:
|
||||
try:
|
||||
self.cleanupvts()
|
||||
except:
|
||||
pass
|
||||
|
||||
def execute(self,statements,bindings=None,parse=True, localbindings=None): # overload execute statement
|
||||
if localbindings!=None:
|
||||
bindings=localbindings
|
||||
else:
|
||||
if bindings==None:
|
||||
bindings=variables.__dict__
|
||||
else:
|
||||
if type(bindings) is dict:
|
||||
bindings.update(variables.__dict__)
|
||||
|
||||
if not parse:
|
||||
self.__query = statements
|
||||
return self.executetrace(statements,bindings)
|
||||
|
||||
svts=sqltransform.transform(statements, multiset_functions.keys(), functions['vtable'], functions['row'].keys(), substitute=functions['row']['subst'])
|
||||
s=svts[0]
|
||||
try:
|
||||
if self.__vtables != []:
|
||||
self.executetrace(''.join(['drop table ' + 'temp.'+x +';' for x in reversed(self.__vtables)]))
|
||||
self.__vtables = []
|
||||
for i in svts[1]:
|
||||
createvirtualsql=None
|
||||
if re.match(r'\s*$', i[2]) is None:
|
||||
sep=','
|
||||
else:
|
||||
sep=''
|
||||
createvirtualsql = VTCREATE+i[0]+ ' using ' + i[1] + "(" + i[2] + sep + "'automatic_vtable:1'" +")"
|
||||
try:
|
||||
self.executetrace(createvirtualsql)
|
||||
except Exception, e:
|
||||
strex = mstr(e)
|
||||
if SQLITEAFTER3711 or type(e) != apsw.SQLError or strex.find('already exists')==-1 or strex.find(i[0])==-1:
|
||||
raise e, None, sys.exc_info()[2]
|
||||
else:
|
||||
self.__permanentvtables[i[0]]=createvirtualsql
|
||||
|
||||
if len(i)==4:
|
||||
self.__permanentvtables[i[0]]=createvirtualsql
|
||||
else:
|
||||
self.__vtables.append(i[0])
|
||||
self.__query = s
|
||||
return self.executetrace(s, bindings)
|
||||
except Exception, e:
|
||||
if settings['tracing']:
|
||||
traceback.print_exc(limit=sys.getrecursionlimit())
|
||||
try: # avoid masking exception in recover statements
|
||||
raise e, None, sys.exc_info()[2]
|
||||
finally:
|
||||
try:
|
||||
self.cleanupvts()
|
||||
except:
|
||||
pass
|
||||
|
||||
def getdescriptionsafe(self):
|
||||
try:
|
||||
# Try to get the schema the normal way
|
||||
schema = self.__wrapped.getdescription()
|
||||
except apsw.ExecutionCompleteError:
|
||||
# Else create a tempview and query the view
|
||||
if not self.__query.strip().lower().startswith('select'):
|
||||
raise apsw.ExecutionCompleteError
|
||||
try:
|
||||
list(self.executetrace('create temp view temp.___schemaview as '+ self.__query + ';'))
|
||||
schema = [(x[1], x[2]) for x in list(self.executetrace('pragma table_info(___schemaview);'))]
|
||||
list(self.executetrace('drop view temp.___schemaview;'))
|
||||
except Exception, e:
|
||||
raise apsw.ExecutionCompleteError
|
||||
|
||||
return schema
|
||||
|
||||
def close(self, force=False):
|
||||
self.cleanupvts()
|
||||
return self.__wrapped.close(force)
|
||||
|
||||
def cleanupvts(self):
|
||||
if self.__vtables!=[]:
|
||||
for t in reversed(self.__vtables):
|
||||
self.executetrace('drop table if exists ' + 'temp.'+t)
|
||||
self.__vtables=[]
|
||||
|
||||
|
||||
class Connection(apsw.Connection):
|
||||
def cursor(self):
|
||||
if 'registered' not in self.__dict__:
|
||||
self.registered=True
|
||||
register(self)
|
||||
self.openiters = {}
|
||||
|
||||
return Cursor(apsw.Connection.cursor(self))
|
||||
|
||||
def queryplan(self, statements, bindings=None, parse=True, localbindings=None):
|
||||
def authorizer(operation, paramone, paramtwo, databasename, triggerorview):
|
||||
"""Called when each operation is prepared. We can return SQLITE_OK, SQLITE_DENY or SQLITE_IGNORE"""
|
||||
# find the operation name
|
||||
plan.append([apsw.mapping_authorizer_function[operation], paramone, paramtwo, databasename, triggerorview])
|
||||
return apsw.SQLITE_OK
|
||||
|
||||
def buststatementcache():
|
||||
c = self.cursor()
|
||||
for i in xrange(110):
|
||||
a = list(c.execute("select "+str(i)))
|
||||
|
||||
plan = []
|
||||
|
||||
buststatementcache()
|
||||
|
||||
cursor = self.cursor()
|
||||
|
||||
cursor.setexectrace(lambda v1, v2, v3: apsw.SQLITE_DENY)
|
||||
|
||||
self.setauthorizer(authorizer)
|
||||
|
||||
cursor.execute(statements)
|
||||
|
||||
self.setauthorizer(None)
|
||||
|
||||
cursor.close()
|
||||
|
||||
yield (('operation', 'text'), ('paramone', 'text'), ('paramtwo', 'text'), ('databasename', 'text'), ('triggerorview', 'text'))
|
||||
|
||||
for r in plan:
|
||||
if r[1] not in ('sqlite_temp_master', 'sqlite_master'):
|
||||
yield r
|
||||
|
||||
@echofunctionmember
|
||||
def close(self):
|
||||
apsw.Connection.close(self)
|
||||
|
||||
def register(connection=None):
|
||||
global firstimport, oldexecdb
|
||||
|
||||
if connection == None:
|
||||
if 'SQLITE_OPEN_URI' in apsw.__dict__:
|
||||
connection = Connection(':memory:', flags=apsw.SQLITE_OPEN_READWRITE | apsw.SQLITE_OPEN_CREATE | apsw.SQLITE_OPEN_URI)
|
||||
else:
|
||||
connection = Connection(':memory:')
|
||||
|
||||
connection.openiters = {}
|
||||
connection.registered = True
|
||||
connection.cursor().execute("attach database ':memory:' as mem;", parse=False)
|
||||
|
||||
variables.filename = connection.filename
|
||||
|
||||
# To avoid db corruption set connection to fullfsync mode when MacOS is detected
|
||||
if sys.platform == 'darwin':
|
||||
c = connection.cursor().execute('pragma fullfsync=1;', parse=False)
|
||||
|
||||
functionspath=os.path.abspath(__path__[0])
|
||||
|
||||
def findmodules(abspath, relativepath):
|
||||
return [ os.path.splitext(file)[0] for file
|
||||
in os.listdir(os.path.join(abspath , relativepath))
|
||||
if file.endswith(".py") and not file.startswith("_") ]
|
||||
|
||||
## Register main functions of madis (functions)
|
||||
rowfiles = findmodules(functionspath, 'row')
|
||||
aggrfiles = findmodules(functionspath, 'aggregate')
|
||||
vtabfiles = findmodules(functionspath, 'vtable')
|
||||
|
||||
[__import__("functions.row" + "." + module) for module in rowfiles]
|
||||
[__import__("functions.aggregate" + "." + module) for module in aggrfiles]
|
||||
[__import__("functions.vtable" + "." + module) for module in vtabfiles]
|
||||
|
||||
# Register aggregate functions
|
||||
for module in aggrfiles:
|
||||
moddict = aggregate.__dict__[module]
|
||||
register_ops(moddict,connection)
|
||||
|
||||
# Register row functions
|
||||
for module in rowfiles:
|
||||
moddict = row.__dict__[module]
|
||||
register_ops(moddict,connection)
|
||||
|
||||
register_ops(vtable,connection)
|
||||
|
||||
## Register madis local functions (functionslocal)
|
||||
functionslocalpath=os.path.abspath(os.path.join(functionspath,'..','functionslocal'))
|
||||
|
||||
flrowfiles = findmodules(functionslocalpath, 'row')
|
||||
flaggrfiles = findmodules(functionslocalpath, 'aggregate')
|
||||
flvtabfiles = findmodules(functionslocalpath, 'vtable')
|
||||
|
||||
for module in flrowfiles:
|
||||
tmp=__import__("functionslocal.row." + module)
|
||||
register_ops(tmp.row.__dict__[module], connection)
|
||||
|
||||
for module in flaggrfiles:
|
||||
tmp=__import__("functionslocal.aggregate." + module)
|
||||
register_ops(tmp.aggregate.__dict__[module], connection)
|
||||
|
||||
localvtable=lambda x:x
|
||||
for module in flvtabfiles:
|
||||
localvtable.__dict__[module]=__import__("functionslocal.vtable." + module, fromlist=['functionslocal.vtable'])
|
||||
|
||||
if len(flvtabfiles)!=0:
|
||||
register_ops(localvtable,connection)
|
||||
|
||||
## Register db local functions (functions in db path)
|
||||
if variables.execdb!=oldexecdb:
|
||||
oldexecdb=variables.execdb
|
||||
dbpath=None
|
||||
|
||||
if variables.execdb!=None:
|
||||
dbpath=os.path.join(os.path.abspath(os.path.dirname(variables.execdb)),'functions')
|
||||
|
||||
if dbpath==None or not os.path.exists(dbpath):
|
||||
currentpath=os.path.abspath(os.path.join(os.path.abspath('.'), 'functions'))
|
||||
if os.path.exists(currentpath):
|
||||
dbpath=currentpath
|
||||
|
||||
if dbpath!=None and os.path.exists(dbpath):
|
||||
if os.path.abspath(dbpath)!=os.path.abspath(functionspath):
|
||||
|
||||
sys.path.append(dbpath)
|
||||
|
||||
if os.path.exists(os.path.join(dbpath, 'row')):
|
||||
lrowfiles = findmodules(dbpath, 'row')
|
||||
sys.path.append((os.path.abspath(os.path.join(os.path.join(dbpath),'row'))))
|
||||
for module in lrowfiles:
|
||||
tmp=__import__(module)
|
||||
register_ops(tmp, connection)
|
||||
|
||||
if os.path.exists(os.path.join(dbpath, 'aggregate')):
|
||||
sys.path.append((os.path.abspath(os.path.join(os.path.join(dbpath),'aggregate'))))
|
||||
laggrfiles = findmodules(dbpath, 'aggregate')
|
||||
for module in laggrfiles:
|
||||
tmp=__import__(module)
|
||||
register_ops(tmp, connection)
|
||||
|
||||
if os.path.exists(os.path.join(dbpath, 'vtable')):
|
||||
sys.path.append((os.path.abspath(os.path.join(os.path.join(dbpath),'vtable'))))
|
||||
lvtabfiles = findmodules(dbpath, 'vtable')
|
||||
tmp=lambda x:x
|
||||
for module in lvtabfiles:
|
||||
tmp.__dict__[module]=__import__(module)
|
||||
|
||||
if localvtable!=None:
|
||||
register_ops(tmp,connection)
|
||||
|
||||
firstimport=False
|
||||
|
||||
def register_ops(module, connection):
|
||||
global rowfuncs, firstimport
|
||||
|
||||
def opexists(op):
|
||||
if firstimport:
|
||||
return op in functions['vtable'] or op in functions['row'] or op in functions['aggregate']
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def wrapfunction(con, opfun):
|
||||
return lambda *args: iterwrapper(con, opfun, *args)
|
||||
|
||||
def wrapaggr(con, opfun):
|
||||
return lambda self: iterwrapperaggr(con, opfun, self)
|
||||
|
||||
def wrapaggregatefactory(wlambda):
|
||||
return lambda cls: (cls(), cls.step, wlambda)
|
||||
|
||||
|
||||
for f in module.__dict__:
|
||||
fobject = module.__dict__[f]
|
||||
if hasattr(fobject, 'registered') and type(fobject.registered).__name__ == 'bool' and fobject.registered == True:
|
||||
opname=f.lower()
|
||||
|
||||
if firstimport:
|
||||
if opname!=f:
|
||||
raise MadisError("Extended SQLERROR: Function '"+module.__name__+'.'+f+"' uses uppercase characters. Functions should be lowercase")
|
||||
|
||||
if opname.upper() in sqltransform.sqlparse.keywords.KEYWORDS:
|
||||
raise MadisError("Extended SQLERROR: Function '"+module.__name__+'.'+opname+"' is a reserved SQL function")
|
||||
|
||||
if type(fobject).__name__ == 'module':
|
||||
if opexists(opname):
|
||||
raise MadisError("Extended SQLERROR: Vtable '"+opname+"' name collision with other operator")
|
||||
functions['vtable'][opname] = fobject
|
||||
modinstance = fobject.Source()
|
||||
modinstance._madisVT = True
|
||||
connection.createmodule(opname, modinstance)
|
||||
|
||||
if type(fobject).__name__ == 'function':
|
||||
if opexists(opname):
|
||||
raise MadisError("Extended SQLERROR: Row operator '"+module.__name__+'.'+opname+"' name collision with other operator")
|
||||
functions['row'][opname] = fobject
|
||||
if isgeneratorfunction(fobject):
|
||||
fobject=wrapfunction(connection, fobject)
|
||||
fobject.multiset=True
|
||||
setattr(rowfuncs, opname, fobject)
|
||||
connection.createscalarfunction(opname, fobject)
|
||||
|
||||
if type(fobject).__name__ == 'classobj':
|
||||
if opexists(opname):
|
||||
raise MadisError("Extended SQLERROR: Aggregate operator '"+module.__name__+'.'+opname+"' name collision with other operator")
|
||||
functions['aggregate'][opname] = fobject
|
||||
|
||||
if isgeneratorfunction(fobject.final):
|
||||
wlambda = wrapaggr(connection, fobject.final)
|
||||
fobject.multiset = True
|
||||
setattr(fobject, 'factory', classmethod(wrapaggregatefactory(wlambda)))
|
||||
connection.createaggregatefunction(opname, fobject.factory)
|
||||
else:
|
||||
setattr(fobject, 'factory', classmethod(lambda cls:(cls(), cls.step, cls.final)))
|
||||
connection.createaggregatefunction(opname, fobject.factory)
|
||||
|
||||
try:
|
||||
if fobject.multiset:
|
||||
multiset_functions[opname] = True
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def testfunction():
|
||||
global test_connection, settings
|
||||
|
||||
test_connection = Connection(':memory:')
|
||||
register(test_connection)
|
||||
variables.execdb=':memory:'
|
||||
|
||||
def settestdb(testdb):
|
||||
global test_connection, settings
|
||||
|
||||
abstestdb=str(os.path.abspath(os.path.expandvars(os.path.expanduser(os.path.normcase(testdb)))))
|
||||
test_connection = Connection(abstestdb)
|
||||
register(test_connection)
|
||||
variables.execdb=abstestdb
|
||||
|
||||
def sql(sqlquery):
|
||||
import locale
|
||||
from lib import pptable
|
||||
global test_connection
|
||||
|
||||
language, output_encoding = locale.getdefaultlocale()
|
||||
|
||||
if output_encoding==None:
|
||||
output_encoding="UTF8"
|
||||
|
||||
test_cursor=test_connection.cursor()
|
||||
|
||||
e=test_cursor.execute(sqlquery.decode(output_encoding))
|
||||
try:
|
||||
desc=test_cursor.getdescription()
|
||||
print pptable.indent([[x[0] for x in desc]]+[x for x in e], hasHeader=True),
|
||||
except apsw.ExecutionCompleteError:
|
||||
print '',
|
||||
test_cursor.close()
|
||||
|
||||
def table(tab, num=''):
|
||||
import shlex
|
||||
"""
|
||||
Creates a test table named "table". It's columns are fitted to the data
|
||||
given to it and are automatically named a, b, c, ...
|
||||
|
||||
'num' parameter:
|
||||
If a 'num' parameter is given then the table will be named for example
|
||||
table1 when num=1, table2 when num=2 ...
|
||||
|
||||
Example:
|
||||
|
||||
table('''
|
||||
1 2 3
|
||||
4 5 6
|
||||
''')
|
||||
|
||||
will create a table named 'table' having the following data:
|
||||
|
||||
a b c
|
||||
---------
|
||||
1 2 3
|
||||
4 5 6
|
||||
|
||||
"""
|
||||
|
||||
colnames="abcdefghijklmnop"
|
||||
import re
|
||||
tab=tab.splitlines()
|
||||
tab=[re.sub(r'[\s\t]+',' ',x.strip()) for x in tab]
|
||||
tab=[x for x in tab if x!='']
|
||||
# Convert NULL to None
|
||||
tab=[[(y if y!='NULL' else None) for y in shlex.split(x)] for x in tab]
|
||||
|
||||
numberofcols=len(tab[0])
|
||||
|
||||
if num=='':
|
||||
num='0'
|
||||
|
||||
createsql='create table table'+str(num)+'('
|
||||
insertsql="insert into table"+str(num)+" values("
|
||||
for i in range(0,numberofcols):
|
||||
createsql=createsql+colnames[i]+' str'+','
|
||||
insertsql=insertsql+'?,'
|
||||
|
||||
createsql=createsql[0:-1]+')'
|
||||
insertsql=insertsql[0:-1]+')'
|
||||
|
||||
test_cursor=test_connection.cursor()
|
||||
try:
|
||||
test_cursor.execute(createsql)
|
||||
except:
|
||||
test_cursor.execute("drop table table"+str(num))
|
||||
test_cursor.execute(createsql)
|
||||
|
||||
test_cursor.executemany(insertsql, tab)
|
||||
|
||||
def table1(tab):
|
||||
table(tab, num=1)
|
||||
|
||||
def table2(tab):
|
||||
table(tab, num=2)
|
||||
|
||||
def table3(tab):
|
||||
table(tab, num=3)
|
||||
|
||||
def table4(tab):
|
||||
table(tab, num=4)
|
||||
|
||||
def table5(tab):
|
||||
table(tab, num=5)
|
||||
|
||||
def table6(tab):
|
||||
table(tab, num=6)
|
||||
|
||||
def setlogfile(file):
|
||||
pass
|
|
@ -0,0 +1,271 @@
|
|||
import Queue
|
||||
import setpath
|
||||
import functions
|
||||
import datetime
|
||||
from lib import iso8601
|
||||
|
||||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
def timedelta2millisec(tdelta):
|
||||
return tdelta.days*24*60*60*1000+tdelta.seconds*1000+tdelta.microseconds/1000
|
||||
|
||||
class mindtdiff:
|
||||
"""
|
||||
.. function:: mindtdiff(date)
|
||||
|
||||
Returns the minimum difference *date* values of the group in milliseconds. Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... '2007-01-01 00:03:13'
|
||||
... '2007-01-01 00:03:27'
|
||||
... '2007-01-01 00:03:36'
|
||||
... '2007-01-01 00:04:39'
|
||||
... '2007-01-01 00:04:40'
|
||||
... '2007-01-01 00:04:49'
|
||||
... ''')
|
||||
>>> sql("select mindtdiff(a) from table1")
|
||||
mindtdiff(a)
|
||||
------------
|
||||
1000
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
>>> sql("select mindtdiff(a) from (select '2005-01-01' as a) ")
|
||||
mindtdiff(a)
|
||||
------------
|
||||
None
|
||||
>>> sql("select mindtdiff(a) from (select 5 as a where a!=5) ")
|
||||
mindtdiff(a)
|
||||
------------
|
||||
None
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.dates=Queue.PriorityQueue()
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("mindtdiff","No arguments")
|
||||
dt=iso8601.parse_date(args[0])
|
||||
self.dates.put_nowait(dt)
|
||||
|
||||
|
||||
|
||||
def final(self):
|
||||
mindiff=None
|
||||
dtp=None
|
||||
if not self.dates:
|
||||
return
|
||||
while not self.dates.empty():
|
||||
if not mindiff:
|
||||
if not dtp:
|
||||
dtp=self.dates.get_nowait()
|
||||
continue
|
||||
dt=self.dates.get_nowait()
|
||||
diff=timedelta2millisec(dt-dtp)
|
||||
if mindiff==None:
|
||||
mindiff=diff
|
||||
elif mindiff>diff:
|
||||
mindiff=diff
|
||||
dtp=dt
|
||||
import types
|
||||
|
||||
return mindiff
|
||||
|
||||
class avgdtdiff:
|
||||
"""
|
||||
.. function:: avgdtdiff(date)
|
||||
|
||||
Returns the average difference *date* values of the group in milliseconds. Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... '2007-01-01 00:04:37'
|
||||
... '2007-01-01 00:04:39'
|
||||
... '2007-01-01 00:04:40'
|
||||
... '2007-01-01 00:04:49'
|
||||
... ''')
|
||||
>>> sql("select avgdtdiff(a) from table1")
|
||||
avgdtdiff(a)
|
||||
------------
|
||||
3000.0
|
||||
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
|
||||
>>> sql("select avgdtdiff(a) from (select '2005-01-01' as a) ")
|
||||
avgdtdiff(a)
|
||||
------------
|
||||
None
|
||||
>>> sql("select avgdtdiff(a) from (select 5 as a where a!=5) ")
|
||||
avgdtdiff(a)
|
||||
------------
|
||||
None
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.dates=Queue.PriorityQueue()
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("avgdtdiff","No arguments")
|
||||
dt=iso8601.parse_date(args[0])
|
||||
self.dates.put_nowait(dt)
|
||||
|
||||
|
||||
|
||||
def final(self):
|
||||
avgdiff=0
|
||||
cntdiff=0
|
||||
dtp=None
|
||||
while not self.dates.empty():
|
||||
if avgdiff==0:
|
||||
if not dtp:
|
||||
cntdiff+=1
|
||||
dtp=self.dates.get_nowait()
|
||||
continue
|
||||
dt=self.dates.get_nowait()
|
||||
diff=timedelta2millisec(dt-dtp)
|
||||
cntdiff+=1
|
||||
avgdiff+=diff
|
||||
dtp=dt
|
||||
if cntdiff<2:
|
||||
return None
|
||||
return float(avgdiff)/cntdiff
|
||||
|
||||
class dategroupduration:
|
||||
"""
|
||||
.. function:: dategroupduration(date)
|
||||
|
||||
Returns the duration of the group of dates in seconds. Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... '2007-01-01 00:04:37'
|
||||
... '2007-01-01 00:04:39'
|
||||
... '2007-01-01 00:04:40'
|
||||
... '2007-01-01 00:04:49'
|
||||
... ''')
|
||||
>>> sql("select dategroupduration(a) from table1")
|
||||
dategroupduration(a)
|
||||
--------------------
|
||||
12
|
||||
|
||||
>>> sql("select dategroupduration(a) from (select '2005-01-01' as a) ")
|
||||
dategroupduration(a)
|
||||
--------------------
|
||||
0
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.datemin = None
|
||||
self.datemax = None
|
||||
|
||||
def step(self, *args):
|
||||
pdate = iso8601.parse_date(args[0])
|
||||
|
||||
if self.datemin == None:
|
||||
self.datemin = pdate
|
||||
|
||||
if self.datemax == None:
|
||||
self.datemax = pdate
|
||||
|
||||
if pdate < self.datemin:
|
||||
self.datemin = pdate
|
||||
|
||||
if pdate > self.datemax:
|
||||
self.datemax = pdate
|
||||
|
||||
def final(self):
|
||||
if self.datemin == None or self.datemax == None:
|
||||
return 0
|
||||
|
||||
diff=self.datemax - self.datemin
|
||||
|
||||
return diff.days*86400+diff.seconds
|
||||
|
||||
|
||||
class frecencyindex:
|
||||
"""
|
||||
.. function:: frecencyindex(date)
|
||||
|
||||
Returns the frecency Index which is computed based on a set of *date* values, using predifend time-windows.
|
||||
Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... '2011-04-01 00:04:37'
|
||||
... '2011-01-01 00:04:39'
|
||||
... '2011-02-12 00:04:40'
|
||||
... '2011-02-14 00:04:49'
|
||||
... ''')
|
||||
>>> sql("select frecencyindex(a) from table1")
|
||||
frecencyindex(a)
|
||||
----------------
|
||||
2.9
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.monthCounter=0
|
||||
self.trimesterCounter=0
|
||||
self.semesterCounter=0
|
||||
self.yearCounter=0
|
||||
self.twoyearsCounter=0
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("frecencyindex","No arguments")
|
||||
|
||||
now = datetime.datetime.now()
|
||||
now = iso8601.parse_date(now.strftime("%Y-%m-%d %H:%M:%S"))
|
||||
d = args[0].replace('T',' ')
|
||||
dt = iso8601.parse_date(args[0].replace('Z',''))
|
||||
diff=now-dt
|
||||
|
||||
if (diff.days)<30:
|
||||
self.monthCounter+=1
|
||||
elif (diff.days)<3*30:
|
||||
self.trimesterCounter+=1
|
||||
elif (diff.days)<6*30:
|
||||
self.semesterCounter+=1
|
||||
elif (diff.days)<12*30:
|
||||
self.yearCounter+=1
|
||||
elif (diff.days)<24*30:
|
||||
self.twoyearsCounter+=1
|
||||
|
||||
|
||||
|
||||
def final(self):
|
||||
|
||||
return self.monthCounter*1 + self.trimesterCounter*0.7 + self.semesterCounter*0.5 + self.yearCounter*0.3+ self.twoyearsCounter*0.2
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -0,0 +1,635 @@
|
|||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
import setpath
|
||||
import json
|
||||
from hashlib import md5
|
||||
from binascii import b2a_base64
|
||||
import math
|
||||
import collections
|
||||
import functions
|
||||
|
||||
class graphpowerhash:
|
||||
"""
|
||||
.. function:: graphpowerhash(steps, [undirected_edge], node1, node2, [node1_details, edge_details, node2_details]) -> jpack of graph node hashes
|
||||
|
||||
Graph power hashing is based on a `power iteration algorithm <http://en.wikipedia.org/wiki/Power_iteration>`_
|
||||
that calculates hashes on every processing step. The produced output, contains for every node in the input graph
|
||||
a hash that "describes" its "surroundings".
|
||||
|
||||
Parameters:
|
||||
|
||||
:steps:
|
||||
The *steps* option controls the number of steps that the power hashing will be executed for. Another
|
||||
way to conceptualize the *steps* parameter is to think of it as the radius of the graph around
|
||||
a particular node that the node's hash covers.
|
||||
|
||||
Steps parameter's possible value are:
|
||||
|
||||
- null (default). When steps=null, then steps is automatically set to number_of_nodes/2
|
||||
- Positive integer value.
|
||||
- -1 . Steps is set to number_of_nodes
|
||||
- Negative integers, steps is set to number_of_nodes / absolute_value(steps)
|
||||
|
||||
:undirected_edge':
|
||||
|
||||
This option can only have the *null* value.
|
||||
|
||||
- Parameter absent. The graph is assumed to be directed.
|
||||
- Parameter present and having a *null* value. The graph is assumed to be undirected
|
||||
|
||||
:node1,node2:
|
||||
|
||||
Node1 connects to Node2. If node1 doesn't connect to any node, then *node2*'s value should be null.
|
||||
|
||||
:node and edge details:
|
||||
|
||||
Optional details, that are processed with the graph's structure. In essence these
|
||||
parameters define "tags" on the nodes and edges of the graph.
|
||||
|
||||
.. note::
|
||||
The graph power hash algorithm is an experimental algorithm created by me, Lefteris Stamatogiannakis. I haven't
|
||||
proved its correctness, so please use it with care. Due to its hash usage, there is a (very low probability)
|
||||
that two different graphs could hash to the same power hash.
|
||||
|
||||
I would be very very thankfull to anyone knowledgable in graph theory, who could prove it to be wrong (or correct).
|
||||
If the reader knows of a paper that describes another algorithm similar to this algorithm, i would be glad to be pointed towards it.
|
||||
|
||||
.. note::
|
||||
The computational complexity of the powerhash algorithm is O(n * steps * average_node_degree). The optimal value for
|
||||
the hash to fully cover the graph, is to set the steps parameter to *graph_diameter* / 2.
|
||||
|
||||
Right now for steps=null, we take the worse upper bound of n / 2, so the computational complexity becomes
|
||||
O(n * ~(n/2) * average_node_degree).
|
||||
|
||||
Examples:
|
||||
|
||||
Directed graph:
|
||||
|
||||
>>> table1('''
|
||||
... 1 2
|
||||
... 2 3
|
||||
... 3 4
|
||||
... 4 5
|
||||
... 5 3
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphpowerhash(null, a,b) from table1")
|
||||
graphpowerhash(null, a,b)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
["OaNj+OtIZPqcwjc3QVvKpg","Um7OU79ApcRNA2TKrdcBcA","ZyQT/AoKyjIkwWMNvceK2A","3vaHWSLU/H32HvHTVBkpUQ","+3uZjYUMSXwyZs7HFHKNVg"]
|
||||
|
||||
|
||||
Above graph having its nodes renumbered (its powerhash is the same as above):
|
||||
|
||||
>>> table2('''
|
||||
... 2 5
|
||||
... 5 4
|
||||
... 4 1
|
||||
... 1 3
|
||||
... 3 4
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphpowerhash(null, a,b) from table2")
|
||||
graphpowerhash(null, a,b)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
["OaNj+OtIZPqcwjc3QVvKpg","Um7OU79ApcRNA2TKrdcBcA","ZyQT/AoKyjIkwWMNvceK2A","3vaHWSLU/H32HvHTVBkpUQ","+3uZjYUMSXwyZs7HFHKNVg"]
|
||||
|
||||
|
||||
Above graph with a small change (its hash differs from above graphs):
|
||||
|
||||
>>> table3('''
|
||||
... 2 5
|
||||
... 5 4
|
||||
... 4 1
|
||||
... 1 3
|
||||
... 3 5
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphpowerhash(null, a,b) from table3")
|
||||
graphpowerhash(null, a,b)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
["APq1eISun1GpYjgUhiMrLA","NPPh9FLzC5cUedxldXV77Q","VVZ93zo6gePuMeRf6f00Zg","df/4yDABlitCTfOGut0NvA","lqo+lY4fcjqujlgsYr+3Yw"]
|
||||
|
||||
|
||||
Actual testing of equality or inequality of above graphs:
|
||||
|
||||
>>> sql("select hashmd5( (select graphpowerhash(null, a,b) from table1) )=hashmd5( (select graphpowerhash(null, a,b) from table2) ) as grapheq")
|
||||
grapheq
|
||||
-------
|
||||
1
|
||||
|
||||
>>> sql("select hashmd5( (select graphpowerhash(null, a,b) from table1) )=hashmd5( (select graphpowerhash(null, a,b) from table3) ) as grapheq")
|
||||
grapheq
|
||||
-------
|
||||
0
|
||||
|
||||
|
||||
Graph with only one node:
|
||||
|
||||
>>> sql("select graphpowerhash(null, a, null) from (select * from table1 limit 1)")
|
||||
graphpowerhash(null, a, null)
|
||||
-----------------------------
|
||||
["TOiuilAk4RLkg01tIwyvcg"]
|
||||
|
||||
|
||||
Undirected version of table1's graph:
|
||||
|
||||
>>> sql("select graphpowerhash(null, null, a,b) from table1")
|
||||
graphpowerhash(null, null, a,b)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
["JudlYSkYV7rFHjk94abY/A","W88IN4kgDSeVX9kaY36SJg","W88IN4kgDSeVX9kaY36SJg","6ez9ee0N2ogdvKJVQ8VKWA","7gz+LT/LtsyFc+GxMUlL8g"]
|
||||
|
||||
|
||||
Same graph as above, but some of the edges have been reversed (the undirected powerhash matches the powerhash above):
|
||||
|
||||
>>> table4('''
|
||||
... 2 1
|
||||
... 2 3
|
||||
... 3 4
|
||||
... 4 5
|
||||
... 3 5
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphpowerhash(null, null, a,b) from table4")
|
||||
graphpowerhash(null, null, a,b)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
["JudlYSkYV7rFHjk94abY/A","W88IN4kgDSeVX9kaY36SJg","W88IN4kgDSeVX9kaY36SJg","6ez9ee0N2ogdvKJVQ8VKWA","7gz+LT/LtsyFc+GxMUlL8g"]
|
||||
|
||||
|
||||
Graph similarity, using the step parameter (value of step defines the radius of the similar subgraphs that can be found):
|
||||
|
||||
>>> sql("select jaccard( (select graphpowerhash(3, a, b) from table1), (select graphpowerhash(3, a, b) from table3) ) as jacsim")
|
||||
jacsim
|
||||
------
|
||||
0.0
|
||||
|
||||
>>> sql("select jaccard( (select graphpowerhash(1, a, b) from table1), (select graphpowerhash(1, a, b) from table3) ) as jacsim")
|
||||
jacsim
|
||||
------
|
||||
0.25
|
||||
|
||||
|
||||
Powerhash of graph having details (using a chemical composition):
|
||||
|
||||
>>> table5('''
|
||||
... 1 2 O = C
|
||||
... 2 3 C = O
|
||||
... ''')
|
||||
|
||||
First without details:
|
||||
|
||||
>>> sql("select graphpowerhash(null, null, a, b) from table5")
|
||||
graphpowerhash(null, null, a, b)
|
||||
----------------------------------------------------------------------------
|
||||
["Rw3sDN24TI7YARBNOOmYSg","9m5wcZf9iUxDwgzQkzu6Ag","9m5wcZf9iUxDwgzQkzu6Ag"]
|
||||
|
||||
Second with all details:
|
||||
|
||||
>>> sql("select graphpowerhash(null, null, a, b, c, d, e) from table5")
|
||||
graphpowerhash(null, null, a, b, c, d, e)
|
||||
----------------------------------------------------------------------------
|
||||
["CPebw+eZYzw5bWgx47/tkg","CPebw+eZYzw5bWgx47/tkg","WNn4aDDBKcoMMi+nrz5JEA"]
|
||||
|
||||
"""
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.nodes={}
|
||||
self.steps=None
|
||||
|
||||
def step(self, *args):
|
||||
directed=True
|
||||
argslen=len(args)
|
||||
largs=args
|
||||
|
||||
if largs[0]!=None:
|
||||
self.steps=largs[0]
|
||||
|
||||
if largs[1]==None:
|
||||
directed=False
|
||||
largs=list(largs)
|
||||
del(largs[1])
|
||||
argslen-=1
|
||||
|
||||
if directed:
|
||||
if argslen>4:
|
||||
edgedetailslr='1'+chr(30)+str(largs[4])
|
||||
edgedetailsrl='0'+chr(30)+str(largs[4])
|
||||
else:
|
||||
edgedetailslr='1'
|
||||
edgedetailsrl='0'
|
||||
else:
|
||||
if argslen>4:
|
||||
edgedetailslr='1'+ chr(30)+str(largs[4])
|
||||
edgedetailsrl=edgedetailslr
|
||||
else:
|
||||
edgedetailslr='1'
|
||||
edgedetailsrl=edgedetailslr
|
||||
|
||||
if largs[1] not in self.nodes:
|
||||
if argslen>3:
|
||||
self.nodes[largs[1]]=[ [( largs[2],edgedetailslr )] , str(largs[3])]
|
||||
else:
|
||||
self.nodes[largs[1]]=[ [( largs[2],edgedetailslr )] , '']
|
||||
else:
|
||||
self.nodes[largs[1]][0].append( ( largs[2],edgedetailslr ) )
|
||||
|
||||
|
||||
if largs[2]!=None:
|
||||
if largs[2] not in self.nodes:
|
||||
if argslen>5:
|
||||
self.nodes[largs[2]]=[ [(largs[1],edgedetailsrl )], str(largs[5])]
|
||||
else:
|
||||
self.nodes[largs[2]]=[ [(largs[1],edgedetailsrl )] , '']
|
||||
else:
|
||||
self.nodes[largs[2]][0].append( ( largs[1],edgedetailsrl ) )
|
||||
|
||||
def final(self):
|
||||
ncount=len(self.nodes)
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
v[1]=str(len(v[0]))+chr(31)+v[1]
|
||||
|
||||
if ncount==1:
|
||||
self.steps=1
|
||||
|
||||
if self.steps==None:
|
||||
# Calculate approximate worse case diameter
|
||||
degreeseq=set()
|
||||
mindegree=ncount
|
||||
maxdegree=0
|
||||
invdegree=0.0
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
ndegree=len(v[0])
|
||||
mindegree=min(mindegree, ndegree)
|
||||
maxdegree=max(maxdegree, ndegree)
|
||||
degreeseq.add(ndegree)
|
||||
invdegree+=1.0/ndegree
|
||||
|
||||
self.steps=int(min(
|
||||
# Obvious upper bounds
|
||||
ncount-max(2, maxdegree) + 2,
|
||||
# P. Dankelmann "Diameter and inverse degree"
|
||||
(3*invdegree+3)*math.log(ncount)/math.log(math.log(ncount)) if ncount>16 else ncount,
|
||||
# Simon Mukwembi "A note on diameter and the degree sequence of a graph"
|
||||
1+3*(ncount - len(degreeseq)+1)/float((mindegree+1)), ncount - len(degreeseq)+2))/2
|
||||
|
||||
if self.steps<0:
|
||||
self.steps=ncount/abs(self.steps)
|
||||
|
||||
nhashes={}
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
nhashes[n]=md5(str(v[1]+chr(30))).digest()
|
||||
|
||||
if ncount>1:
|
||||
for s in xrange(self.steps):
|
||||
nhashes1={}
|
||||
nhashcount={}
|
||||
for n, v in self.nodes.iteritems():
|
||||
nhash=md5(v[1]+chr(30)+chr(30).join(sorted([nhashes[x]+chr(29)+y for x,y in v[0]]))).digest()
|
||||
nhashes1[n]=nhash
|
||||
if nhash in nhashcount:
|
||||
nhashcount[nhash]+=1
|
||||
else:
|
||||
nhashcount[nhash]=1
|
||||
nhashes=nhashes1
|
||||
|
||||
# TODO Find new upper bound of diameter via calculating Spanning Tree starting from distincthash
|
||||
# if len(nhashcount)>0:
|
||||
# distincthash=min([x for x,y in nhashcount.iteritems() if y==1])
|
||||
|
||||
|
||||
return json.dumps([b2a_base64(x)[0:-3] for x in sorted(nhashes.values())], separators=(',',':'), ensure_ascii=False)
|
||||
|
||||
class graphtodot:
|
||||
"""
|
||||
.. function:: graphtodot(graphname, [undirected_edge], node1, node2, [node1_details, edge_details, node2_details]) -> graphviz dot graph
|
||||
|
||||
Returns the *Graphviz* DOT representation of the input graph.
|
||||
|
||||
Examples:
|
||||
|
||||
Directed graph:
|
||||
|
||||
>>> table1('''
|
||||
... 1 2
|
||||
... 2 3
|
||||
... 3 4
|
||||
... 4 5
|
||||
... 5 3
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphtodot(null, a,b) from table1")
|
||||
graphtodot(null, a,b)
|
||||
------------------------------------------------------------------------
|
||||
digraph {
|
||||
"1" -> "2";
|
||||
"2" -> "3";
|
||||
"3" -> "4";
|
||||
"4" -> "5";
|
||||
"5" -> "3";
|
||||
}
|
||||
|
||||
Undirected graph:
|
||||
|
||||
>>> table2('''
|
||||
... 2 5
|
||||
... 5 4
|
||||
... 4 1
|
||||
... 1 3
|
||||
... 3 4
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphtodot(null, null, a,b) from table2")
|
||||
graphtodot(null, null, a,b)
|
||||
----------------------------------------------------------------------
|
||||
graph {
|
||||
"1" -- "3";
|
||||
"2" -- "5";
|
||||
"3" -- "4";
|
||||
"4" -- "1";
|
||||
"5" -- "4";
|
||||
}
|
||||
|
||||
Graph with details:
|
||||
|
||||
>>> table5('''
|
||||
... 1 2 O = C
|
||||
... 2 3 C = O
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphtodot('chem_comp_1', null, a, b, c, d, e) from table5")
|
||||
graphtodot('chem_comp_1', null, a, b, c, d, e)
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
graph chem_comp_1 {
|
||||
"1" [label="O"];
|
||||
"1" -- "2" [label="="];
|
||||
"2" [label="C"];
|
||||
"2" -- "3" [label="="];
|
||||
"3" [label="O"];
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.nodes={}
|
||||
self.steps=None
|
||||
self.graphname=None
|
||||
self.directed=True
|
||||
|
||||
def step(self, *args):
|
||||
directed=True
|
||||
argslen=len(args)
|
||||
largs=args
|
||||
|
||||
if largs[0]!=None:
|
||||
self.graphname=largs[0]
|
||||
|
||||
if largs[1]==None:
|
||||
self.directed=False
|
||||
largs=list(largs)
|
||||
del(largs[1])
|
||||
argslen-=1
|
||||
|
||||
if argslen>4:
|
||||
edgedetailslr=unicode(largs[4])
|
||||
else:
|
||||
edgedetailslr=None
|
||||
|
||||
if largs[1] not in self.nodes:
|
||||
if argslen>3:
|
||||
self.nodes[largs[1]]=[ [( largs[2],edgedetailslr )] , largs[3]]
|
||||
else:
|
||||
self.nodes[largs[1]]=[ [( largs[2],edgedetailslr )] , None]
|
||||
else:
|
||||
self.nodes[largs[1]][0].append( ( largs[2],edgedetailslr ) )
|
||||
|
||||
|
||||
if largs[2]!=None:
|
||||
if largs[2] not in self.nodes:
|
||||
if argslen>5:
|
||||
self.nodes[largs[2]]=[ [], largs[5]]
|
||||
else:
|
||||
self.nodes[largs[2]]=[ [] , None]
|
||||
|
||||
def final(self):
|
||||
if self.graphname==None:
|
||||
self.graphname=''
|
||||
|
||||
if type(self.graphname) in (int, float):
|
||||
self.graphname=u'g'+unicode(self.graphname)
|
||||
else:
|
||||
self.graphname=unicode(self.graphname)
|
||||
|
||||
dot=u''
|
||||
if self.directed:
|
||||
dot=u'di'
|
||||
|
||||
if self.graphname==None:
|
||||
self.graphname='""'
|
||||
|
||||
dot+=u'graph '+self.graphname+u' {\n'
|
||||
|
||||
digraph=False
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
if v[1]!=None:
|
||||
dot+=json.dumps(unicode(n))+' [label="'+unicode(v[1]).replace('"',"'")+'"];\n'
|
||||
for e in v[0]:
|
||||
dot+=json.dumps(unicode(n)) + ' '
|
||||
if self.directed:
|
||||
dot+='-> '
|
||||
else:
|
||||
dot+='-- '
|
||||
dot += json.dumps(unicode(e[0]))
|
||||
if e[1]!=None:
|
||||
dot+=u' [label="'+unicode(e[1]).replace('"',"'")+'"]'
|
||||
dot+=u';\n'
|
||||
|
||||
dot+='}'
|
||||
|
||||
return dot
|
||||
|
||||
class graphtotgf:
|
||||
"""
|
||||
.. function:: graphtotgf(node1, node2, [node1_details, edge_details, node2_details]) -> TGF graph
|
||||
|
||||
Returns the TGF representation of the input graph.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 1 2
|
||||
... 2 3
|
||||
... 3 4
|
||||
... 4 5
|
||||
... 5 3
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphtotgf(a,b) from table1") # doctest: +NORMALIZE_WHITESPACE
|
||||
graphtotgf(a,b)
|
||||
------------------------------------------
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
#
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 3
|
||||
|
||||
Graph with details:
|
||||
|
||||
>>> table5('''
|
||||
... 1 2 O = C
|
||||
... 2 3 C = O
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphtotgf(a, b, c, d, e) from table5")
|
||||
graphtotgf(a, b, c, d, e)
|
||||
--------------------------
|
||||
1 O
|
||||
2 C
|
||||
3 O
|
||||
#
|
||||
1 2 =
|
||||
2 3 =
|
||||
|
||||
"""
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.nodes={}
|
||||
self.steps=None
|
||||
self.directed=True
|
||||
|
||||
def step(self, *args):
|
||||
argslen=len(args)
|
||||
largs=args
|
||||
|
||||
if argslen>3:
|
||||
edgedetailslr=unicode(largs[3])
|
||||
else:
|
||||
edgedetailslr=None
|
||||
|
||||
if largs[0] not in self.nodes:
|
||||
if argslen>2:
|
||||
self.nodes[largs[0]]=[ [( largs[1],edgedetailslr )] , largs[2]]
|
||||
else:
|
||||
self.nodes[largs[0]]=[ [( largs[1],edgedetailslr )] , None]
|
||||
else:
|
||||
self.nodes[largs[0]][0].append( ( largs[1],edgedetailslr ) )
|
||||
|
||||
|
||||
if largs[1]!=None:
|
||||
if largs[1] not in self.nodes:
|
||||
if argslen>4:
|
||||
self.nodes[largs[1]]=[ [], largs[4]]
|
||||
else:
|
||||
self.nodes[largs[1]]=[ [] , None]
|
||||
|
||||
def final(self):
|
||||
tgf=''
|
||||
|
||||
def clearname(n):
|
||||
return unicode(n).replace(' ','_').replace('"',"'")
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
tgf+=clearname(n) + ' ' + (clearname(v[1]) if v[1]!=None else '') +'\n'
|
||||
|
||||
tgf+='#\n'
|
||||
|
||||
for n,v in self.nodes.iteritems():
|
||||
for e in v[0]:
|
||||
tgf+=clearname(n)+ ' ' + clearname(e[0])+ ' '+ (clearname(e[1]) if e[1]!=None else '') + '\n'
|
||||
|
||||
return tgf
|
||||
|
||||
class graphcliques:
|
||||
"""
|
||||
.. function:: graphcliques(node1, node2) -> graph cliques
|
||||
|
||||
Finds and returns the cliques in the graph defined by the node1<->node2 links.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... n1 n2
|
||||
... n2 n3
|
||||
... n1 n3
|
||||
... n3 n4
|
||||
... n4 n5
|
||||
... n5 n3
|
||||
... n1 n6
|
||||
... ''')
|
||||
|
||||
>>> sql("select graphcliques(a,b) from table1") # doctest: +NORMALIZE_WHITESPACE
|
||||
cliqueid | nodeid
|
||||
-----------------
|
||||
0 | n1
|
||||
0 | n2
|
||||
0 | n3
|
||||
1 | n3
|
||||
1 | n4
|
||||
1 | n5
|
||||
|
||||
"""
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.G = collections.defaultdict(set)
|
||||
|
||||
def step(self, *args):
|
||||
if len(args)!=2:
|
||||
raise functions.OperatorError('graphcliques', 'Two parameters should be provided')
|
||||
|
||||
self.G[args[0]].add(args[1])
|
||||
self.G[args[1]].add(args[0])
|
||||
|
||||
def _bors_kerbosch(self, R, P, X):
|
||||
if not P and not X: # if both are empty
|
||||
if len(R) > 2:
|
||||
yield sorted(R)
|
||||
return
|
||||
|
||||
pivot = max(((len(self.G[v]), v) for v in P.union(X)))[1]
|
||||
|
||||
for v in P.difference(self.G[pivot]):
|
||||
for c in self._bors_kerbosch(R.union((v,)), P.intersection(self.G[v]), X.intersection(self.G[v])):
|
||||
yield c
|
||||
P.remove(v)
|
||||
X.add(v)
|
||||
|
||||
def final(self):
|
||||
cid = 0
|
||||
|
||||
yield ('cliqueid', 'nodeid')
|
||||
for c in self._bors_kerbosch(set([]), set(self.G.keys()), set([])):
|
||||
for n in c:
|
||||
yield cid, n
|
||||
cid += 1
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -0,0 +1,356 @@
|
|||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
import setpath
|
||||
import lib.jopts as jopts
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
# Python 2.6
|
||||
from lib.collections26 import OrderedDict
|
||||
|
||||
|
||||
class jgroup:
|
||||
"""
|
||||
.. function:: jgroup(columns)
|
||||
|
||||
Groups columns of a group into a jpack.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... word1 1
|
||||
... word2 1
|
||||
... word3 2
|
||||
... word4 2
|
||||
... ''')
|
||||
>>> sql("select jgroup(a) from table1 group by b")
|
||||
jgroup(a)
|
||||
-----------------
|
||||
["word1","word2"]
|
||||
["word3","word4"]
|
||||
>>> sql("select jgroup(a,b) from table1")
|
||||
jgroup(a,b)
|
||||
-------------------------------------------------
|
||||
[["word1",1],["word2",1],["word3",2],["word4",2]]
|
||||
|
||||
>>> table2('''
|
||||
... [1,2] 1
|
||||
... [3,4] 1
|
||||
... [5,6] 2
|
||||
... [7,8] 2
|
||||
... ''')
|
||||
|
||||
>>> sql("select jgroup(a) from table2")
|
||||
jgroup(a)
|
||||
-------------------------
|
||||
[[1,2],[3,4],[5,6],[7,8]]
|
||||
|
||||
>>> sql("select jgroup(a,b) from table2")
|
||||
jgroup(a,b)
|
||||
-----------------------------------------
|
||||
[[[1,2],1],[[3,4],1],[[5,6],2],[[7,8],2]]
|
||||
|
||||
>>> sql("select jgroup(jdict('a',a,'b',b)) from table2")
|
||||
jgroup(jdict('a',a,'b',b))
|
||||
-------------------------------------------------------------------------
|
||||
[{"a":[1,2],"b":1},{"a":[3,4],"b":1},{"a":[5,6],"b":2},{"a":[7,8],"b":2}]
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = []
|
||||
|
||||
def step(self, *args):
|
||||
if len(args) == 1:
|
||||
self.outgroup += (jopts.elemfromj(args[0]))
|
||||
else:
|
||||
self.outgroup.append(jopts.elemfromj(*args))
|
||||
|
||||
def final(self):
|
||||
return jopts.toj(self.outgroup)
|
||||
|
||||
|
||||
class jdictgroup:
|
||||
"""
|
||||
.. function:: jdictgroup(columns)
|
||||
|
||||
Groups columns of a group into a jdict.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... word1 1
|
||||
... word2 1
|
||||
... word3 2
|
||||
... word4 2
|
||||
... ''')
|
||||
>>> sql("select jdictgroup(a) from table1 group by b")
|
||||
jdictgroup(a)
|
||||
---------------------------
|
||||
{"word1":null,"word2":null}
|
||||
{"word3":null,"word4":null}
|
||||
|
||||
>>> sql("select jdictgroup(a,b) from table1")
|
||||
jdictgroup(a,b)
|
||||
-----------------------------------------
|
||||
{"word1":1,"word2":1,"word3":2,"word4":2}
|
||||
|
||||
>>> table2('''
|
||||
... [1,2] 1
|
||||
... [3,4] 1
|
||||
... [5,6] 2
|
||||
... [7,8] 2
|
||||
... ''')
|
||||
|
||||
>>> sql("select jdictgroup(a) from table2")
|
||||
jdictgroup(a)
|
||||
-----------------------------------------------------
|
||||
{"[1,2]":null,"[3,4]":null,"[5,6]":null,"[7,8]":null}
|
||||
|
||||
>>> sql("select jdictgroup(a,b) from table2")
|
||||
jdictgroup(a,b)
|
||||
-----------------------------------------
|
||||
{"[1,2]":1,"[3,4]":1,"[5,6]":2,"[7,8]":2}
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = OrderedDict()
|
||||
|
||||
def step(self, *args):
|
||||
if len(args) == 1:
|
||||
self.outgroup[args[0]] = None
|
||||
else:
|
||||
self.outgroup[args[0]] = jopts.fromjsingle(*args[1:])
|
||||
|
||||
def final(self):
|
||||
return jopts.toj(self.outgroup)
|
||||
|
||||
|
||||
class jgroupunion:
|
||||
"""
|
||||
.. function:: jgroupunion(columns) -> jpack
|
||||
|
||||
Calculates the union of the jpacks (by treating them as sets) inside a group.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... '[1,2]' 6
|
||||
... '[2,3]' 7
|
||||
... '[2,4]' '[8,11]'
|
||||
... 5 9
|
||||
... ''')
|
||||
>>> sql("select jgroupunion(a,b) from table1")
|
||||
jgroupunion(a,b)
|
||||
----------------------
|
||||
[1,2,6,3,7,4,8,11,5,9]
|
||||
|
||||
>>> sql("select jgroupunion(1)")
|
||||
jgroupunion(1)
|
||||
--------------
|
||||
1
|
||||
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = OrderedDict()
|
||||
self.outgroupupdate = self.outgroup.update
|
||||
|
||||
def step(self, *args):
|
||||
self.outgroupupdate([(x, None) for x in jopts.fromj(*args)])
|
||||
|
||||
def final(self):
|
||||
return jopts.toj(list(self.outgroup))
|
||||
|
||||
|
||||
class jgroupintersection:
|
||||
"""
|
||||
.. function:: jgroupintersection(columns) -> jpack
|
||||
|
||||
Calculates the intersection of all jpacks (by treating them as sets) inside a group.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... '[1,2]' 2
|
||||
... '[2,3]' 2
|
||||
... '[2,4]' '[2,11]'
|
||||
... 2 2
|
||||
... ''')
|
||||
>>> sql("select jgroupintersection(a,b) from table1")
|
||||
jgroupintersection(a,b)
|
||||
-----------------------
|
||||
2
|
||||
|
||||
>>> sql("select jgroupintersection(1)")
|
||||
jgroupintersection(1)
|
||||
---------------------
|
||||
1
|
||||
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = None
|
||||
self.outset = None
|
||||
|
||||
def step(self, *args):
|
||||
if self.outgroup == None:
|
||||
self.outgroup = OrderedDict([(x, None) for x in jopts.fromj(args[0])])
|
||||
self.outset = set(self.outgroup)
|
||||
for jp in args:
|
||||
for i in self.outset.difference(jopts.fromj(jp)):
|
||||
del (self.outgroup[i])
|
||||
self.outset = set(self.outgroup)
|
||||
|
||||
def final(self):
|
||||
return jopts.toj(list(self.outgroup))
|
||||
|
||||
|
||||
class jdictgroupunion:
|
||||
"""
|
||||
.. function:: jgroupunion(jdicts) -> jdict
|
||||
|
||||
Calculates the union of all jdicts inside a group. The returned jdict's key values, are
|
||||
calculated as the max length of the lists (or dictionaries) that have been found inside
|
||||
the individual jdicts of the group.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... '{"b":1, "a":1}'
|
||||
... '{"c":1, "d":[1,2,3]}'
|
||||
... '{"b":{"1":2,"3":4}, "d":1}'
|
||||
... ''')
|
||||
>>> sql("select jdictgroupunion(a) from table1")
|
||||
jdictgroupunion(a)
|
||||
-------------------------
|
||||
{"b":2,"a":1,"c":1,"d":3}
|
||||
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = OrderedDict()
|
||||
|
||||
def step(self, *args):
|
||||
for d in args:
|
||||
for x, v in json.loads(d, object_pairs_hook=OrderedDict).iteritems():
|
||||
vlen = 1
|
||||
if type(v) in (list, OrderedDict):
|
||||
vlen = len(v)
|
||||
try:
|
||||
if vlen > self.outgroup[x]:
|
||||
self.outgroup[x] = vlen
|
||||
except KeyError:
|
||||
self.outgroup[x] = vlen
|
||||
|
||||
def final(self):
|
||||
return json.dumps(self.outgroup, separators=(',', ':'), ensure_ascii=False)
|
||||
|
||||
|
||||
class jgroupunionkeys:
|
||||
"""
|
||||
.. function:: jgroupunionkeys(columns) -> jpack
|
||||
|
||||
Calculates the union of the jdict keys. Use it with care, because for performance
|
||||
reasons the input data are not checked at all. They should all be jdicts.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... '{"1":1, "2":3}' '{"a":5}'
|
||||
... '{"2":1, "3":3}' '{}'
|
||||
... ''')
|
||||
>>> sql("select jgroupunionkeys(a,b) from table1")
|
||||
jgroupunionkeys(a,b)
|
||||
--------------------
|
||||
["1","2","a","3"]
|
||||
|
||||
>>> sql("select jgroupunionkeys('{}')")
|
||||
jgroupunionkeys('{}')
|
||||
---------------------
|
||||
[]
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.outgroup = OrderedDict()
|
||||
self.outgroupset = set()
|
||||
|
||||
def step(self, *args):
|
||||
for arg in args:
|
||||
v = json.loads(arg)
|
||||
if not set(v).issubset(self.outgroup):
|
||||
self.outgroupset.update(v)
|
||||
self.outgroup.update([(k, None) for k in json.loads(arg, object_pairs_hook=OrderedDict).iterkeys()])
|
||||
|
||||
def final(self):
|
||||
return jopts.toj(list(self.outgroup))
|
||||
|
||||
|
||||
class jgroupuniquelimit:
|
||||
"""
|
||||
.. function:: jgroupuniquelimit(jpack, k, limit) -> jpack
|
||||
|
||||
Returns the k where the unique values inside all jpacks have reached limit.
|
||||
|
||||
Example:
|
||||
|
||||
>>> table1('''
|
||||
... '[1,2]' 1
|
||||
... '[2,3,4,5]' 2
|
||||
... '[2,4]' 3
|
||||
... 5 4
|
||||
... ''')
|
||||
>>> sql("select jgroupuniquelimit(a,b,3) from table1")
|
||||
jgroupuniquelimit(a,b,3)
|
||||
------------------------
|
||||
2
|
||||
|
||||
"""
|
||||
|
||||
registered = True #Value to define db operator
|
||||
|
||||
def __init__(self):
|
||||
self.gset = set()
|
||||
self.k = None
|
||||
|
||||
def step(self, *args):
|
||||
if self.k is None:
|
||||
self.gset.update([(x, None) for x in jopts.fromj(args[0])])
|
||||
|
||||
if len(self.gset) >= args[-1]:
|
||||
self.k = args[1]
|
||||
|
||||
def final(self):
|
||||
return self.k
|
||||
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
|
@ -0,0 +1,415 @@
|
|||
import re
|
||||
import itertools
|
||||
import setpath
|
||||
import functions
|
||||
import lib.jopts as jopts
|
||||
from operator import itemgetter
|
||||
import random
|
||||
|
||||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
re_params=re.compile('(\w*):(.*)')
|
||||
|
||||
def consumer(func):
|
||||
"""A decorator, advances func to its first yield point when called.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args,**kw):
|
||||
gen = func(*args, **kw)
|
||||
gen.next()
|
||||
return gen
|
||||
return wrapper
|
||||
|
||||
|
||||
class freqitemsets:
|
||||
"""
|
||||
.. function:: freqitemsets(datacol, [threshold, noautothres, stats, maxlen]) -> [itemset_id:int, itemset_length:int, itemset_frequency:int, item:text]
|
||||
|
||||
Calculates frequent itemsets on a given column (datacol). The algorithm is tuned for the
|
||||
case when we have many different items (in the order of millions), many input itemsets, but
|
||||
small itemset length (10-20).
|
||||
|
||||
Returned table schema:
|
||||
|
||||
:itemset_id: Automatic itemset id
|
||||
:itemset_length: Length of itemset
|
||||
:itemset_frequency: How many times an itemset has been found
|
||||
:item: Itemset's item value
|
||||
|
||||
Parameters:
|
||||
|
||||
:datacol:
|
||||
|
||||
Column on which to calculate frequent itemsets
|
||||
|
||||
:threshold: Default is 2
|
||||
|
||||
How many times an freq. itemset must appear for it to appear in the results
|
||||
|
||||
:noautothres: 1/0 (Default is 0)
|
||||
|
||||
Do not calculate the threshold automatically
|
||||
|
||||
:stats: 1/0 (Default is 0)
|
||||
|
||||
Return frequent itemset statistics
|
||||
|
||||
:maxlen: NUMBER (Default is no limit at all)
|
||||
|
||||
Maximum itemset length to search
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 'car wood bike' 'first group'
|
||||
... 'car car wood' 'first group'
|
||||
... 'car wood' 'first group'
|
||||
... 'car wood ice' 'first group'
|
||||
... 'ice' 'second group'
|
||||
... 'car ice' 'second group'
|
||||
... 'car cream toy' 'second group'
|
||||
... 'icecream ice car toy' 'second group'
|
||||
... ''')
|
||||
>>> sql("select b,freqitemsets(a, 'threshold:2', 'noautothres:1', 'maxlen:2') from table1 group by b")
|
||||
b | itemset_id | itemset_length | itemset_frequency | item
|
||||
---------------------------------------------------------------------
|
||||
first group | 1 | 1 | 4 | wood
|
||||
first group | 2 | 1 | 4 | car
|
||||
first group | 3 | 2 | 4 | car
|
||||
first group | 3 | 2 | 4 | wood
|
||||
second group | 1 | 1 | 3 | ice
|
||||
second group | 2 | 1 | 3 | car
|
||||
second group | 3 | 1 | 2 | toy
|
||||
second group | 4 | 2 | 2 | car
|
||||
second group | 4 | 2 | 2 | ice
|
||||
second group | 5 | 2 | 2 | car
|
||||
second group | 5 | 2 | 2 | toy
|
||||
|
||||
>>> sql("select b,freqitemsets(a, 'stats:1') from table1 group by b")
|
||||
b | MaxTransactionLength | CombinationCount | PassedTransactions | ValidKeywords
|
||||
-------------------------------------------------------------------------------------------
|
||||
first group | 3 | 2 | 3 | 2
|
||||
first group | 3 | 1 | 1 | 2
|
||||
first group | 3 | 0 | 0 | 0
|
||||
second group | 4 | 3 | 3 | 3
|
||||
second group | 4 | 0 | 3 | 0
|
||||
"""
|
||||
|
||||
|
||||
registered=True
|
||||
multiset=True
|
||||
|
||||
def __init__(self):
|
||||
self.threshold=2
|
||||
self.startingthreshold=2
|
||||
self.autothres=1
|
||||
self.compress=0
|
||||
self.initstatic=False
|
||||
self.input={}
|
||||
self.maxlength=0
|
||||
self.kwcode={}
|
||||
self.codekw={}
|
||||
self.maxkwcode=0
|
||||
self.overthres={}
|
||||
self.belowthres={}
|
||||
self.passedkw={}
|
||||
self.init=True
|
||||
self.itemset_id=0
|
||||
self.maxlen=None
|
||||
self.stats=False
|
||||
|
||||
def initargs(self, args):
|
||||
self.init=False
|
||||
for i in xrange(1, len(args)):
|
||||
v=re_params.match(args[i])
|
||||
if v is not None and v.groups()[0]!='' and v.groups()[1]!='' and i>0:
|
||||
v=v.groups()
|
||||
if v[0]=='threshold':
|
||||
try:
|
||||
self.threshold=int(v[1])
|
||||
self.startingthreshold=self.threshold
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
raise functions.OperatorError("FreqItemsets",'No integer value given for threshold')
|
||||
if v[0]=='noautothres':
|
||||
self.autothres=0
|
||||
if v[0]=='compress':
|
||||
self.compress=1
|
||||
if v[0]=='maxlen':
|
||||
self.maxlen=int(v[1])
|
||||
if v[0]=='stats':
|
||||
self.stats=True
|
||||
|
||||
def demultiplex(self, data):
|
||||
iterable=None
|
||||
iterpos=-1
|
||||
|
||||
for i in xrange(len(data)):
|
||||
if hasattr(data[i],'__iter__')==True:
|
||||
iterable=data[i]
|
||||
iterpos=i
|
||||
break
|
||||
|
||||
if iterpos==-1:
|
||||
yield list(data)
|
||||
else:
|
||||
pre=list(data[0:iterpos])
|
||||
post=list(data[iterpos+1:])
|
||||
for i in iterable:
|
||||
if hasattr(i,'__iter__')==False:
|
||||
yield pre+[i]+post
|
||||
else:
|
||||
yield pre+list(i)+post
|
||||
|
||||
def insertcombfreq(self, comb, freq):
|
||||
if comb in self.overthres:
|
||||
self.overthres[comb]+=freq
|
||||
else:
|
||||
if comb in self.belowthres:
|
||||
self.belowthres[comb]+=freq
|
||||
else:
|
||||
self.belowthres[comb]=freq
|
||||
|
||||
if self.belowthres[comb]>=self.threshold:
|
||||
self.overthres[comb]=self.belowthres[comb]
|
||||
del(self.belowthres[comb])
|
||||
for k in comb:
|
||||
if self.compress==0:
|
||||
self.passedkw[k]=True
|
||||
elif not k in self.passedkw:
|
||||
self.passedkw[k]=self.overthres[comb]
|
||||
else:
|
||||
self.passedkw[k]+=self.overthres[comb]
|
||||
|
||||
def insertitemset(self, itemset):
|
||||
if itemset not in self.input:
|
||||
self.input[itemset]=1
|
||||
else:
|
||||
self.input[itemset]+=1
|
||||
|
||||
def cleanitemsets(self, minlength):
|
||||
newitemsets={}
|
||||
for k,v in self.input.iteritems():
|
||||
itemset=tuple(i for i in k if i in self.passedkw)
|
||||
if self.compress==1:
|
||||
esoteric_itemset=tuple(i for i in itemset if self.passedkw[i]==v)
|
||||
if len(esoteric_itemset)>0:
|
||||
if len(itemset)>=minlength:
|
||||
self.overthres[itemset]=v
|
||||
itemset=tuple(i for i in itemset if self.passedkw[i]!=v)
|
||||
if len(itemset)>=minlength:
|
||||
if itemset not in newitemsets:
|
||||
newitemsets[itemset]=v
|
||||
else:
|
||||
newitemsets[itemset]+=v
|
||||
|
||||
self.input=newitemsets
|
||||
|
||||
def step(self, *args):
|
||||
if self.init==True:
|
||||
self.initargs(args)
|
||||
|
||||
if len(args[0])==0:
|
||||
return
|
||||
|
||||
itms=sorted(set(args[0].split(' ')))
|
||||
itms=[x for x in itms if x!='']
|
||||
li=len(itms)
|
||||
if li>0:
|
||||
if li>self.maxlength:
|
||||
self.maxlength=li
|
||||
|
||||
inputkws=[]
|
||||
for kw in itms:
|
||||
if len(kw)==0:
|
||||
print itms, args[0], len(args[0]), li
|
||||
if kw not in self.kwcode:
|
||||
self.kwcode[kw]=self.maxkwcode
|
||||
self.codekw[self.maxkwcode]=kw
|
||||
inputkws.append(self.maxkwcode)
|
||||
self.insertcombfreq( (self.maxkwcode,),1 )
|
||||
self.maxkwcode+=1
|
||||
else:
|
||||
itm=self.kwcode[kw]
|
||||
self.insertcombfreq( (itm,),1 )
|
||||
inputkws.append(itm)
|
||||
|
||||
if len(inputkws)>1:
|
||||
self.insertitemset(tuple(inputkws))
|
||||
|
||||
def final(self):
|
||||
if not self.stats:
|
||||
yield ('itemset_id', 'itemset_length', 'itemset_frequency', 'item')
|
||||
else:
|
||||
yield ('MaxTransactionLength', 'CombinationCount', 'PassedTransactions', 'ValidKeywords')
|
||||
|
||||
splist=[{},{}]
|
||||
del(self.kwcode)
|
||||
splist[1]=self.overthres
|
||||
|
||||
if self.stats:
|
||||
yield [self.maxlength, len(splist[1]), len(self.input), len(self.passedkw)]
|
||||
|
||||
if not self.stats:
|
||||
for its,v in sorted(splist[1].items(), key=itemgetter(1),reverse=True):
|
||||
self.itemset_id+=1
|
||||
for i in self.demultiplex( (self.itemset_id, len([self.codekw[i] for i in its]), v, [self.codekw[i] for i in its]) ):
|
||||
yield i
|
||||
|
||||
if self.maxlen==None:
|
||||
self.maxlen=self.maxlength
|
||||
for l in xrange(2, min(self.maxlength+1, self.maxlen+1)):
|
||||
splist.append({})
|
||||
self.belowthres={}
|
||||
self.overthres={}
|
||||
prevl=l-1
|
||||
|
||||
# Autothresholding
|
||||
if self.autothres==1:
|
||||
if len(self.input)==0 or len(self.passedkw)==0:
|
||||
break
|
||||
else:
|
||||
self.threshold=self.startingthreshold + int(len(self.passedkw)/len(self.input))
|
||||
|
||||
self.cleanitemsets(l)
|
||||
self.passedkw={}
|
||||
prevsplist = splist[prevl]
|
||||
icombs = itertools.combinations
|
||||
insertcomb = self.insertcombfreq
|
||||
|
||||
for k,v in self.input.iteritems():
|
||||
for k in icombs(k,l):
|
||||
insertit=True
|
||||
for i1 in icombs(k, prevl):
|
||||
if i1 not in prevsplist:
|
||||
insertit=False
|
||||
break
|
||||
|
||||
if insertit:
|
||||
insertcomb( k,v )
|
||||
|
||||
splist[l-1]={}
|
||||
splist[l]=self.overthres
|
||||
|
||||
if self.stats:
|
||||
yield [self.maxlength, len(splist[l]), len(self.input), len(self.passedkw)]
|
||||
|
||||
if not self.stats:
|
||||
for its,v in sorted(splist[l].items(), key=itemgetter(1),reverse=True):
|
||||
self.itemset_id+=1
|
||||
for i in self.demultiplex( (self.itemset_id, len([self.codekw[i] for i in its]), v, [self.codekw[i] for i in its]) ):
|
||||
yield i
|
||||
|
||||
del(self.overthres)
|
||||
del(self.belowthres)
|
||||
del(self.passedkw)
|
||||
del(self.input)
|
||||
del(self.codekw)
|
||||
del(splist)
|
||||
|
||||
class sampledistvals:
|
||||
"""
|
||||
|
||||
.. function:: sampledistvals(sample_size, C1, C2, C3) -> [C1, C2, C3]
|
||||
|
||||
Sampledistvals returns sample_size distinct values for each of the input C1..Cn columns.
|
||||
|
||||
>>> table1('''
|
||||
... test1 2 3
|
||||
... test1 2 3
|
||||
... test2 4 2
|
||||
... test4 2 t
|
||||
... ''')
|
||||
>>> sql("select sampledistvals(3, a, b, c) from table1")
|
||||
C1 | C2 | C3
|
||||
---------------------------------------------
|
||||
["test1","test2","test4"] | [2,4] | [2,3,"t"]
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.vals=None
|
||||
self.lenargs = -1
|
||||
self.init=True
|
||||
|
||||
def step(self, *args):
|
||||
if self.init:
|
||||
self.lenargs = len(args)
|
||||
self.vals = a=[set() for i in xrange(self.lenargs-1)]
|
||||
self.init = False
|
||||
|
||||
for i in xrange(1, self.lenargs):
|
||||
if len(self.vals[i-1])<args[0] and args[i] not in self.vals[i-1]:
|
||||
self.vals[i-1].add(args[i])
|
||||
|
||||
def final(self):
|
||||
yield tuple(['C'+str(i) for i in xrange(1, self.lenargs)] )
|
||||
yield [jopts.toj(list(i)) for i in self.vals]
|
||||
|
||||
class samplegroup:
|
||||
"""
|
||||
|
||||
.. function:: samplegroup(sample_size, C1, C2, C3)
|
||||
|
||||
Returns a random sample_size set of rows.
|
||||
|
||||
>>> table1('''
|
||||
... test1 2 3
|
||||
... test1 2 3
|
||||
... test2 4 2
|
||||
... test4 2 t
|
||||
... ''')
|
||||
|
||||
>>> sql("select samplegroup(2, a, b, c) from table1") # doctest: +ELLIPSIS
|
||||
C1 | C2 | C3
|
||||
---------------
|
||||
...
|
||||
|
||||
>>> sql("select samplegroup(2) from (select 5 where 5=6)") # doctest: +ELLIPSIS
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.samplelist = []
|
||||
self.index = 0
|
||||
self.random = random.randint
|
||||
|
||||
def step(self, *args):
|
||||
# Generate the reservoir
|
||||
if self.index < args[0]:
|
||||
self.samplelist.append(args)
|
||||
else:
|
||||
r = self.random(0, self.index)
|
||||
if r < args[0]:
|
||||
self.samplelist[r] = args
|
||||
|
||||
self.index += 1
|
||||
|
||||
def final(self):
|
||||
if self.samplelist == []:
|
||||
yield tuple(['C1'])
|
||||
else:
|
||||
yield tuple(['C'+str(i) for i in xrange(1, len(self.samplelist[0]))] )
|
||||
for r in self.samplelist:
|
||||
yield list(r[1:])
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import functions
|
||||
import operator
|
||||
|
||||
class partialsort:
|
||||
"""
|
||||
|
||||
.. function:: partialsort(n,col1,col2,col3,....)
|
||||
|
||||
sorts the first n columns of its input
|
||||
|
||||
:Returned multiset schema:
|
||||
Columns are automatically named as col1, col2 ...
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... aa 43
|
||||
... ac 34
|
||||
... ab 21
|
||||
... as 23
|
||||
... ''')
|
||||
>>> sql("select partialsort(1,a,b) from table1")
|
||||
c1 | c2
|
||||
-------
|
||||
aa | 43
|
||||
ab | 21
|
||||
ac | 34
|
||||
as | 23
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.topn=[]
|
||||
self.lessval=None
|
||||
self.stepsnum=0
|
||||
self.sortnum = None
|
||||
|
||||
def step(self, *args):
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("partialsort","Wrong number of arguments")
|
||||
if not self.sortnum:
|
||||
self.sortnum = tuple(i for i in xrange(args[0]))
|
||||
self.topn.append(args[1:])
|
||||
self.stepsnum+=1
|
||||
pass
|
||||
|
||||
def final(self):
|
||||
yield tuple('c'+str(i) for i in xrange(1,len(self.topn[0])+1))
|
||||
self.topn.sort(key=operator.itemgetter(*self.sortnum))
|
||||
for el in self.topn:
|
||||
yield el
|
||||
|
||||
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -0,0 +1,396 @@
|
|||
import setpath
|
||||
import Queue
|
||||
import functions
|
||||
|
||||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
class imax:
|
||||
"""
|
||||
|
||||
.. function:: imax(i,value)
|
||||
|
||||
Returns the i-th max value of the group.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 34 la
|
||||
... 18 lo
|
||||
... 120.0 all
|
||||
... ''')
|
||||
>>> sql("select imax(1,a) as first from table1")
|
||||
first
|
||||
-----
|
||||
120
|
||||
>>> sql("select imax(3,a) as third from table1")
|
||||
third
|
||||
-----
|
||||
18
|
||||
>>> sql("select imax(2,cast( a as text)) as secstr from table1")
|
||||
secstr
|
||||
------
|
||||
18
|
||||
>>> sql("select imax(4,a) from table1")
|
||||
imax(4,a)
|
||||
---------
|
||||
None
|
||||
>>> sql("select imax(4,a) from (select 5 as a where a!=5)")
|
||||
imax(4,a)
|
||||
---------
|
||||
None
|
||||
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.topn=None
|
||||
self.size=None
|
||||
self.strtype=False
|
||||
self.anytype=True
|
||||
self.lessval=None
|
||||
self.stepsnum=0
|
||||
self.valarg=None
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("imax","No arguments")
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("imax","Wrong number of arguments")
|
||||
if not self.size:
|
||||
try:
|
||||
self.size=int(args[0])
|
||||
self.topn=Queue.PriorityQueue(self.size)
|
||||
except ValueError:
|
||||
raise functions.OperatorError("imax","Wrong type in first argument")
|
||||
|
||||
curval=args[1]
|
||||
if not self.topn.full():
|
||||
self.topn.put_nowait(curval)
|
||||
else:
|
||||
curless=self.topn.get()
|
||||
self.topn.put_nowait(max(curval,curless))
|
||||
self.stepsnum+=1
|
||||
|
||||
|
||||
def final(self):
|
||||
if not self.size:
|
||||
return
|
||||
if self.stepsnum<self.size:
|
||||
return None
|
||||
return self.topn.get()
|
||||
|
||||
class q2list:
|
||||
def __init__(self,queue):
|
||||
self.q=queue
|
||||
def __iter__(self):
|
||||
return self
|
||||
def next(self):
|
||||
if self.q.empty():
|
||||
raise StopIteration
|
||||
a=self.q.get_nowait()
|
||||
self.q.put_nowait(a)
|
||||
return a
|
||||
|
||||
|
||||
def typed(arg):
|
||||
try:
|
||||
arg=int(arg)
|
||||
except ValueError:
|
||||
try:
|
||||
arg=float(arg)
|
||||
except ValueError:
|
||||
pass
|
||||
return
|
||||
|
||||
class minrow:
|
||||
"""
|
||||
|
||||
.. function:: minrow(compare,value)
|
||||
|
||||
Compares group members over the first argument (i.e. *compare*).
|
||||
When the minimum is located, it returns the corresponding value in the second argument (i.e. *value*).
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 34 la
|
||||
... 18 lo
|
||||
... 120.0 all
|
||||
... ''')
|
||||
>>> sql("select minrow(a,b) as b from table1")
|
||||
b
|
||||
--
|
||||
lo
|
||||
>>> sql("select minrow(a,a) as a from table1")
|
||||
a
|
||||
--
|
||||
18
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
>>> sql("select minrow(a,a) as a from (select 5 as a where a!=5)")
|
||||
a
|
||||
----
|
||||
None
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.minv=None
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("minrow","No arguments")
|
||||
if len(args)!=2:
|
||||
raise functions.OperatorError("minrow","Wrong number of arguments")
|
||||
if not self.minv:
|
||||
self.minv=(args[0],args[1])
|
||||
elif args[0]<self.minv[0]:
|
||||
self.minv=(args[0],args[1])
|
||||
|
||||
|
||||
def final(self):
|
||||
if not self.minv:
|
||||
return None
|
||||
return self.minv[1]
|
||||
|
||||
class maxrow:
|
||||
"""
|
||||
.. function:: maxrow(compare,value)
|
||||
|
||||
Compares group members over the first argument (i.e. *compare*).
|
||||
When the maximum is located, it returns the corresponding value in the second argument (i.e. *value*).
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 34 la
|
||||
... 18 lo
|
||||
... 120.0 all
|
||||
... ''')
|
||||
>>> sql("select maxrow(a,b) as b from table1")
|
||||
b
|
||||
---
|
||||
all
|
||||
>>> sql("select maxrow(a,a) as a from table1")
|
||||
a
|
||||
---
|
||||
120
|
||||
>>> sql("select maxrow(b,a) as a from table1")
|
||||
a
|
||||
--
|
||||
18
|
||||
"""
|
||||
registered=True
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.maxv=None
|
||||
self.first=True
|
||||
|
||||
def step(self, *args):
|
||||
if self.first:
|
||||
if not args:
|
||||
raise functions.OperatorError("maxrow","No arguments")
|
||||
if len(args)!=2:
|
||||
raise functions.OperatorError("maxrow","Wrong number of arguments")
|
||||
self.maxv=(args[0],args[1])
|
||||
self.first=False
|
||||
return
|
||||
self.maxv=max(self.maxv,args)
|
||||
|
||||
|
||||
def final(self):
|
||||
if not self.maxv:
|
||||
return None
|
||||
return self.maxv[1]
|
||||
|
||||
class groupdiff:
|
||||
"""
|
||||
.. function:: groupdiff(compare,values)
|
||||
|
||||
Compares group members over the first argument (i.e. *compare*). It keeps only the rows where *compare* changes.
|
||||
It appends a column at the end containing how many times *compare* repeats.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 0 a
|
||||
... 0 b
|
||||
... 1 c
|
||||
... 1 d
|
||||
... 2 e
|
||||
... 3 e
|
||||
... 3 f
|
||||
... 3 g
|
||||
... ''')
|
||||
>>> sql("select groupdiff(a,b) as b from table1")
|
||||
b1 | b2 | b3
|
||||
------------
|
||||
0 | a | 2
|
||||
1 | c | 2
|
||||
2 | e | 1
|
||||
3 | e | 3
|
||||
>>> sql("select groupdiff(a) as a from table1")
|
||||
a1 | a2
|
||||
-------
|
||||
0 | 2
|
||||
1 | 2
|
||||
2 | 1
|
||||
3 | 3
|
||||
>>> sql("select groupdiff(b,a) as a from table1")
|
||||
a1 | a2 | a3
|
||||
------------
|
||||
a | 0 | 1
|
||||
b | 0 | 1
|
||||
c | 1 | 1
|
||||
d | 1 | 1
|
||||
e | 2 | 2
|
||||
f | 3 | 1
|
||||
g | 3 | 1
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.first=True
|
||||
self.data=[]
|
||||
self.prevcomp=None
|
||||
self.size=0
|
||||
self.repeat=1
|
||||
|
||||
def step(self, *args):
|
||||
if self.first:
|
||||
if not args:
|
||||
raise functions.OperatorError("groupdiff","No arguments")
|
||||
self.prevcomp=args[0]
|
||||
self.data.append(list(args))
|
||||
self.first=False
|
||||
self.size=len(args)
|
||||
return
|
||||
|
||||
if args[0]!=self.prevcomp:
|
||||
self.prevcomp=args[0]
|
||||
self.data[-1].append(self.repeat)
|
||||
self.data.append(list(args))
|
||||
self.repeat=1
|
||||
else:
|
||||
self.repeat+=1
|
||||
|
||||
def final(self):
|
||||
self.data[-1].append(self.repeat)
|
||||
yield tuple(["compid"]+["C"+str(i) for i in xrange(1,self.size)]+["repetition"])
|
||||
for i in self.data:
|
||||
yield i
|
||||
|
||||
|
||||
class ontop:
|
||||
"""
|
||||
|
||||
.. function:: ontop(n,compare,value1,value2,....) -> [colname1, colname2 ...]
|
||||
|
||||
Compares group members over the second argument (i.e. *compare*), so as to locate the top *n* members
|
||||
(specified in the first argument) and then returns the corresponding data under the specified columns
|
||||
*value1, value2, ....*.
|
||||
|
||||
:Returned multiset schema:
|
||||
Columns are automatically named as *colname1 text, colname2 text...*
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`tutmultiset` functions
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... 34 la
|
||||
... 18 lo
|
||||
... 120.0 all
|
||||
... ''')
|
||||
>>> sql("select ontop(1,a,b) from table1")
|
||||
top1
|
||||
----
|
||||
all
|
||||
>>> sql("select ontop(2,a,a,b) from table1")
|
||||
top1 | top2
|
||||
-----------
|
||||
120 | all
|
||||
34 | la
|
||||
|
||||
>>> sql("select ontop(2,a,a,b,a,b) from table1")
|
||||
top1 | top2 | top3 | top4
|
||||
-------------------------
|
||||
120 | all | 120 | all
|
||||
34 | la | 34 | la
|
||||
|
||||
>>> sql("select ontop(pk) from (select 5 as pk where pk!=5)")
|
||||
top1
|
||||
-
|
||||
"""
|
||||
registered=True
|
||||
multiset=True
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.topn=None
|
||||
self.size=None
|
||||
self.lessval=None
|
||||
self.stepsnum=0
|
||||
self.argnum = 1
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("ontop","No arguments")
|
||||
if len(args)<3:
|
||||
raise functions.OperatorError("ontop","Wrong number of arguments")
|
||||
if not self.size:
|
||||
try:
|
||||
self.size=int(args[0])
|
||||
self.topn=Queue.PriorityQueue(self.size)
|
||||
self.argnum = len(args)-2
|
||||
except ValueError:
|
||||
raise functions.OperatorError("ontop","Wrong type in first argument")
|
||||
|
||||
inparg=args[1]
|
||||
outarg=args[2:]
|
||||
|
||||
if not self.topn.full():
|
||||
self.topn.put_nowait((inparg,outarg))
|
||||
else:
|
||||
inparg_old , outarg_old=self.topn.get_nowait()
|
||||
self.topn.put_nowait(max((inparg,outarg),(inparg_old ,outarg_old)))
|
||||
|
||||
self.stepsnum+=1
|
||||
|
||||
|
||||
def final(self):
|
||||
output=[]
|
||||
if self.topn:
|
||||
while not self.topn.empty():
|
||||
output+=[self.topn.get_nowait()[1]]
|
||||
|
||||
yield tuple(["top"+str(i+1) for i in xrange(self.argnum)])
|
||||
|
||||
for el in reversed(output):
|
||||
yield el
|
||||
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import sys, os
|
||||
curmodulepath = os.path.dirname( os.path.abspath(__file__) )
|
||||
sys.path.append(os.path.abspath(os.path.join(curmodulepath,'..','..')))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,667 @@
|
|||
import setpath
|
||||
import Queue
|
||||
import functions
|
||||
from lib import iso8601
|
||||
from operator import itemgetter
|
||||
from lib import jopts
|
||||
from lib.unicodeops import unistr
|
||||
|
||||
__docformat__ = 'reStructuredText en'
|
||||
|
||||
|
||||
def timedelta2millisec(tdelta):
|
||||
return tdelta.days*24*60*60*1000+tdelta.seconds*1000+tdelta.microseconds
|
||||
|
||||
class groupsum:
|
||||
"""
|
||||
.. function:: groupsum(n,col1,col2,col3,....)
|
||||
|
||||
It groups by the first n columns of the input, and sums/jsets the rest.
|
||||
|
||||
:Returned schema:
|
||||
Columns are automatically named as col1, col2 ...
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... aa t1 43
|
||||
... ac t2 34
|
||||
... aa t3 12
|
||||
... ab t4 21
|
||||
... ac t5 14
|
||||
... as t6 23
|
||||
... ''')
|
||||
>>> sql("select groupsum(1,a,b,c) from table1")
|
||||
c1 | c2 | c3
|
||||
---------------------
|
||||
ac | ["t2","t5"] | 48
|
||||
aa | ["t1","t3"] | 55
|
||||
ab | t4 | 21
|
||||
as | t6 | 23
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.notchecked = True
|
||||
self.groupsdict = {}
|
||||
self.grouplen = 0
|
||||
self.numofargs = 0
|
||||
def step(self, *args):
|
||||
if self.notchecked:
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("groupsum","Wrong number of arguments")
|
||||
self.grouplen = args[0]
|
||||
self.numofargs = len(args)
|
||||
self.notchecked = False
|
||||
|
||||
groupkey = args[1:self.grouplen+1]
|
||||
try:
|
||||
group = self.groupsdict[groupkey]
|
||||
j = 0
|
||||
for i in xrange(self.grouplen+1,self.numofargs):
|
||||
group[j].append(args[i])
|
||||
j += 1
|
||||
except KeyError:
|
||||
self.groupsdict[groupkey] = [[x] for x in args[self.grouplen+1:]]
|
||||
|
||||
def final(self):
|
||||
yield tuple('c'+str(i) for i in xrange(1,self.numofargs))
|
||||
for groupkey, sumcols in self.groupsdict.iteritems():
|
||||
cols = list(groupkey)
|
||||
for col in sumcols:
|
||||
try:
|
||||
cols.append(sum(col))
|
||||
except TypeError:
|
||||
cols.append(jopts.toj(sorted(set( jopts.fromj(*col) ))))
|
||||
yield cols
|
||||
|
||||
|
||||
class groupmax:
|
||||
"""
|
||||
.. function:: groupmax(n,col1,col2,col3,....)
|
||||
|
||||
It groups by the first n columns of the input, and returns the maximum value of the rest.
|
||||
|
||||
:Returned schema:
|
||||
Columns are automatically named as col1, col2 ...
|
||||
|
||||
Examples:
|
||||
|
||||
>>> table1('''
|
||||
... aa t1 43
|
||||
... ac t2 34
|
||||
... aa t3 12
|
||||
... ab t4 21
|
||||
... ac t5 14
|
||||
... as t6 23
|
||||
... ''')
|
||||
>>> sql("select groupmax(1,a,b,c) from table1")
|
||||
c1 | c2 | c3
|
||||
------------
|
||||
ac | t5 | 34
|
||||
aa | t3 | 43
|
||||
ab | t4 | 21
|
||||
as | t6 | 23
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.notchecked = True
|
||||
self.groupsdict = {}
|
||||
self.grouplen = 0
|
||||
self.numofargs = 0
|
||||
def step(self, *args):
|
||||
if self.notchecked:
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("groupmax","Wrong number of arguments")
|
||||
self.grouplen = args[0]
|
||||
self.numofargs = len(args)
|
||||
self.notchecked = False
|
||||
|
||||
groupkey = args[1:self.grouplen+1]
|
||||
try:
|
||||
group = self.groupsdict[groupkey]
|
||||
j = 0
|
||||
for i in xrange(self.grouplen+1,self.numofargs):
|
||||
group[j].append(args[i])
|
||||
j += 1
|
||||
except KeyError:
|
||||
self.groupsdict[groupkey] = [[x] for x in args[self.grouplen+1:]]
|
||||
|
||||
def final(self):
|
||||
yield tuple('c'+str(i) for i in xrange(1,self.numofargs))
|
||||
for groupkey, sumcols in self.groupsdict.iteritems():
|
||||
cols = list(groupkey)
|
||||
for col in sumcols:
|
||||
cols.append(max(col))
|
||||
|
||||
yield cols
|
||||
|
||||
|
||||
|
||||
class condbreak:
|
||||
"""
|
||||
|
||||
.. function:: condbreak(groupid, C1, C2 ,...., condition, orderby) -> [bgroupid,C1,C2....]
|
||||
|
||||
Returns an expanded *groupid* and the *value1...valueN*, perfoming new groupings when condition is true. Rows grouped together
|
||||
are the ones that order by *orderby* column have no intermediate true values for *condition*.
|
||||
|
||||
:Returned multiset schema:
|
||||
- *bgroupid*
|
||||
*groupid* appended with an integer value indicating the subgroup of the row.
|
||||
- *C1, C2 ..*
|
||||
The input values of the row.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`tutmultiset` functions
|
||||
|
||||
>>> table1('''
|
||||
... 1 user1 open
|
||||
... 2 user1 read
|
||||
... 3 user1 close
|
||||
... 4 user1 open
|
||||
... 5 user1 write
|
||||
... 6 user1 close
|
||||
... 7 user2 open
|
||||
... 8 user2 write
|
||||
... ''')
|
||||
>>> sql("select condbreak(b,c,c='open',a) from table1 group by b")
|
||||
bgroupid | C1
|
||||
----------------
|
||||
user11 | open
|
||||
user11 | read
|
||||
user11 | close
|
||||
user12 | open
|
||||
user12 | write
|
||||
user12 | close
|
||||
user21 | open
|
||||
user21 | write
|
||||
>>> sql("select condbreak(b,c,c='open',a) from (select 4 as a, 6 as b, 9 as c where c!=9)")
|
||||
|
||||
"""
|
||||
registered=True
|
||||
multiset=True
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.vals=[]
|
||||
|
||||
def step(self, *args):
|
||||
if not args:
|
||||
raise functions.OperatorError("condbreak","No arguments")
|
||||
if len(args)<4:
|
||||
raise functions.OperatorError("condbreak","Wrong number of arguments")
|
||||
self.vals.append(list(args))
|
||||
|
||||
|
||||
|
||||
def final(self):
|
||||
self.vals.sort(key=lambda x:x[-1])
|
||||
if self.vals==[]:
|
||||
size=0
|
||||
else:
|
||||
size=len(self.vals[0])-2
|
||||
|
||||
if size<=0:
|
||||
yield ("bgroupid","C1")
|
||||
else:
|
||||
yield tuple(["bgroupid"]+["C"+str(i+1) for i in xrange(size-1)])
|
||||
|
||||
counter=0
|
||||
for el in self.vals:
|
||||
if el[-2]==True:
|
||||
counter+=1
|
||||
bid=unistr(el[0])+str(counter)
|
||||
yield [bid]+el[1:-2]
|
||||
|
||||
|
||||
class datediffbreak:
|
||||
"""
|
||||
|
||||
.. function:: datediffbreak(groupid, C1, C2 ,...., date, maxdiff[,'order',orderbycol1,orderbycol2,...]) -> [bgroupid,C1,C2....]
|
||||
|
||||
Returns an expanded *groupid* and the *value1...valueN*, perfoming new groupings when subsequent rows *date* values differ more than *maxdiff* milliseconds. Rows grouped together
|
||||
are the ones that order by *orderby* column or if ommited by the given order have less *date* distance than *maxdiff*. Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
:Returned multiset schema:
|
||||
- *bgroupid*
|
||||
*groupid* appended with an integer value indicating the subgroup of the row.
|
||||
- *C1, C2 ..*
|
||||
The input values of the row.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`tutmultiset` functions
|
||||
|
||||
>>> table1('''
|
||||
... 1 session1 '2007-01-01 00:03:13'
|
||||
... 2 session1 '2007-01-01 00:03:27'
|
||||
... 3 session1 '2007-01-01 00:03:36'
|
||||
... 4 session2 '2007-01-01 00:04:39'
|
||||
... 5 session2 '2007-01-01 00:04:40'
|
||||
... 6 session3 '2007-01-01 00:04:49'
|
||||
... 7 session3 '2007-01-01 00:04:59'
|
||||
... ''')
|
||||
>>> sql("select datediffbreak(b,a,c,10*1000,'order',c,a) from table1 group by b")
|
||||
bgroupid | C1
|
||||
--------------
|
||||
session10 | 1
|
||||
session11 | 2
|
||||
session11 | 3
|
||||
session20 | 4
|
||||
session20 | 5
|
||||
session30 | 6
|
||||
session30 | 7
|
||||
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
>>> sql("select datediffbreak(b,c,c='open',a) from (select 4 as a, 6 as b, 9 as c where c!=9)")
|
||||
bgroupid | C1
|
||||
---------------
|
||||
None | None
|
||||
>>> sql("select datediffbreak(b,a,c,10*1000,a,c) from table1 group by b") #doctest:+ELLIPSIS +NORMALIZE_WHITESPACE
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
OperatorError: Madis SQLError:
|
||||
Operator DATEDIFFBREAK: Wrong date format: 1
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.vals=[]
|
||||
self.init=True
|
||||
self.position=None
|
||||
self.comparesize=0
|
||||
self.fullsize=0
|
||||
|
||||
def initargs(self, args):
|
||||
self.init=False
|
||||
if not args:
|
||||
raise functions.OperatorError("datediffbreak","No arguments")
|
||||
if len(args)<4:
|
||||
raise functions.OperatorError("datediffbreak","Wrong number of arguments")
|
||||
self.maxdiff=args[-1]
|
||||
for i in xrange(len(args)):
|
||||
if args[i]=='order':
|
||||
self.position=i
|
||||
self.maxdiff=args[i-1]
|
||||
self.comparesize=len(args)-(i+1)
|
||||
if len(args)<5:
|
||||
raise functions.OperatorError("datediffbreak","Wrong number of arguments")
|
||||
break
|
||||
|
||||
def step(self, *args):
|
||||
if self.init:
|
||||
self.initargs(args)
|
||||
|
||||
if not self.position:
|
||||
self.vals.append(list(args[:-1]))
|
||||
else:
|
||||
self.vals.append(list(args[:self.position-1]+args[self.position+1:]))
|
||||
|
||||
|
||||
def final(self):
|
||||
if self.position:
|
||||
self.vals.sort(key=lambda x:tuple(x[-self.comparesize:]))
|
||||
if self.vals==[]:
|
||||
size=0
|
||||
else:
|
||||
size=len(self.vals[0])-self.comparesize-1
|
||||
|
||||
if size<=0:
|
||||
yield ("bgroupid","C1")
|
||||
yield [None, None]
|
||||
return
|
||||
|
||||
yield tuple(["bgroupid"]+["C"+str(i) for i in xrange(1,size)])
|
||||
|
||||
counter=0
|
||||
dt=None
|
||||
dtpos=self.comparesize+1
|
||||
for el in self.vals:
|
||||
try:
|
||||
dtnew=iso8601.parse_date(el[-dtpos])
|
||||
except Exception:
|
||||
raise functions.OperatorError("datediffbreak","Wrong date format: %s" %(el[-dtpos]))
|
||||
if dt and timedelta2millisec(dtnew-dt)>self.maxdiff:
|
||||
counter+=1
|
||||
dt=dtnew
|
||||
bid=unistr(el[0])+str(counter)
|
||||
yield [bid]+el[1:-dtpos]
|
||||
|
||||
class datediffnewsesid:
|
||||
"""
|
||||
|
||||
.. function:: datediffnewsesid(maxdiff, date, groupid, C1, C2 ,....) -> [bgroupid, C1, C2, ...]
|
||||
|
||||
Returns only the C1, C2, ... that should be updated with bgroupid, so as for the input groups to be effectively broken on maxdiff times.
|
||||
Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
|
||||
:Returned multiset schema:
|
||||
- *bgroupid*
|
||||
*groupid* appended with an integer value indicating the subgroup of the row.
|
||||
- *C1, C2 ..*
|
||||
The input values of the row.
|
||||
|
||||
>>> table1('''
|
||||
... 1 session1 '2007-01-01 00:03:13'
|
||||
... 2 session1 '2007-01-01 00:03:27'
|
||||
... 3 session1 '2007-01-01 00:03:36'
|
||||
... 4 session2 '2007-01-01 00:04:39'
|
||||
... 5 session2 '2007-01-01 00:05:40'
|
||||
... 6 session3 '2007-01-01 00:04:49'
|
||||
... 7 session3 '2007-01-01 00:06:59'
|
||||
... 8 session3 '2007-01-01 00:06:59'
|
||||
... 9 session4 '2007-01-01 00:04:59'
|
||||
... ''')
|
||||
>>> sql("select datediffnewsesid(10, c, b, a) from table1 group by b")
|
||||
bgroupid | C1
|
||||
--------------
|
||||
session11 | 2
|
||||
session11 | 3
|
||||
session21 | 5
|
||||
session31 | 7
|
||||
session31 | 8
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
|
||||
>>> sql("select datediffnewsesid(10, c, b, a) from (select 4 as a, 6 as b, 9 as c where c!=9)")
|
||||
bgroupid | C1
|
||||
---------------
|
||||
None | None
|
||||
|
||||
>>> table2('''
|
||||
... 1 session1 '2007-05-01T21:10:51Z'
|
||||
... 9 session1 '2012-01-08T18:24:32Z'
|
||||
... ''')
|
||||
>>> sql("select datediffnewsesid(1800, c, b, a) from table2 group by b")
|
||||
bgroupid | C1
|
||||
--------------
|
||||
session11 | 9
|
||||
"""
|
||||
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.vals=[]
|
||||
self.init=True
|
||||
self.maxdiff=0
|
||||
|
||||
def initargs(self, args):
|
||||
self.init=False
|
||||
if not args:
|
||||
raise functions.OperatorError("datediffnewsesid","No arguments")
|
||||
if len(args)<4:
|
||||
raise functions.OperatorError("datediffnewsesid","Wrong number of arguments")
|
||||
self.maxdiff=args[0]
|
||||
|
||||
def step(self, *args):
|
||||
if self.init:
|
||||
self.initargs(args)
|
||||
|
||||
self.vals.append(list(args[1:]))
|
||||
|
||||
def final(self):
|
||||
lenofvals=len(self.vals)
|
||||
if lenofvals<=0:
|
||||
yield ("bgroupid", "C1")
|
||||
yield [None, None, None]
|
||||
return
|
||||
|
||||
yield tuple(["bgroupid"]+["C"+str(i) for i in xrange(1,len(self.vals[0])-1)])
|
||||
|
||||
counter=0
|
||||
if lenofvals!=1:
|
||||
for el in self.vals:
|
||||
try:
|
||||
el.insert(0,iso8601.parse_date(el[0]))
|
||||
except Exception:
|
||||
raise functions.OperatorError("datediffnewsesid","Wrong date format: %s" %(el[0]))
|
||||
self.vals.sort(key=itemgetter(0))
|
||||
dt=self.vals[0][0]
|
||||
for el in self.vals[1:]:
|
||||
dtnew=el[0]
|
||||
diff=dtnew-dt
|
||||
dt=dtnew
|
||||
if (diff.days*86400+diff.seconds)>self.maxdiff:
|
||||
counter+=1
|
||||
if counter!=0:
|
||||
bid=unistr(el[2])+str(counter)
|
||||
yield [bid]+el[3:]
|
||||
|
||||
class datedifffilter:
|
||||
"""
|
||||
|
||||
.. function:: datedifffilter(maxdiff, date, C1, C2 ....) -> [date,C1,C2....]
|
||||
|
||||
Returns only a subset of the provided entries, performing a sort of entry clustering based on the entries date difference. Each cluster is
|
||||
represented by the latest entry.
|
||||
The first argument defines the time differnece threshold that is employed for entry clustering, and it is provided in seconds.
|
||||
The second argument is assumed to contain the date column. Entries are assumed to be provided in an ascending order by the date column.
|
||||
Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
All subsequent columns remain unchanged.
|
||||
|
||||
|
||||
:Returned multiset schema:
|
||||
- *date, C1, C2 ..*
|
||||
The selected input values of the row.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`tutmultiset` functions
|
||||
|
||||
>>> table1('''
|
||||
... 2010-01-01T01:32:03Z value1
|
||||
... 2010-01-01T01:32:04Z value2
|
||||
... 2010-01-01T01:32:06Z value3
|
||||
... 2010-01-01T01:32:08Z value4
|
||||
... 2010-01-01T01:32:29Z value5
|
||||
... 2010-01-01T02:35:03Z value6
|
||||
... 2010-01-01T02:35:04Z value7
|
||||
... 2010-01-01T03:55:04Z value8
|
||||
... ''')
|
||||
>>> sql("select datedifffilter(20, a,b) from table1")
|
||||
date | C1
|
||||
-----------------------------
|
||||
2010-01-01T01:32:08Z | value4
|
||||
2010-01-01T01:32:29Z | value5
|
||||
2010-01-01T02:35:04Z | value7
|
||||
2010-01-01T03:55:04Z | value8
|
||||
|
||||
>>> table1('''
|
||||
... 2010-01-01T01:32:03Z value1
|
||||
... ''')
|
||||
>>> sql("select datedifffilter(20, a,b) from table1")
|
||||
date | C1
|
||||
-----------------------------
|
||||
2010-01-01T01:32:03Z | value1
|
||||
|
||||
>>> table1('''
|
||||
... '2010-01-01 01:32:03' value1
|
||||
... '2010-01-01 01:32:04' value2
|
||||
... '2010-01-01 01:32:06' value3
|
||||
... '2010-01-01 01:32:08' value4
|
||||
... '2010-01-01 01:32:29' value5
|
||||
... '2010-01-01 02:35:03' value6
|
||||
... '2010-01-01 02:35:04' value7
|
||||
... '2010-01-01 03:55:04' value8
|
||||
... ''')
|
||||
>>> sql("select datedifffilter(30, a,b) from table1")
|
||||
date | C1
|
||||
----------------------------
|
||||
2010-01-01 01:32:29 | value5
|
||||
2010-01-01 02:35:04 | value7
|
||||
2010-01-01 03:55:04 | value8
|
||||
|
||||
"""
|
||||
registered=True
|
||||
|
||||
def __init__(self):
|
||||
self.init=True
|
||||
self.vals=[]
|
||||
self.maxdiff=0
|
||||
|
||||
def initargs(self, args):
|
||||
self.init=False
|
||||
if not args:
|
||||
raise functions.OperatorError("datedifffilter","No arguments")
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("datedifffilter","Wrong number of arguments")
|
||||
self.maxdiff=args[0]
|
||||
|
||||
def step(self, *args):
|
||||
if self.init==True:
|
||||
self.initargs(args)
|
||||
|
||||
self.vals.append(list(args[1:]))
|
||||
|
||||
def final(self):
|
||||
lenofvals=len(self.vals)
|
||||
if lenofvals==0:
|
||||
yield ("date","C1")
|
||||
yield [None,None]
|
||||
return
|
||||
|
||||
yield tuple(["date"]+["C"+str(i) for i in xrange(1, len(self.vals[0]))])
|
||||
|
||||
dt=None
|
||||
dtpos=0
|
||||
diff=0
|
||||
if lenofvals==1:
|
||||
yield(self.vals[dtpos])
|
||||
else:
|
||||
for el in self.vals:
|
||||
el.append(iso8601.parse_date(el[0]))
|
||||
self.vals.sort(key=itemgetter(-1))
|
||||
for el in self.vals:
|
||||
if dtpos<lenofvals-1:
|
||||
dt = el[-1]
|
||||
dtnew =self.vals[dtpos+1][-1]
|
||||
diff=dtnew-dt
|
||||
dtpos+=1
|
||||
if (diff.days*86400+diff.seconds)>self.maxdiff:
|
||||
yield(el[0:-1])
|
||||
if dtpos==lenofvals-1:
|
||||
yield(self.vals[dtpos][0:-1])
|
||||
|
||||
class datediffgroup:
|
||||
"""
|
||||
|
||||
.. function:: datediffgroup(maxdiff, date, C1, C2 ....) -> [groupid, date,C1,C2....]
|
||||
|
||||
Performing a sort of entry clustering based on the entries date difference.
|
||||
The cluster id that is assigned to each entry is returned in the first column, and it is followed by the entry's original contents.
|
||||
|
||||
The first argument defines the time differnece threshold that is employed for entry clustering, and it is provided in seconds.
|
||||
The second argument is assumed to contain the date column. Entries are assumed to be provided in an ascending order by the date column.
|
||||
Input dates should be in :ref:`ISO 8601 format <iso8601>`.
|
||||
All subsequent columns remain unchanged.
|
||||
|
||||
|
||||
:Returned multiset schema:
|
||||
- *date, C1, C2 ..*
|
||||
The selected input values of the row.
|
||||
|
||||
.. seealso::
|
||||
|
||||
* :ref:`tutmultiset` functions
|
||||
|
||||
>>> table1('''
|
||||
... 2010-01-01T01:32:03Z value1
|
||||
... 2010-01-01T01:32:04Z value2
|
||||
... 2010-01-01T01:32:06Z value3
|
||||
... 2010-01-01T01:32:08Z value4
|
||||
... 2010-01-01T01:32:29Z value5
|
||||
... 2010-01-01T02:35:03Z value6
|
||||
... 2010-01-01T02:35:04Z value7
|
||||
... 2010-01-01T03:55:04Z value8
|
||||
... ''')
|
||||
>>> sql("select datediffgroup(20,a,b) from table1")
|
||||
groupid | date | C1
|
||||
---------------------------------------
|
||||
1 | 2010-01-01T01:32:03Z | value1
|
||||
1 | 2010-01-01T01:32:04Z | value2
|
||||
1 | 2010-01-01T01:32:06Z | value3
|
||||
1 | 2010-01-01T01:32:08Z | value4
|
||||
2 | 2010-01-01T01:32:29Z | value5
|
||||
3 | 2010-01-01T02:35:03Z | value6
|
||||
3 | 2010-01-01T02:35:04Z | value7
|
||||
4 | 2010-01-01T03:55:04Z | value8
|
||||
"""
|
||||
registered=True
|
||||
multiset=True
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.init=True
|
||||
self.vals=[]
|
||||
self.maxdiff=0
|
||||
self.counter=0
|
||||
self.tablesize=0
|
||||
self.groupIdCounter=1
|
||||
|
||||
|
||||
def initargs(self, args):
|
||||
self.init=False
|
||||
if not args:
|
||||
raise functions.OperatorError("datediffgroup","No arguments")
|
||||
if len(args)<2:
|
||||
raise functions.OperatorError("datediffgroup","Wrong number of arguments")
|
||||
self.tablesize=len(args)-1
|
||||
self.maxdiff=args[0]
|
||||
|
||||
|
||||
|
||||
def step(self, *args):
|
||||
if self.init==True:
|
||||
self.initargs(args)
|
||||
|
||||
self.vals.append(list(args[1:]))
|
||||
self.counter+=1
|
||||
|
||||
def final(self):
|
||||
if self.tablesize<=0:
|
||||
yield ("groupid","date","C1")
|
||||
else:
|
||||
yield tuple(["groupid"]+["date"]+["C"+str(i+1) for i in xrange(self.tablesize-1)])
|
||||
|
||||
dt=None
|
||||
dtpos=0
|
||||
diff=0
|
||||
|
||||
for el in self.vals:
|
||||
|
||||
if dtpos<self.counter-1:
|
||||
dt = iso8601.parse_date(el[0])
|
||||
dtnew =iso8601.parse_date(self.vals[dtpos+1][0])
|
||||
diff=dtnew-dt
|
||||
yield [str(self.groupIdCounter)]+el
|
||||
if (diff.days*24*60*60+diff.seconds)>self.maxdiff:
|
||||
self.groupIdCounter+=1
|
||||
|
||||
dtpos+=1
|
||||
if dtpos==self.counter-1:
|
||||
yield [str(self.groupIdCounter)]+self.vals[dtpos]
|
||||
|
||||
if not ('.' in __name__):
|
||||
"""
|
||||
This is needed to be able to test the function, put it at the end of every
|
||||
new function you create
|
||||
"""
|
||||
import sys
|
||||
import setpath
|
||||
from functions import *
|
||||
testfunction()
|
||||
if __name__ == "__main__":
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue