mathematical 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -4
- data/.gitmodules +0 -4
- data/README.md +108 -28
- data/Rakefile +3 -31
- data/ext/mathematical/README.itex2MML.md +11 -0
- data/ext/mathematical/README.lasem.md +11 -0
- data/ext/mathematical/extconf.rb +51 -0
- data/ext/mathematical/itex2MML.h +63 -0
- data/ext/mathematical/lasemrender.c +257 -0
- data/ext/mathematical/lex.yy.c +6548 -0
- data/ext/mathematical/lsm.c +30 -0
- data/ext/mathematical/lsm.h +36 -0
- data/ext/mathematical/lsmattributes.c +279 -0
- data/ext/mathematical/lsmattributes.h +75 -0
- data/ext/mathematical/lsmcairo.c +598 -0
- data/ext/mathematical/lsmcairo.h +51 -0
- data/ext/mathematical/lsmdebug.c +179 -0
- data/ext/mathematical/lsmdebug.h +76 -0
- data/ext/mathematical/lsmdom.h +43 -0
- data/ext/mathematical/lsmdomcharacterdata.c +114 -0
- data/ext/mathematical/lsmdomcharacterdata.h +59 -0
- data/ext/mathematical/lsmdomdocument.c +292 -0
- data/ext/mathematical/lsmdomdocument.h +82 -0
- data/ext/mathematical/lsmdomdocumentfragment.c +81 -0
- data/ext/mathematical/lsmdomdocumentfragment.h +55 -0
- data/ext/mathematical/lsmdomelement.c +148 -0
- data/ext/mathematical/lsmdomelement.h +62 -0
- data/ext/mathematical/lsmdomentities.c +2155 -0
- data/ext/mathematical/lsmdomentities.h +35 -0
- data/ext/mathematical/lsmdomenumtypes.c +99 -0
- data/ext/mathematical/lsmdomenumtypes.c.template +39 -0
- data/ext/mathematical/lsmdomenumtypes.h +26 -0
- data/ext/mathematical/lsmdomenumtypes.h.template +26 -0
- data/ext/mathematical/lsmdomimplementation.c +82 -0
- data/ext/mathematical/lsmdomimplementation.h +41 -0
- data/ext/mathematical/lsmdomnamednodemap.c +118 -0
- data/ext/mathematical/lsmdomnamednodemap.h +64 -0
- data/ext/mathematical/lsmdomnode.c +725 -0
- data/ext/mathematical/lsmdomnode.h +120 -0
- data/ext/mathematical/lsmdomnodelist.c +70 -0
- data/ext/mathematical/lsmdomnodelist.h +58 -0
- data/ext/mathematical/lsmdomparser.c +461 -0
- data/ext/mathematical/lsmdomparser.h +54 -0
- data/ext/mathematical/lsmdomtext.c +82 -0
- data/ext/mathematical/lsmdomtext.h +55 -0
- data/ext/mathematical/lsmdomtypes.h +44 -0
- data/ext/mathematical/lsmdomview.c +422 -0
- data/ext/mathematical/lsmdomview.h +94 -0
- data/ext/mathematical/lsmmathml.h +66 -0
- data/ext/mathematical/lsmmathmlactionelement.c +93 -0
- data/ext/mathematical/lsmmathmlactionelement.h +57 -0
- data/ext/mathematical/lsmmathmlaligngroupelement.c +102 -0
- data/ext/mathematical/lsmmathmlaligngroupelement.h +56 -0
- data/ext/mathematical/lsmmathmlalignmarkelement.c +102 -0
- data/ext/mathematical/lsmmathmlalignmarkelement.h +56 -0
- data/ext/mathematical/lsmmathmlattributes.c +197 -0
- data/ext/mathematical/lsmmathmlattributes.h +126 -0
- data/ext/mathematical/lsmmathmldocument.c +306 -0
- data/ext/mathematical/lsmmathmldocument.h +61 -0
- data/ext/mathematical/lsmmathmlelement.c +491 -0
- data/ext/mathematical/lsmmathmlelement.h +107 -0
- data/ext/mathematical/lsmmathmlenums.c +429 -0
- data/ext/mathematical/lsmmathmlenums.h +182 -0
- data/ext/mathematical/lsmmathmlenumtypes.c +666 -0
- data/ext/mathematical/lsmmathmlenumtypes.c.template +39 -0
- data/ext/mathematical/lsmmathmlenumtypes.h +90 -0
- data/ext/mathematical/lsmmathmlenumtypes.h.template +26 -0
- data/ext/mathematical/lsmmathmlerrorelement.c +58 -0
- data/ext/mathematical/lsmmathmlerrorelement.h +56 -0
- data/ext/mathematical/lsmmathmlfencedelement.c +178 -0
- data/ext/mathematical/lsmmathmlfencedelement.h +65 -0
- data/ext/mathematical/lsmmathmlfractionelement.c +253 -0
- data/ext/mathematical/lsmmathmlfractionelement.h +62 -0
- data/ext/mathematical/lsmmathmlglyphtableams.c +597 -0
- data/ext/mathematical/lsmmathmlglyphtableams.h +45 -0
- data/ext/mathematical/lsmmathmlitexelement.c +187 -0
- data/ext/mathematical/lsmmathmlitexelement.h +60 -0
- data/ext/mathematical/lsmmathmllayoututils.c +191 -0
- data/ext/mathematical/lsmmathmllayoututils.h +58 -0
- data/ext/mathematical/lsmmathmlmathelement.c +204 -0
- data/ext/mathematical/lsmmathmlmathelement.h +81 -0
- data/ext/mathematical/lsmmathmloperatordictionary.c +3332 -0
- data/ext/mathematical/lsmmathmloperatordictionary.h +54 -0
- data/ext/mathematical/lsmmathmloperatorelement.c +307 -0
- data/ext/mathematical/lsmmathmloperatorelement.h +73 -0
- data/ext/mathematical/lsmmathmlpaddedelement.c +58 -0
- data/ext/mathematical/lsmmathmlpaddedelement.h +56 -0
- data/ext/mathematical/lsmmathmlphantomelement.c +71 -0
- data/ext/mathematical/lsmmathmlphantomelement.h +56 -0
- data/ext/mathematical/lsmmathmlpresentationcontainer.c +43 -0
- data/ext/mathematical/lsmmathmlpresentationcontainer.h +54 -0
- data/ext/mathematical/lsmmathmlpresentationtoken.c +303 -0
- data/ext/mathematical/lsmmathmlpresentationtoken.h +83 -0
- data/ext/mathematical/lsmmathmlradicalelement.c +266 -0
- data/ext/mathematical/lsmmathmlradicalelement.h +71 -0
- data/ext/mathematical/lsmmathmlrowelement.c +58 -0
- data/ext/mathematical/lsmmathmlrowelement.h +56 -0
- data/ext/mathematical/lsmmathmlscriptelement.c +282 -0
- data/ext/mathematical/lsmmathmlscriptelement.h +78 -0
- data/ext/mathematical/lsmmathmlsemanticselement.c +82 -0
- data/ext/mathematical/lsmmathmlsemanticselement.h +56 -0
- data/ext/mathematical/lsmmathmlspaceelement.c +142 -0
- data/ext/mathematical/lsmmathmlspaceelement.h +60 -0
- data/ext/mathematical/lsmmathmlstringelement.c +123 -0
- data/ext/mathematical/lsmmathmlstringelement.h +58 -0
- data/ext/mathematical/lsmmathmlstyle.c +130 -0
- data/ext/mathematical/lsmmathmlstyle.h +81 -0
- data/ext/mathematical/lsmmathmlstyleelement.c +307 -0
- data/ext/mathematical/lsmmathmlstyleelement.h +87 -0
- data/ext/mathematical/lsmmathmltablecellelement.c +122 -0
- data/ext/mathematical/lsmmathmltablecellelement.h +62 -0
- data/ext/mathematical/lsmmathmltableelement.c +545 -0
- data/ext/mathematical/lsmmathmltableelement.h +78 -0
- data/ext/mathematical/lsmmathmltablerowelement.c +120 -0
- data/ext/mathematical/lsmmathmltablerowelement.h +64 -0
- data/ext/mathematical/lsmmathmltraits.c +819 -0
- data/ext/mathematical/lsmmathmltraits.h +119 -0
- data/ext/mathematical/lsmmathmltypes.h +66 -0
- data/ext/mathematical/lsmmathmlunderoverelement.c +485 -0
- data/ext/mathematical/lsmmathmlunderoverelement.h +82 -0
- data/ext/mathematical/lsmmathmlutils.c +170 -0
- data/ext/mathematical/lsmmathmlutils.h +50 -0
- data/ext/mathematical/lsmmathmlview.c +1048 -0
- data/ext/mathematical/lsmmathmlview.h +164 -0
- data/ext/mathematical/lsmproperties.c +418 -0
- data/ext/mathematical/lsmproperties.h +85 -0
- data/ext/mathematical/lsmstr.c +231 -0
- data/ext/mathematical/lsmstr.h +114 -0
- data/ext/mathematical/lsmsvg.h +67 -0
- data/ext/mathematical/lsmsvgaelement.c +73 -0
- data/ext/mathematical/lsmsvgaelement.h +55 -0
- data/ext/mathematical/lsmsvgattributes.h +113 -0
- data/ext/mathematical/lsmsvgcircleelement.c +153 -0
- data/ext/mathematical/lsmsvgcircleelement.h +59 -0
- data/ext/mathematical/lsmsvgclippathelement.c +134 -0
- data/ext/mathematical/lsmsvgclippathelement.h +59 -0
- data/ext/mathematical/lsmsvgcolors.c +212 -0
- data/ext/mathematical/lsmsvgcolors.h +39 -0
- data/ext/mathematical/lsmsvgdefselement.c +74 -0
- data/ext/mathematical/lsmsvgdefselement.h +55 -0
- data/ext/mathematical/lsmsvgdocument.c +230 -0
- data/ext/mathematical/lsmsvgdocument.h +58 -0
- data/ext/mathematical/lsmsvgelement.c +367 -0
- data/ext/mathematical/lsmsvgelement.h +81 -0
- data/ext/mathematical/lsmsvgellipseelement.c +158 -0
- data/ext/mathematical/lsmsvgellipseelement.h +60 -0
- data/ext/mathematical/lsmsvgenums.c +544 -0
- data/ext/mathematical/lsmsvgenums.h +357 -0
- data/ext/mathematical/lsmsvgenumtypes.c +1083 -0
- data/ext/mathematical/lsmsvgenumtypes.c.template +39 -0
- data/ext/mathematical/lsmsvgenumtypes.h +111 -0
- data/ext/mathematical/lsmsvgenumtypes.h.template +26 -0
- data/ext/mathematical/lsmsvgfilterblend.c +105 -0
- data/ext/mathematical/lsmsvgfilterblend.h +58 -0
- data/ext/mathematical/lsmsvgfiltercomposite.c +109 -0
- data/ext/mathematical/lsmsvgfiltercomposite.h +58 -0
- data/ext/mathematical/lsmsvgfilterelement.c +266 -0
- data/ext/mathematical/lsmsvgfilterelement.h +66 -0
- data/ext/mathematical/lsmsvgfilterflood.c +86 -0
- data/ext/mathematical/lsmsvgfilterflood.h +55 -0
- data/ext/mathematical/lsmsvgfiltergaussianblur.c +114 -0
- data/ext/mathematical/lsmsvgfiltergaussianblur.h +57 -0
- data/ext/mathematical/lsmsvgfiltermerge.c +98 -0
- data/ext/mathematical/lsmsvgfiltermerge.h +55 -0
- data/ext/mathematical/lsmsvgfiltermergenode.c +87 -0
- data/ext/mathematical/lsmsvgfiltermergenode.h +57 -0
- data/ext/mathematical/lsmsvgfilteroffset.c +112 -0
- data/ext/mathematical/lsmsvgfilteroffset.h +58 -0
- data/ext/mathematical/lsmsvgfilterprimitive.c +168 -0
- data/ext/mathematical/lsmsvgfilterprimitive.h +66 -0
- data/ext/mathematical/lsmsvgfilterspecularlighting.c +127 -0
- data/ext/mathematical/lsmsvgfilterspecularlighting.h +60 -0
- data/ext/mathematical/lsmsvgfiltersurface.c +455 -0
- data/ext/mathematical/lsmsvgfiltersurface.h +66 -0
- data/ext/mathematical/lsmsvgfiltertile.c +102 -0
- data/ext/mathematical/lsmsvgfiltertile.h +57 -0
- data/ext/mathematical/lsmsvggelement.c +73 -0
- data/ext/mathematical/lsmsvggelement.h +55 -0
- data/ext/mathematical/lsmsvggradientelement.c +151 -0
- data/ext/mathematical/lsmsvggradientelement.h +68 -0
- data/ext/mathematical/lsmsvgimageelement.c +261 -0
- data/ext/mathematical/lsmsvgimageelement.h +67 -0
- data/ext/mathematical/lsmsvglength.c +93 -0
- data/ext/mathematical/lsmsvglength.h +59 -0
- data/ext/mathematical/lsmsvglineargradientelement.c +271 -0
- data/ext/mathematical/lsmsvglineargradientelement.h +60 -0
- data/ext/mathematical/lsmsvglineelement.c +153 -0
- data/ext/mathematical/lsmsvglineelement.h +60 -0
- data/ext/mathematical/lsmsvgmarkerelement.c +266 -0
- data/ext/mathematical/lsmsvgmarkerelement.h +74 -0
- data/ext/mathematical/lsmsvgmaskelement.c +232 -0
- data/ext/mathematical/lsmsvgmaskelement.h +64 -0
- data/ext/mathematical/lsmsvgmatrix.c +205 -0
- data/ext/mathematical/lsmsvgmatrix.h +59 -0
- data/ext/mathematical/lsmsvgpathelement.c +115 -0
- data/ext/mathematical/lsmsvgpathelement.h +59 -0
- data/ext/mathematical/lsmsvgpatternelement.c +398 -0
- data/ext/mathematical/lsmsvgpatternelement.h +69 -0
- data/ext/mathematical/lsmsvgpolygonelement.c +106 -0
- data/ext/mathematical/lsmsvgpolygonelement.h +57 -0
- data/ext/mathematical/lsmsvgpolylineelement.c +106 -0
- data/ext/mathematical/lsmsvgpolylineelement.h +57 -0
- data/ext/mathematical/lsmsvgradialgradientelement.c +323 -0
- data/ext/mathematical/lsmsvgradialgradientelement.h +61 -0
- data/ext/mathematical/lsmsvgrectelement.c +184 -0
- data/ext/mathematical/lsmsvgrectelement.h +62 -0
- data/ext/mathematical/lsmsvgstopelement.c +106 -0
- data/ext/mathematical/lsmsvgstopelement.h +57 -0
- data/ext/mathematical/lsmsvgstyle.c +558 -0
- data/ext/mathematical/lsmsvgstyle.h +217 -0
- data/ext/mathematical/lsmsvgsvgelement.c +260 -0
- data/ext/mathematical/lsmsvgsvgelement.h +71 -0
- data/ext/mathematical/lsmsvgswitchelement.c +103 -0
- data/ext/mathematical/lsmsvgswitchelement.h +55 -0
- data/ext/mathematical/lsmsvgsymbolelement.c +74 -0
- data/ext/mathematical/lsmsvgsymbolelement.h +55 -0
- data/ext/mathematical/lsmsvgtextelement.c +170 -0
- data/ext/mathematical/lsmsvgtextelement.h +58 -0
- data/ext/mathematical/lsmsvgtraits.c +1158 -0
- data/ext/mathematical/lsmsvgtraits.h +103 -0
- data/ext/mathematical/lsmsvgtransformable.c +106 -0
- data/ext/mathematical/lsmsvgtransformable.h +54 -0
- data/ext/mathematical/lsmsvgtspanelement.c +143 -0
- data/ext/mathematical/lsmsvgtspanelement.h +58 -0
- data/ext/mathematical/lsmsvgtypes.h +77 -0
- data/ext/mathematical/lsmsvguseelement.c +237 -0
- data/ext/mathematical/lsmsvguseelement.h +69 -0
- data/ext/mathematical/lsmsvgview.c +2400 -0
- data/ext/mathematical/lsmsvgview.h +168 -0
- data/ext/mathematical/lsmtraits.c +119 -0
- data/ext/mathematical/lsmtraits.h +49 -0
- data/ext/mathematical/lsmtypes.h +36 -0
- data/ext/mathematical/lsmutils.c +54 -0
- data/ext/mathematical/lsmutils.h +56 -0
- data/ext/mathematical/mathematical.c +122 -0
- data/ext/mathematical/y.tab.c +6179 -0
- data/ext/mathematical/y.tab.h +389 -0
- data/lib/mathematical.rb +7 -3
- data/lib/mathematical/parser.rb +1 -1
- data/lib/mathematical/render.rb +51 -77
- data/lib/mathematical/version.rb +1 -1
- data/mathematical.gemspec +5 -3
- data/script/bench +21 -0
- data/script/single_test +7 -0
- data/test/mathematical/basic_test.rb +30 -1
- data/test/mathematical/fixtures/after/brackets_display.html +1 -0
- data/test/mathematical/fixtures/after/dollar_sign_inline.html +1 -0
- data/test/mathematical/fixtures/after/equation_display.html +1 -0
- data/test/mathematical/fixtures/after/multiple_dollar_inline.html +1 -0
- data/test/mathematical/fixtures/after/parens_inline.html +1 -0
- data/test/mathematical/fixtures/before/brackets_display.text +1 -0
- data/test/mathematical/fixtures/before/{basic.text → dollar_sign_inline.text} +0 -0
- data/test/mathematical/fixtures/before/equation_display.text +1 -0
- data/test/mathematical/fixtures/before/multiple_dollar_inline.text +1 -0
- data/test/mathematical/fixtures/before/parens_inline.text +1 -0
- data/test/mathematical/fixtures/performance/big_file.text +1767 -0
- data/test/mathematical/performance_test.rb +13 -0
- data/test/test_helper.rb +1 -0
- metadata +303 -18
- data/test/mathematical/fixtures/after/basic.html +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c14fe131c5b4079e2bbe97ce285fcd667d4be3dd
|
4
|
+
data.tar.gz: 23e84555231c9fc95d7cb52f2e35018088e27e4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5564644e717a270346c927ff7ef6157eaf74924c20739f096277d6cccd50e625a704ae6034e7a8dbb19909ddf3ebee5560d3060e28c329badf7e4d0556b29494
|
7
|
+
data.tar.gz: 43c6e5740f9d46d36429741dc4a775963066b82dd7292a6b61f8a23f777c3c5d506c8e4bd93267ee16b3a9524d45c8d9136a5638144c6baa6af6abf9638027cb
|
data/.gitignore
CHANGED
data/.gitmodules
CHANGED
data/README.md
CHANGED
@@ -23,42 +23,122 @@ Or install it yourself as:
|
|
23
23
|
The simplest way to do this is
|
24
24
|
|
25
25
|
``` ruby
|
26
|
-
Mathematical::Render.new.render(
|
26
|
+
Mathematical::Render.new.render(string_with_math)
|
27
27
|
```
|
28
28
|
|
29
|
-
`
|
29
|
+
`string_with_math` should just be a string, containing inline or display style math.
|
30
|
+
The output will be all the math equations, as SVGs, converted into base64 encoded images.
|
31
|
+
They look something like this:
|
30
32
|
|
31
|
-
|
33
|
+
``` html
|
34
|
+
<img class="type-inline" data-math-type="type-inline" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0..."/>
|
35
|
+
|
36
|
+
```
|
37
|
+
Inline math will have `class="type-inline" data-math-type="type-inline"` set, and display math will have
|
38
|
+
`class="type-display" data-math-type="type-display"`.
|
39
|
+
|
40
|
+
### Matched math notations
|
32
41
|
|
33
|
-
|
42
|
+
Currently, the following formats are supported:
|
34
43
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
which is a *huge* package. `dvipng` is installed under */usr/texbin/dvipng*.
|
44
|
+
| inline formulas | displayed equations |
|
45
|
+
| ------------- |-------------|
|
46
|
+
| `$...$` | `[...]`
|
47
|
+
| `(...)` | `\begin{equation}...\end{equation}`
|
40
48
|
|
41
|
-
##
|
49
|
+
## Options
|
42
50
|
|
43
|
-
|
44
|
-
math equations to a variety of formats. There needs to be a sane way to show math
|
45
|
-
equations in the browser. The options are:
|
51
|
+
`Mathematical::Render.new` can take a few options:
|
46
52
|
|
47
|
-
*
|
48
|
-
|
49
|
-
* MathJax. While extremely popular, I dislike the "stuttering" effect caused by
|
50
|
-
pages loading math. JavaScript shouldn't be used in situations where server-rendering
|
51
|
-
is a possibility, in my opinion.
|
52
|
-
* SVG: This would be a great choice, but, unfortunately, there are some [security concerns](http://www.hgi.ruhr-uni-bochum.de/media/hgi/veroeffentlichungen/2011/10/19/svgSecurity-ccs11.pdf) [PDF]
|
53
|
-
that make me nervous
|
54
|
-
* PNG: This is the format which `blahtexml` is capable of outputting. Working
|
55
|
-
with a binary format has the downside of requiring it to be *hosted* somewhere.
|
53
|
+
* `:ppi`, the pixels per inch of the resulting SVG (default: `72.0`)
|
54
|
+
* `:zoom`, the zoome level of the resulting SVG (default: `1.0`)
|
56
55
|
|
57
|
-
|
58
|
-
the most sense. You get the benefit of browser compatibility without needing
|
59
|
-
to serve an image somewhere online.
|
56
|
+
Pass these in as an options hash; these *must* be Float values! For example:
|
60
57
|
|
61
|
-
|
58
|
+
``` ruby
|
59
|
+
opts = { :ppi => 200.0, :zoom => 5.0 }
|
60
|
+
renderer = Mathematical::Render.new(opts)
|
61
|
+
```
|
62
|
+
|
63
|
+
## Dependencies
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
+
This package depends on the following libraries:
|
66
|
+
|
67
|
+
* glib-2.0
|
68
|
+
* gdk-pixbuf-2.0
|
69
|
+
* xml2
|
70
|
+
* cairo
|
71
|
+
* pango
|
72
|
+
* pangocairo
|
73
|
+
|
74
|
+
* On a Mac, pretty much everything can be installed via Homebrew.
|
75
|
+
* On a *nix machine, I'm sure it's possible via package managers to install all of these.
|
76
|
+
* On a Windows machine, I have no idea.
|
77
|
+
|
78
|
+
## History
|
79
|
+
|
80
|
+
There are a smattering of libraries written in various languages to convert math
|
81
|
+
into a variety of formats. But there needs to be a sane way to show math
|
82
|
+
equations in the browser. With browser support for MathML under attack, it's
|
83
|
+
unfortunately not a sustainable solution. A PNG or SVG representation of the
|
84
|
+
equation is the safest way to go.
|
85
|
+
|
86
|
+
Most advice suggests using [MathJax](http://www.mathjax.org/). While extremely popular
|
87
|
+
I dislike the "stuttering" effect caused by pages loading math. JavaScript
|
88
|
+
shouldn't be used in situations where server-rendering is a possibility, in my opinion.
|
89
|
+
|
90
|
+
To that end, I obsessed over the problem of server-side math rendering for over a
|
91
|
+
week. Here was my journey:
|
92
|
+
|
93
|
+
* I started out with [`blahtexml`](https://github.com/gvanas/blahtexml), which takes
|
94
|
+
TeX equations and converts them to PNG. This wasn't a bad idea, but it took too long;
|
95
|
+
for twelve equations, it took eight seconds. It was slow because it shelled out
|
96
|
+
to [`LaTeX`](http://www.latex-project.org/), *then* [`dvipng`](http://www.nongnu.org/dvipng/).
|
97
|
+
In fact, as I discovered, most projects on the 'Net shell out to `LaTeX`, then
|
98
|
+
something else, which makes performance absolutely horrid. I had to find something
|
99
|
+
better, with no preferably dependency on `LaTeX`.
|
100
|
+
|
101
|
+
* [`mimetex`](http://www.forkosh.com/mimetex.html) was my next attempt. It looked
|
102
|
+
great: a pure C implementation that turned TeX equations into a rasterized representation,
|
103
|
+
and then into a PNG. The speed was there, but the output image was pretty jagged.
|
104
|
+
I tweaked the program to output BMPs, and tried to sharpen those with [`potrace`](http://potrace.sourceforge.net/),
|
105
|
+
but the results were less then pleasant. The "update" to `mimetex` is [`mathtex`](http://www.forkosh.com/mathtex.html),
|
106
|
+
but it, too, depend on `LaTeX` and `dvipng` binaries to produce images.
|
107
|
+
|
108
|
+
* [`pmml2svg`](http://pmml2svg.sourceforge.net/) had potential. It's a set of
|
109
|
+
XSLT stylesheets to convert MathML to SVG. Unfortunately, it relies on XSLT 2.0,
|
110
|
+
of which there are no Ruby bindings (at the time of this writing, April '14). It
|
111
|
+
had to rely on [Saxon](http://saxon.sourceforge.net/) and Java.
|
112
|
+
|
113
|
+
* [`tth`](http://hutchinson.belmont.ma.us/tth/) converts TeX to HTML, but the
|
114
|
+
output is aesthetically unpleasing, so I passed.
|
115
|
+
|
116
|
+
* Wikipedia uses [`texvc`](https://github.com/dlitz/texvc), which is written in OCaml,
|
117
|
+
a language I am utterly unfamiliar with. In any event, I could not get the code
|
118
|
+
to compile on my machine.
|
119
|
+
|
120
|
+
* It took me forever to finally compile [`gtkmathview`](https://github.com/khaledhosny/gtkmathview),
|
121
|
+
and when it did, I got a bunch of SVG images with screwed up fonts.
|
122
|
+
|
123
|
+
* [`dvisvgm`](http://dvisvgm.sourceforge.net/) worked well, but still depended
|
124
|
+
on two external binaries (`LaTeX` to convert the text to dvi, and `dvisvgm` to turn
|
125
|
+
it into SVG)
|
126
|
+
|
127
|
+
* At one point, I began to try and convert the MathJax code to Ruby to figure out
|
128
|
+
how it accomplished its `toSVG` methods. The MathJax codebase, while written by
|
129
|
+
geniuses, is absoloutely incomprehnsible, due in part to JavaScript's inability
|
130
|
+
to possess a coherent structure.
|
131
|
+
|
132
|
+
* Near the end of my wits, I mimicked the behavior of [`mathrender2`](https://github.com/quipper/mathrender2),
|
133
|
+
which uses [PhantomJS](http://phantomjs.org/) to embed MathJax onto a fake
|
134
|
+
HTML page. This produced exactly what I needed: a bunch of accurate SVG files with
|
135
|
+
no intermediate binaries. It was, unfortunately, a bit slow: for an arbitrary
|
136
|
+
composition of 880 equations, it took about eight seconds to complete. Could I
|
137
|
+
do better?
|
138
|
+
|
139
|
+
* I came across [Lasem](https://wiki.gnome.org/action/show/Projects/Lasem?action=show&redirect=Lasem),
|
140
|
+
which meet every need. It has no external binary dependencies (only library packages),
|
141
|
+
can convert directly to SVG, and it's fast. The same arbitrary 880 equations were
|
142
|
+
rendered in less than three seconds.
|
143
|
+
|
144
|
+
And thus a wrapper was born.
|
data/Rakefile
CHANGED
@@ -12,34 +12,6 @@ end
|
|
12
12
|
|
13
13
|
task :default => [:test]
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
task :init do
|
19
|
-
system "git submodule init"
|
20
|
-
system "git submodule update"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
task :makebin do
|
26
|
-
host_os = RbConfig::CONFIG['host_os']
|
27
|
-
Dir.chdir "ext/blahtexml" do
|
28
|
-
case host_os
|
29
|
-
# when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
30
|
-
# :windows
|
31
|
-
when /darwin|mac os/
|
32
|
-
`make blahtex-mac`
|
33
|
-
FileUtils.mkdir_p "../../bin/blahtex/macosx/"
|
34
|
-
FileUtils.cp "blahtex", "../../bin/blahtex/macosx/"
|
35
|
-
when /linux/
|
36
|
-
`make blahtex-linux`
|
37
|
-
FileUtils.mkdir_p "../../bin/blahtex/linux/"
|
38
|
-
FileUtils.cp "blahtex", "../../bin/blahtex/linux/"
|
39
|
-
# when /solaris|bsd/
|
40
|
-
# :unix
|
41
|
-
else
|
42
|
-
raise Error, "unknown os: #{host_os.inspect}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
15
|
+
require 'rake/extensiontask'
|
16
|
+
spec = Gem::Specification.load('mathematical.gemspec')
|
17
|
+
Rake::ExtensionTask.new('mathematical', spec)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
itex2MML transforms itex (a dialect of latex) into MathML. itex2MML is developed by
|
2
|
+
Paul Gartside and Jacques Distler.
|
3
|
+
|
4
|
+
Currently, this is version `itex2MML@1.5.1`.
|
5
|
+
|
6
|
+
Some documentation can be found here:
|
7
|
+
|
8
|
+
* http://pear.math.pitt.edu/mathzilla/itex2mml.html
|
9
|
+
* http://golem.ph.utexas.edu/~distler/blog/
|
10
|
+
* http://golem.ph.utexas.edu/~distler/blog/archives/000644.html
|
11
|
+
* http://golem.ph.utexas.edu/~distler/blog/itex2MMLcommands.html
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Lasem aims to be a C/Gobject based SVG/Mathml renderer and editor, supporting CSS
|
2
|
+
style sheets (only rendering is implemented for now). It uses cairo and pango as
|
3
|
+
it's rendering abstraction layer, and then support numerous output formats: xlib,
|
4
|
+
PNG, SVG, PDF, PS, EPS... It's written by Emmanuel Pacaud.
|
5
|
+
|
6
|
+
Currently, this is version `lasem@0.4.1`.
|
7
|
+
|
8
|
+
Some documentation can be found here:
|
9
|
+
|
10
|
+
* http://blogs.gnome.org/emmanuel/category/lasem/
|
11
|
+
* https://github.com/GNOME/lasem
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
extension_name = 'mathematical'
|
4
|
+
|
5
|
+
# dir_config(extension_name)
|
6
|
+
|
7
|
+
pkg_config("glib-2.0")
|
8
|
+
pkg_config("gdk-pixbuf-2.0")
|
9
|
+
|
10
|
+
have_library("xml2")
|
11
|
+
find_header("libxml/tree.h", "/usr/include/libxml2", "/usr/local/include/libxml2")
|
12
|
+
find_header("libxml/parser.h", "/usr/include/libxml2", "/usr/local/include/libxml2")
|
13
|
+
find_header("libxml/xpath.h", "/usr/include/libxml2", "/usr/local/include/libxml2")
|
14
|
+
find_header("libxml/xpathInternals.h", "/usr/include/libxml2", "/usr/local/include/libxml2")
|
15
|
+
|
16
|
+
have_library("cairo")
|
17
|
+
find_header("cairo.h", "/opt/X11/include/cairo")
|
18
|
+
|
19
|
+
have_library("pangocairo")
|
20
|
+
HEADER_DIRS = [
|
21
|
+
# First search /opt/local for macports
|
22
|
+
'/opt/boxen/homebrew/Cellar/pango/1.36.3/include/pango-1.0/',
|
23
|
+
]
|
24
|
+
|
25
|
+
LIB_DIRS = [
|
26
|
+
# First search /opt/local for macports
|
27
|
+
'/opt/boxen/homebrew/opt/pango/lib/'
|
28
|
+
]
|
29
|
+
|
30
|
+
dir_config('pango', HEADER_DIRS, LIB_DIRS)
|
31
|
+
find_header("pango/pangocairo.h")
|
32
|
+
find_header("pango/pango-font.h")
|
33
|
+
|
34
|
+
unless find_library('pango-1.0', 'pango_font_description_new')
|
35
|
+
abort "libpango is missing. please install libpango"
|
36
|
+
end
|
37
|
+
|
38
|
+
dir_config('pangocairo', HEADER_DIRS, LIB_DIRS)
|
39
|
+
unless find_library('pangocairo-1.0', 'pango_cairo_font_map_get_default')
|
40
|
+
abort "libpango is missing. please install libpango"
|
41
|
+
end
|
42
|
+
|
43
|
+
find_header("pango/pangocairo.h" , "/opt/boxen/homebrew/Cellar/pango/1.36.3/include/pango-1.0/")
|
44
|
+
find_header("pango/pango-font.h" , "/opt/boxen/homebrew/Cellar/pango/1.36.3/include/pango-1.0/")
|
45
|
+
find_header("pango/pango-fontmap.h" , "/opt/boxen/homebrew/Cellar/pango/1.36.3/include/pango-1.0/")
|
46
|
+
|
47
|
+
# pangocairo-fontmap.c
|
48
|
+
create_makefile(extension_name)
|
49
|
+
|
50
|
+
# /opt/boxen/homebrew/opt/pango/lib/
|
51
|
+
# otool -L lib/mathematical.bundle
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/* itex2MML 1.5.1
|
2
|
+
* itex2MML.h last modified 1/5/2014
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef ITEX2MML_H
|
6
|
+
#define ITEX2MML_H
|
7
|
+
|
8
|
+
#define ITEX2MML_VERSION "1.5.1"
|
9
|
+
|
10
|
+
#ifdef __cplusplus
|
11
|
+
extern "C" {
|
12
|
+
#endif
|
13
|
+
|
14
|
+
/* Step 1. Parse a buffer with itex source; return value is mathml, or 0 on failure (e.g., parse error).
|
15
|
+
*/
|
16
|
+
extern char * itex2MML_parse (const char * buffer, unsigned long length);
|
17
|
+
|
18
|
+
/* Step 2. Free the string from Step 1.
|
19
|
+
*/
|
20
|
+
extern void itex2MML_free_string (char * str);
|
21
|
+
|
22
|
+
|
23
|
+
/* Alternatively, to filter generic source and converting embedded equations, use:
|
24
|
+
*/
|
25
|
+
extern int itex2MML_filter (const char * buffer, unsigned long length);
|
26
|
+
|
27
|
+
extern int itex2MML_html_filter (const char * buffer, unsigned long length);
|
28
|
+
extern int itex2MML_strict_html_filter (const char * buffer, unsigned long length);
|
29
|
+
|
30
|
+
|
31
|
+
/* To change output methods:
|
32
|
+
*
|
33
|
+
* Note: If length is 0, then buffer is treated like a string; otherwise only length bytes are written.
|
34
|
+
*/
|
35
|
+
extern void (*itex2MML_write) (const char * buffer, unsigned long length); /* default writes to stdout */
|
36
|
+
extern void (*itex2MML_write_mathml) (const char * mathml); /* default calls itex2MML_write(mathml,0) */
|
37
|
+
extern void (*itex2MML_error) (const char * msg); /* default writes to stderr */
|
38
|
+
|
39
|
+
|
40
|
+
/* Other stuff:
|
41
|
+
*/
|
42
|
+
extern void itex2MML_setup (const char * buffer, unsigned long length);
|
43
|
+
|
44
|
+
extern void itex2MML_restart ();
|
45
|
+
|
46
|
+
extern char * itex2MML_copy_string (const char * str);
|
47
|
+
extern char * itex2MML_copy_string_extra (const char * str, unsigned extra);
|
48
|
+
extern char * itex2MML_copy2 (const char * first, const char * second);
|
49
|
+
extern char * itex2MML_copy3 (const char * first, const char * second, const char * third);
|
50
|
+
extern char * itex2MML_copy_escaped (const char * str);
|
51
|
+
|
52
|
+
extern char * itex2MML_empty_string;
|
53
|
+
|
54
|
+
extern int itex2MML_lineno;
|
55
|
+
|
56
|
+
extern int itex2MML_rowposn;
|
57
|
+
extern int itex2MML_displaymode;
|
58
|
+
|
59
|
+
#ifdef __cplusplus
|
60
|
+
}
|
61
|
+
#endif
|
62
|
+
|
63
|
+
#endif /* ! ITEX2MML_H */
|
@@ -0,0 +1,257 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright © 2007-2008 Emmanuel Pacaud
|
3
|
+
*
|
4
|
+
* This library is free software; you can redistribute it and/or
|
5
|
+
* modify it under the terms of the GNU Lesser General Public
|
6
|
+
* License as published by the Free Software Foundation; either
|
7
|
+
* version 2 of the License, or (at your option) any later version.
|
8
|
+
*
|
9
|
+
* This library is distributed in the hope that it will be useful,
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
* Lesser General Public License for more details.
|
13
|
+
*
|
14
|
+
* You should have received a copy of the GNU Lesser General
|
15
|
+
* Public License along with this library; if not, write to the
|
16
|
+
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
17
|
+
* Boston, MA 02111-1307, USA.
|
18
|
+
*
|
19
|
+
* Author:
|
20
|
+
* Emmanuel Pacaud <emmanuel@gnome.org>
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include <stdio.h>
|
24
|
+
#include <string.h>
|
25
|
+
#include <stdlib.h>
|
26
|
+
#include <lsm.h>
|
27
|
+
#include <lsmmathml.h>
|
28
|
+
#include <glib.h>
|
29
|
+
#include <glib/gi18n.h>
|
30
|
+
#include <glib/gprintf.h>
|
31
|
+
#include <gio/gio.h>
|
32
|
+
#include <cairo-pdf.h>
|
33
|
+
#include <cairo-svg.h>
|
34
|
+
#include <cairo-ps.h>
|
35
|
+
|
36
|
+
#include "itex2MML.h"
|
37
|
+
|
38
|
+
static char *option_debug_domains = NULL;
|
39
|
+
static char *option_output_file_format = NULL;
|
40
|
+
static char **option_input_filenames = NULL;
|
41
|
+
static char *option_output_filename = NULL;
|
42
|
+
double option_ppi = 72.0;
|
43
|
+
double option_zoom = 1.0;
|
44
|
+
|
45
|
+
typedef enum {
|
46
|
+
FORMAT_SVG,
|
47
|
+
FORMAT_PDF,
|
48
|
+
FORMAT_PS,
|
49
|
+
FORMAT_PNG,
|
50
|
+
FORMAT_UNKNOWN
|
51
|
+
} FileFormat;
|
52
|
+
|
53
|
+
static char const *file_formats[] = {
|
54
|
+
"svg",
|
55
|
+
"pdf",
|
56
|
+
"ps",
|
57
|
+
"png",
|
58
|
+
"svg"
|
59
|
+
};
|
60
|
+
|
61
|
+
static const GOptionEntry entries[] =
|
62
|
+
{
|
63
|
+
{ G_OPTION_REMAINING, ' ', 0, G_OPTION_ARG_FILENAME_ARRAY,
|
64
|
+
&option_input_filenames, NULL, NULL},
|
65
|
+
{ "output", 'o', 0, G_OPTION_ARG_FILENAME,
|
66
|
+
&option_output_filename, N_("Output filename"), NULL},
|
67
|
+
{ "format", 'f', 0, G_OPTION_ARG_STRING,
|
68
|
+
&option_output_file_format, N_("Output format"), NULL },
|
69
|
+
{ "ppi", 'p', 0, G_OPTION_ARG_DOUBLE,
|
70
|
+
&option_ppi, N_("Pixel per inch"), NULL },
|
71
|
+
{ "zoom", 'z', 0, G_OPTION_ARG_DOUBLE,
|
72
|
+
&option_zoom, N_("Zoom"), NULL },
|
73
|
+
{ "debug", 'd', 0, G_OPTION_ARG_STRING,
|
74
|
+
&option_debug_domains, N_("Debug domains"), NULL },
|
75
|
+
{ NULL }
|
76
|
+
};
|
77
|
+
|
78
|
+
int mainbar(int argc, char **argv)
|
79
|
+
{
|
80
|
+
LsmDomDocument *document;
|
81
|
+
LsmDomView *view;
|
82
|
+
cairo_t *cairo;
|
83
|
+
cairo_surface_t *surface;
|
84
|
+
GError *error = NULL;
|
85
|
+
GOptionContext *context;
|
86
|
+
FileFormat format;
|
87
|
+
char *output_filename;
|
88
|
+
char *input_filename;
|
89
|
+
double height_pt, width_pt;
|
90
|
+
unsigned int height, width;
|
91
|
+
|
92
|
+
g_type_init ();
|
93
|
+
|
94
|
+
context = g_option_context_new (NULL);
|
95
|
+
g_option_context_add_main_entries (context, entries, NULL);
|
96
|
+
|
97
|
+
// if (!g_option_context_parse (context, &argc, &argv, &error))
|
98
|
+
// {
|
99
|
+
// g_option_context_free (context);
|
100
|
+
// g_print (_("Option parsing failed: %s\n"), error->message);
|
101
|
+
// return EXIT_FAILURE;
|
102
|
+
// }
|
103
|
+
|
104
|
+
g_option_context_free (context);
|
105
|
+
|
106
|
+
// if (option_zoom < 0.0) {
|
107
|
+
// g_print (_("Invalid zoom value"));
|
108
|
+
// return EXIT_FAILURE;
|
109
|
+
// }
|
110
|
+
|
111
|
+
lsm_debug_enable (option_debug_domains);
|
112
|
+
|
113
|
+
// if (option_input_filenames == NULL || g_strv_length (option_input_filenames) > 1) {
|
114
|
+
// g_print (_("One input file name is required\n"));
|
115
|
+
// return EXIT_FAILURE;
|
116
|
+
// }
|
117
|
+
// option_input_filenames = ;
|
118
|
+
|
119
|
+
input_filename = "/Users/garentorikian/Downloads/lasem-ruby/foo.mml";
|
120
|
+
|
121
|
+
if (option_output_file_format != NULL) {
|
122
|
+
for (format = 0; format < G_N_ELEMENTS(file_formats) - 1; format++)
|
123
|
+
if (g_ascii_strcasecmp (option_output_file_format, file_formats[format]) == 0)
|
124
|
+
break;
|
125
|
+
if (FORMAT_UNKNOWN == format) {
|
126
|
+
g_print (_("Unknown format : %s\n"), option_output_file_format);
|
127
|
+
return EXIT_FAILURE;
|
128
|
+
}
|
129
|
+
} else
|
130
|
+
format = FORMAT_UNKNOWN;
|
131
|
+
|
132
|
+
if (option_output_filename != NULL) {
|
133
|
+
char *extension;
|
134
|
+
|
135
|
+
output_filename = option_output_filename;
|
136
|
+
|
137
|
+
extension = g_strrstr (output_filename, ".");
|
138
|
+
if (extension != NULL) {
|
139
|
+
extension++;
|
140
|
+
for (format = 0; format < G_N_ELEMENTS(file_formats) - 1; format++)
|
141
|
+
if (g_ascii_strcasecmp (extension, file_formats[format]) == 0)
|
142
|
+
break;
|
143
|
+
}
|
144
|
+
} else {
|
145
|
+
char *filename;
|
146
|
+
char *directory;
|
147
|
+
char *extension;
|
148
|
+
char *new_filename;
|
149
|
+
|
150
|
+
filename = g_path_get_basename (input_filename);
|
151
|
+
directory = g_path_get_dirname (input_filename);
|
152
|
+
|
153
|
+
extension = g_strrstr (filename, ".");
|
154
|
+
if (extension != NULL)
|
155
|
+
*extension = '\0';
|
156
|
+
|
157
|
+
new_filename = g_strconcat (filename, ".", file_formats[format], NULL);
|
158
|
+
output_filename = g_build_filename (directory, new_filename, NULL);
|
159
|
+
|
160
|
+
g_free (filename);
|
161
|
+
g_free (new_filename);
|
162
|
+
g_free (directory);
|
163
|
+
}
|
164
|
+
|
165
|
+
document = lsm_dom_document_new_from_path (input_filename,
|
166
|
+
NULL);
|
167
|
+
if (document == NULL) {
|
168
|
+
document = lsm_dom_document_new_from_url (input_filename,
|
169
|
+
NULL);
|
170
|
+
if (document == NULL) {
|
171
|
+
document = LSM_DOM_DOCUMENT (lsm_mathml_document_new_from_itex_path (input_filename,
|
172
|
+
NULL));
|
173
|
+
if (document == NULL) {
|
174
|
+
document = LSM_DOM_DOCUMENT (lsm_mathml_document_new_from_itex_url (input_filename,
|
175
|
+
NULL));
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
if (document != NULL) {
|
181
|
+
if (lsm_debug_check (&lsm_debug_category_dom, LSM_DEBUG_LEVEL_LOG)) {
|
182
|
+
void *buffer;
|
183
|
+
int size;
|
184
|
+
|
185
|
+
lsm_dom_document_save_to_memory (document, &buffer, &size, NULL);
|
186
|
+
|
187
|
+
if (buffer != NULL) {
|
188
|
+
g_printf ("%*s\n", size, (char *) buffer);
|
189
|
+
g_free (buffer);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
view = lsm_dom_document_create_view (document);
|
194
|
+
lsm_dom_view_set_resolution (view, option_ppi);
|
195
|
+
|
196
|
+
width_pt = 2.0;
|
197
|
+
height_pt = 2.0;
|
198
|
+
|
199
|
+
lsm_dom_view_get_size (view, &width_pt, &height_pt, NULL);
|
200
|
+
lsm_dom_view_get_size_pixels (view, &width, &height, NULL);
|
201
|
+
|
202
|
+
width_pt *= option_zoom;
|
203
|
+
height_pt *= option_zoom;
|
204
|
+
width *= option_zoom;
|
205
|
+
height *= option_zoom;
|
206
|
+
|
207
|
+
switch (format) {
|
208
|
+
case FORMAT_PDF:
|
209
|
+
surface = cairo_pdf_surface_create (output_filename,
|
210
|
+
width_pt, height_pt);
|
211
|
+
break;
|
212
|
+
case FORMAT_PS:
|
213
|
+
surface = cairo_ps_surface_create (output_filename,
|
214
|
+
width_pt, height_pt);
|
215
|
+
break;
|
216
|
+
case FORMAT_PNG:
|
217
|
+
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
218
|
+
width,
|
219
|
+
height);
|
220
|
+
break;
|
221
|
+
case FORMAT_SVG:
|
222
|
+
default:
|
223
|
+
surface = cairo_svg_surface_create (output_filename,
|
224
|
+
width_pt, height_pt);
|
225
|
+
break;
|
226
|
+
}
|
227
|
+
|
228
|
+
cairo = cairo_create (surface);
|
229
|
+
cairo_surface_destroy (surface);
|
230
|
+
cairo_scale (cairo, option_zoom, option_zoom);
|
231
|
+
|
232
|
+
lsm_dom_view_render (view, cairo, 0, 0);
|
233
|
+
|
234
|
+
switch (format) {
|
235
|
+
case FORMAT_PNG:
|
236
|
+
cairo_surface_write_to_png (cairo_get_target (cairo),
|
237
|
+
output_filename);
|
238
|
+
break;
|
239
|
+
default:
|
240
|
+
break;
|
241
|
+
}
|
242
|
+
|
243
|
+
cairo_destroy (cairo);
|
244
|
+
|
245
|
+
g_object_unref (view);
|
246
|
+
|
247
|
+
g_object_unref (document);
|
248
|
+
|
249
|
+
lsm_debug_render ("width = %g pt, height = %g pt", width_pt, height_pt);
|
250
|
+
} else {
|
251
|
+
g_print (_("Can't load '%s'\n"), input_filename);
|
252
|
+
|
253
|
+
return EXIT_FAILURE;
|
254
|
+
}
|
255
|
+
|
256
|
+
return EXIT_SUCCESS;
|
257
|
+
}
|