mathematical 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9fad17d831541b401f9eda17a2bcac80e41dd490
4
+ data.tar.gz: da0a7b96a1e43f8cd9a49e5bcf01a83a26881749
5
+ SHA512:
6
+ metadata.gz: 973f40da8c62e2f7c16df0e846c72252abebb022ae6465e85714ccf3af743642664573980ffc016e308aa07a9c2a2aa04161a3dcfe133bc32b186392abab762d
7
+ data.tar.gz: c20e0733a2efac5d629104bddecd3bb306ad04f677d2e371bf4d1f90691867eeb5746ebc88bd87a801b8d0e1ec73970726eb74cb6e884b97fd3f37f08a2b0c51
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /vendor/gems/
19
+ bin/
20
+ ext/blahtexml/Source/extconf.rb
21
+ ext/blahtexml/Source/makefile
22
+ ext/blahtexml/bin-blahtex
23
+ ext/blahtexml/blahtex
data/.gitmodules ADDED
@@ -0,0 +1,4 @@
1
+ [submodule "ext/blahtexml"]
2
+ path = ext/blahtexml
3
+ url = git@github.com:gvanas/blahtexml.git
4
+ ignore = dirty
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mathematical.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Garen Torikian
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Mathematical
2
+
3
+ Convert mathematical equations to base64 encoded images.
4
+
5
+ ![](https://i.imgur.com/JC7HT32.gif)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'mathematical'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mathematical
20
+
21
+ ## Usage
22
+
23
+ The simplest way to do this is
24
+
25
+ ``` ruby
26
+ Mathematical::Render.new.render(contents)
27
+ ```
28
+
29
+ `contents` should just be a block of text, containing inline or display style math.
30
+
31
+ ## Dependencies
32
+
33
+ Two dependencies are needed:
34
+
35
+ * [blahtexml](https://github.com/gvanas/blahtexml). This does all the conversion
36
+ from math to PNG. It's available for OS X (`make blahtex-mac`) and Linux (`make blahtex-linux`).
37
+ * [dvipng](http://sourceforge.net/projects/dvipng/). I'm on a Mac, and could not
38
+ for the life of me figure out how to build this. I ended up downloading [MacTex](https://www.tug.org/mactex/),
39
+ which is a *huge* package. `dvipng` is installed under */usr/texbin/dvipng*.
40
+
41
+ ## Why did you...?
42
+
43
+ There are a smattering of Ruby, C, and Ruby+C libraries out there for converting
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:
46
+
47
+ * MathML: With browser support for MathML under attack, it's unfortunately not a sustainable
48
+ solution
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.
56
+
57
+ After considering these choices, I thought that a base64 encoded image made
58
+ the most sense. You get the benefit of browser compatibility without needing
59
+ to serve an image somewhere online.
60
+
61
+ ## Further readings
62
+
63
+ * ftp://ftp.ams.org/ams/doc/amsmath/short-math-guide.pdf - a short math guide
64
+ * http://gva.noekeon.org/blahtexml/blahtexml-0.9-doc.pdf - the blahtex documentation
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ require 'rbconfig'
5
+ require 'fileutils'
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.verbose = true
11
+ end
12
+
13
+ task :default => [:test]
14
+
15
+ namespace :git do
16
+ namespace :submodules do
17
+ desc "Initialize git submodules"
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
@@ -0,0 +1,8 @@
1
+ require "mathematical/parser"
2
+ require "mathematical/render"
3
+ require "mathematical/version"
4
+
5
+ module Mathematical
6
+ # Raised when missing binaries for images rendering.
7
+ class CommandNotFoundError < Exception; end
8
+ end
@@ -0,0 +1,30 @@
1
+ module Mathematical
2
+ class Parser
3
+ # https://stackoverflow.com/questions/14182879/regex-to-match-latex-equations
4
+ REGEX = /
5
+ (?<!\\) # negative look-behind to make sure start is not escaped
6
+ (?: # start non-capture group for all possible match starts
7
+ # group 1, match dollar signs only
8
+ # single or double dollar sign enforced by look-arounds
9
+ ((?<!\$)\${1,2}(?!\$))|
10
+ # group 2, match escaped parenthesis
11
+ (\\\()|
12
+ # group 3, match escaped bracket
13
+ (\\\[)|
14
+ # group 4, match begin equation
15
+ (\\begin\{equation\})
16
+ )
17
+ (.*(\g<1>)?.*) # match everything in between including nested LaTeX equations
18
+ (?<!\\) # negative look-behind to make sure end is not escaped
19
+ # if group 1 was start, match \1
20
+ (?(1)(?<!\$)\1(?!\$)|
21
+ # if group 2 was start, escaped parenthesis is end
22
+ (?(2)\\\)|
23
+ # if group 3 was start, escaped bracket is end
24
+ (?(3)\\\]|
25
+ # otherwise group 4 was start, match end equation
26
+ \\end\{equation\}
27
+ )))
28
+ /x
29
+ end
30
+ end
@@ -0,0 +1,101 @@
1
+ require 'rbconfig'
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+ require 'shellwords'
5
+ require 'base64'
6
+
7
+ module Mathematical
8
+ class Render
9
+ DEFAULT_OPTS = {
10
+ :html_png_resolution => 200
11
+ }
12
+
13
+ def initialize(opts = {})
14
+ @os ||= (
15
+ host_os = RbConfig::CONFIG['host_os']
16
+ case host_os
17
+ when /darwin|mac os/
18
+ "macosx"
19
+ when /linux/
20
+ "linux"
21
+ else
22
+ raise Error, "unknown os: #{host_os.inspect}"
23
+ end
24
+ )
25
+
26
+ opts = DEFAULT_OPTS.merge(opts)
27
+ @temp_dir = Dir.mktmpdir
28
+ @args = [
29
+ '--png',
30
+ '--use-preview-package',
31
+ # '--shell-dvipng',
32
+ # "'dvipng -D #{Shellwords.shellescape opts[:html_png_resolution].to_s}'",
33
+ ]
34
+ end
35
+
36
+
37
+ def render(contents)
38
+ in_tmpdir do |tmpdir|
39
+ @args << "--temp-directory #{Shellwords.shellescape tmpdir.first}"
40
+ @args << "--png-directory #{Shellwords.shellescape tmpdir.first}"
41
+
42
+ contents.gsub(Mathematical::Parser::REGEX) do |maths|
43
+ if maths =~ /^\$(?!\$)/
44
+ maths = maths[1..-2]
45
+ type = :inline
46
+ else
47
+ type = :display
48
+ end
49
+
50
+ data = run_blahtex(maths, type)
51
+ if filename = data.match("<md5>(.+?)</md5>")[1]
52
+ "<img class=\"#{type.to_s}-math\" src=\"data:image/png;base64,#{png_to_base64(File.join(tmpdir, "#{filename}.png"))}\"/>"
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def run_blahtex(tex, type)
59
+ raise CommandNotFoundError, "Required commands missing: #{missing_commands.join(', ')} in PATH. (#{ENV['PATH']})" unless missing_commands.empty?
60
+ @args << '--displaymath' if type == :equation
61
+
62
+ IO.popen(["bin/blahtex/#{@os}/blahtex", *@args].join(' '), 'w+') do |blahtex|
63
+ blahtex.write tex
64
+ blahtex.close_write
65
+
66
+ output = blahtex.read
67
+ blahtex.close_read
68
+
69
+ raise "Error running blahtex" unless $?.success?
70
+
71
+ output
72
+ end
73
+ end
74
+
75
+ def png_to_base64(path)
76
+ File.open(path, 'r') { |image_file| Base64.encode64(image_file.read).gsub(/\n/, '') }
77
+ end
78
+
79
+ private
80
+
81
+ # Check toolchain availability and returns array of missing tools
82
+ def missing_commands
83
+ commands = []
84
+ commands << "dvipng" unless can_run?("dvipng -v")
85
+ commands
86
+ end
87
+
88
+ # Trial command and check if return code is zero
89
+ def can_run?(command)
90
+ `#{command} 2>&1`
91
+ $?.exitstatus.zero?
92
+ end
93
+
94
+ def in_tmpdir
95
+ path = FileUtils.mkdir_p Dir.tmpdir
96
+ yield path
97
+ ensure
98
+ FileUtils.rm_rf( path )
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ module Mathematical
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mathematical/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mathematical"
8
+ spec.version = Mathematical::VERSION
9
+ spec.authors = ["Garen Torikian"]
10
+ spec.email = ["gjtorikian@gmail.com"]
11
+ spec.summary = %q{Turn maths into PNGs.}
12
+ spec.description = %q{Turn maths into PNGs.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ end
data/script/bootstrap ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ export CC=gcc
5
+
6
+ echo "==> Installing gem dependencies…"
7
+ bundle check --path vendor/gems 2>&1 > /dev/null || {
8
+ bundle install --binstubs bin --path vendor/gems --quiet
9
+ }
@@ -0,0 +1,9 @@
1
+ require "test_helper"
2
+ require "mathematical"
3
+
4
+ class Mathematical::BasicTest < Test::Unit::TestCase
5
+
6
+ def test_it_has_a_version
7
+ assert Mathematical::VERSION
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ When <img class="inline-math" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAUCAMAAAAusUTNAAAANlBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHL6OuAAAAEXRSTlMAQKOPaOEsfMNW+dMW7bPx81p55n0AAADiSURBVCgVtVLZAoQgCCSPrM0O//9ndyA1tK235YE4holDoheJL7lbypkailuwl1fD2vAX9zoSuUkne1tRWwF+hh6ifEXtpQtvVbYzg+ozBU5OnvVgrL3PoKhjcozbViiHkvGslpgX2Q98Fg5w9kR/2MS8JEpSWTFPkYyegJZuZhiNWD1R7mQBQ+K4yf+sFZoaGJly8WhkBkQtZ+O2j12aLxx1g5E7jiiR8sItuyoOkZWyhOus4DYpzvpQpikFG18+cMmIB0OmyceO+gSpa11/hWVkvU3o2blTP2P/Sk38En7LF60+BSj8TilKAAAAAElFTkSuQmCC"/>, there are two solutions...
@@ -0,0 +1 @@
1
+ When $a \ne 0$, there are two solutions...
@@ -0,0 +1,31 @@
1
+ require "test_helper"
2
+
3
+ class Mathematical::FixturesTest < Test::Unit::TestCase
4
+
5
+ Dir['test/mathematical/fixtures/before/*.text'].each do |before|
6
+ name = before.split('/').last
7
+
8
+ define_method "test_#{name}" do
9
+ source = File.read(before)
10
+
11
+ expected_file = before.sub(/before/, "after").sub(/text/, "html")
12
+ expected = File.read(expected_file).rstrip
13
+ actual = Mathematical::Render.new.render(source).rstrip
14
+
15
+ if source != expected
16
+ assert(source != actual, "#{name} did not render anything")
17
+ end
18
+
19
+ diff = IO.popen("diff -u - #{expected_file}", 'r+') do |f|
20
+ f.write actual
21
+ f.close_write
22
+ f.read
23
+ end
24
+
25
+ assert expected == actual, <<message
26
+ #{File.basename expected_file}'s contents don't match command output:
27
+ #{diff}
28
+ message
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ require 'bundler/setup'
2
+ require 'mathematical'
3
+ require 'test/unit'
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mathematical
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Garen Torikian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Turn maths into PNGs.
42
+ email:
43
+ - gjtorikian@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .gitmodules
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/mathematical.rb
55
+ - lib/mathematical/parser.rb
56
+ - lib/mathematical/render.rb
57
+ - lib/mathematical/version.rb
58
+ - mathematical.gemspec
59
+ - script/bootstrap
60
+ - test/mathematical/basic_test.rb
61
+ - test/mathematical/fixtures/after/basic.html
62
+ - test/mathematical/fixtures/before/basic.text
63
+ - test/mathematical/fixtures_test.rb
64
+ - test/test_helper.rb
65
+ homepage: ''
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Turn maths into PNGs.
89
+ test_files:
90
+ - test/mathematical/basic_test.rb
91
+ - test/mathematical/fixtures/after/basic.html
92
+ - test/mathematical/fixtures/before/basic.text
93
+ - test/mathematical/fixtures_test.rb
94
+ - test/test_helper.rb