asciidoctor-texnical 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a148ca7bec668b2c33d5acb1e5bed167f1cfeefe
4
+ data.tar.gz: 9d01676555554965858f2d91bff15aaa03c2275e
5
+ SHA512:
6
+ metadata.gz: 18b2341245d86864dc0c9bd3703d89335498e3890db70b6c46c186a02fe1348c5761631437f1c7d495ec639dbc6531ba64df6005554b154abaa35ae2e1db9f9c
7
+ data.tar.gz: e86b2573ed3b692099321538a12771ed8b59fbf5cbd0bba250516d55917f57bbf5d070b216ce6028f37b80af56bb5078e16d8a0f149d0c0406bd70724e5c71c8
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'asciidoctor-texnical/extension'
4
+
5
+ Asciidoctor::Extensions.register do
6
+ treeprocessor TexnicalTreeprocessor
7
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'asciidoctor/extensions'
5
+
6
+ require_relative 'mathematical'
7
+
8
+ autoload :Digest, 'digest'
9
+
10
+ class TexnicalTreeprocessor < Asciidoctor::Extensions::Treeprocessor
11
+ def process(document)
12
+ ppi_s = (document.attr 'texnical-ppi') || '192.0'
13
+ ppi = ppi_s.to_f
14
+
15
+ target_dir = document.attr('imagesdir')
16
+ ::Asciidoctor::Helpers.mkdir_p target_dir unless ::File.directory? target_dir
17
+ texnical = ::Mathematical.new ppi, target_dir
18
+
19
+ unless (stem_blocks = document.find_by context: :stem).nil_or_empty?
20
+ stem_blocks.each do |stem|
21
+ texnical.handle_stem_block stem, self
22
+ end
23
+ end
24
+
25
+ prose_blocks = document.find_by do |b|
26
+ (b.content_model == :simple && (b.subs.include? :macros)) || b.context == :list_item
27
+ end
28
+
29
+ unless prose_blocks.nil_or_empty?
30
+ prose_blocks.each do |prose|
31
+ texnical.handle_prose_block prose
32
+ end
33
+ end
34
+ # # handle table cells of the "asciidoc" type, as suggested by mojavelinux
35
+ # # at asciidoctor/asciidoctor-mathematical#20.
36
+ # unless (table_blocks = document.find_by context: :table).nil_or_empty?
37
+ # table_blocks.each do |table|
38
+ # (table.rows[:body] + table.rows[:foot]).each do |row|
39
+ # row.each do |cell|
40
+ # if cell.style == :asciidoc
41
+ # process cell.inner_document
42
+ # elsif cell.style != :literal
43
+ # handle_nonasciidoc_table_cell cell, mathematical, image_output_dir, image_target_dir, format, inline
44
+ # end
45
+ # end
46
+ # end
47
+ # end
48
+ # end
49
+
50
+ # unless (sect_blocks = document.find_by content: :section).nil_or_empty?
51
+ # sect_blocks.each do |sect|
52
+ # handle_section_title sect, mathematical, image_output_dir, image_target_dir, format, inline
53
+ # end
54
+ # end
55
+
56
+ nil
57
+ end
58
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
4
+ require 'open3'
5
+
6
+ HEADER = '\documentclass[12pt]{article}
7
+ \usepackage[utf8]{inputenc}
8
+ \usepackage{amsmath}
9
+ \usepackage{amsthm}
10
+ \usepackage{amssymb}
11
+ \usepackage{amsfonts}
12
+ \usepackage{anyfontsize}
13
+ \usepackage{bm}
14
+ \pagestyle{empty}'
15
+
16
+ # The Image class represents an image that is generated from a latex equation expression.
17
+ class Image
18
+ def self.generate_inline(equ_data, equ_id, handler)
19
+ Image.new %($#{equ_data}$), equ_id, handler
20
+ end
21
+
22
+ def self.generate_block(equ_data, equ_id, handler)
23
+ Image.new %($$#{equ_data}$$), equ_id, handler
24
+ end
25
+
26
+ def initialize(input, equ_id, handler)
27
+ equ_id ||= %(stem-#{::Digest::MD5.hexdigest input})
28
+ @filename = %(#{equ_id}.png)
29
+ target_path = File.absolute_path handler.image_target_dir
30
+ dir = Dir.mktmpdir
31
+ tpth = File.join dir, @filename
32
+ Dir.chdir(dir) do
33
+ generate_png(input, tpth, handler.ppi)
34
+ FileUtils.cp(tpth, target_path)
35
+ end
36
+ end
37
+
38
+ def generate_png(input, pth, ppi)
39
+ File.open('eq.tex', 'w') do |file|
40
+ file.write("#{HEADER}\\begin{document} #{input}\\end{document} ")
41
+ end
42
+ _ = Open3.capture2('latex -interaction=batchmode eq.tex')
43
+ stdout, = Open3.capture2("dvipng -o #{pth} -T tight -z9 -D #{ppi} -q --height --width eq.dvi")
44
+ extract_dimensions_from_output(stdout)
45
+ end
46
+
47
+ def extract_dimensions_from_output(captured_stdout)
48
+ @height = captured_stdout.scan(/height=-?(\d+)/)[0][0].to_i
49
+ @width = captured_stdout.scan(/width=(\d+)/)[0][0].to_i
50
+ end
51
+
52
+ attr_reader :width
53
+ attr_reader :height
54
+ attr_reader :filename
55
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'asciidoctor/extensions'
4
+
5
+ require_relative 'image'
6
+ require 'pathname'
7
+
8
+ class Mathematical
9
+ STEM_INLINE_MACRO_RX = /\\?(?:stem|latexmath):([a-z,]*)\[(.*?[^\\])\]/m.freeze
10
+ LINE_FEED = %(\n)
11
+
12
+ def initialize(ppi, image_target_dir)
13
+ @ppi = ppi
14
+ @image_target_dir = image_target_dir
15
+ end
16
+
17
+ def handle_prose_block(prose)
18
+ if prose.context == :list_item
19
+ text = prose.instance_variable_get :@text
20
+ text_new = handle_inline_stem prose, text
21
+ prose.instance_variable_set :@text, text_new unless text_new.nil?
22
+ else
23
+ text = prose.lines * LINE_FEED
24
+ text_new = handle_inline_stem prose, text
25
+ prose.lines = text_new.split LINE_FEED unless text_new.nil?
26
+ end
27
+ end
28
+
29
+ def handle_stem_block(stem, processor)
30
+ return unless stem.style.to_sym == :latexmath
31
+
32
+ ::IO.write 'test.txt', stem.content
33
+
34
+ result = Image.generate_block stem.content, stem.id, self
35
+
36
+ alt_text = stem.attr 'alt', %($$#{stem.content}$$)
37
+ attrs = { 'target' => result.filename,
38
+ 'alt' => alt_text,
39
+ 'align' => 'center',
40
+ 'width' => (result.width * 0.5).to_s,
41
+ 'height' => (result.height * 0.5).to_s }
42
+
43
+ stem_image = processor.create_image_block stem.parent, attrs
44
+ stem_image.id = stem.id if stem.id
45
+ if (title = stem.attributes['title'])
46
+ stem_image.title = title
47
+ end
48
+ stem.parent.blocks[stem.parent.blocks.index stem] = stem_image
49
+ end
50
+
51
+ def handle_inline_stem(_node, text)
52
+ source_modified = false
53
+ if !text.nil? && (text.include? ':') && ((text.include? 'stem:') || (text.include? 'latexmath:'))
54
+ text.gsub!(STEM_INLINE_MACRO_RX) do
55
+ eq_id = Regexp.last_match[1] unless Regexp.last_match[1].nil_or_empty?
56
+ eq_data = Regexp.last_match[2]
57
+ source_modified = true
58
+ img = Image.generate_inline eq_data, eq_id, self
59
+ "image:#{img.filename}[width=#{img.width * 0.5},height=#{img.height * 0.5}]"
60
+ end
61
+ end
62
+ text if source_modified
63
+ end
64
+
65
+ attr_reader :image_target_dir
66
+ attr_reader :ppi
67
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Texnical
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asciidoctor-texnical
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Holger Peters
8
+ - Tobias Stumm
9
+ - Zhang Yang
10
+ - Dan Allen
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2018-12-29 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: asciidoctor
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.4'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ - !ruby/object:Gem::Dependency
31
+ name: asciidoctor-pdf
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: '1.4'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.4'
44
+ - !ruby/object:Gem::Dependency
45
+ name: rake
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '12'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '12'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '3'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '3'
72
+ description: An Asciidoctor extension to converts latexmath equations to SVG or PNGs
73
+ email:
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - lib/asciidoctor-texnical.rb
79
+ - lib/asciidoctor-texnical/extension.rb
80
+ - lib/asciidoctor-texnical/image.rb
81
+ - lib/asciidoctor-texnical/mathematical.rb
82
+ - lib/asciidoctor-texnical/version.rb
83
+ homepage: https://github.com/HolgerPeters/asciidoctor-texnical
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.6.8
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Asciidoctor STEM processor shelling out to latex
107
+ test_files: []