├── .bowerrc ├── .gitignore ├── Gruntfile.js ├── LICENSE.txt ├── assets └── images │ └── photo.png ├── bower.json ├── css ├── latex2html5.css └── website.css ├── examples ├── mixed.html ├── peg.html ├── peg.js ├── polymer.html └── tex │ ├── index.html │ └── index.tex ├── index.html ├── installation.html ├── latex2html5.js ├── latex2html5.min.js ├── lib ├── expressions.js ├── init.js ├── parse.js ├── psgraph.js └── renderer.js ├── package.json ├── plugins ├── jquery.latex2html5.js ├── latex2html5.image.js └── latex2html5.waypoint.js ├── readme.md ├── server.js └── templates └── macros.html /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "components" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.sw[op] 3 | *~ 4 | *.DS_Store 5 | *.log 6 | dist/ 7 | components/ 8 | npm-debug.log 9 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.initConfig({ 3 | 4 | dist: { 5 | // the files to concatenate 6 | src: ['vendor/*.js', 'lib/*.js'], 7 | // the location of the resulting JS file 8 | dest: 'dist/latex2html5.js' 9 | }, 10 | concat: { 11 | options: { 12 | separator: ';', 13 | }, 14 | dist: { 15 | src: [ 16 | 'components/jquery/jquery.js', 17 | 'components/underscore/underscore.js', 18 | 'components/handlebars/handlebars.js', 19 | 'components/backbone/backbone.js', 20 | 'components/layoutmanager/backbone.layoutmanager.js', 21 | 'components/d3/d3.js', 22 | 'lib/init.js', 23 | 'lib/expressions.js', 24 | 'lib/parse.js', 25 | 'lib/psgraph.js', 26 | 'lib/renderer.js', 27 | 'plugins/latex2html5.image.js', 28 | 'plugins/latex2html5.waypoint.js', 29 | 'plugins/jquery.latex2html5.js' 30 | ], 31 | dest: 'dist/latex2html5.js', 32 | }, 33 | }, 34 | uglify: { 35 | dist: { 36 | files: { 37 | 'dist/latex2html5.min.js': 'dist/latex2html5.js' 38 | } 39 | } 40 | }, 41 | jshint: { 42 | // define the files to lint 43 | files: ['lib/*.js'], 44 | // configure JSHint (documented at http://www.jshint.com/docs/) 45 | options: { 46 | // more options here if you want to override JSHint defaults 47 | evil: true, 48 | globals: { 49 | jQuery: true, 50 | console: true, 51 | module: true 52 | } 53 | } 54 | } 55 | }); 56 | grunt.loadNpmTasks('grunt-contrib-clean'); 57 | grunt.loadNpmTasks('grunt-contrib-uglify'); 58 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 59 | grunt.loadNpmTasks('grunt-contrib-concat'); 60 | grunt.loadNpmTasks('grunt-contrib-jshint'); 61 | 62 | // the default task can be run just by typing "grunt" on the command line 63 | grunt.registerTask('default', ['jshint', 'concat', 'uglify']); 64 | 65 | }; 66 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Dan Lynch 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL Dan Lynch BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /assets/images/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mathapedia/LaTeX2HTML5/8c7cf659233dac1721d609df3c262ec19bb16db9/assets/images/photo.png -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LaTeX2HTML5", 3 | "version": "0.0.0", 4 | "main": "index.html", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components" 9 | ], 10 | "dependencies": { 11 | "handlebars": "1.0.0", 12 | "jquery": "1.10.2", 13 | "underscore": "1.5.2", 14 | "backbone": "1.0.0", 15 | "layoutmanager": "0.9.3", 16 | "d3": "3.3.7" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /css/latex2html5.css: -------------------------------------------------------------------------------- 1 | /*! mathapedia */ 2 | html, body, div, svg { 3 | -webkit-tap-highlight-color: rgba(0,0,0,0); 4 | } 5 | 6 | article > h1, 7 | section > h3, 8 | .books h1 { 9 | text-align: center; 10 | } 11 | 12 | .pspicture-view { 13 | position: relative; 14 | margin: auto; 15 | } 16 | 17 | span.tt { 18 | font-family: courier; 19 | } 20 | 21 | span.rm { 22 | font-family: 'Arbutus Slab', serif; 23 | } 24 | 25 | 26 | p.quotation { 27 | padding: 0 0 0 15px; 28 | margin: 0 0 20px; 29 | font-size: 10pt; 30 | } 31 | 32 | .well { 33 | margin-top: 20px; 34 | min-height: 20px; 35 | padding: 19px; 36 | margin-bottom: 20px; 37 | background-color: #f5f5f5; 38 | border: 1px solid #e3e3e3; 39 | -webkit-border-radius: 4px; 40 | -moz-border-radius: 4px; 41 | border-radius: 4px; 42 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); 43 | -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); 44 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); 45 | } 46 | 47 | 48 | body { 49 | margin: 0; 50 | /*font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;*/ 51 | font-family: 'Arbutus Slab', serif; 52 | font-size: 14px; 53 | line-height: 20px; 54 | color: #333333; 55 | background-color: #ffffff; 56 | } 57 | 58 | .latex-container { 59 | max-width: 870px; 60 | margin-right: auto; 61 | margin-left: auto; 62 | *zoom: 1; 63 | } 64 | 65 | @media (min-width: 1200px) { 66 | 67 | } 68 | 69 | @media (min-width: 768px) and (max-width: 979px) { 70 | .latex-container { 71 | width: 724px; 72 | } 73 | } 74 | 75 | @media (max-width: 767px) { 76 | body { 77 | padding-right: 20px; 78 | padding-left: 20px; 79 | } 80 | .latex-container { 81 | width: auto; 82 | } 83 | } 84 | 85 | @media (max-width: 979px) { 86 | body { 87 | padding-top: 0; 88 | } 89 | } 90 | 91 | img { 92 | height: auto; 93 | max-width: 100%; 94 | vertical-align: middle; 95 | border: 0; 96 | -ms-interpolation-mode: bicubic; 97 | } 98 | 99 | pre { 100 | overflow: auto; 101 | } -------------------------------------------------------------------------------- /css/website.css: -------------------------------------------------------------------------------- 1 | .home-image { 2 | max-width: 100%; 3 | text-align: center; 4 | } 5 | 6 | @media (min-width: 768px) { 7 | .home-image > img { 8 | max-width: 600px; 9 | } 10 | } 11 | 12 | .index-font { 13 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 14 | } -------------------------------------------------------------------------------- /examples/mixed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 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 | Fork me on GitHub 76 | 77 | 78 |
79 | $$ 80 | % create the definition symbol 81 | \def\bydef{\stackrel{\Delta}{=}} 82 | %\def\circconv{\otimes} 83 | \def\circconv{\circledast} 84 | 85 | \newcommand{\qed}{\mbox{ } \Box} 86 | 87 | 88 | \newcommand{\infint}{\int_{-\infty}^{\infty}} 89 | 90 | % z transform 91 | \newcommand{\ztp}{ ~~ \mathop{\mathcal{Z}}\limits_{\longleftrightarrow} ~~ } 92 | \newcommand{\iztp}{ ~~ \mathop{\mathcal{Z}^{-1}}\limits_{\longleftrightarrow} ~~ } 93 | % fourier transform pair 94 | \newcommand{\ftp}{ ~~ \mathop{\mathcal{F}}\limits_{\longleftrightarrow} ~~ } 95 | \newcommand{\iftp}{ ~~ \mathop{\mathcal{F}^{-1}}\limits_{\longleftrightarrow} ~~ } 96 | % laplace transform 97 | \newcommand{\ltp}{ ~~ \mathop{\mathcal{L}}\limits_{\longleftrightarrow} ~~ } 98 | \newcommand{\iltp}{ ~~ \mathop{\mathcal{L}^{-1}}\limits_{\longleftrightarrow} ~~ } 99 | 100 | \newcommand{\ftrans}[1]{ \mathcal{F} \left\{#1\right\} } 101 | \newcommand{\iftrans}[1]{ \mathcal{F}^{-1} \left\{#1\right\} } 102 | \newcommand{\ztrans}[1]{ \mathcal{Z} \left\{#1\right\} } 103 | \newcommand{\iztrans}[1]{ \mathcal{Z}^{-1} \left\{#1\right\} } 104 | \newcommand{\ltrans}[1]{ \mathcal{L} \left\{#1\right\} } 105 | \newcommand{\iltrans}[1]{ \mathcal{L}^{-1} \left\{#1\right\} } 106 | 107 | 108 | % coordinate vector relative to a basis (linear algebra) 109 | \newcommand{\cvrb}[2]{\left[ \vec{#1} \right]_{#2} } 110 | % change of coordinate matrix (linear algebra) 111 | \newcommand{\cocm}[2]{ \mathop{P}\limits_{#2 \leftarrow #1} } 112 | % Transformed vector set 113 | \newcommand{\tset}[3]{\{#1\lr{\vec{#2}_1}, #1\lr{\vec{#2}_2}, \dots, #1\lr{\vec{#2}_{#3}}\}} 114 | % sum transformed vector set 115 | \newcommand{\tsetcsum}[4]{{#1}_1#2(\vec{#3}_1) + {#1}_2#2(\vec{#3}_2) + \cdots + {#1}_{#4}#2(\vec{#3}_{#4})} 116 | \newcommand{\tsetcsumall}[4]{#2\lr{{#1}_1\vec{#3}_1 + {#1}_2\vec{#3}_2 + \cdots + {#1}_{#4}\vec{#3}_{#4}}} 117 | \newcommand{\cvecsum}[3]{{#1}_1\vec{#2}_1 + {#1}_2\vec{#2}_2 + \cdots + {#1}_{#3}\vec{#2}_{#3}} 118 | 119 | 120 | % function def 121 | \newcommand{\fndef}[3]{#1:#2 \to #3} 122 | % vector set 123 | \newcommand{\vset}[2]{\{\vec{#1}_1, \vec{#1}_2, \dots, \vec{#1}_{#2}\}} 124 | % absolute value 125 | \newcommand{\abs}[1]{\left| #1 \right|} 126 | % vector norm 127 | \newcommand{\norm}[1]{\left|\left| #1 \right|\right|} 128 | % trans 129 | \newcommand{\trans}{\mapsto} 130 | % evaluate integral 131 | \newcommand{\evalint}[3]{\left. #1 \right|_{#2}^{#3}} 132 | % slist 133 | \newcommand{\slist}[2]{{#1}_{1},{#1}_{2},\dots,{#1}_{#2}} 134 | 135 | % vectors 136 | \newcommand{\vc}[1]{\textbf{#1}} 137 | 138 | % real 139 | \newcommand{\Real}[1]{{\Re \mit{e}\left\{{#1}\right\}}} 140 | % imaginary 141 | \newcommand{\Imag}[1]{{\Im \mit{m}\left\{{#1}\right\}}} 142 | 143 | \newcommand{\mcal}[1]{\mathcal{#1}} 144 | \newcommand{\bb}[1]{\mathbb{#1}} 145 | \newcommand{\N}{\mathbb{N}} 146 | \newcommand{\Z}{\mathbb{Z}} 147 | \newcommand{\Q}{\mathbb{Q}} 148 | \newcommand{\R}{\mathbb{R}} 149 | \newcommand{\C}{\mathbb{C}} 150 | \newcommand{\I}{\mathbb{I}} 151 | \newcommand{\Th}[1]{\mathop\mathrm{Th(#1)}} 152 | \newcommand{\intersect}{\cap} 153 | \newcommand{\union}{\cup} 154 | \newcommand{\intersectop}{\bigcap} 155 | \newcommand{\unionop}{\bigcup} 156 | \newcommand{\setdiff}{\backslash} 157 | \newcommand{\iso}{\cong} 158 | \newcommand{\aut}[1]{\mathop{\mathrm{Aut(#1)}}} 159 | \newcommand{\inn}[1]{\mathop{\mathrm{Inn(#1)}}} 160 | \newcommand{\Ann}[1]{\mathop{\mathrm{Ann(#1)}}} 161 | \newcommand{\dom}[1]{\mathop{\mathrm{dom} #1}} 162 | \newcommand{\cod}[1]{\mathop{\mathrm{cod} #1}} 163 | \newcommand{\id}{\mathrm{id}} 164 | \newcommand{\st}{\ |\ } 165 | \newcommand{\mbf}[1]{\mathbf{#1}} 166 | \newcommand{\enclose}[1]{\left\langle #1\right\rangle} 167 | \newcommand{\lr}[1]{\left( #1\right)} 168 | \newcommand{\lrsq}[1]{\left[ #1\right]} 169 | \newcommand{\op}{\mathrm{op}} 170 | \newcommand{\dotarr}{\dot{\rightarrow}} 171 | %Category Names: 172 | \newcommand{\Grp}{\mathbf{Grp}} 173 | \newcommand{\Ab}{\mathbf{Ab}} 174 | \newcommand{\Set}{\mathbf{Set}} 175 | \newcommand{\Matr}{\mathbf{Matr}} 176 | \newcommand{\IntDom}{\mathbf{IntDom}} 177 | \newcommand{\Field}{\mathbf{Field}} 178 | \newcommand{\Vect}{\mathbf{Vect}} 179 | 180 | \newcommand{\thm}[1]{\begin{theorem} #1 \end{theorem}} 181 | \newcommand{\clm}[1]{\begin{claim} #1 \end{claim}} 182 | \newcommand{\cor}[1]{\begin{corollary} #1 \end{corollary}} 183 | \newcommand{\ex}[1]{\begin{example} #1 \end{example}} 184 | \newcommand{\prf}[1]{\begin{proof} #1 \end{proof}} 185 | \newcommand{\prbm}[1]{\begin{problem} #1 \end{problem}} 186 | \newcommand{\soln}[1]{\begin{solution} #1 \end{solution}} 187 | \newcommand{\rmk}[1]{\begin{remark} #1 \end{remark}} 188 | \newcommand{\defn}[1]{\begin{definition} #1 \end{definition}} 189 | 190 | \newcommand{\ifff}{\LeftRightArrow} 191 | 192 | 193 | \newcommand{\rr}{\R} 194 | \newcommand{\reals}{\R} 195 | \newcommand{\ii}{\Z} 196 | \newcommand{\cc}{\C} 197 | \newcommand{\nn}{\N} 198 | \newcommand{\nats}{\N} 199 | 200 | 204 | 205 | 208 | \newcommand{\strong}[1]{\textbf{#1}} 209 | 210 | 213 | \newcommand{\set}[1]{\textit{#1}} 214 | $$ 215 |
216 | 579 | 580 |
581 | 582 |
583 | 584 | 599 | 600 | 601 | 602 | 603 | -------------------------------------------------------------------------------- /examples/peg.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | The integral $\int f(x) dx = 0$ 37 | 38 | 39 | 71 | 72 | 76 | 77 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/polymer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 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 | Fork me on GitHub 77 | 78 | 79 |
80 | $$ 81 | % create the definition symbol 82 | \def\bydef{\stackrel{\Delta}{=}} 83 | %\def\circconv{\otimes} 84 | \def\circconv{\circledast} 85 | 86 | \newcommand{\qed}{\mbox{ } \Box} 87 | 88 | 89 | \newcommand{\infint}{\int_{-\infty}^{\infty}} 90 | 91 | % z transform 92 | \newcommand{\ztp}{ ~~ \mathop{\mathcal{Z}}\limits_{\longleftrightarrow} ~~ } 93 | \newcommand{\iztp}{ ~~ \mathop{\mathcal{Z}^{-1}}\limits_{\longleftrightarrow} ~~ } 94 | % fourier transform pair 95 | \newcommand{\ftp}{ ~~ \mathop{\mathcal{F}}\limits_{\longleftrightarrow} ~~ } 96 | \newcommand{\iftp}{ ~~ \mathop{\mathcal{F}^{-1}}\limits_{\longleftrightarrow} ~~ } 97 | % laplace transform 98 | \newcommand{\ltp}{ ~~ \mathop{\mathcal{L}}\limits_{\longleftrightarrow} ~~ } 99 | \newcommand{\iltp}{ ~~ \mathop{\mathcal{L}^{-1}}\limits_{\longleftrightarrow} ~~ } 100 | 101 | \newcommand{\ftrans}[1]{ \mathcal{F} \left\{#1\right\} } 102 | \newcommand{\iftrans}[1]{ \mathcal{F}^{-1} \left\{#1\right\} } 103 | \newcommand{\ztrans}[1]{ \mathcal{Z} \left\{#1\right\} } 104 | \newcommand{\iztrans}[1]{ \mathcal{Z}^{-1} \left\{#1\right\} } 105 | \newcommand{\ltrans}[1]{ \mathcal{L} \left\{#1\right\} } 106 | \newcommand{\iltrans}[1]{ \mathcal{L}^{-1} \left\{#1\right\} } 107 | 108 | 109 | % coordinate vector relative to a basis (linear algebra) 110 | \newcommand{\cvrb}[2]{\left[ \vec{#1} \right]_{#2} } 111 | % change of coordinate matrix (linear algebra) 112 | \newcommand{\cocm}[2]{ \mathop{P}\limits_{#2 \leftarrow #1} } 113 | % Transformed vector set 114 | \newcommand{\tset}[3]{\{#1\lr{\vec{#2}_1}, #1\lr{\vec{#2}_2}, \dots, #1\lr{\vec{#2}_{#3}}\}} 115 | % sum transformed vector set 116 | \newcommand{\tsetcsum}[4]{{#1}_1#2(\vec{#3}_1) + {#1}_2#2(\vec{#3}_2) + \cdots + {#1}_{#4}#2(\vec{#3}_{#4})} 117 | \newcommand{\tsetcsumall}[4]{#2\lr{{#1}_1\vec{#3}_1 + {#1}_2\vec{#3}_2 + \cdots + {#1}_{#4}\vec{#3}_{#4}}} 118 | \newcommand{\cvecsum}[3]{{#1}_1\vec{#2}_1 + {#1}_2\vec{#2}_2 + \cdots + {#1}_{#3}\vec{#2}_{#3}} 119 | 120 | 121 | % function def 122 | \newcommand{\fndef}[3]{#1:#2 \to #3} 123 | % vector set 124 | \newcommand{\vset}[2]{\{\vec{#1}_1, \vec{#1}_2, \dots, \vec{#1}_{#2}\}} 125 | % absolute value 126 | \newcommand{\abs}[1]{\left| #1 \right|} 127 | % vector norm 128 | \newcommand{\norm}[1]{\left|\left| #1 \right|\right|} 129 | % trans 130 | \newcommand{\trans}{\mapsto} 131 | % evaluate integral 132 | \newcommand{\evalint}[3]{\left. #1 \right|_{#2}^{#3}} 133 | % slist 134 | \newcommand{\slist}[2]{{#1}_{1},{#1}_{2},\dots,{#1}_{#2}} 135 | 136 | % vectors 137 | \newcommand{\vc}[1]{\textbf{#1}} 138 | 139 | % real 140 | \newcommand{\Real}[1]{{\Re \mit{e}\left\{{#1}\right\}}} 141 | % imaginary 142 | \newcommand{\Imag}[1]{{\Im \mit{m}\left\{{#1}\right\}}} 143 | 144 | \newcommand{\mcal}[1]{\mathcal{#1}} 145 | \newcommand{\bb}[1]{\mathbb{#1}} 146 | \newcommand{\N}{\mathbb{N}} 147 | \newcommand{\Z}{\mathbb{Z}} 148 | \newcommand{\Q}{\mathbb{Q}} 149 | \newcommand{\R}{\mathbb{R}} 150 | \newcommand{\C}{\mathbb{C}} 151 | \newcommand{\I}{\mathbb{I}} 152 | \newcommand{\Th}[1]{\mathop\mathrm{Th(#1)}} 153 | \newcommand{\intersect}{\cap} 154 | \newcommand{\union}{\cup} 155 | \newcommand{\intersectop}{\bigcap} 156 | \newcommand{\unionop}{\bigcup} 157 | \newcommand{\setdiff}{\backslash} 158 | \newcommand{\iso}{\cong} 159 | \newcommand{\aut}[1]{\mathop{\mathrm{Aut(#1)}}} 160 | \newcommand{\inn}[1]{\mathop{\mathrm{Inn(#1)}}} 161 | \newcommand{\Ann}[1]{\mathop{\mathrm{Ann(#1)}}} 162 | \newcommand{\dom}[1]{\mathop{\mathrm{dom} #1}} 163 | \newcommand{\cod}[1]{\mathop{\mathrm{cod} #1}} 164 | \newcommand{\id}{\mathrm{id}} 165 | \newcommand{\st}{\ |\ } 166 | \newcommand{\mbf}[1]{\mathbf{#1}} 167 | \newcommand{\enclose}[1]{\left\langle #1\right\rangle} 168 | \newcommand{\lr}[1]{\left( #1\right)} 169 | \newcommand{\lrsq}[1]{\left[ #1\right]} 170 | \newcommand{\op}{\mathrm{op}} 171 | \newcommand{\dotarr}{\dot{\rightarrow}} 172 | %Category Names: 173 | \newcommand{\Grp}{\mathbf{Grp}} 174 | \newcommand{\Ab}{\mathbf{Ab}} 175 | \newcommand{\Set}{\mathbf{Set}} 176 | \newcommand{\Matr}{\mathbf{Matr}} 177 | \newcommand{\IntDom}{\mathbf{IntDom}} 178 | \newcommand{\Field}{\mathbf{Field}} 179 | \newcommand{\Vect}{\mathbf{Vect}} 180 | 181 | \newcommand{\thm}[1]{\begin{theorem} #1 \end{theorem}} 182 | \newcommand{\clm}[1]{\begin{claim} #1 \end{claim}} 183 | \newcommand{\cor}[1]{\begin{corollary} #1 \end{corollary}} 184 | \newcommand{\ex}[1]{\begin{example} #1 \end{example}} 185 | \newcommand{\prf}[1]{\begin{proof} #1 \end{proof}} 186 | \newcommand{\prbm}[1]{\begin{problem} #1 \end{problem}} 187 | \newcommand{\soln}[1]{\begin{solution} #1 \end{solution}} 188 | \newcommand{\rmk}[1]{\begin{remark} #1 \end{remark}} 189 | \newcommand{\defn}[1]{\begin{definition} #1 \end{definition}} 190 | 191 | \newcommand{\ifff}{\LeftRightArrow} 192 | 193 | 194 | \newcommand{\rr}{\R} 195 | \newcommand{\reals}{\R} 196 | \newcommand{\ii}{\Z} 197 | \newcommand{\cc}{\C} 198 | \newcommand{\nn}{\N} 199 | \newcommand{\nats}{\N} 200 | 201 | 205 | 206 | 209 | \newcommand{\strong}[1]{\textbf{#1}} 210 | 211 | 214 | \newcommand{\set}[1]{\textit{#1}} 215 | $$ 216 |
217 | 218 |
219 | 220 |

Polymer is a library that helps build web components before we have them. Here we demonstrate how to make a new latex HTMLElement

221 | 222 |

Currently there are a few issues with polymer and latex2html5 causing the interactivity does not work.

223 | 224 | 225 | What frequencies can be present in a signal $\vec{x}$? The harmonics are given by a signal with period $p$ are $\{0,\omega_0,2\omega_0,\dots,(p-1)\omega_0\}$. Notice that $p\omega_0$ is missing. This is because $e^{ip\omega_0n}=e^{i2\pi n} = e^{i0n}$. Keep in mind that $\omega_0 = 2\pi/p$. In fact, the complex exponential basis of vectors is periodic with respect to $n$ and their indices $k$. 226 | 227 | \begin{align*} 228 | \Psi_k(n+p) &= e^{ik\omega_0(n+p)}=e^{ik\omega_0n}e^{ik\omega_0p}=e^{ik\omega_0n} = \Psi_k(n) \\ 229 | \Psi_{k+p}(n) &= e^{i(k+p)\omega_0n} = e^{ik\omega_0n}e^{ip\omega_0n} = \Psi_k(n) 230 | \end{align*} 231 | 232 | 233 | 234 |

Here is some HTML between two latex tags

235 | 236 | 237 | 238 | So we know that $\Psi_{-1}(n) = e^{-i\omega_0n} = \Psi_{p-1}(n) = e^{i(p-1)\omega_0n }$. So we can see that in general, we can write out a discrete fourier series expansion over any continuous set of $p$ integers. The notation used is 239 | $$ x(n) = \sum \limits_{k=\langle p \rangle} X_ke^{ik\omega_0n}$$ 240 | 241 | 242 | Given a periodic signal $x$ in CT, we can estimate the signal using the formula: 243 | 244 | $$ \hat{x}(t) = \sum \limits_{k=-N}^{N}\alpha_k e^{ik\omega_0 t} $$ 245 | 246 | How can we determine the coefficients that make the estimates closest in terms of error energy? Let $W\in\R^{2N+1}$ be a subspace spanned by the set of orthogonal basis vectors $\Psi_0, \Psi_1, \Psi_{-1} \dots, \Psi_{N}, \Psi_{-N}$. If $x$ is a vector that is not in the column space of $W$, then we can project $x$ onto the column space of $W$, producing an approximation vector $\hat{x}$, which has a distance of $\abs{\left| \mathcal{E}_N\right|}$ from the vector $x$. The vectors $\mathcal{E}_N$ and $\hat{x}$ are orthogonal. 247 | 248 | 249 | 250 |

Here is some HTML between two latex tags

251 | 252 | 253 | 254 | \psset{unit=1cm} 255 | \begin{center} 256 | \begin{pspicture}(-1,-3)(9,4) 257 | 258 | \pscustom[fillstyle=solid,fillcolor=gray!40,linestyle=none]{ 259 | \psline[linewidth=1 pt](0,0)(4,1.2) 260 | \psline[linewidth=1 pt](4,1.2)(8.4,0) 261 | \psline[linewidth=1 pt](8.4,0)(4,-1.2) 262 | \psline[linewidth=1 pt](4,-1.2)(0,0) 263 | } 264 | 265 | \psline[linewidth=1 pt](0,0)(4,1.2) 266 | \psline[linewidth=1 pt](4,1.2)(8.4,0) 267 | \psline[linewidth=1 pt](8.4,0)(4,-1.2) 268 | \psline[linewidth=1 pt](4,-1.2)(0,0) 269 | 270 | \rput(0.78,0){$W$} 271 | 272 | 273 | % new vector 274 | \rput(6,3.3){$x$} 275 | \psline[linewidth=1.5 pt,linecolor=red]{->}(2.2,0.2)(6,3) 276 | 277 | % new vector 278 | \rput(6.35,1.5){$\mathcal{E}_N$} 279 | \psline[linewidth=1.5 pt]{->}(6,0)(6,3) 280 | 281 | % new vector 282 | \rput(4,-0.3){$\hat{x}_N$} 283 | \psline[linewidth=1.5 pt]{->}(2.2,0.2)(6,0) 284 | 285 | % new vector 286 | \psline[linewidth=1.5 pt](2.2,0.2)(6,0) 287 | 288 | 289 | \end{pspicture} 290 | \end{center} 291 | We want to minimize $\abs{\left| \mathcal{E}_N\right|}$ to make the best approximation. $\mathcal{E}_N = x - \hat{x}_N$, hence $\abs{\left| \mathcal{E}_N\right|} = \abs{\left| x-\hat{x}_N\right|}$. Since $\mathcal{E} \perp W$, then we can use the inner product and the properties of orthogonality to solve for the coefficients. Since $W \in \R^{2N+1}$, we have $2N+1$ equations and $2N+1$ coefficients. 292 | 293 | \begin{align*} 294 | \langle \hat{x}_N, \Psi_\ell\rangle &= \langle \sum \limits_{k=-N}^{N}\alpha_k e^{ik\omega_0 t} , \Psi_\ell\rangle \\ 295 | \langle \hat{x}_N, \Psi_\ell\rangle &= \sum \limits_{k=-N}^{N}\alpha_k \langle e^{ik\omega_0 t} , \Psi_\ell\rangle \\ 296 | \langle \hat{x}_N, \Psi_\ell\rangle &= \alpha_\ell \langle e^{i\ell\omega_0 t} , \Psi_\ell\rangle \\ 297 | \langle \hat{x}_N, \Psi_\ell\rangle &= \alpha_\ell \langle \Psi_\ell , \Psi_\ell\rangle \\ 298 | \alpha_\ell &= \frac{\langle \hat{x}_N, \Psi_\ell\rangle }{\langle \Psi_\ell , \Psi_\ell\rangle } \\ 299 | \end{align*} 300 | 301 | if $\hat{x}(t) = \sum \limits_{k=0}^{M-1}\alpha_k \Psi_k$, where $x$ is a $p$-periodic signal, which $\Psi_k$'s would you choose? Since we are taking a subset, the larger exponentials are better since they dominate. Otherwise, using $\{0,1,\dots,M\}\in\Z$ is not using very much. Pick the largest in magnitude FS coefficient, and then go down from there, but it doesn't have to be continguous. 302 | 303 | 304 | \begin{pspicture}(-5,-5)(5,5) 305 | \rput(0.3,3.75){ $Im$ } 306 | \psline{->}(0,-3.75)(0,3.75) 307 | \rput(3.75,0.3){ $Re$ } 308 | \psline{->}(-3.75,0)(3.75,0) 309 | \pscircle(0,0){ 3 } 310 | \pscircle(0,0){ 2 } 311 | \pscircle(0,0){ 1 } 312 | \rput(2.3,1){$e^{i\omega}-\alpha$} 313 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(1.121,2.121) 314 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 315 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 316 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 317 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 318 | \rput(-0.75,-4.25){$1+\alpha$} 319 | \rput(2.25,-4.25){$1-\alpha$} 320 | \psline{<->}(-3,-4)(1.5,-4) 321 | \psline{<->}(1.5,-4)(3,-4) 322 | \psline[linestyle=dashed](3,-4.5)(3,0) 323 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 324 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 325 | \end{pspicture} 326 | 327 | 328 | Many of us think our thoughts using a language of some sort---there is usually some voice in our minds. Language in some ways, makes us who we are. Some even argue in the world of cognitive science that language is the foundation of our consciousness. 329 | 330 | 331 | An author who has in their minds representations of intelligent concepts should be able to freely express herself through language with free association---digital expressions of these ideas in some cases requires total control of the computer and all of its processes. 332 | 333 | 334 | The vision behind the personal computer was that any person could have full command of the functions of their device. I think this vision has come true to some degree, but not fully when it comes to creating graphics, especially mathematical diagrams online. 335 | 336 | 337 | Does the common mathematician or professor have the ability to express concepts through web technology? The Web has its own language, and the goal of this project is to help blur the lines between what authoring the mathematical Web should be like and typesetting beautiful Math. 338 | 339 | 340 | If you know \LaTeX, then get ready to author interactive diagrams in real-time (try using mouse or touch to interact with diagrams). 341 | 342 | 343 | \begin{interactive} 344 | 345 | 346 | What matters most is minimizing the distance between our expression of an idea and the execution of that idea. For example, I can describe a vector at $(0,0)$ and initial value of the head at $(2,2)$ that will follow a user touch or mouse event. This will produce the following interaction: 347 | 348 | 349 | \begin{center} 350 | \begin{pspicture}(-2,-2)(2,2) 351 | \psframe(-2,-2)(2,2) 352 | \userline[linewidth=1.5 pt]{->}(0,0)(2,2) 353 | \end{pspicture} 354 | \end{center} 355 | 356 | 357 | This was as easy as using this \TeX, which many math professors could understand. 358 | 359 | \begin{verbatim} 360 | \begin{pspicture}(-2,-2)(2,2) 361 | \psframe(-2,-2)(2,2) 362 | \userline[linewidth=1.5 pt]{->}(0,0)(2,2) 363 | \end{pspicture} 364 | \end{verbatim} 365 | 366 | 367 | \begin{pspicture}(-2,-2)(2,2) 368 | \psframe(-2,-2)(2,2) 369 | \userline[linewidth=2pt,linecolor=green]{->}(0,0)(2,2){-x}{-y} 370 | \userline[linewidth=2pt,linecolor=red]{->}(0,0)(2,2){0}{y} 371 | \userline[linewidth=2pt,linecolor=purple]{->}(0,0)(2,2){-x}{cos(y)} 372 | \userline[linewidth=2pt,linecolor=lightblue]{->}(0,0)(2,2)(sin(x)}{-y} 373 | \end{pspicture} 374 | 375 | \begin{verbatim} 376 | \begin{pspicture}(-2,-2)(2,2) 377 | \psframe(-2,-2)(2,2) 378 | \userline[linewidth=2pt,linecolor=green]{->}(0,0)(2,2){-x}{-y} 379 | \userline[linewidth=2pt,linecolor=red]{->}(0,0)(2,2){0}{y} 380 | \userline[linewidth=2pt,linecolor=purple]{->}(0,0)(2,2){-x}{cos(y)} 381 | \userline[linewidth=2pt,linecolor=lightblue]{->}(0,0)(2,2)(sin(x)}{-y} 382 | \end{pspicture} 383 | \end{verbatim} 384 | 385 | I can also draw a more complex version, and start to make more useful diagrams to describe vectors: 386 | 387 | \begin{center} 388 | \begin{pspicture}(-5,-5)(5,5) 389 | 390 | % y-axis 391 | \rput(0.3,3.75){ $Im$ } 392 | \psline{->}(0,-3.75)(0,3.75) 393 | 394 | % x-axis 395 | \rput(3.75,0.3){ $Re$ } 396 | \psline{->}(-3.75,0)(3.75,0) 397 | 398 | % the circle 399 | \pscircle(0,0){ 3 } 400 | 401 | 402 | % new vector 403 | \rput(2.3,1){$e^{i\omega}-\alpha$} 404 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 405 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 406 | 407 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 408 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 409 | 410 | \rput(-0.75,-4.25){$1+\alpha$} 411 | \rput(2.25,-4.25){$1-\alpha$} 412 | \psline{<->}(-3,-4)(1.5,-4) 413 | \psline{<->}(1.5,-4)(3,-4) 414 | \psline[linestyle=dashed](3,-4.5)(3,0) 415 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 416 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 417 | 418 | 419 | \end{pspicture} 420 | \end{center} 421 | 422 | 423 | \begin{verbatim} 424 | \begin{pspicture}(-5,-5)(5,5) 425 | \rput(0.3,3.75){ $Im$ } 426 | \psline{->}(0,-3.75)(0,3.75) 427 | \rput(3.75,0.3){ $Re$ } 428 | \psline{->}(-3.75,0)(3.75,0) 429 | \pscircle(0,0){ 3 } 430 | \rput(2.3,1){$e^{i\omega}-\alpha$} 431 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 432 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 433 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 434 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 435 | \rput(-0.75,-4.25){$1+\alpha$} 436 | \rput(2.25,-4.25){$1-\alpha$} 437 | \psline{<->}(-3,-4)(1.5,-4) 438 | \psline{<->}(1.5,-4)(3,-4) 439 | \psline[linestyle=dashed](3,-4.5)(3,0) 440 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 441 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 442 | \end{pspicture} 443 | \end{verbatim} 444 | 445 | 446 | Think about the student learning a new concept. Here is an example of teaching integration using ``area under the curve'', for example, you can represent $\int_a^b f(x) dx$ as: 447 | 448 | \begin{center} 449 | \begin{pspicture}(-4,-3)(4,3) 450 | 451 | \uservariable{alpha}(0,0){x} 452 | 453 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{-4}{alpha}{sin(x)} 454 | \psplot[algebraic,linewidth=2pt]{-4}{4}{sin(x)} 455 | 456 | \psline{->}(-4,0)(4,0) 457 | 458 | 459 | \end{pspicture} 460 | \end{center} 461 | 462 | \begin{verbatim} 463 | \begin{pspicture}(-4,-3)(4,3) 464 | \uservariable{alpha}(0,0){x} 465 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{-4}{alpha}{sin(x)} 466 | \psplot[algebraic,linewidth=2pt]{-4}{4}{sin(x)} 467 | \psline{->}(-4,0)(4,0) 468 | \end{pspicture} 469 | \end{verbatim} 470 | 471 | The next example allows you to move the height of the graph and also integrate over a moving interval. 472 | 473 | \begin{center} 474 | \begin{pspicture}(-4,-3)(4,3) 475 | 476 | \uservariable{alpha}(0,0){x} 477 | \uservariable{beta}(0,0){y} 478 | 479 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{alpha-3}{alpha}{beta + sin(x)} 480 | \psplot[algebraic,linewidth=2pt]{-4}{4}{beta + sin(x)} 481 | 482 | \psline{->}(-4,0)(4,0) 483 | 484 | \end{pspicture} 485 | \end{center} 486 | 487 | 488 | \begin{verbatim} 489 | \begin{pspicture}(-4,-3)(4,3) 490 | \uservariable{alpha}(0,0){x} 491 | \uservariable{beta}(0,0){y} 492 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{alpha-3}{alpha}{beta + sin(x)} 493 | \psplot[algebraic,linewidth=2pt]{-4}{4}{beta + sin(x)} 494 | \psline{->}(-4,0)(4,0) 495 | \end{pspicture} 496 | \end{verbatim} 497 | 498 | \end{interactive} 499 | 500 | 501 | 502 | \begin{interactive} 503 | \psset{unit=1cm} 504 | 505 | \begin{center} 506 | \begin{pspicture}(-3.5,-1)(3.75,3.5) 507 | 508 | \slider{1}{8}{n}{$N$}{4} 509 | 510 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-3.14}{3.14}{cos(n*x/2)+1.3} 511 | \psaxes[showorigin=false,labels=none, Dx=1.62](0,0)(-3.25,0)(3.25,2.5) 512 | 513 | \psline[linestyle=dashed](-3.14,0.3)(3.14,0.3) 514 | \psline[linestyle=dashed](-3.14,2.3)(3.14,2.3) 515 | \rput(3.6,2.3){$\frac{1}{1-\alpha}$} 516 | \rput(3.6,0.3){$\frac{1}{1+\alpha}$} 517 | 518 | 519 | \rput(3.14, -0.35){$\pi$} 520 | \rput(1.62, -0.35){$\pi/2$} 521 | \rput(-1.62, -0.35){$-\pi/2$} 522 | \rput(-3.14, -0.35){$-\pi$} 523 | \rput(0, -0.35){$0$} 524 | 525 | \end{pspicture} 526 | \end{center} 527 | \end{interactive} 528 | 529 | \begin{verbatim} 530 | \begin{pspicture}(-3.5,-1)(3.75,3.5) 531 | \slider{1}{8}{n}{$N$}{4} 532 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-3.14}{3.14}{cos(n*x/2)+1.3} 533 | \psaxes[showorigin=false,labels=none, Dx=1.62](0,0)(-3.25,0)(3.25,2.5) 534 | \psline[linestyle=dashed](-3.14,0.3)(3.14,0.3) 535 | \psline[linestyle=dashed](-3.14,2.3)(3.14,2.3) 536 | \rput(3.6,2.3){$\frac{1}{1-\alpha}$} 537 | \rput(3.6,0.3){$\frac{1}{1+\alpha}$} 538 | \rput(3.14, -0.35){$\pi$} 539 | \rput(1.62, -0.35){$\pi/2$} 540 | \rput(-1.62, -0.35){$-\pi/2$} 541 | \rput(-3.14, -0.35){$-\pi$} 542 | \rput(0, -0.35){$0$} 543 | \end{pspicture} 544 | \end{verbatim} 545 | 546 | 547 | 548 | \begin{interactive} 549 | \psset{unit=0.5cm} 550 | \begin{center} 551 | \begin{pspicture}(-13,-5)(13,10) 552 | 553 | \slider{1}{8}{a}{amplitude}{4} 554 | \slider{1}{8}{n}{frequency}{4} 555 | 556 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-12.56}{12.56}{a*sin(n*x)/(n*x)} 557 | \psaxes[showorigin=false,labels=none, Dx=3.14](0,0)(-12.6,0)(12.6,0) 558 | 559 | \rput(0, -0.5){$0$} 560 | 561 | \end{pspicture} 562 | \end{center} 563 | \end{interactive} 564 | 565 | 566 | \begin{verbatim} 567 | \begin{pspicture}(-13,-5)(13,10) 568 | \slider{1}{8}{a}{amplitude}{4} 569 | \slider{1}{8}{n}{frequency}{4} 570 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-12.56}{12.56}{a*sin(n*x)/(n*x)} 571 | \psaxes[showorigin=false,labels=none, Dx=3.14](0,0)(-12.6,0)(12.6,0) 572 | \rput(0, -0.5){$0$} 573 | \end{pspicture} 574 | \end{verbatim} 575 | 576 | 577 | 578 | \begin{center} 579 | \begin{pspicture}(-4,-3)(4,6) 580 | \uservariable{alpha}(0.1,0){x} 581 | \psplot[algebraic,linewidth=2pt]{-4}{4}{pow(x,2)} 582 | \psplot[algebraic,linecolor=blue,linewidth=3]{-4}{4}{4*(x-alpha)*alpha} 583 | \psline{->}(-4,0)(4,0) 584 | \end{pspicture} 585 | \end{center} 586 | 587 | \begin{verbatim} 588 | \begin{pspicture}(-4,-3)(4,6) 589 | \uservariable{alpha}(0.1,0){x} 590 | \psplot[algebraic,linewidth=2pt]{-4}{4}{pow(x,2)} 591 | \psplot[algebraic,linecolor=blue,linewidth=3]{-4}{4}{4*(x-alpha)*alpha} 592 | \psline{->}(-4,0)(4,0) 593 | \end{pspicture} 594 | \end{verbatim} 595 | 596 | 597 |
598 | 599 | 623 | 624 | 625 | 626 | 627 | -------------------------------------------------------------------------------- /examples/tex/index.html: -------------------------------------------------------------------------------- 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 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 65 | 66 | 67 | 68 | 69 | 74 | 75 |
76 | 77 | Powered by MathJax 80 | 81 |
82 | 83 |
84 |

Dan Lynch © LaTeX2HTML5 2013

85 |
86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /examples/tex/index.tex: -------------------------------------------------------------------------------- 1 | \begin{pspicture}(0,-3)(8,3) 2 | \rput(0,0){$x(t)$} 3 | \rput(4,1.5){$f(t)$} 4 | \rput(4,-1.5){$g(t)$} 5 | \rput(8.2,0){$y(t)$} 6 | \rput(1.5,-2){$h(t)$} 7 | \psframe(1,-2.5)(7,2.5) 8 | \psframe(3,1)(5,2) 9 | \psframe(3,-1)(5,-2) 10 | \rput(4,0){$X_k = \frac{1}{p} \sum \limits_{n=\langle p\rangle}x(n)e^{-ik\omega_0n}$} 11 | \psline{->}(0.5,0)(1.5,0) 12 | \psline{->}(1.5,1.5)(3,1.5) 13 | \psline{->}(1.5,-1.5)(3,-1.5) 14 | \psline{->}(6.5,1.5)(6.5,0.25) 15 | \psline{->}(6.5,-1.5)(6.5,-0.25) 16 | \psline{->}(6.75,0)(7.75,0) 17 | \psline(1.5,-1.5)(1.5,1.5) 18 | \psline(5,1.5)(6.5,1.5) 19 | \psline(5,-1.5)(6.5,-1.5) 20 | \psline(6,-1.5)(6.5,-1.5) 21 | \pscircle(6.5,0){0.25} 22 | \psline(6.25,0)(6.75,0) 23 | \psline(6.5,0.5)(6.5,-0.5) 24 | \end{pspicture} 25 | 26 | Many of us think our thoughts using a language of some sort---there is usually some voice in our minds. Language in some ways, makes us who we are. Some even argue in the world of cognitive science that language is the foundation of our consciousness. 27 | 28 | 29 | An author who has in their minds representations of intelligent concepts should be able to freely express herself through language with free association---digital expressions of these ideas in some cases requires total control of the computer and all of its processes. 30 | 31 | 32 | The vision behind the personal computer was that any person could have full command of the functions of their device. I think this vision has come true to some degree, but not fully when it comes to creating graphics, especially mathematical diagrams online. 33 | 34 | 35 | Does the common mathematician or professor have the ability to express concepts through web technology? The Web has its own language, and the goal of this project is to help blur the lines between what authoring the mathematical Web should be like and typesetting beautiful Math. 36 | 37 | 38 | If you know \LaTeX, then get ready to author interactive diagrams in real-time (try using mouse or touch to interact with diagrams). 39 | 40 | 41 | \begin{interactive} 42 | 43 | \waypoint{Lines And Vectors} 44 | 45 | What matters most is minimizing the distance between our expression of an idea and the execution of that idea. For example, I can describe a vector at $(0,0)$ and initial value of the head at $(2,2)$ that will follow a user touch or mouse event. This will produce the following interaction: 46 | 47 | 48 | \begin{center} 49 | \begin{pspicture}(-2,-2)(2,2) 50 | \psframe(-2,-2)(2,2) 51 | \userline[linewidth=1.5 pt]{->}(0,0)(2,2) 52 | \end{pspicture} 53 | \end{center} 54 | 55 | 56 | This was as easy as using this \TeX, which many math professors could understand. 57 | 58 | \begin{verbatim} 59 | \begin{pspicture}(-2,-2)(2,2) 60 | \psframe(-2,-2)(2,2) 61 | \userline[linewidth=1.5 pt]{->}(0,0)(2,2) 62 | \end{pspicture} 63 | \end{verbatim} 64 | 65 | If you specify more arguments, you can create functions for the head and and tail of the vector, which each takes the current $x$ and $y$ position of the users finger or cursor as they move and produces the following interaction: 66 | 67 | \begin{interactive} 68 | 69 | \begin{center} 70 | \begin{pspicture}(-2,-2)(2,2) 71 | \psframe(-2,-2)(2,2) 72 | \userline[linewidth=2pt,linecolor=green]{->}(0,0)(2,2){-x}{-y} 73 | \userline[linewidth=2pt,linecolor=red]{->}(0,0)(2,2){0}{y} 74 | \userline[linewidth=2pt,linecolor=purple]{->}(0,0)(2,2){-x}{cos(y)} 75 | \userline[linewidth=2pt,linecolor=lightblue]{->}(0,0)(2,2)(sin(x)}{-y} 76 | \end{pspicture} 77 | \end{center} 78 | 79 | \end{interactive} 80 | 81 | 82 | 2 extra arguments provide functions for the head, 4 extra arguments allows you to control both and tail 83 | 84 | \begin{verbatim} 85 | \userline[linewidth=2pt,linecolor=green]{->}(0,0)(2,2){-x}{-y} 86 | \userline[linewidth=2pt,linecolor=red]{->}(0,0)(2,2){0}{y} 87 | \userline[linewidth=2pt,linecolor=purple]{->}(0,0)(2,2){-x}{cos(y)} 88 | \userline[linewidth=2pt,linecolor=lightblue]{->}(0,0)(2,2)(sin(x)}{-y} 89 | \end{verbatim} 90 | 91 | I can also draw a more complex version, and start to make more useful diagrams to describe vectors: 92 | 93 | \begin{center} 94 | \begin{pspicture}(-5,-5)(5,5) 95 | 96 | % y-axis 97 | \rput(0.3,3.75){ $Im$ } 98 | \psline{->}(0,-3.75)(0,3.75) 99 | 100 | % x-axis 101 | \rput(3.75,0.3){ $Re$ } 102 | \psline{->}(-3.75,0)(3.75,0) 103 | 104 | % the circle 105 | \pscircle(0,0){ 3 } 106 | 107 | 108 | % new vector 109 | \rput(2.3,1){$e^{i\omega}-\alpha$} 110 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 111 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 112 | 113 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 114 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 115 | 116 | \rput(-0.75,-4.25){$1+\alpha$} 117 | \rput(2.25,-4.25){$1-\alpha$} 118 | \psline{<->}(-3,-4)(1.5,-4) 119 | \psline{<->}(1.5,-4)(3,-4) 120 | \psline[linestyle=dashed](3,-4.5)(3,0) 121 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 122 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 123 | 124 | 125 | \end{pspicture} 126 | \end{center} 127 | 128 | 129 | \begin{verbatim} 130 | \begin{pspicture}(-5,-5)(5,5) 131 | \rput(0.3,3.75){ $Im$ } 132 | \psline{->}(0,-3.75)(0,3.75) 133 | \rput(3.75,0.3){ $Re$ } 134 | \psline{->}(-3.75,0)(3.75,0) 135 | \pscircle(0,0){ 3 } 136 | \rput(2.3,1){$e^{i\omega}-\alpha$} 137 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 138 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 139 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 140 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 141 | \rput(-0.75,-4.25){$1+\alpha$} 142 | \rput(2.25,-4.25){$1-\alpha$} 143 | \psline{<->}(-3,-4)(1.5,-4) 144 | \psline{<->}(1.5,-4)(3,-4) 145 | \psline[linestyle=dashed](3,-4.5)(3,0) 146 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 147 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 148 | \end{pspicture} 149 | \end{verbatim} 150 | 151 | \waypoint{User Variables} 152 | 153 | 154 | The {\tt uservariable} command represents a variable that changes with user interaction such as touch or mouse events over the graphic. 155 | 156 | \begin{verbatim} 157 | \uservariable{variable}(x1,y1){f(x,y)} 158 | \end{verbatim} 159 | {\tt variable} is the variable that you can use in {\tt psplot} and {\tt userline} parameters and equations. Eventually it should be something you can use everywhere, but for the scope of this project, we kept it limited. 160 | 161 | 162 | {\tt x1} and {\tt y1} are the initial values of {\tt x} and {\tt y} for the function $f(x,y)$ that is that last argument for the command. If there are no user interactions, the function is evaluated with the specified inital values. 163 | 164 | 165 | On any user event, such as a touch or mouse event, the function $f(x,y)$ is evaluated and any dependent commands, namely {\tt psplot} and {\tt userline} are immediately notified and re-rendered with updated execution contexts. 166 | 167 | Think about the student learning a new concept. Here is an example of teaching integration using ``area under the curve'', for example, you can represent $\int_a^b f(x) dx$ as: 168 | 169 | \begin{center} 170 | \begin{pspicture}(-4,-3)(4,3) 171 | 172 | \uservariable{alpha}(0,0){x} 173 | 174 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{-4}{alpha}{sin(x)} 175 | \psplot[algebraic,linewidth=2pt]{-4}{4}{sin(x)} 176 | 177 | \psline{->}(-4,0)(4,0) 178 | 179 | 180 | \end{pspicture} 181 | \end{center} 182 | 183 | \begin{verbatim} 184 | \begin{pspicture}(-4,-3)(4,3) 185 | \uservariable{alpha}(0,0){x} 186 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{-4}{alpha}{sin(x)} 187 | \psplot[algebraic,linewidth=2pt]{-4}{4}{sin(x)} 188 | \psline{->}(-4,0)(4,0) 189 | \end{pspicture} 190 | \end{verbatim} 191 | 192 | The next example allows you to move the height of the graph and also integrate over a moving interval. 193 | 194 | \begin{center} 195 | \begin{pspicture}(-4,-3)(4,3) 196 | 197 | \uservariable{alpha}(0,0){x} 198 | \uservariable{beta}(0,0){y} 199 | 200 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{alpha-3}{alpha}{beta + sin(x)} 201 | \psplot[algebraic,linewidth=2pt]{-4}{4}{beta + sin(x)} 202 | 203 | \psline{->}(-4,0)(4,0) 204 | 205 | \end{pspicture} 206 | \end{center} 207 | 208 | 209 | \begin{verbatim} 210 | \begin{pspicture}(-4,-3)(4,3) 211 | \uservariable{alpha}(0,0){x} 212 | \uservariable{beta}(0,0){y} 213 | \psplot[algebraic,linewidth=2pt,fillstyle=solid, fillcolor=lightblue]{alpha-3}{alpha}{beta + sin(x)} 214 | \psplot[algebraic,linewidth=2pt]{-4}{4}{beta + sin(x)} 215 | \psline{->}(-4,0)(4,0) 216 | \end{pspicture} 217 | \end{verbatim} 218 | 219 | \end{interactive} 220 | 221 | \waypoint{Sliders} 222 | 223 | One useful way to expose basic interactive functionality for an end user is the {\tt slider} command. 224 | 225 | 226 | Arguments for the {\tt slider} command are: 227 | 228 | \begin{verbatim} 229 | \slider{min}{max}{variable}{latex}{default} 230 | \end{verbatim} 231 | 232 | The min and max values are for specifying the minimum and maximum of the range of the slider. 233 | 234 | 235 | The {\tt latex} argument is what to display next to the slider to indicate to the end user what variable the slider is changing. Finally, the most important is the {\tt variable} argument. The {\tt variable} specifies the variable that is changed based on the values of the slider, and can be used in the equations of {\tt psplot} commands. 236 | 237 | 238 | Note that using these ``extended'' features are not backwards compatible, a.k.a they don't work on paper! 239 | 240 | 241 | \begin{interactive} 242 | \psset{unit=1cm} 243 | 244 | \begin{center} 245 | \begin{pspicture}(-3.5,-1)(3.75,3.5) 246 | 247 | \slider{1}{8}{n}{$N$}{4} 248 | 249 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-3.14}{3.14}{cos(n*x/2)+1.3} 250 | \psaxes[showorigin=false,labels=none, Dx=1.62](0,0)(-3.25,0)(3.25,2.5) 251 | 252 | \psline[linestyle=dashed](-3.14,0.3)(3.14,0.3) 253 | \psline[linestyle=dashed](-3.14,2.3)(3.14,2.3) 254 | \rput(3.6,2.3){$\frac{1}{1-\alpha}$} 255 | \rput(3.6,0.3){$\frac{1}{1+\alpha}$} 256 | 257 | 258 | \rput(3.14, -0.35){$\pi$} 259 | \rput(1.62, -0.35){$\pi/2$} 260 | \rput(-1.62, -0.35){$-\pi/2$} 261 | \rput(-3.14, -0.35){$-\pi$} 262 | \rput(0, -0.35){$0$} 263 | 264 | \end{pspicture} 265 | \end{center} 266 | \end{interactive} 267 | 268 | \begin{verbatim} 269 | \begin{pspicture}(-3.5,-1)(3.75,3.5) 270 | \slider{1}{8}{n}{$N$}{4} 271 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-3.14}{3.14}{cos(n*x/2)+1.3} 272 | \psaxes[showorigin=false,labels=none, Dx=1.62](0,0)(-3.25,0)(3.25,2.5) 273 | \psline[linestyle=dashed](-3.14,0.3)(3.14,0.3) 274 | \psline[linestyle=dashed](-3.14,2.3)(3.14,2.3) 275 | \rput(3.6,2.3){$\frac{1}{1-\alpha}$} 276 | \rput(3.6,0.3){$\frac{1}{1+\alpha}$} 277 | \rput(3.14, -0.35){$\pi$} 278 | \rput(1.62, -0.35){$\pi/2$} 279 | \rput(-1.62, -0.35){$-\pi/2$} 280 | \rput(-3.14, -0.35){$-\pi$} 281 | \rput(0, -0.35){$0$} 282 | \end{pspicture} 283 | \end{verbatim} 284 | 285 | 286 | 287 | \begin{interactive} 288 | \psset{unit=0.5cm} 289 | \begin{center} 290 | \begin{pspicture}(-13,-5)(13,10) 291 | 292 | \slider{1}{8}{a}{amplitude}{4} 293 | \slider{1}{8}{n}{frequency}{4} 294 | 295 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-12.56}{12.56}{a*sin(n*x)/(n*x)} 296 | \psaxes[showorigin=false,labels=none, Dx=3.14](0,0)(-12.6,0)(12.6,0) 297 | 298 | \rput(0, -0.5){$0$} 299 | 300 | \end{pspicture} 301 | \end{center} 302 | \end{interactive} 303 | 304 | 305 | \begin{verbatim} 306 | \begin{pspicture}(-13,-5)(13,10) 307 | \slider{1}{8}{a}{amplitude}{4} 308 | \slider{1}{8}{n}{frequency}{4} 309 | \psplot[algebraic,linewidth=1.5pt,plotpoints=1000]{-12.56}{12.56}{a*sin(n*x)/(n*x)} 310 | \psaxes[showorigin=false,labels=none, Dx=3.14](0,0)(-12.6,0)(12.6,0) 311 | \rput(0, -0.5){$0$} 312 | \end{pspicture} 313 | \end{verbatim} 314 | 315 | 316 | 317 | \begin{center} 318 | \psset{unit=0.75cm} 319 | \begin{pspicture}(-4,-3)(4,6) 320 | \uservariable{alpha}(0.1,0){x} 321 | \psplot[algebraic,linewidth=2pt]{-4}{4}{pow(x,2)} 322 | \psplot[algebraic,linecolor=blue,linewidth=3]{-4}{4}{4*(x-alpha)*alpha} 323 | \psline{->}(-4,0)(4,0) 324 | \end{pspicture} 325 | \end{center} 326 | 327 | \begin{verbatim} 328 | \begin{pspicture}(-4,-3)(4,6) 329 | \uservariable{alpha}(0.1,0){x} 330 | \psplot[algebraic,linewidth=2pt]{-4}{4}{pow(x,2)} 331 | \psplot[algebraic,linecolor=blue,linewidth=3]{-4}{4}{4*(x-alpha)*alpha} 332 | \psline{->}(-4,0)(4,0) 333 | \end{pspicture} 334 | \end{verbatim} 335 | 336 | 337 | \waypoint{math excerpt} 338 | 339 | What frequencies can be present in a signal $\vec{x}$? The harmonics are given by a signal with period $p$ are $\{0,\omega_0,2\omega_0,\dots,(p-1)\omega_0\}$. Notice that $p\omega_0$ is missing. This is because $e^{ip\omega_0n}=e^{i2\pi n} = e^{i0n}$. Keep in mind that $\omega_0 = 2\pi/p$. In fact, the complex exponential basis of vectors is periodic with respect to $n$ and their indices $k$. 340 | 341 | \begin{align*} 342 | \Psi_k(n+p) &= e^{ik\omega_0(n+p)}=e^{ik\omega_0n}e^{ik\omega_0p}=e^{ik\omega_0n} = \Psi_k(n) \\ 343 | \Psi_{k+p}(n) &= e^{i(k+p)\omega_0n} = e^{ik\omega_0n}e^{ip\omega_0n} = \Psi_k(n) 344 | \end{align*} 345 | 346 | So we know that $\Psi_{-1}(n) = e^{-i\omega_0n} = \Psi_{p-1}(n) = e^{i(p-1)\omega_0n }$. So we can see that in general, we can write out a discrete fourier series expansion over any continuous set of $p$ integers. The notation used is 347 | $$ x(n) = \sum \limits_{k=\langle p \rangle} X_ke^{ik\omega_0n}$$ 348 | 349 | 350 | Given a periodic signal $x$ in CT, we can estimate the signal using the formula: 351 | 352 | $$ \hat{x}(t) = \sum \limits_{k=-N}^{N}\alpha_k e^{ik\omega_0 t} $$ 353 | 354 | How can we determine the coefficients that make the estimates closest in terms of error energy? Let $W\in\R^{2N+1}$ be a subspace spanned by the set of orthogonal basis vectors $\Psi_0, \Psi_1, \Psi_{-1} \dots, \Psi_{N}, \Psi_{-N}$. If $x$ is a vector that is not in the column space of $W$, then we can project $x$ onto the column space of $W$, producing an approximation vector $\hat{x}$, which has a distance of $\abs{\left| \mathcal{E}_N\right|}$ from the vector $x$. The vectors $\mathcal{E}_N$ and $\hat{x}$ are orthogonal. 355 | 356 | 357 | \psset{unit=1cm} 358 | \begin{center} 359 | \begin{pspicture}(-1,-3)(9,4) 360 | 361 | \pscustom[fillstyle=solid,fillcolor=gray!40,linestyle=none]{ 362 | \psline[linewidth=1 pt](0,0)(4,1.2) 363 | \psline[linewidth=1 pt](4,1.2)(8.4,0) 364 | \psline[linewidth=1 pt](8.4,0)(4,-1.2) 365 | \psline[linewidth=1 pt](4,-1.2)(0,0) 366 | } 367 | 368 | \psline[linewidth=1 pt](0,0)(4,1.2) 369 | \psline[linewidth=1 pt](4,1.2)(8.4,0) 370 | \psline[linewidth=1 pt](8.4,0)(4,-1.2) 371 | \psline[linewidth=1 pt](4,-1.2)(0,0) 372 | 373 | \rput(0.78,0){$W$} 374 | 375 | 376 | % new vector 377 | \rput(6,3.3){$x$} 378 | \psline[linewidth=1.5 pt,linecolor=red]{->}(2.2,0.2)(6,3) 379 | 380 | % new vector 381 | \rput(6.35,1.5){$\mathcal{E}_N$} 382 | \psline[linewidth=1.5 pt]{->}(6,0)(6,3) 383 | 384 | % new vector 385 | \rput(4,-0.3){$\hat{x}_N$} 386 | \psline[linewidth=1.5 pt]{->}(2.2,0.2)(6,0) 387 | 388 | % new vector 389 | \psline[linewidth=1.5 pt](2.2,0.2)(6,0) 390 | 391 | 392 | \end{pspicture} 393 | \end{center} 394 | We want to minimize $\abs{\left| \mathcal{E}_N\right|}$ to make the best approximation. $\mathcal{E}_N = x - \hat{x}_N$, hence $\abs{\left| \mathcal{E}_N\right|} = \abs{\left| x-\hat{x}_N\right|}$. Since $\mathcal{E} \perp W$, then we can use the inner product and the properties of orthogonality to solve for the coefficients. Since $W \in \R^{2N+1}$, we have $2N+1$ equations and $2N+1$ coefficients. 395 | 396 | \begin{align*} 397 | \langle \hat{x}_N, \Psi_\ell\rangle &= \langle \sum \limits_{k=-N}^{N}\alpha_k e^{ik\omega_0 t} , \Psi_\ell\rangle \\ 398 | \langle \hat{x}_N, \Psi_\ell\rangle &= \sum \limits_{k=-N}^{N}\alpha_k \langle e^{ik\omega_0 t} , \Psi_\ell\rangle \\ 399 | \langle \hat{x}_N, \Psi_\ell\rangle &= \alpha_\ell \langle e^{i\ell\omega_0 t} , \Psi_\ell\rangle \\ 400 | \langle \hat{x}_N, \Psi_\ell\rangle &= \alpha_\ell \langle \Psi_\ell , \Psi_\ell\rangle \\ 401 | \alpha_\ell &= \frac{\langle \hat{x}_N, \Psi_\ell\rangle }{\langle \Psi_\ell , \Psi_\ell\rangle } \\ 402 | \end{align*} 403 | 404 | if $\hat{x}(t) = \sum \limits_{k=0}^{M-1}\alpha_k \Psi_k$, where $x$ is a $p$-periodic signal, which $\Psi_k$'s would you choose? Since we are taking a subset, the larger exponentials are better since they dominate. Otherwise, using $\{0,1,\dots,M\}\in\Z$ is not using very much. Pick the largest in magnitude FS coefficient, and then go down from there, but it doesn't have to be continguous. 405 | 406 | 407 | \begin{pspicture}(-5,-5)(5,5) 408 | \rput(0.3,3.75){ $Im$ } 409 | \psline{->}(0,-3.75)(0,3.75) 410 | \rput(3.75,0.3){ $Re$ } 411 | \psline{->}(-3.75,0)(3.75,0) 412 | \pscircle(0,0){ 3 } 413 | \pscircle(0,0){ 2 } 414 | \pscircle(0,0){ 1 } 415 | \rput(2.3,1){$e^{i\omega}-\alpha$} 416 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(1.121,2.121) 417 | \userline[linewidth=1.5 pt]{->}(1.500,0.000)(2.121,2.121) 418 | \userline[linewidth=1.5 pt,linecolor=blue]{->}(0,0.000)(2.121,2.121){(x>0) ? 3 * cos( atan(-y/x) ) : -3 * cos( atan(-y/x) ) }{ (x>0) ? -3 * sin( atan(-y/x) ) : 3 * sin( atan(-y/x) )} 419 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){x}{0}{x}{y} 420 | \userline[linewidth=1.5 pt,linestyle=dashed](-1.500,0.000)(2.121,2.121){0}{y}{x}{y} 421 | \rput(-0.75,-4.25){$1+\alpha$} 422 | \rput(2.25,-4.25){$1-\alpha$} 423 | \psline{<->}(-3,-4)(1.5,-4) 424 | \psline{<->}(1.5,-4)(3,-4) 425 | \psline[linestyle=dashed](3,-4.5)(3,0) 426 | \psline[linestyle=dashed](-3,-4.5)(-3,0) 427 | \psline[linestyle=dashed](1.5,-4.5)(1.5,0) 428 | \end{pspicture} 429 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 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 | 46 | 47 | 48 | 49 | 50 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | Fork me on GitHub 89 | 90 |
91 | 92 | 93 |

LaTeX2HTML5

94 |

Author interactive math equations and diagrams online using $\LaTeX$ and PSTricks

95 | 96 |
97 | 98 |
99 | 100 |
101 | 102 |
103 | 104 |

105 | 106 | 107 |

This project is the frontend only version of the code that originated from Mathapedia to enable real-time, dynamic authorship of mathematical ebooks

108 | 109 |

110 | 111 | 112 | 113 | 114 | $$\frac{\delta}{\delta u} \int_{birth}^{death} f(life) du = \mbox{your life}$$ 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
123 | 124 | 125 |
126 | 127 |

128 | 129 | 130 |

131 | 132 |

Check out the examples below or view source to get started. You will also find installation instructions here. There's also documentation here and sandbox here.

For a quick look on this page, we have interactive lines and vectors, user variables, and sliders. 133 | 134 | 135 |
136 | 137 | 138 | 147 | 148 | 149 | 150 | 151 | 583 | 584 | 589 | 590 |
591 | 592 | Powered by MathJax 595 | 596 |
597 | 598 |
599 |

Dan Lynch © LaTeX2HTML5 2013

600 |
601 | 602 | 612 | 613 | 614 | 615 | 616 | -------------------------------------------------------------------------------- /installation.html: -------------------------------------------------------------------------------- 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 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Fork me on GitHub 66 | 67 |
68 | 69 | 70 |

LaTeX2HTML5

71 | 72 |

Installing & Configurating MathJax

73 | 74 |

Make sure you have both the MathJax configuration and script. Put this in your <head> tag:

75 | 76 |
 77 | 
 78 | <script type="text/x-mathjax-config">
 79 |     // <![CDATA[
 80 |     MathJax.Hub.Config({ 
 81 |         TeX: {extensions: ["AMSmath.js", "AMSsymbols.js"]},     
 82 |         extensions: ["tex2jax.js"],
 83 |         jax: ["input/TeX", "output/HTML-CSS"],
 84 |         showProcessingMessages : false,
 85 |         messageStyle : "none" ,    
 86 |         showMathMenu: false ,
 87 |         tex2jax: {
 88 |             processEnvironments: true,
 89 |             inlineMath: [ ['$','$'], ["\(","\)"] ],
 90 |             displayMath: [ ['$$','$$'], ["\[","\]"] ],
 91 |             preview : "none",
 92 |             processEscapes: true
 93 |         },
 94 |         "HTML-CSS": { linebreaks: { automatic:true, width: "latex-container"} }
 95 |     });
 96 |     // ]]>
 97 | </script>
 98 | <script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
 99 |         
100 | 101 | 102 |

LaTeX2HTML5 Installation

103 | 104 |

105 | 106 |

    107 |
  1. 108 | 109 | Simply download the JS and CSS files and include them on your MathJax enabled website: 110 | 111 |
    112 |      <link rel="stylesheet" href="latex2html5.min.css"> 
    113 |      <script type="text/javascript" src="latex2html5.min.js"></script> 
    114 |     
    115 | 116 |
  2. 117 | 118 | If you want the same font as the rendered examples: 119 | 120 |
    121 | <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Arbutus+Slab" type="text/css">
    122 |     
    123 | 124 |
  3. You have three options for parsing the $\LaTeX$: 125 | 126 |
      127 | 128 |
    1. 129 | You can put $\LaTeX$ inside of the current page within a script tag with the type set to "tex/latex": 130 | 131 |
      132 |             <script type="tex/latex">
      133 |                 ... LaTeX here ...
      134 |             </script>
      135 |             <script type="text/javascript">
      136 |                 $('body').latex();
      137 |             </script>
      138 |         
      139 | 140 |
    2. 141 | or you can read a .tex file from somewhere else, which is nice for editing .tex files: 142 | 143 |
      144 |             <latex src="path/to/my/latex.tex">
      145 |             <script type="text/javascript">
      146 |                 $('latex').LaTeX();
      147 |             </script>
      148 |         
      149 | 150 |
    3. 151 | 152 | or you can write it from scratch! 153 | 154 |
      155 | 
      156 |   MathJax.Hub.Register.StartupHook("End",function () {
      157 | 
      158 |       $('[type="tex/latex"]').each(function (i, el) {
      159 |           var $el = $(el);
      160 |           var TEX = new LaTeX2HTML5.TeX({
      161 |               tagName: 'section',
      162 |               className: 'latex-container',
      163 |               latex: $el.text()
      164 |           });
      165 |           TEX.render();
      166 |           $el.replaceWith(TEX.$el);
      167 |       });
      168 |       
      169 |   });
      170 | 
      171 | 
      172 | 
      173 |             
      174 | 175 |
    4. 176 | 177 |
    178 |
  4. 179 | 180 |
181 |

182 | 183 | 184 |
185 | 186 |
187 | 188 | Powered by MathJax 191 | 192 |
193 | 194 |
195 |

Dan Lynch © LaTeX2HTML5 2013

196 |
197 | 198 | 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /lib/expressions.js: -------------------------------------------------------------------------------- 1 | (function (LaTeX2HTML5) { 2 | var Delimiters = LaTeX2HTML5.Delimiters = {}; 3 | 4 | _.each(['pspicture', 5 | 'verbatim', 6 | 'enumerate', 7 | 'print', 8 | 'nicebox' 9 | ], function (name) { 10 | LaTeX2HTML5.addEnvironment(name); 11 | }); 12 | 13 | var Ignore = LaTeX2HTML5.Ignore = [ 14 | /^\%/, 15 | /\\begin\{document\}/, 16 | /\\end\{document\}/, 17 | /\\begin\{interactive\}/, 18 | /\\end\{interactive\}/, 19 | /\\usepackage/, 20 | /\\documentclass/, 21 | /\\tableofcontents/, 22 | /\\author/, 23 | /\\date/, 24 | /\\maketitle/, 25 | /\\title/, 26 | /\\pagestyle/, 27 | /\\smallskip/, 28 | /\\medskip/, 29 | /\\bigskip/, 30 | /\\nobreak/, 31 | /\\begin\{center\}/, 32 | /\\end\{center\}/ 33 | ]; 34 | var Headers = LaTeX2HTML5.Headers = { 35 | Expressions: { 36 | bq: /\\begin\{quotation\}/, 37 | eq: /\\end\{quotation\}/, 38 | proof: /\\begin\{proof\}/, 39 | qed: /\\end\{proof\}/, 40 | example: /\\begin\{example\}/, 41 | definition: /\\begin\{definition\}/, 42 | theorem: /\\begin\{theorem\}/, 43 | claim: /\\begin\{claim\}/, 44 | corollary: /\\begin\{corollary\}/, 45 | problem: /\\begin\{problem\}/, 46 | solution: /\\begin\{solution\}/, 47 | endexample: /\\end\{example\}/, 48 | enddefinition: /\\end\{definition\}/, 49 | endproblem: /\\end\{problem\}/, 50 | endsolution: /\\end\{solution\}/, 51 | endtheorem: /\\end\{theorem\}/, 52 | endclaim: /\\end\{claim\}/, 53 | endcorallary: /\\end\{corallary\}/ 54 | }, 55 | Functions: { 56 | endexample: function () { 57 | return ''; 58 | }, 59 | enddefinition: function () { 60 | return ''; 61 | }, 62 | endproblem: function () { 63 | return ''; 64 | }, 65 | endsolution: function () { 66 | return ''; 67 | }, 68 | endtheorem: function () { 69 | return ''; 70 | }, 71 | endclaim: function () { 72 | return ''; 73 | }, 74 | endcorollary: function () { 75 | return ''; 76 | }, 77 | bq: function () { 78 | return '

'; 79 | }, 80 | eq: function () { 81 | return '

'; 82 | }, 83 | proof: function () { 84 | return '

Proof

'; 85 | }, 86 | qed: function () { 87 | return '$\\qed$'; 88 | }, 89 | example: function () { 90 | return '

Example

'; 91 | }, 92 | definition: function () { 93 | return '

Definition

'; 94 | }, 95 | problem: function () { 96 | return '

Problem

'; 97 | }, 98 | solution: function () { 99 | return '

Solution

'; 100 | }, 101 | theorem: function () { 102 | return '

Theorem

'; 103 | }, 104 | corollary: function () { 105 | return '

Corollary

'; 106 | }, 107 | claim: function () { 108 | return '

Claim

'; 109 | } 110 | } 111 | }; 112 | /** 113 | * TEXT 114 | */ 115 | LaTeX2HTML5.utils = { 116 | 117 | }; 118 | 119 | var simplerepl = LaTeX2HTML5.utils.simplerepl = function (regex, replace) { 120 | return function (m, contents) { 121 | return contents.replace(regex, replace); 122 | }; 123 | }; 124 | var matchrepl = LaTeX2HTML5.utils.matchrepl = function (regex, callback) { 125 | return function (m, contents) { 126 | _.each(m, function (match) { 127 | var m2 = match.match(regex); 128 | contents = contents.replace(m2.input, callback(m2)); 129 | }); 130 | return contents; 131 | }; 132 | }; 133 | LaTeX2HTML5.Text = { 134 | Expressions: { 135 | emph: /\\emph\{[^}]*\}/g, 136 | bf: /\{*\\bf [^}]*\}/g, 137 | rm: /\{*\\rm [^}]*\}/g, 138 | sl: /\{*\\sl [^}]*\}/g, 139 | it: /\{*\\it [^}]*\}/g, 140 | tt: /\{*\\tt [^}]*\}/g, 141 | mdash: /---/g, 142 | ndash: /--/g, 143 | openq: /``/g, 144 | closeq: /''/g, 145 | TeX: /\\TeX\\|\\TeX/g, 146 | LaTeX: /\\LaTeX\\|\\LaTeX/g, 147 | vspace: /\\vspace/g, 148 | cite: /\\cite\[\d+\]\{[^}]*\}/g, 149 | href: /\\href\{[^}]*\}\{[^}]*\}/g, 150 | img: /\\img\{[^}]*\}/g, 151 | set: /\\set\{[^}]*\}/g, 152 | youtube: /\\youtube\{[^}]*\}/g, 153 | euler: /Euler\^/g, 154 | 155 | }, 156 | Functions: { 157 | 158 | cite: function (m, contents) { 159 | _.each(m, function (match) { 160 | var m2 = match.match(/\\cite\[(\d+)\]\{([^}]*)\}/); 161 | var m = location.pathname.match(/\/books\/(\d+)\//); 162 | var book_id = 0; 163 | if (m) { 164 | book_id = m[1]; 165 | } 166 | contents = contents.replace(m2.input, '[p' + m2[1] + ']'); 167 | }); 168 | return contents; 169 | }, 170 | img: matchrepl(/\\img\{([^}]*)\}/, function (m) { 171 | return '
'; 172 | }), 173 | youtube: matchrepl(/\\youtube\{([^}]*)\}/, function (m) { 174 | return '
'; 175 | }), 176 | href: matchrepl(/\\href\{([^}]*)\}\{([^}]*)\}/, function (m) { 177 | return '' + m[2] + ''; 178 | }), 179 | set: matchrepl(/\\set\{([^}]*)\}/, function (m) { 180 | return '' + m[1] + ''; 181 | }), 182 | euler: simplerepl(/Euler\^/, 'exp'), 183 | emph: matchrepl(/\{([^}]*)\}/, function (m) { 184 | return '' + m[1] + ''; 185 | }), 186 | bf: matchrepl(/\{*\\bf ([^}]*)\}/, function (m) { 187 | return '' + m[1] + ''; 188 | }), 189 | rm: matchrepl(/\{*\\rm ([^}]*)\}/, function (m) { 190 | return '' + m[1] + ''; 191 | }), 192 | sl: matchrepl(/\{*\\sl ([^}]*)\}/, function (m) { 193 | return '' + m[1] + ''; 194 | }), 195 | it: matchrepl(/\{*\\it ([^}]*)\}/, function (m) { 196 | return '' + m[1] + ''; 197 | }), 198 | tt: matchrepl(/\{*\\tt ([^}]*)\}/, function (m) { 199 | return '' + m[1] + ''; 200 | }), 201 | ndash: simplerepl(/--/g, '–'), 202 | mdash: simplerepl(/---/g, '—'), 203 | openq: simplerepl(/``/g, '“'), 204 | closeq: simplerepl(/''/g, '”'), 205 | vspace: simplerepl(/\\vspace/g, '
'), 206 | TeX: simplerepl(/\\TeX\\|\\TeX/g, '$\\TeX$'), 207 | LaTeX: simplerepl(/\\LaTeX\\|\\LaTeX/g, '$\\LaTeX$') 208 | } 209 | }; 210 | // OPTIONS 211 | // converts [showorigin=false,labels=none, Dx=3.14] to {showorigin: 'false', labels: 'none', Dx: '3.14'} 212 | var parseOptions = function (opts) { 213 | var options = opts.replace(/[\]\[]/g, ''); 214 | var all = options.split(','); 215 | var obj = {}; 216 | _.each(all, function (option) { 217 | var kv = option.split('='); 218 | if (kv.length == 2) { 219 | obj[kv[0].trim()] = kv[1].trim(); 220 | } 221 | }); 222 | return obj; 223 | }; 224 | /** 225 | * SETTINGS 226 | */ 227 | var convertUnits = function (value) { 228 | var m = null; 229 | if ((m = value.match(/([^c]+)\s*cm/))) { 230 | var num1 = Number(m[1]); 231 | return num1 * 50; //118; 232 | } else if ((m = value.match(/([^i]+)\s*in/))) { 233 | var num2 = Number(m[1]); 234 | return num2 * 20; //46; 235 | } else if ((m = value.match(/(.*)/))) { 236 | var num3 = Number(m[1]); 237 | return num3 * 50; 238 | } else { 239 | var num4 = Number(value); 240 | return num4; 241 | } 242 | }; 243 | var Settings = { 244 | Expressions: { 245 | fillcolor: /^fillcolor$/, 246 | fillstyle: /^fillstyle$/, 247 | linecolor: /^linecolor$/, 248 | linestyle: /^linestyle$/, 249 | unit: /^unit/, 250 | runit: /^runit/, 251 | xunit: /^xunit/, 252 | yunit: /^yunit/ 253 | }, 254 | Functions: { 255 | fillcolor: function (o, v) { 256 | o.fillcolor = v; 257 | }, 258 | fillstyle: function (o, v) { 259 | o.fillstyle = v; 260 | }, 261 | linecolor: function (o, v) { 262 | o.linecolor = v; 263 | }, 264 | linestyle: function (o, v) { 265 | o.linestyle = v; 266 | }, 267 | unit: function (o, v) { 268 | v = convertUnits(v); 269 | o.unit = v; 270 | o.runit = v; 271 | o.xunit = v; 272 | o.yunit = v; 273 | }, 274 | runit: function (o, v) { 275 | v = convertUnits(v); 276 | o.runit = v; 277 | }, 278 | xunit: function (o, v) { 279 | v = convertUnits(v); 280 | o.xunit = v; 281 | }, 282 | yunit: function (o, v) { 283 | v = convertUnits(v); 284 | o.yunit = v; 285 | } 286 | } 287 | }; 288 | /** 289 | * PSTRICKS 290 | */ 291 | var parseArrows = function (m) { 292 | var lineType = m; 293 | var arrows = [ 294 | 0, 295 | 0 296 | ]; 297 | var dots = [ 298 | 0, 299 | 0 300 | ]; 301 | if (lineType) { 302 | var type = lineType.match(/\{([^\-]*)?\-([^\-]*)?\}/); 303 | if (type) { 304 | if (type[1]) { 305 | // check starting point 306 | if (type[1].match(/\*/)) { 307 | dots[0] = 1; 308 | } else if (type[1].match(//)) { 317 | arrows[1] = 1; 318 | } 319 | } 320 | } 321 | } 322 | return { 323 | arrows: arrows, 324 | dots: dots 325 | }; 326 | }; 327 | var evaluate = function (exp) { 328 | var num = Number(exp); 329 | if (_.isNaN(num)) { 330 | var expression = ''; 331 | _.each(this.variables, function (val, name) { 332 | expression += 'var ' + name + ' = ' + val + ';'; 333 | }); 334 | expression += 'with (Math){' + exp + '}'; 335 | return eval(expression); 336 | } else { 337 | return num; 338 | } 339 | }; 340 | var X = function (v) { 341 | return (this.w - (this.x1 - Number(v))) * this.xunit; 342 | }; 343 | var Xinv = function (v) { 344 | return Number(v) / this.xunit - this.w + this.x1; 345 | }; 346 | var Y = function (v) { 347 | return (this.y1 - Number(v)) * this.yunit; 348 | }; 349 | var Yinv = function (v) { 350 | return this.y1 - Number(v) / this.yunit; 351 | }; 352 | var RE = { 353 | options: '(\\[[^\\]]*\\])?', 354 | type: '(\\{[^\\}]*\\})?', 355 | squiggle: '\\{([^\\}]*)\\}', 356 | squiggleOpt: '(\\{[^\\}]*\\})?', 357 | coordsOpt: '(\\(\\s*([^\\)]*),([^\\)]*)\\s*\\))?', 358 | coords: '\\(\\s*([^\\)]*),([^\\)]*)\\s*\\)' 359 | }; 360 | 361 | LaTeX2HTML5.Transformations = { 362 | X: X, 363 | Y: Y, 364 | Xinv: Xinv, 365 | Yinv: Yinv 366 | }; 367 | LaTeX2HTML5.PSTricks = { 368 | Expressions: { 369 | pspicture: /\\begin\{pspicture\}\(\s*(.*),(.*)\s*\)\(\s*(.*),(.*)\s*\)/, 370 | psframe: /\\psframe\(\s*(.*),(.*)\s*\)\(\s*(.*),(.*)\s*\)/, 371 | psplot: /\\psplot(\[[^\]]*\])?\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}/, 372 | psarc: new RegExp('\\\\psarc' + RE.options + RE.type + RE.coords + RE.squiggle + RE.squiggle + RE.squiggle), 373 | pscircle: /\\pscircle.*\(\s*(.*),(.*)\s*\)\{(.*)\}/, 374 | pspolygon: new RegExp('\\\\pspolygon' + RE.options + '(.*)'), 375 | psaxes: new RegExp('\\\\psaxes' + RE.options + RE.type + RE.coords + RE.coordsOpt + RE.coordsOpt), 376 | slider: new RegExp('\\\\slider' + RE.options + RE.squiggle + RE.squiggle + RE.squiggle + RE.squiggle + RE.squiggle), 377 | psline: new RegExp('\\\\psline' + RE.options + RE.type + RE.coords + RE.coordsOpt), 378 | userline: new RegExp('\\\\userline' + RE.options + RE.type + RE.coords + RE.coords + RE.squiggleOpt + RE.squiggleOpt + RE.squiggleOpt + RE.squiggleOpt), 379 | uservariable: new RegExp('\\\\uservariable' + RE.options + RE.squiggle + RE.coords + RE.squiggle), 380 | rput: /\\rput\((.*),(.*)\)\{(.*)\}/, 381 | psset: /\\psset\{(.*)\}/ 382 | }, 383 | Functions: { 384 | slider: function (m) { 385 | // console.log(m); 386 | var obj = { 387 | scalar: 1, 388 | min: Number(m[2]), 389 | max: Number(m[3]), 390 | variable: m[4], 391 | latex: m[5], 392 | value: Number(m[6]) 393 | }; 394 | this.variables = this.variables || {}; 395 | this.variables[obj.variable] = obj.value; 396 | this.sliders = this.sliders || []; 397 | this.sliders.push(obj); 398 | if (m[1]) { 399 | _.extend(obj, parseOptions(m[1])); 400 | } 401 | return obj; 402 | }, 403 | pspicture: function (m) { 404 | var p = { 405 | x0: Number(m[1]), 406 | y0: Number(m[2]), 407 | x1: Number(m[3]), 408 | y1: Number(m[4]) 409 | }; 410 | var s = { 411 | w: p.x1 - p.x0, 412 | h: p.y1 - p.y0 413 | }; 414 | _.extend(this, p, s); 415 | return _.extend(p, s); 416 | }, 417 | psframe: function (m) { 418 | var obj = { 419 | x1: X.call(this, m[1]), 420 | y1: Y.call(this, m[2]), 421 | x2: X.call(this, m[3]), 422 | y2: Y.call(this, m[4]) 423 | }; 424 | return obj; 425 | }, 426 | pscircle: function (m) { 427 | var obj = { 428 | cx: X.call(this, m[1]), 429 | cy: Y.call(this, m[2]), 430 | r: this.xunit * m[3] 431 | }; 432 | return obj; 433 | }, 434 | psaxes: function (m) { 435 | var obj = { 436 | dx: 1 * this.xunit, 437 | dy: 1 * this.yunit, 438 | arrows: [ 439 | 0, 440 | 0 441 | ], 442 | dots: [ 443 | 0, 444 | 0 445 | ], 446 | ticks: 'all' 447 | }; 448 | if (m[1]) { 449 | var options = parseOptions(m[1]); 450 | if (options.Dx) { 451 | obj.dx = Number(options.Dx) * this.xunit; 452 | } 453 | if (options.Dy) { 454 | obj.dy = Number(options.Dy) * this.yunit; 455 | } 456 | } 457 | // arrows? 458 | var l = parseArrows(m[2]); 459 | obj.arrows = l.arrows; 460 | obj.dots = l.dots; 461 | // \psaxes*[par]{arrows}(x0,y0)(x1,y1)(x2,y2) 462 | // m[1] [options] 463 | // m[2] {<->} 464 | // origin 465 | // m[3] x0 466 | // m[4] y0 467 | // bottom left corner 468 | // m[6] x1 469 | // m[7] y1 470 | // top right corner 471 | // m[9] x2 472 | // m[10] y2 473 | if (m[5] && !m[8]) { 474 | // If (x0,y0) is omitted, then the origin is (x1,y1). 475 | obj.origin = [ 476 | X.call(this, m[3]), 477 | Y.call(this, m[4]) 478 | ]; 479 | obj.bottomLeft = [ 480 | X.call(this, m[3]), 481 | Y.call(this, m[4]) 482 | ]; 483 | obj.topRight = [ 484 | X.call(this, m[6]), 485 | Y.call(this, m[7]) 486 | ]; 487 | } else if (!m[5] && !m[8]) { 488 | // If both (x0,y0) and (x1,y1) are omitted, (0,0) is used as the default. 489 | obj.origin = [ 490 | X.call(this, 0), 491 | Y.call(this, 0) 492 | ]; 493 | obj.bottomLeft = [ 494 | X.call(this, 0), 495 | Y.call(this, 0) 496 | ]; 497 | obj.topRight = [ 498 | X.call(this, m[3]), 499 | Y.call(this, m[6]) 500 | ]; 501 | } else { 502 | // all three are specified 503 | obj.origin = [ 504 | X.call(this, m[3]), 505 | Y.call(this, m[4]) 506 | ]; 507 | obj.bottomLeft = [ 508 | X.call(this, m[6]), 509 | Y.call(this, m[7]) 510 | ]; 511 | obj.topRight = [ 512 | X.call(this, m[9]), 513 | Y.call(this, m[10]) 514 | ]; 515 | } 516 | return obj; 517 | }, 518 | psplot: function (m) { 519 | var startX = evaluate.call(this, m[2]); 520 | var endX = evaluate.call(this, m[3]); 521 | var data = []; 522 | var x; 523 | // get env 524 | var expression = ''; 525 | _.each(this.variables, function (val, name) { 526 | expression += 'var ' + name + ' = ' + val + ';'; 527 | }); 528 | expression += 'with (Math){' + m[4] + '}'; 529 | // console.log(expression); 530 | for (x = startX; x <= endX; x += 0.005) { 531 | data.push(X.call(this, x)); 532 | // data.push(Y.call(this, Math.cos(x/2))); 533 | data.push(Y.call(this, eval(expression))); 534 | } 535 | var obj = { 536 | linecolor: 'black', 537 | linestyle: 'solid', 538 | fillstyle: 'none', 539 | fillcolor: 'none', 540 | linewidth: 2 541 | }; 542 | if (m[1]) 543 | _.extend(obj, parseOptions(m[1])); 544 | obj.data = data; 545 | return obj; 546 | }, 547 | pspolygon: function (m) { 548 | var coords = m[2]; 549 | if (!coords) 550 | return; 551 | var manyCoords = new RegExp(RE.coords, 'g'); 552 | var matches = coords.match(manyCoords); 553 | var singleCoord = new RegExp(RE.coords); 554 | var data = []; 555 | _.each(matches, function (coord) { 556 | var d = singleCoord.exec(coord); 557 | data.push(X.call(this, d[1])); 558 | data.push(Y.call(this, d[2])); 559 | }, this); 560 | var obj = { 561 | linecolor: 'black', 562 | linestyle: 'solid', 563 | fillstyle: 'none', 564 | fillcolor: 'black', 565 | linewidth: 2, 566 | data: data 567 | }; 568 | if (m[1]) 569 | _.extend(obj, parseOptions(m[1])); 570 | return obj; 571 | }, 572 | psarc: function (m) { 573 | // console.log(m); 574 | var l = parseArrows(m[2]); 575 | var arrows = l.arrows; 576 | var dots = l.dots; 577 | var obj = { 578 | linecolor: 'black', 579 | linestyle: 'solid', 580 | fillstyle: 'solid', 581 | fillcolor: 'black', 582 | linewidth: 2, 583 | arrows: arrows, 584 | dots: dots, 585 | cx: X.call(this, 0), 586 | cy: Y.call(this, 0) 587 | }; 588 | if (m[1]) { 589 | _.extend(obj, parseOptions(m[1])); 590 | } 591 | // m[1] options 592 | // m[2] arrows 593 | // m[3] x1 594 | // m[4] y1 595 | // m[5] radius 596 | // m[6] angleA 597 | // m[7] angleB 598 | if (m[3]) { 599 | obj.cx = X.call(this, m[3]); 600 | } 601 | if (m[4]) { 602 | obj.cy = Y.call(this, m[4]); 603 | } 604 | // choose x units over y, no reason... 605 | obj.r = Number(m[5]) * this.xunit; 606 | obj.angleA = Number(m[6]) * Math.PI / 180; 607 | obj.angleB = Number(m[7]) * Math.PI / 180; 608 | obj.A = { 609 | x: X.call(this, Number(m[5]) * Math.cos(obj.angleA)), 610 | y: Y.call(this, Number(m[5]) * Math.sin(obj.angleA)) 611 | }; 612 | obj.B = { 613 | x: X.call(this, Number(m[5]) * Math.cos(obj.angleB)), 614 | y: Y.call(this, Number(m[5]) * Math.sin(obj.angleB)) 615 | }; 616 | return obj; 617 | }, 618 | psline: function (m) { 619 | var options = m[1], lineType = m[2]; 620 | var l = parseArrows(lineType); 621 | var arrows = l.arrows; 622 | var dots = l.dots; 623 | var obj = { 624 | linecolor: 'black', 625 | linestyle: 'solid', 626 | fillstyle: 'solid', 627 | fillcolor: 'black', 628 | linewidth: 2, 629 | arrows: arrows, 630 | dots: dots 631 | }; 632 | if (m[5]) { 633 | obj.x1 = X.call(this, m[3]); 634 | obj.y1 = Y.call(this, m[4]); 635 | obj.x2 = X.call(this, m[6]); 636 | obj.y2 = Y.call(this, m[7]); 637 | } else { 638 | obj.x1 = X.call(this, 0); 639 | obj.y1 = Y.call(this, 0); 640 | obj.x2 = X.call(this, m[3]); 641 | obj.y2 = Y.call(this, m[4]); 642 | } 643 | if (options) { 644 | _.extend(obj, parseOptions(options)); 645 | } 646 | // TODO: add regex 647 | if (typeof obj.linewidth === 'string') { 648 | obj.linewidth = 2; 649 | } 650 | return obj; 651 | }, 652 | uservariable: function (m) { 653 | var options = m[1]; 654 | var coords = []; 655 | if (this.userx && this.usery) { 656 | // coords.push( Xinv.call(this, this.userx) ); 657 | // coords.push( Yinv.call(this, this.usery) ); 658 | coords.push(Number(this.userx)); 659 | coords.push(Number(this.usery)); 660 | } else { 661 | coords.push(X.call(this, m[3])); 662 | coords.push(Y.call(this, m[4])); 663 | } 664 | var nx1 = Xinv.call(this, coords[0]); 665 | var ny1 = Yinv.call(this, coords[1]); 666 | var expx1 = 'var x = ' + nx1 + ';'; 667 | var expy1 = 'var y = ' + ny1 + ';'; 668 | // return X.call(this, eval(expy1 + expx1 + xExp)); 669 | var obj = { 670 | name: m[2], 671 | x: X.call(this, m[3]), 672 | y: Y.call(this, m[4]), 673 | func: m[5], 674 | value: eval(expx1 + expy1 + m[5]) 675 | }; 676 | return obj; 677 | }, 678 | userline: function (m) { 679 | var options = m[1], 680 | // WE ARENT USING THIS YET!!!! e.g., [linecolor=green] 681 | lineType = m[2]; 682 | var l = parseArrows(lineType); 683 | var arrows = l.arrows; 684 | var dots = l.dots; 685 | var xExp = m[7]; 686 | var yExp = m[8]; 687 | if (xExp) 688 | xExp = 'with (Math){' + xExp.replace(/^\{/, '').replace(/\}$/, '') + '}'; 689 | if (yExp) 690 | yExp = 'with (Math){' + yExp.replace(/^\{/, '').replace(/\}$/, '') + '}'; 691 | var xExp2 = m[9]; 692 | var yExp2 = m[10]; 693 | if (xExp2) 694 | xExp2 = 'with (Math){' + xExp2.replace(/^\{/, '').replace(/\}$/, '') + '}'; 695 | if (yExp2) 696 | yExp2 = 'with (Math){' + yExp2.replace(/^\{/, '').replace(/\}$/, '') + '}'; 697 | var expression = ''; 698 | _.each(this.variables, function (val, name) { 699 | expression += 'var ' + name + ' = ' + val + ';'; 700 | }); 701 | var obj = { 702 | x1: X.call(this, m[3]), 703 | y1: Y.call(this, m[4]), 704 | x2: X.call(this, m[5]), 705 | y2: Y.call(this, m[6]), 706 | xExp: xExp, 707 | yExp: yExp, 708 | xExp2: xExp2, 709 | yExp2: yExp2, 710 | userx: _.bind(function (coords) { 711 | var nx1 = Xinv.call(this, coords[0]); 712 | var ny1 = Yinv.call(this, coords[1]); 713 | var expx1 = 'var x = ' + nx1 + ';'; 714 | var expy1 = 'var y = ' + ny1 + ';'; 715 | return X.call(this, eval(expression + expy1 + expx1 + xExp)); 716 | }, this), 717 | usery: _.bind(function (coords) { 718 | var nx2 = Xinv.call(this, coords[0]); 719 | var ny2 = Yinv.call(this, coords[1]); 720 | var expx2 = 'var x = ' + nx2 + ';'; 721 | var expy2 = 'var y = ' + ny2 + ';'; 722 | return Y.call(this, eval(expression + expy2 + expx2 + yExp)); 723 | }, this), 724 | userx2: _.bind(function (coords) { 725 | var nx3 = Xinv.call(this, coords[0]); 726 | var ny3 = Yinv.call(this, coords[1]); 727 | var expx3 = 'var x = ' + nx3 + ';'; 728 | var expy3 = 'var y = ' + ny3 + ';'; 729 | return X.call(this, eval(expression + expy3 + expx3 + xExp2)); 730 | }, this), 731 | usery2: _.bind(function (coords) { 732 | var nx4 = Xinv.call(this, coords[0]); 733 | var ny4 = Yinv.call(this, coords[1]); 734 | var expx4 = 'var x = ' + nx4 + ';'; 735 | var expy4 = 'var y = ' + ny4 + ';'; 736 | return Y.call(this, eval(expression + expy4 + expx4 + yExp2)); 737 | }, this), 738 | linecolor: 'black', 739 | linestyle: 'solid', 740 | fillstyle: 'solid', 741 | fillcolor: 'black', 742 | linewidth: 2, 743 | arrows: arrows, 744 | dots: dots 745 | }; 746 | if (options) { 747 | _.extend(obj, parseOptions(options)); 748 | } 749 | // TODO: add regex 750 | if (typeof obj.linewidth === 'string') { 751 | obj.linewidth = 2; 752 | } 753 | // console.log('check options!!!!'); 754 | // console.log(obj); 755 | return obj; 756 | }, 757 | rput: function (m) { 758 | return { 759 | x: X.call(this, m[1]), 760 | y: Y.call(this, m[2]), 761 | text: m[3] 762 | }; 763 | }, 764 | psset: function (m) { 765 | var pairs = _.map(m[1].split(','), function (pair) { 766 | return pair.split('='); 767 | }); 768 | var obj = {}; 769 | _.each(pairs, function (pair) { 770 | var key = pair[0]; 771 | var value = pair[1]; 772 | _.each(Settings.Expressions, function (exp, setting) { 773 | if (key.match(exp)) { 774 | Settings.Functions[setting](obj, value); 775 | } 776 | }); 777 | }); 778 | return obj; 779 | } 780 | } 781 | }; 782 | }(LaTeX2HTML5)); 783 | -------------------------------------------------------------------------------- /lib/init.js: -------------------------------------------------------------------------------- 1 | var LaTeX2HTML5 = { 2 | version: '0.0.1', 3 | addEnvironment: function(name) { 4 | var delim = {}; 5 | delim.begin = new RegExp('\\\\begin\\{'+name+'\\}'); 6 | delim.end = new RegExp('\\\\end\\{'+name+'\\}'); 7 | LaTeX2HTML5.Delimiters[name] = delim; 8 | }, 9 | 10 | addView: function (name, options) { 11 | LaTeX2HTML5.addEnvironment(name); 12 | var view = {}; 13 | LaTeX2HTML5.Views[name] = LaTeX2HTML5.BaseEnvView.extend(options); 14 | }, 15 | 16 | addText: function (name, exp, func) { 17 | 18 | LaTeX2HTML5.Text.Expressions[name] = exp; 19 | LaTeX2HTML5.Text.Functions[name] = func; 20 | 21 | }, 22 | 23 | addHeaders: function (name, begin, end) { 24 | var exp = {}, beginHash = name + 'begin', endHash = name + 'end'; 25 | exp[beginHash] = new RegExp('\\\\begin\\{'+name+'\\}'); 26 | exp[endHash] = new RegExp('\\\\end\\{'+name+'\\}'); 27 | _.extend(LaTeX2HTML5.Headers.Expressions, exp); 28 | var fns = {}; 29 | fns[beginHash] = function() { 30 | return begin || ''; 31 | }; 32 | fns[endHash] = function() { 33 | return end || ''; 34 | }; 35 | _.extend(LaTeX2HTML5.Headers.Functions, fns); 36 | }, 37 | events: _.clone(Backbone.Events) 38 | 39 | 40 | }; -------------------------------------------------------------------------------- /lib/parse.js: -------------------------------------------------------------------------------- 1 | (function(LaTeX2HTML5) { 2 | 3 | var PSTricks = LaTeX2HTML5.PSTricks; 4 | var Delimiters = LaTeX2HTML5.Delimiters; 5 | var Headers = LaTeX2HTML5.Headers; 6 | var Ignore = LaTeX2HTML5.Ignore; 7 | 8 | 9 | 10 | function Parser() { 11 | this.objects = []; 12 | this.environment = null; 13 | // emulating a match 14 | this.settings = PSTricks.Functions.psset.call(this, [ 15 | '', 16 | 'units=1cm,linecolor=black,linestyle=solid,fillstyle=none' 17 | ]); 18 | } 19 | Parser.prototype = { 20 | parse: function (text) { 21 | if (!text) 22 | return {}; 23 | var lines = text.split('\n'); 24 | this.parseEnvText(lines); 25 | this.parseEnv(lines); 26 | _.each(this.objects, function (obj) { 27 | if (obj.type.match(/pspicture/)) { 28 | obj.plot = this.parsePSTricks(obj.lines, obj.env); 29 | } 30 | }, this); 31 | return this.objects; 32 | }, 33 | newEnvironment: function (type) { 34 | if (this.environment && this.environment.lines.length) { 35 | this.environment.settings = _.clone(this.settings); 36 | this.objects.push(this.environment); 37 | } 38 | this.environment = { 39 | type: type, 40 | lines: [] 41 | }; 42 | }, 43 | pushLine: function (line) { 44 | var add = true; 45 | _.each(Ignore, function (exp) { 46 | if (exp.test(line)) { 47 | add = false; 48 | } 49 | }); 50 | if (add) { 51 | if (typeof line === 'string' && line.trim().length) { 52 | if (PSTricks.Expressions.psset.test(line)) { 53 | this.parseUnits(line); 54 | } else { 55 | this.environment.lines.push(line); 56 | } 57 | } 58 | } 59 | }, 60 | parseUnits: function (line) { 61 | var m = line.match(PSTricks.Expressions.psset); 62 | _.extend(this.settings, PSTricks.Functions.psset.call(this, m)); 63 | }, 64 | metaData: function (environment, line) { 65 | if (PSTricks.Expressions.hasOwnProperty(environment)) { 66 | this.environment.match = line.match(PSTricks.Expressions[environment]); 67 | this.environment.env = PSTricks.Functions[environment].call(this.settings, this.environment.match); 68 | if (environment.match(/pspicture/)) { 69 | _.defaults(this.environment.env, _.pick(this.settings, 'xunit', 'yunit')); 70 | } 71 | } 72 | }, 73 | parseEnv: function (lines) { 74 | this.objects = []; 75 | this.environment = { 76 | type: 'math', 77 | lines: [] 78 | }; 79 | // for(var i=0; i'); 534 | 535 | $_.html(this.text).css({ 536 | position: 'absolute', 537 | top: this.y, 538 | left: this.x 539 | }); 540 | 541 | $(el).append($_); 542 | 543 | var process = MathJax.Hub.Queue(["Typeset",MathJax.Hub,$_[0]]); 544 | if (typeof process === 'function') process(); 545 | 546 | //rput defaults to centering the element in pstricks, so then so do we! 547 | var x = this.x; 548 | var y = this.y; 549 | setTimeout(function(){ 550 | var w = $_.width(); 551 | var h = $_.height(); 552 | $_.css({ 553 | top: y-h/2, 554 | left: x-w/2 555 | }); 556 | },0); 557 | 558 | return $_; 559 | 560 | } 561 | 562 | }; 563 | 564 | })(); 565 | 566 | LaTeX2HTML5.Graph = psgraph; 567 | 568 | }(LaTeX2HTML5)); -------------------------------------------------------------------------------- /lib/renderer.js: -------------------------------------------------------------------------------- 1 | (function(LaTeX2HTML5) { 2 | 3 | 4 | var Graph = LaTeX2HTML5.Graph; 5 | 6 | Backbone.Layout.configure({ 7 | fetchTemplate: function (path) { 8 | return path; 9 | }, 10 | renderTemplate: function (template, context) { 11 | return Handlebars.compile(template)(context); 12 | } 13 | }); 14 | 15 | var BaseView = LaTeX2HTML5.BaseView = Backbone.Layout.extend({ 16 | 17 | }); 18 | 19 | var BaseEnvView = LaTeX2HTML5.BaseEnvView = BaseView.extend({ 20 | beforeRender: function () { 21 | $(this.el).html(this.options.content.lines.join('\n')); 22 | }, 23 | afterRender: function () { 24 | var process = MathJax.Hub.Queue([ 25 | 'Typeset', 26 | MathJax.Hub, 27 | this.el 28 | ]); 29 | if (typeof process === 'function') 30 | process(); 31 | } 32 | }); 33 | 34 | var TeXViews = LaTeX2HTML5.Views = {}; 35 | 36 | _.extend(TeXViews, { 37 | pspicture: BaseView.extend({ 38 | className: 'pspicture-view latex2html5', 39 | initialize: function (options) { 40 | this.options = options; 41 | var env = this.env = this.options.content.settings; 42 | var svg = this.svg = Graph.init.call(env, this.el); 43 | var self = this; 44 | var plots = this.options.content.plot; 45 | 46 | 47 | if (!this.svg) { 48 | throw new Error('svg is required!'); 49 | } 50 | 51 | 52 | svg.on('touchmove', function () { 53 | d3.event.preventDefault(); 54 | var touchcoords = d3.touches(this)[0]; 55 | userEvent(touchcoords); 56 | }, false); 57 | 58 | svg.on('mousemove', function () { 59 | var coords = d3.mouse(this); 60 | userEvent(coords); 61 | }, false); 62 | 63 | function userEvent(coords) { 64 | svg.selectAll('.userline').remove(); 65 | svg.selectAll('.psplot').remove(); 66 | var currentEnvironment = {}; 67 | // find special vars 68 | _.each(plots, function (plot, k) { 69 | if (k.match(/uservariable/)) { 70 | _.each(plot, function (data) { 71 | data.env.userx = coords[0]; 72 | data.env.usery = coords[1]; 73 | var dd = data.fn.call(data.env, data.match); 74 | currentEnvironment[data.data.name] = dd.value; 75 | }); 76 | } 77 | }); 78 | _.each(plots, function (plot, k) { 79 | if (k.match(/psplot/)) { 80 | _.each(plot, function (data) { 81 | _.each(currentEnvironment, function (variable, name) { 82 | data.env.variables[name] = variable; 83 | }); 84 | var d = data.fn.call(data.env, data.match); 85 | d.global = {}; 86 | _.extend(d.global, env); 87 | // give pspicture! 88 | Graph[k].call(d, svg); 89 | }); 90 | } 91 | if (k.match(/userline/)) { 92 | _.each(plot, function (data) { 93 | var d = data.fn.call(data.env, data.match); 94 | data.env.x2 = coords[0]; 95 | // / env.xunit; 96 | data.env.y2 = coords[1]; 97 | // / env.yunit; 98 | data.data.x2 = data.env.x2; 99 | data.data.y2 = data.env.y2; 100 | if (data.data.xExp2) { 101 | data.data.x2 = d.userx2(coords); 102 | data.data.x1 = d.userx(coords); 103 | } else if (data.data.xExp) { 104 | data.data.x2 = d.userx(coords); 105 | } 106 | if (data.data.yExp2) { 107 | data.data.y2 = d.usery2(coords); 108 | data.data.y1 = d.usery(coords); 109 | } else if (data.data.yExp) { 110 | data.data.y2 = d.usery(coords); 111 | } 112 | d.global = {}; 113 | _.extend(d.global, env); 114 | // give pspicture! 115 | _.extend(d, data.data); 116 | Graph[k].call(d, svg); 117 | }); 118 | } 119 | }); 120 | } 121 | }, 122 | afterRender: function () { 123 | var env = this.env; 124 | var svg = this.svg; 125 | var el = this.el; 126 | var plots = this.options.content.plot; 127 | _.each(plots, function (plot, k) { 128 | if (k.match(/rput/)) 129 | return; 130 | if (Graph.hasOwnProperty(k)) { 131 | _.each(plot, function (data) { 132 | data.data.global = env; 133 | // give access to pspicture! 134 | Graph[k].call(data.data, svg); 135 | }); 136 | } 137 | }); 138 | _.each(plots.rput, function (rput) { 139 | var elem = Graph.rput.call(rput.data, this.el); 140 | }, this); 141 | } 142 | }), 143 | 144 | math: BaseEnvView.extend({ 145 | className: 'mathjax-view latex2html5' 146 | }), 147 | 148 | nicebox: BaseEnvView.extend({ 149 | className: 'well latex2html5' 150 | }), 151 | 152 | enumerate: BaseEnvView.extend({ 153 | className: 'mathjax-view latex2html5', 154 | tagName: 'ul', 155 | beforeRender: function () { 156 | var ls = []; 157 | _.each(this.options.content.lines, function (line) { 158 | var m = line.match(/\\item (.*)/); 159 | if (m) { 160 | ls.push('
  • ' + m[1] + '
  • '); 161 | } else { 162 | ls.push(line); 163 | } 164 | }); 165 | $(this.el).html(ls.join('\n')); 166 | } 167 | }), 168 | 169 | verbatim: BaseView.extend({ 170 | tagName: 'pre latex2html5', 171 | beforeRender: function () { 172 | $(this.el).html(this.options.content.lines.join('\n')); 173 | } 174 | }), 175 | 176 | slider: BaseView.extend({ 177 | template: '

    {{latex}}

    ', 178 | initialize: function (options) { 179 | this.options = options; 180 | if (!options.svg) { 181 | throw new Error('svg is required!'); 182 | } 183 | 184 | }, 185 | serialize: function () { 186 | var slider = this.options.slider; 187 | return { 188 | latex: slider.latex, 189 | scalar: slider.scalar, 190 | variable: slider.variable, 191 | min: slider.min * slider.scalar, 192 | max: slider.max * slider.scalar, 193 | value: slider.value 194 | }; 195 | }, 196 | afterRender: function () { 197 | var slid = this.$('input[type=range]'); 198 | var p = this.$('h4+p'); 199 | var svg = this.options.svg; 200 | var env = this.options.env; 201 | var plots = this.options.plot; 202 | // THIS SHOULD DELEGATE, NOT BE RESPONSIBLE FOR RENDERING! 203 | slid.on('change', function () { 204 | var value = this.value / this.getAttribute('scalar'); 205 | var variable = this.getAttribute('variable'); 206 | p.html(value); 207 | env.variables[variable] = value; 208 | svg.selectAll('.psplot').remove(); 209 | _.each(plots, function (plot, k) { 210 | if (k.match(/psplot/)) { 211 | _.each(plot, function (data) { 212 | var d = data.fn.call(data.env, data.match); 213 | // var d = _.extend({}, data, env); 214 | Graph[k].call(d, svg); 215 | }); 216 | } 217 | }); 218 | }); 219 | var process = MathJax.Hub.Queue([ 220 | 'Typeset', 221 | MathJax.Hub, 222 | this.el 223 | ]); 224 | if (typeof process === 'function') 225 | process(); 226 | } 227 | }), 228 | 229 | sliders: BaseView.extend({ 230 | className: 'well interactive', 231 | initialize: function (options) { 232 | this.options = options; 233 | if (!options.svg) { 234 | throw new Error('svg is required!'); 235 | } 236 | 237 | }, 238 | beforeRender: function () { 239 | _.each(this.options.sliders, function (slider) { 240 | var view = new TeXViews.slider({ 241 | svg: this.options.svg, 242 | env: this.options.env, 243 | plot: this.options.plot, 244 | slider: slider 245 | }); 246 | this.insertView(view); 247 | }, this); 248 | } 249 | }) 250 | 251 | }); 252 | 253 | LaTeX2HTML5.TeX = BaseView.extend({ 254 | initialize: function (options) { 255 | if (options.latex) { 256 | var parser = new LaTeX2HTML5.Parser(); 257 | this.options.parsed = parser.parse(options.latex); 258 | } 259 | }, 260 | beforeRender: function () { 261 | _.each(this.options.parsed, function (element) { 262 | if (!element.hasOwnProperty('type')) { 263 | throw new Error('no type!'); 264 | } 265 | var matchedView = null; 266 | _.any(TeXViews, function (view, hash) { 267 | if (element.type == hash) { 268 | var fn = TeXViews[hash]; 269 | if (_.isFunction(fn)) { 270 | var v = new fn({ content: element }); 271 | this.insertView(v); 272 | matchedView = v; 273 | return v; 274 | } 275 | } 276 | }, this); 277 | if (matchedView && element.env && element.env.sliders && element.env.sliders.length) { 278 | //give related interactive elements the SVG reference!! 279 | var slidersView = new TeXViews.sliders({ 280 | env: element.env, 281 | sliders: element.env.sliders, 282 | plot: element.plot, 283 | svg: matchedView.svg 284 | }); 285 | this.insertView(slidersView); 286 | } 287 | }, this); 288 | }, 289 | afterRender: function() { 290 | LaTeX2HTML5.events.trigger('afterRender'); 291 | } 292 | }); 293 | 294 | }(LaTeX2HTML5)); 295 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "latex2html5", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "grunt": "~0.4.1", 6 | "grunt-contrib-jshint": "*", 7 | "grunt-contrib-clean": "*", 8 | "grunt-contrib-concat": "*", 9 | "grunt-contrib-cssmin": "*", 10 | "grunt-contrib-uglify": "*", 11 | "grunt-contrib-handlebars": "*", 12 | "express":"3.4.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /plugins/jquery.latex2html5.js: -------------------------------------------------------------------------------- 1 | // 2 | // will get replaced with the tex rendered 3 | $.fn.LaTeX = function () { 4 | 5 | $.each(this, function (i, el) { 6 | var $el = $(el); 7 | var url = $el.attr('src'); 8 | if (!url) { 9 | throw new Error('!Error: latex element requires src attribute'); 10 | } 11 | 12 | jQuery.ajax({ 13 | url: url, 14 | success: function(data) { 15 | 16 | MathJax.Hub.Register.StartupHook("End",function () { 17 | var TEX = new LaTeX2HTML5.TeX({ 18 | tagName: 'section', 19 | className: 'latex-container', 20 | latex: data 21 | }); 22 | TEX.render(); 23 | $el.replaceWith(TEX.$el); 24 | }); 25 | }, 26 | async: true 27 | }); 28 | }); 29 | 30 | }; 31 | 32 | 33 | $.fn.latex = function () { 34 | 35 | var $parent = $(this); 36 | 37 | MathJax.Hub.Register.StartupHook("End",function () { 38 | 39 | $parent.find('[type="tex/latex"]').each(function (i, el) { 40 | var $el = $(el); 41 | var TEX = new LaTeX2HTML5.TeX({ 42 | tagName: 'section', 43 | className: 'latex-container', 44 | latex: $el.text() 45 | }); 46 | TEX.render(); 47 | $el.replaceWith(TEX.$el); 48 | }); 49 | 50 | }); 51 | 52 | }; -------------------------------------------------------------------------------- /plugins/latex2html5.image.js: -------------------------------------------------------------------------------- 1 | // usage: \image{url} 2 | LaTeX2HTML5.addText( 3 | 'image', 4 | /\\image\{[^}]*\}/g, 5 | LaTeX2HTML5.utils.matchrepl(/\\image\{([^}]*)\}/, function (m) { 6 | return '
    '; 7 | })); -------------------------------------------------------------------------------- /plugins/latex2html5.waypoint.js: -------------------------------------------------------------------------------- 1 | 2 | LaTeX2HTML5.addText( 3 | 'waypoint', 4 | /\\waypoint\{[^}]*\}/g, 5 | LaTeX2HTML5.utils.matchrepl(/\\waypoint\{([^}]*)\}/, function (m) { 6 | var name = m[1].replace(/\s+/g, '_').toLowerCase(); 7 | return '

    '+m[1]+'

    '; 8 | })); 9 | 10 | 11 | LaTeX2HTML5.addText( 12 | 'waypointlink', 13 | /\\waypointlink\{[^}]*\}\{([^}]*)\}/g, 14 | LaTeX2HTML5.utils.matchrepl(/\\waypointlink\{([^}]*)\}\{([^}]*)\}/, function (m) { 15 | var name = m[1].replace(/\s+/g, '_').toLowerCase(); 16 | return ''+m[2]+''; 17 | })); -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | LaTeX2HTML5 2 | ==================== 3 | 4 | This project is the frontend only version of [mathapedia](https://mathapedia.com) ([github](https://github.com/pyramation/Mathapedia)) 5 | 6 | [LaTeX2HTML5 demo website](http://latex2html5.com) 7 | 8 | [Installation instructions](http://latex2html5.com/installation.html) 9 | 10 | 11 | The loose structure and nature of user interface design poses a problem for documenting science and related interfaces in a consistent manner. TeX provides us with some "laws" to obey in order to design the output of a text and graphical language around. Hence, we can attempt to create a synthesis of a structured user interface specification (TeX) and a structured functional specification (HTML5) to provide a publishing platform for the current and next generation. 12 | 13 | The Art is where we can blend these two standards bodies; higher levels of abstraction allow people to express their ideas without having to worry about the mechanisms by which the technology is rendering their works. It is in these environments when people can express themselves freely. 14 | 15 | ![LaTeX2HTML5](http://latex2html5.com/assets/images/photo.png) 16 | 17 | 18 | [video](http://www.youtube.com/watch?v=QYMLMUKJyFc) 19 | 20 | Adding new LaTeX commands 21 | ========================= 22 | 23 | If there is one takeaway for developers, the most important files for adding (LaTeX) functionality: expressions.js, psgraph.js, renderer.js 24 | 25 | 26 | Make your push/pull life easier 27 | ------------------------------- 28 | 29 | git remote set-url origin git@github.com:Mathapedia/LaTeX2HTML5.git 30 | 31 | # Dev Requirements 32 | 33 | [Bower](http://bower.io/) 34 | 35 | [Grunt](http://gruntjs.com/) 36 | 37 | # Frontend Requirements 38 | 39 | [MathJax](http://www.mathjax.org/) 40 | 41 | [Backbone](https://github.com/documentcloud/backbone) 42 | 43 | [Backbone Layout Manager](https://github.com/tbranyen/backbone.layoutmanager) 44 | 45 | [D3](http://d3js.org/) 46 | 47 | [jQuery](http://jquery.com/) 48 | 49 | [underscore.js](http://underscorejs.org/) 50 | 51 | [handlebars.js](http://handlebarsjs.com/) 52 | 53 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express') 2 | , app = express() 3 | , server = require('http').createServer(app); 4 | 5 | app.configure(function(){ 6 | app.use(express.static(__dirname + '/')); 7 | }); 8 | 9 | server.listen(7777); 10 | app.get('/', function (req, res) { 11 | res.sendfile(__dirname + '/index.html'); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /templates/macros.html: -------------------------------------------------------------------------------- 1 |
    2 | $$ 3 | % create the definition symbol 4 | \def\bydef{\stackrel{\Delta}{=}} 5 | %\def\circconv{\otimes} 6 | \def\circconv{\circledast} 7 | 8 | \newcommand{\qed}{\mbox{ } \Box} 9 | 10 | 11 | \newcommand{\infint}{\int_{-\infty}^{\infty}} 12 | 13 | % z transform 14 | \newcommand{\ztp}{ ~~ \mathop{\mathcal{Z}}\limits_{\longleftrightarrow} ~~ } 15 | \newcommand{\iztp}{ ~~ \mathop{\mathcal{Z}^{-1}}\limits_{\longleftrightarrow} ~~ } 16 | % fourier transform pair 17 | \newcommand{\ftp}{ ~~ \mathop{\mathcal{F}}\limits_{\longleftrightarrow} ~~ } 18 | \newcommand{\iftp}{ ~~ \mathop{\mathcal{F}^{-1}}\limits_{\longleftrightarrow} ~~ } 19 | % laplace transform 20 | \newcommand{\ltp}{ ~~ \mathop{\mathcal{L}}\limits_{\longleftrightarrow} ~~ } 21 | \newcommand{\iltp}{ ~~ \mathop{\mathcal{L}^{-1}}\limits_{\longleftrightarrow} ~~ } 22 | 23 | \newcommand{\ftrans}[1]{ \mathcal{F} \left\{#1\right\} } 24 | \newcommand{\iftrans}[1]{ \mathcal{F}^{-1} \left\{#1\right\} } 25 | \newcommand{\ztrans}[1]{ \mathcal{Z} \left\{#1\right\} } 26 | \newcommand{\iztrans}[1]{ \mathcal{Z}^{-1} \left\{#1\right\} } 27 | \newcommand{\ltrans}[1]{ \mathcal{L} \left\{#1\right\} } 28 | \newcommand{\iltrans}[1]{ \mathcal{L}^{-1} \left\{#1\right\} } 29 | 30 | 31 | % coordinate vector relative to a basis (linear algebra) 32 | \newcommand{\cvrb}[2]{\left[ \vec{#1} \right]_{#2} } 33 | % change of coordinate matrix (linear algebra) 34 | \newcommand{\cocm}[2]{ \mathop{P}\limits_{#2 \leftarrow #1} } 35 | % Transformed vector set 36 | \newcommand{\tset}[3]{\{#1\lr{\vec{#2}_1}, #1\lr{\vec{#2}_2}, \dots, #1\lr{\vec{#2}_{#3}}\}} 37 | % sum transformed vector set 38 | \newcommand{\tsetcsum}[4]{{#1}_1#2(\vec{#3}_1) + {#1}_2#2(\vec{#3}_2) + \cdots + {#1}_{#4}#2(\vec{#3}_{#4})} 39 | \newcommand{\tsetcsumall}[4]{#2\lr{{#1}_1\vec{#3}_1 + {#1}_2\vec{#3}_2 + \cdots + {#1}_{#4}\vec{#3}_{#4}}} 40 | \newcommand{\cvecsum}[3]{{#1}_1\vec{#2}_1 + {#1}_2\vec{#2}_2 + \cdots + {#1}_{#3}\vec{#2}_{#3}} 41 | 42 | 43 | % function def 44 | \newcommand{\fndef}[3]{#1:#2 \to #3} 45 | % vector set 46 | \newcommand{\vset}[2]{\{\vec{#1}_1, \vec{#1}_2, \dots, \vec{#1}_{#2}\}} 47 | % absolute value 48 | \newcommand{\abs}[1]{\left| #1 \right|} 49 | % vector norm 50 | \newcommand{\norm}[1]{\left|\left| #1 \right|\right|} 51 | % trans 52 | \newcommand{\trans}{\mapsto} 53 | % evaluate integral 54 | \newcommand{\evalint}[3]{\left. #1 \right|_{#2}^{#3}} 55 | % slist 56 | \newcommand{\slist}[2]{{#1}_{1},{#1}_{2},\dots,{#1}_{#2}} 57 | 58 | % vectors 59 | \newcommand{\vc}[1]{\textbf{#1}} 60 | 61 | % real 62 | \newcommand{\Real}[1]{{\Re \mit{e}\left\{{#1}\right\}}} 63 | % imaginary 64 | \newcommand{\Imag}[1]{{\Im \mit{m}\left\{{#1}\right\}}} 65 | 66 | \newcommand{\mcal}[1]{\mathcal{#1}} 67 | \newcommand{\bb}[1]{\mathbb{#1}} 68 | \newcommand{\N}{\mathbb{N}} 69 | \newcommand{\Z}{\mathbb{Z}} 70 | \newcommand{\Q}{\mathbb{Q}} 71 | \newcommand{\R}{\mathbb{R}} 72 | \newcommand{\C}{\mathbb{C}} 73 | \newcommand{\I}{\mathbb{I}} 74 | \newcommand{\Th}[1]{\mathop\mathrm{Th(#1)}} 75 | \newcommand{\intersect}{\cap} 76 | \newcommand{\union}{\cup} 77 | \newcommand{\intersectop}{\bigcap} 78 | \newcommand{\unionop}{\bigcup} 79 | \newcommand{\setdiff}{\backslash} 80 | \newcommand{\iso}{\cong} 81 | \newcommand{\aut}[1]{\mathop{\mathrm{Aut(#1)}}} 82 | \newcommand{\inn}[1]{\mathop{\mathrm{Inn(#1)}}} 83 | \newcommand{\Ann}[1]{\mathop{\mathrm{Ann(#1)}}} 84 | \newcommand{\dom}[1]{\mathop{\mathrm{dom} #1}} 85 | \newcommand{\cod}[1]{\mathop{\mathrm{cod} #1}} 86 | \newcommand{\id}{\mathrm{id}} 87 | \newcommand{\st}{\ |\ } 88 | \newcommand{\mbf}[1]{\mathbf{#1}} 89 | \newcommand{\enclose}[1]{\left\langle #1\right\rangle} 90 | \newcommand{\lr}[1]{\left( #1\right)} 91 | \newcommand{\lrsq}[1]{\left[ #1\right]} 92 | \newcommand{\op}{\mathrm{op}} 93 | \newcommand{\dotarr}{\dot{\rightarrow}} 94 | %Category Names: 95 | \newcommand{\Grp}{\mathbf{Grp}} 96 | \newcommand{\Ab}{\mathbf{Ab}} 97 | \newcommand{\Set}{\mathbf{Set}} 98 | \newcommand{\Matr}{\mathbf{Matr}} 99 | \newcommand{\IntDom}{\mathbf{IntDom}} 100 | \newcommand{\Field}{\mathbf{Field}} 101 | \newcommand{\Vect}{\mathbf{Vect}} 102 | 103 | \newcommand{\thm}[1]{\begin{theorem} #1 \end{theorem}} 104 | \newcommand{\clm}[1]{\begin{claim} #1 \end{claim}} 105 | \newcommand{\cor}[1]{\begin{corollary} #1 \end{corollary}} 106 | \newcommand{\ex}[1]{\begin{example} #1 \end{example}} 107 | \newcommand{\prf}[1]{\begin{proof} #1 \end{proof}} 108 | \newcommand{\prbm}[1]{\begin{problem} #1 \end{problem}} 109 | \newcommand{\soln}[1]{\begin{solution} #1 \end{solution}} 110 | \newcommand{\rmk}[1]{\begin{remark} #1 \end{remark}} 111 | \newcommand{\defn}[1]{\begin{definition} #1 \end{definition}} 112 | 113 | \newcommand{\ifff}{\LeftRightArrow} 114 | 115 | 116 | \newcommand{\rr}{\R} 117 | \newcommand{\reals}{\R} 118 | \newcommand{\ii}{\Z} 119 | \newcommand{\cc}{\C} 120 | \newcommand{\nn}{\N} 121 | \newcommand{\nats}{\N} 122 | 123 | 127 | 128 | 131 | \newcommand{\strong}[1]{\textbf{#1}} 132 | 133 | 136 | \newcommand{\set}[1]{\textit{#1}} 137 | $$ 138 |
    --------------------------------------------------------------------------------