texd 0.2.0 → 0.3.0
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 +4 -4
- data/.rubocop.yml +3 -1
- data/Gemfile.lock +1 -1
- data/Makefile +1 -1
- data/README.md +122 -7
- data/gemfiles/rails-6.0.lock +1 -1
- data/gemfiles/rails-6.1.lock +1 -1
- data/gemfiles/rails-7.0.lock +1 -1
- data/lib/texd/attachment.rb +11 -1
- data/lib/texd/cache.rb +103 -0
- data/lib/texd/client.rb +0 -18
- data/lib/texd/config.rb +17 -9
- data/lib/texd/document.rb +8 -8
- data/lib/texd/helpers.rb +3 -2
- data/lib/texd/version.rb +1 -1
- data/lib/texd.rb +9 -4
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f90c7123f60872130f0a2c36a6a6fa44154d1e3956c140f45e07e6815761363
|
|
4
|
+
data.tar.gz: a1c855d5a76517dae7eb2c5a2a9cc9be621236fa59018e62fbeeaa9b31ee0d49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ecc5d22800aea0f4b77e76c0c052106cb80bb47c3c3a478696c712957fbc178ac74c7014d3927ff09bd45c4472a167fc8ebd7bcbd9ff154f12c90f2724df319d
|
|
7
|
+
data.tar.gz: 88dad14c7c7f95fbb53bb12bd9777de8033d8b8aceafe896efabcf8f0c33463ece25b90ef43e2e3108c617586007171c498a969fe7184763d73812cf35ed0cf4
|
data/.rubocop.yml
CHANGED
|
@@ -288,7 +288,9 @@ Style/RedundantAssignment:
|
|
|
288
288
|
Enabled: true
|
|
289
289
|
|
|
290
290
|
Style/RedundantFetchBlock:
|
|
291
|
-
Enabled:
|
|
291
|
+
Enabled: false
|
|
292
|
+
Exclude:
|
|
293
|
+
- spec/lib/texd/cache_spec.rb # not called on Hash
|
|
292
294
|
|
|
293
295
|
Style/RedundantFileExtensionInRequire:
|
|
294
296
|
Enabled: true
|
data/Gemfile.lock
CHANGED
data/Makefile
CHANGED
data/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
texd is a Ruby client for the [texd web service](https://github.com/digineo/texd).
|
|
4
4
|
|
|
5
|
+
It leverages ActionView's template rendering mechanism to compile `.tex`
|
|
6
|
+
templates to PDF documents. The primary use case is to render documents
|
|
7
|
+
in background jobs.
|
|
8
|
+
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
7
11
|
You need to meet the following requirements for this gem to work:
|
|
@@ -34,11 +38,15 @@ end
|
|
|
34
38
|
|
|
35
39
|
```rb
|
|
36
40
|
Texd.configure do |config|
|
|
37
|
-
config.endpoint
|
|
38
|
-
config.
|
|
39
|
-
config.
|
|
40
|
-
config.
|
|
41
|
-
config.
|
|
41
|
+
config.endpoint = ENV.fetch("TEXD_ENDPOINT", "http://localhost:2201/")
|
|
42
|
+
config.open_timeout = ENV.fetch("TEXD_OPEN_TIMEOUT", 60)
|
|
43
|
+
config.read_timeout = ENV.fetch("TEXD_READ_TIMEOUT", 180)
|
|
44
|
+
config.write_timeout = ENV.fetch("TEXD_WRITE_TIMEOUT", 60)
|
|
45
|
+
config.error_format = ENV.fetch("TEXD_ERRORS", "full")
|
|
46
|
+
config.tex_engine = ENV["TEXD_ENGINE"]
|
|
47
|
+
config.tex_image = ENV["TEXD_IMAGE"]
|
|
48
|
+
config.helpers = []
|
|
49
|
+
config.lookup_paths = [] # Rails.root.join("app/tex") is always inserted as first entry
|
|
42
50
|
end
|
|
43
51
|
```
|
|
44
52
|
|
|
@@ -56,8 +64,115 @@ about other installation methods.
|
|
|
56
64
|
|
|
57
65
|
## Usage
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
First, create a few files:
|
|
68
|
+
|
|
69
|
+
<details><summary><code>app/views/layouts/application.tex.erb</code></summary>
|
|
70
|
+
|
|
71
|
+
This is the default layout. Here, you should define a `\documentclass`
|
|
72
|
+
and use `yield`. In this example, we're using ERB (Erubi) to include
|
|
73
|
+
dynamic content into a `.tex` file.
|
|
74
|
+
|
|
75
|
+
```erb
|
|
76
|
+
\documentclass{article}
|
|
77
|
+
\usepackage{graphicx}
|
|
78
|
+
<%= content_for :preamble %>
|
|
79
|
+
|
|
80
|
+
\begin{document}
|
|
81
|
+
<%= yield %>
|
|
82
|
+
\end{document}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
</details>
|
|
86
|
+
<details><summary><code>app/views/document/doc.tex.erb</code></summary>
|
|
87
|
+
|
|
88
|
+
In `document/doc.tex`, we're specifying some stuff for the preamble,
|
|
89
|
+
render a partial, and add content for the document:
|
|
90
|
+
|
|
91
|
+
```erb
|
|
92
|
+
<% content_for :preamble do %>
|
|
93
|
+
\usepackage{blindtext}
|
|
94
|
+
|
|
95
|
+
\title{Demo document}
|
|
96
|
+
\date{\today}
|
|
97
|
+
\author{<%= user.full_name %>}
|
|
98
|
+
<% end %>
|
|
99
|
+
|
|
100
|
+
<%= render partial: "document/title_page" %>
|
|
101
|
+
|
|
102
|
+
\Blinddocument
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
OK, that wasn't true. We're leveraging the `blindtext` package to add
|
|
106
|
+
content for us :)
|
|
107
|
+
|
|
108
|
+
The `user` variable is passed as local method to `Texd.render` (see below).
|
|
109
|
+
|
|
110
|
+
</details>
|
|
111
|
+
<details><summary><code>app/views/document/_title_page.tex.erb</code></summary>
|
|
112
|
+
|
|
113
|
+
This partial embeds an image and creates the title page.
|
|
114
|
+
|
|
115
|
+
```erb
|
|
116
|
+
\begin{center}
|
|
117
|
+
\includegraphics[width=0.5\linewidth]{<%= texd_attach "logo.png" %>}
|
|
118
|
+
\end{center}
|
|
119
|
+
|
|
120
|
+
\titlepage
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
With `texd_attach`, we're referencing a file *outside* ActionView's lookup
|
|
124
|
+
paths, but in Texd's lookup paths (`RAILS_ROOT/app/tex` by default).
|
|
125
|
+
|
|
126
|
+
You can use this directory to store and deploy static assets.
|
|
127
|
+
|
|
128
|
+
Please be aware, that attachments will be renamed (`att00123.png`)
|
|
129
|
+
in the POST body, and `att00123.png` will be returned from `texd_attach`.
|
|
130
|
+
You can skip the renaming, if you want/need to:
|
|
131
|
+
|
|
132
|
+
```erb
|
|
133
|
+
% attaches RAILS_ROOT/app/tex/logo.png, and inserts "logo.png":
|
|
134
|
+
<%= texd_attach "logo.png", rename: false %>
|
|
135
|
+
|
|
136
|
+
% attaches RAILS_ROOT/app/tex/logo.png, and inserts "assets/logo.png":
|
|
137
|
+
<%= texd_attach "logo.png", rename: "assets/logo.png" %>
|
|
138
|
+
|
|
139
|
+
% attaches RAILS_ROOT/app/tex/common.tex, and inserts "att00042" (or similar):
|
|
140
|
+
<%= texd_attach "common.tex", without_extension: true %>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
</details>
|
|
144
|
+
<details><summary><code>app/tex/logo.png</code></summary>
|
|
145
|
+
|
|
146
|
+
*(Imagine your logo here.)*
|
|
147
|
+
|
|
148
|
+
</details>
|
|
149
|
+
|
|
150
|
+
With those files in place, you can create a PDF document:
|
|
151
|
+
|
|
152
|
+
```rb
|
|
153
|
+
begin
|
|
154
|
+
blob = Texd.render(template: "documents/doc", locals: {
|
|
155
|
+
user: User.find(1)
|
|
156
|
+
})
|
|
157
|
+
Rails.root.join("tmp/doc.pdf").open("wb") { |f|
|
|
158
|
+
f.write blob
|
|
159
|
+
}
|
|
160
|
+
rescue Texd::Client::QueueError => err
|
|
161
|
+
# texd server is busy, please retry in a moment
|
|
162
|
+
rescue Texd::Client::InputError => err
|
|
163
|
+
# file input processing failed, maybe some file names were invalid
|
|
164
|
+
rescue Texd::Client::CompilationError => err
|
|
165
|
+
# compilation failed
|
|
166
|
+
if err.logs
|
|
167
|
+
# TeX compiler logs, only available if Texd.config.error_format
|
|
168
|
+
# is "full" or "condensed"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
All errors inherit from `Texd::Client::RenderError` and should have
|
|
174
|
+
a `details` attribute (a Hash) containing the actual error returned
|
|
175
|
+
from the server.
|
|
61
176
|
|
|
62
177
|
## Development
|
|
63
178
|
|
data/gemfiles/rails-6.0.lock
CHANGED
data/gemfiles/rails-6.1.lock
CHANGED
data/gemfiles/rails-7.0.lock
CHANGED
data/lib/texd/attachment.rb
CHANGED
|
@@ -202,9 +202,19 @@ module Texd
|
|
|
202
202
|
}
|
|
203
203
|
end
|
|
204
204
|
|
|
205
|
+
def self.cache
|
|
206
|
+
@cache ||= Cache.new(Texd.config.ref_cache_size)
|
|
207
|
+
end
|
|
208
|
+
|
|
205
209
|
# @api private
|
|
206
210
|
def checksum
|
|
207
|
-
@checksum ||=
|
|
211
|
+
@checksum ||= create_checksum
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# @api private
|
|
215
|
+
def create_checksum
|
|
216
|
+
key = [::File.stat(absolute_path).mtime, absolute_path]
|
|
217
|
+
self.class.cache.fetch(key) do
|
|
208
218
|
digest = Digest::SHA256.file(absolute_path).digest
|
|
209
219
|
encoded = Base64.urlsafe_encode64(digest)
|
|
210
220
|
"sha256:#{encoded}"
|
data/lib/texd/cache.rb
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Texd
|
|
4
|
+
# Cache is a simple LRU cache with a double linked list.
|
|
5
|
+
# If the cache is full the last element from the list will be removed.
|
|
6
|
+
class Cache
|
|
7
|
+
class LinkedList
|
|
8
|
+
attr_reader :head
|
|
9
|
+
|
|
10
|
+
def add(node)
|
|
11
|
+
if @head
|
|
12
|
+
node.next = @head
|
|
13
|
+
node.prev = @head.prev
|
|
14
|
+
@head.prev.next = node
|
|
15
|
+
@head.prev = node
|
|
16
|
+
else
|
|
17
|
+
node.next = node
|
|
18
|
+
node.prev = node
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
@head = node
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def remove(node)
|
|
25
|
+
if node.next == node
|
|
26
|
+
# remove last element, should never happen
|
|
27
|
+
@head = nil
|
|
28
|
+
else
|
|
29
|
+
node.prev.next = node.next
|
|
30
|
+
node.next.prev = node.prev
|
|
31
|
+
@head = node.next if node == @head
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class Node
|
|
37
|
+
attr_reader :key
|
|
38
|
+
attr_accessor :value, :prev, :next
|
|
39
|
+
|
|
40
|
+
def initialize(key)
|
|
41
|
+
@key = key
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
attr_reader :list, :count, :capacity
|
|
46
|
+
delegate :keys, to: :@hash
|
|
47
|
+
|
|
48
|
+
def initialize(capacity)
|
|
49
|
+
@list = LinkedList.new
|
|
50
|
+
@hash = {}
|
|
51
|
+
@mtx = Mutex.new
|
|
52
|
+
@count = 0
|
|
53
|
+
@capacity = capacity
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def fetch(key)
|
|
57
|
+
read(key) || write(key, yield)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def read(key)
|
|
61
|
+
@mtx.synchronize do
|
|
62
|
+
node = @hash[key]
|
|
63
|
+
return unless node
|
|
64
|
+
|
|
65
|
+
list.remove(node)
|
|
66
|
+
list.add(node)
|
|
67
|
+
node.value
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def write(key, value)
|
|
72
|
+
@mtx.synchronize do
|
|
73
|
+
node = @hash[key]
|
|
74
|
+
|
|
75
|
+
if node
|
|
76
|
+
list.remove(node)
|
|
77
|
+
else
|
|
78
|
+
node = add_node(key)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
list.add(node)
|
|
82
|
+
node.value = value
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def add_node(key)
|
|
89
|
+
node = Node.new(key)
|
|
90
|
+
|
|
91
|
+
if count >= capacity
|
|
92
|
+
last = list.head.prev
|
|
93
|
+
@hash.delete(last.key)
|
|
94
|
+
list.remove(last)
|
|
95
|
+
else
|
|
96
|
+
@count += 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@hash[key] = node
|
|
100
|
+
node
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/lib/texd/client.rb
CHANGED
|
@@ -60,24 +60,6 @@ module Texd
|
|
|
60
60
|
"reference" => ReferenceError,
|
|
61
61
|
}.freeze
|
|
62
62
|
|
|
63
|
-
class ResponseError < Error
|
|
64
|
-
attr_reader :body, :content_type
|
|
65
|
-
|
|
66
|
-
def initialize(code, content_type, body)
|
|
67
|
-
@body = body
|
|
68
|
-
@content_type = content_type
|
|
69
|
-
|
|
70
|
-
if json?
|
|
71
|
-
super format("%s error: %s", body.delete("category"), body.delete("error"))
|
|
72
|
-
elsif log?
|
|
73
|
-
tex_errors = body.lines.select { |l| l.start_with?("!") }.map(&:strip)
|
|
74
|
-
super "Compilation failed:\n\t#{tex_errors.join('\n\t')}"
|
|
75
|
-
else
|
|
76
|
-
super "Server responded with status #{code} (#{content_type})"
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
63
|
USER_AGENT = "texd-ruby/#{VERSION} Ruby/#{RUBY_VERSION}"
|
|
82
64
|
|
|
83
65
|
attr_reader :config
|
data/lib/texd/config.rb
CHANGED
|
@@ -22,15 +22,16 @@ module Texd
|
|
|
22
22
|
|
|
23
23
|
# This is the default configuration. It is applied in the constructor.
|
|
24
24
|
DEFAULT_CONFIGURATION = {
|
|
25
|
-
endpoint:
|
|
26
|
-
open_timeout:
|
|
27
|
-
read_timeout:
|
|
28
|
-
write_timeout:
|
|
29
|
-
error_format:
|
|
30
|
-
tex_engine:
|
|
31
|
-
tex_image:
|
|
32
|
-
helpers:
|
|
33
|
-
lookup_paths:
|
|
25
|
+
endpoint: ENV.fetch("TEXD_ENDPOINT", "http://localhost:2201/"),
|
|
26
|
+
open_timeout: ENV.fetch("TEXD_OPEN_TIMEOUT", 60),
|
|
27
|
+
read_timeout: ENV.fetch("TEXD_READ_TIMEOUT", 180),
|
|
28
|
+
write_timeout: ENV.fetch("TEXD_WRITE_TIMEOUT", 60),
|
|
29
|
+
error_format: ENV.fetch("TEXD_ERRORS", "full"),
|
|
30
|
+
tex_engine: ENV["TEXD_ENGINE"],
|
|
31
|
+
tex_image: ENV["TEXD_IMAGE"],
|
|
32
|
+
helpers: Set.new,
|
|
33
|
+
lookup_paths: [], # Rails.root.join("app/tex") is inserted in railtie.rb
|
|
34
|
+
ref_cache_size: 128,
|
|
34
35
|
}.freeze
|
|
35
36
|
|
|
36
37
|
# Supported endpoint protocols.
|
|
@@ -107,6 +108,13 @@ module Texd
|
|
|
107
108
|
# A Texd::LookupContext is constructed from this set.
|
|
108
109
|
attr_accessor :lookup_paths
|
|
109
110
|
|
|
111
|
+
# Cache size for file hashes computed by Texd::Attachment::Reference.
|
|
112
|
+
# Cannot be changed after the first document (using the `texd_reference`
|
|
113
|
+
# helper) was renderered.
|
|
114
|
+
#
|
|
115
|
+
# By default, the cache keeps hashes of the last 128 reference files.
|
|
116
|
+
attr_accessor :ref_cache_size
|
|
117
|
+
|
|
110
118
|
def initialize(**options)
|
|
111
119
|
DEFAULT_CONFIGURATION.each do |key, default_value|
|
|
112
120
|
public_send "#{key}=", options.fetch(key, default_value.dup)
|
data/lib/texd/document.rb
CHANGED
|
@@ -6,8 +6,8 @@ module Texd
|
|
|
6
6
|
attr_reader :attachments
|
|
7
7
|
|
|
8
8
|
# Shorthand for `new.compile`.
|
|
9
|
-
def self.compile(
|
|
10
|
-
new.compile(
|
|
9
|
+
def self.compile(template:, locals: {})
|
|
10
|
+
new.compile(template: template, locals: locals)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def initialize
|
|
@@ -18,16 +18,16 @@ module Texd
|
|
|
18
18
|
# Compile converts templates into TeX sources and collects file
|
|
19
19
|
# references (created with `texd_attach` and `texd_reference` helpers).
|
|
20
20
|
#
|
|
21
|
-
# @param
|
|
22
|
-
#
|
|
21
|
+
# @param [String] template name of template file in ActionView's lookup
|
|
22
|
+
# context.
|
|
23
|
+
# @param [Hash, nil] locals will be made available as getter methods in
|
|
24
|
+
# the template.
|
|
23
25
|
# @return [Compilation]
|
|
24
|
-
def compile(
|
|
25
|
-
locals = args.last.delete(:locals) if args.last.is_a?(Hash)
|
|
26
|
+
def compile(template:, locals: {})
|
|
26
27
|
helper_mod = ::Texd.helpers(attachments, locals)
|
|
27
|
-
|
|
28
28
|
tex_source = Class.new(ApplicationController) {
|
|
29
29
|
helper helper_mod
|
|
30
|
-
}.render(
|
|
30
|
+
}.render(template: template, format: :tex)
|
|
31
31
|
|
|
32
32
|
main = attachments.main_input(tex_source)
|
|
33
33
|
Compilation.new(main.name, attachments)
|
data/lib/texd/helpers.rb
CHANGED
|
@@ -28,8 +28,9 @@ module Texd
|
|
|
28
28
|
|
|
29
29
|
# Escapes the given text, making it safe for use in TeX documents.
|
|
30
30
|
def escape(text, line_break = "\\\\\\", typographic: true)
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
return "" if text.blank?
|
|
32
|
+
|
|
33
|
+
text.to_s.dup.tap do |str|
|
|
33
34
|
str.gsub!(ESCAPE_RE) do |m|
|
|
34
35
|
if Regexp.last_match(1)
|
|
35
36
|
"\\#{m}"
|
data/lib/texd/version.rb
CHANGED
data/lib/texd.rb
CHANGED
|
@@ -12,6 +12,7 @@ require "rails"
|
|
|
12
12
|
require_relative "texd/version"
|
|
13
13
|
require_relative "texd/config"
|
|
14
14
|
require_relative "texd/helpers"
|
|
15
|
+
require_relative "texd/cache"
|
|
15
16
|
require_relative "texd/client"
|
|
16
17
|
require_relative "texd/attachment"
|
|
17
18
|
require_relative "texd/document"
|
|
@@ -94,8 +95,8 @@ module Texd
|
|
|
94
95
|
# Render compiles a template, uploads the files to the texd instance,
|
|
95
96
|
# and returns the PDF.
|
|
96
97
|
#
|
|
97
|
-
# The arguments are directly forwarded to
|
|
98
|
-
#
|
|
98
|
+
# The arguments are directly forwarded to Texd::Document (and end up in
|
|
99
|
+
# ActionView::Renderer#render).
|
|
99
100
|
#
|
|
100
101
|
# @example Render app/views/document/document.tex.erb
|
|
101
102
|
# begin
|
|
@@ -114,12 +115,16 @@ module Texd
|
|
|
114
115
|
# # something went wrong before we even got to sent data to the server
|
|
115
116
|
# end
|
|
116
117
|
#
|
|
118
|
+
# @param [String] template name of template file in ActionView's lookup
|
|
119
|
+
# context.
|
|
120
|
+
# @param [Hash, nil] locals will be made available as getter methods in
|
|
121
|
+
# the template.
|
|
117
122
|
# @raise [Texd::Client::ResponseError] on input and queue errors. Also on
|
|
118
123
|
# compilation errors, if Texd.config.error_format is set to JSON.
|
|
119
124
|
# @raise [Texd::Error] on other Texd related errors.
|
|
120
125
|
# @return [String] the PDF object
|
|
121
|
-
def render(
|
|
122
|
-
doc = Document.compile(
|
|
126
|
+
def render(template:, locals: {})
|
|
127
|
+
doc = Document.compile(template: template, locals: locals)
|
|
123
128
|
|
|
124
129
|
client.render doc.to_upload_ios,
|
|
125
130
|
input: doc.main_input_name
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: texd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dominik Menke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-03-
|
|
11
|
+
date: 2022-03-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: multipart-post
|
|
@@ -125,6 +125,7 @@ files:
|
|
|
125
125
|
- gemfiles/rails-7.0.lock
|
|
126
126
|
- lib/texd.rb
|
|
127
127
|
- lib/texd/attachment.rb
|
|
128
|
+
- lib/texd/cache.rb
|
|
128
129
|
- lib/texd/client.rb
|
|
129
130
|
- lib/texd/config.rb
|
|
130
131
|
- lib/texd/document.rb
|
|
@@ -140,7 +141,7 @@ metadata:
|
|
|
140
141
|
rubygems_mfa_required: 'true'
|
|
141
142
|
homepage_uri: https://github.com/digineo/texd-ruby
|
|
142
143
|
source_code_uri: https://github.com/digineo/texd-ruby
|
|
143
|
-
changelog_uri: https://github.com/digineo/texd-ruby/blob/v0.
|
|
144
|
+
changelog_uri: https://github.com/digineo/texd-ruby/blob/v0.3.0/CHANGELOG.md
|
|
144
145
|
post_install_message:
|
|
145
146
|
rdoc_options: []
|
|
146
147
|
require_paths:
|