texd 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Texd
4
+ # LookupContext is used to find files accross gem, engine and application
5
+ # barriers. This allows other gems and engines to define additional paths
6
+ # to look into, when searching for files.
7
+ #
8
+ # This mechanism is useful, if you want to build a Rails engine to provide
9
+ # default files, and reuse those defaults accross multiple Rails apps.
10
+ #
11
+ # To add a file to the loolup path set, configure Texd:
12
+ #
13
+ # # in lib/yourgem/railtie.rb
14
+ # module Yourgem::Railtie < Rails::Railtie
15
+ # initializer "configure Texd" do
16
+ # Texd.configure do |config|
17
+ # config.lookup_paths << Pathname.new(__dir__).join("../../app/tex")
18
+ # end
19
+ # end
20
+ # end
21
+ #
22
+ # Then files in your `app/tex/` directory will be used, if they are not
23
+ # found in the host application's `app/tex/` directory ("app/tex" is just
24
+ # a convention, you could add arbitrary directories).
25
+ class LookupContext
26
+ # @!parse
27
+ # # Raised when LookupContext#find could not find a file.
28
+ # class MissingFileError < RenderError; end
29
+ MissingFileError = Class.new Error
30
+
31
+ # A list of directories, in priority order, to search files in.
32
+ attr_reader :paths
33
+
34
+ # @param [Array<String, Pathname>] paths is a set of paths to search
35
+ # files in; usually configured with `Texd.config.lookup_paths`
36
+ def initialize(paths)
37
+ @paths = (paths || []).map { |path| expand(path) }
38
+ end
39
+
40
+ # Performs file look up in the configured paths.
41
+ #
42
+ # @param [String, Pathname] name of file to find.
43
+ # @return [Pathname] path to file, when found
44
+ # @raise [MissingFileError] when file could not be found
45
+ def find(name)
46
+ return expand(name) if File.absolute_path?(name)
47
+
48
+ paths.each do |path|
49
+ candidate = path.join(name).expand_path
50
+ return candidate if candidate.exist?
51
+ end
52
+
53
+ msg = format "file %p not found\nsearch paths:\n\t", name
54
+ msg << paths.join("\n\t")
55
+ raise MissingFileError, msg
56
+ end
57
+
58
+ private
59
+
60
+ def expand(path)
61
+ Pathname.new(path).expand_path
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Texd
4
+ class Railtie < ::Rails::Railtie
5
+ initializer "initialize texd" do
6
+ # register MIME type for .tex files
7
+ Mime::Type.register "text/x-tex", :tex, ["text/plain"], ["tex"]
8
+
9
+ # prepend app/tex for Rails host application
10
+ Texd.config.lookup_paths.unshift Rails.root.join("app/tex")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Texd
4
+ VERSION = "0.1.0"
5
+ end
data/lib/texd.rb ADDED
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Texd
4
+ # @!parse
5
+ # # Catch-all error for all exceptions raised by Texd
6
+ # class Error < StandarError; end
7
+ Error = Class.new StandardError
8
+ end
9
+
10
+ require "rails"
11
+
12
+ require_relative "texd/version"
13
+ require_relative "texd/config"
14
+ require_relative "texd/helpers"
15
+ require_relative "texd/client"
16
+ require_relative "texd/attachment"
17
+ require_relative "texd/document"
18
+ require_relative "texd/lookup_context"
19
+ require_relative "texd/railtie"
20
+
21
+ module Texd
22
+ extend self
23
+
24
+ # Reconfigures Texd. Should be called once in your initializer.
25
+ #
26
+ # @example config/initializers/texd.rb
27
+ # Texd.configure do |config|
28
+ # config.endpoint = ENV.fetch("TEXD_ENDPOINT", "http://localhost:2201/")
29
+ # config.error_format = ENV.fetch("TEXD_ERRORS", "full")
30
+ # config.tex_engine = ENV["TEXD_ENGINE"]
31
+ # config.tex_image = ENV["TEXD_IMAGE"]
32
+ # config.helpers = []
33
+ # config.lookup_paths = [Rails.root.join("app/tex")]
34
+ # end
35
+ #
36
+ # @yield [Texd::Configuration] the previous config object
37
+ # @return [Texd::Configuration] the new current config object
38
+ def configure
39
+ yield config if block_given?
40
+ config
41
+ end
42
+
43
+ # @return [Texd::Configuration] the current config object.
44
+ def config
45
+ @config ||= Configuration.new
46
+ end
47
+
48
+ # @return [Texd::Client] the currently configured HTTP client.
49
+ def client
50
+ if (new_hash = config.hash) && new_hash != @config_hash
51
+ @client = Client.new(config)
52
+ @config_hash = new_hash
53
+ end
54
+
55
+ @client
56
+ end
57
+
58
+ # Creates a helper module containing (a) the `texd_attach` helper,
59
+ # and (b) any other helper configured in Text.config.helpers.
60
+ #
61
+ # This needs to be dynamic, because the attachment list is volatile.
62
+ #
63
+ # @api private
64
+ def helpers(attachments)
65
+ Module.new do
66
+ include Texd::Helpers
67
+
68
+ define_method :texd_attach do |path, rename: true, with_extension: true|
69
+ attachments.attach(path, rename).name(with_extension)
70
+ end
71
+
72
+ define_method :texd_reference do |path, rename: true, with_extension: true|
73
+ attachments.reference(path, rename).name(with_extension)
74
+ end
75
+
76
+ alias_method :texd_references, :texd_reference
77
+
78
+ Texd.config.helpers.each do |mod|
79
+ include mod
80
+ end
81
+ end
82
+ end
83
+
84
+ # Render compiles a template, uploads the files to the texd instance,
85
+ # and returns the PDF.
86
+ #
87
+ # The arguments are directly forwarded to ApplicationController#render
88
+ # (which in turn delegates to ActionView::Renderer#render).
89
+ #
90
+ # @example Render app/views/document/document.tex.erb
91
+ # begin
92
+ # pdf = Texd.render(template: "documents/document")
93
+ # rescue Texd::Client::CompilationError => err
94
+ # # Compilation failed and we might have a log in err.logs (only
95
+ # # Texd.config.error_format is "full" or "condensed").
96
+ # # Otherwise some details might be available in err.details.
97
+ # # have a log in err.details
98
+ # rescue Texd::Client::InputError => err
99
+ # # something failed during input file processing. For details see
100
+ # # err.details
101
+ # rescue Texd::Client::QueueError => err
102
+ # # server is busy, try again later.
103
+ # rescue Texd::Error => err
104
+ # # something went wrong before we even got to sent data to the server
105
+ # end
106
+ #
107
+ # @raise [Texd::Client::ResponseError] on input and queue errors. Also on
108
+ # compilation errors, if Texd.config.error_format is set to JSON.
109
+ # @raise [Texd::Error] on other Texd related errors.
110
+ # @return [String] the PDF object
111
+ def render(*args)
112
+ doc = Document.compile(*args)
113
+
114
+ client.render doc.to_upload_ios,
115
+ input: doc.main_input_name
116
+ rescue Client::ReferenceError => err
117
+ # retry once with resolved references
118
+ client.render doc.to_upload_ios(missing_refs: err.references),
119
+ input: doc.main_input_name
120
+ end
121
+ end
data/texd.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/texd/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "texd"
7
+ spec.version = Texd::VERSION
8
+ spec.authors = ["Dominik Menke"]
9
+ spec.email = ["dom@digineo.de"]
10
+
11
+ spec.summary = "texd is a Ruby client for the texd web service."
12
+ spec.description = "The texd project provides a network reachable TeX compiler. This gem is a client for that."
13
+ spec.homepage = "https://github.com/digineo/texd-ruby"
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = ">= 2.7.0"
17
+
18
+ spec.metadata["rubygems_mfa_required"] = "true"
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = spec.homepage
21
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/v#{Texd::VERSION}/CHANGELOG.md"
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) {
26
+ `git ls-files -z`.split("\x0").reject do |f|
27
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
28
+ end
29
+ }
30
+
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_dependency "multipart-post", "~> 2.0"
36
+ spec.add_dependency "rails", ">= 6.0", "< 8"
37
+
38
+ spec.add_development_dependency "combustion"
39
+ spec.add_development_dependency "rake", "~> 13.0"
40
+ spec.add_development_dependency "rspec", "~> 3.0"
41
+ spec.add_development_dependency "rspec-rails"
42
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: texd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dominik Menke
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multipart-post
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '8'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '6.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '8'
47
+ - !ruby/object:Gem::Dependency
48
+ name: combustion
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '13.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec-rails
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: The texd project provides a network reachable TeX compiler. This gem
104
+ is a client for that.
105
+ email:
106
+ - dom@digineo.de
107
+ executables: []
108
+ extensions: []
109
+ extra_rdoc_files: []
110
+ files:
111
+ - ".rspec"
112
+ - ".rubocop.yml"
113
+ - CHANGELOG.md
114
+ - Gemfile
115
+ - Gemfile.lock
116
+ - LICENSE
117
+ - Makefile
118
+ - README.md
119
+ - Rakefile
120
+ - gemfiles/rails-6.0
121
+ - gemfiles/rails-6.0.lock
122
+ - gemfiles/rails-6.1
123
+ - gemfiles/rails-6.1.lock
124
+ - gemfiles/rails-7.0
125
+ - gemfiles/rails-7.0.lock
126
+ - lib/texd.rb
127
+ - lib/texd/attachment.rb
128
+ - lib/texd/client.rb
129
+ - lib/texd/config.rb
130
+ - lib/texd/document.rb
131
+ - lib/texd/helpers.rb
132
+ - lib/texd/lookup_context.rb
133
+ - lib/texd/railtie.rb
134
+ - lib/texd/version.rb
135
+ - texd.gemspec
136
+ homepage: https://github.com/digineo/texd-ruby
137
+ licenses:
138
+ - MIT
139
+ metadata:
140
+ rubygems_mfa_required: 'true'
141
+ homepage_uri: https://github.com/digineo/texd-ruby
142
+ source_code_uri: https://github.com/digineo/texd-ruby
143
+ changelog_uri: https://github.com/digineo/texd-ruby/blob/v0.1.0/CHANGELOG.md
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 2.7.0
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubygems_version: 3.1.6
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: texd is a Ruby client for the texd web service.
163
+ test_files: []