jektex 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 290626aa91c28cc4961baf40ec00dde81928da68e0a923ee84999027e7f3c9b0
4
- data.tar.gz: 4ec8d501a4ab6f1b068ec01bb21a7d84bd844a5bca7d105bdc0c9c6e2652eec8
3
+ metadata.gz: 476a24b916af7e71a30a60cd2476063fa2d627959060179104e8a41871c5d4ab
4
+ data.tar.gz: 93243e4af6fea3e355f0cc4401e990cdb107f77c717b7e63d4902a172b56a7d0
5
5
  SHA512:
6
- metadata.gz: ccdddba235b4d0462ccb5e4d2ee4cbf5b97e9964c10fd0395e814635281563c6363a381422feeefdd9eb6a895877a47aba6fae95de36c98a6f710785ed18ba51
7
- data.tar.gz: 4d0a8dad642c30c5f26ca5903d715e3728d918bb17fe1eaeaf3ce8ad814a25e9c50d0df15533522275665978971ee269164a2969cf73db9823b71b9ea29a7217
6
+ metadata.gz: d0ae577416fec788441659e670f4e85c0b34c091c81f666ab1cd62f5a39b3500548efb4238f53d77f1ea0dd30bd3571f001aa418311dcf6786a70afbbd3d0e8c
7
+ data.tar.gz: a7feff881708ffb27bffb76c2f00146c0bb4f7f4a90fe341ea88f121f1442ace72294596112f8c139e9a5628f4f14f0022e2f18dabe5a7e15e56e985d31c9d73
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/jektex.svg)](https://rubygems.org/gems/jektex)
2
+
1
3
  # Jektex
2
4
  Jekyll plugin for blazing fast server side cached LaTeX rendering with support of macros.
3
5
  Enjoy comfort of latex and markdown without cluttering your site with bloated javascript.
@@ -14,6 +16,7 @@ Enjoy comfort of latex and markdown without cluttering your site with bloated ja
14
16
  - Marks invalid syntax in document
15
17
  - Prints location of invalid expression during rendering
16
18
  - Highly configurable but still having sensible defaults
19
+ - Makes sure that cache does not contain expression rendered with outdated configuration
17
20
 
18
21
  ## Usage
19
22
 
@@ -98,8 +101,7 @@ jektex:
98
101
  - ["\\C", "\\mathbb{C}"]
99
102
  ```
100
103
  And yes you have to escape backlash(`\`) with another backlash. This is caused by
101
- [yaml definition](https://yaml.org/). YOU SHOULD ALWAYS delete jektex cache after changing
102
- definition of a macro for change to take effect.
104
+ [yaml definition](https://yaml.org/).
103
105
 
104
106
  **Complete examples**
105
107
  Recommended config:
@@ -146,7 +148,7 @@ and do not forget to add `katex.min.css` to you html head:
146
148
  ```html
147
149
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css" integrity="sha384-MlJdn/WNKDGXveldHDdyRP1R4CTHr3FeuDNfhsLPYrq2t0UBkUdK2jyTnXPEK1NQ" crossorigin="anonymous">
148
150
  ```
149
- It is much better practice to download **css** file and load it as an asset from your server directly.
151
+ It is much better practice to download [**css** file](https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css) and load it as an asset from your server directly.
150
152
  You can find more information on [KaTeX's website](https://katex.org/docs/browser.html).
151
153
 
152
154
  ## Contributions and bug reports
data/lib/jektex/jektex.rb CHANGED
@@ -9,91 +9,97 @@ CACHE_FILE = "jektex-cache.marshal"
9
9
  KATEX = ExecJS.compile(open(PATH_TO_JS).read)
10
10
  PARSE_ERROR_PLACEHOLDER = "<b style='color: red;'>PARSE ERROR</b>"
11
11
  FRONT_MATTER_TAG = "jektex"
12
+ INDENT = " " * 13
13
+
12
14
  $global_macros = Hash.new
15
+ $updated_global_macros = Array.new
16
+
13
17
  $count_newly_generated_expressions = 0
18
+
14
19
  $path_to_cache = File.join(DEFAULT_CACHE_DIR, CACHE_FILE)
15
20
  $cache = nil
16
21
  $disable_disk_cache = false
22
+
17
23
  $ignored = Array.new
18
24
 
25
+ def get_list_of_updated_global_macros(current_macros, cached_global_macros)
26
+ return Array.new unless cached_global_macros || current_macros
27
+ return current_macros.keys unless cached_global_macros
28
+ return cached_global_macros.keys unless current_macros
29
+
30
+ macro_set = Set.new(cached_global_macros.keys + current_macros.keys)
31
+ macro_set.delete_if { |m| cached_global_macros[m] == current_macros[m] }
32
+ return macro_set.to_a
33
+ end
34
+
19
35
  def is_ignored?(page)
20
- for patern in $ignored
21
- if File.fnmatch?(patern, page.relative_path, File::FNM_DOTMATCH) then
22
- return true
23
- end
24
- end
25
- return false
36
+ return true if page.data[FRONT_MATTER_TAG] == "false"
37
+ return $ignored.any? { |patern| File.fnmatch?(patern, page.relative_path, File::FNM_DOTMATCH) }
38
+ end
39
+
40
+ def contains_updated_global_macro?(expression)
41
+ return $updated_global_macros.any? { |m| expression[m] }
42
+ end
43
+
44
+ def print_stats
45
+ print "#{INDENT}LaTeX: " \
46
+ "#{$count_newly_generated_expressions} expressions rendered " \
47
+ "(#{$cache.size} already cached)".ljust(72) + "\r"
48
+ $stdout.flush
26
49
  end
27
50
 
28
51
  def render(page)
29
52
  # check if document is not set to be ignored
30
- if page.data == nil or is_ignored?(page) or page.data[FRONT_MATTER_TAG] == "false" then
31
- return page.output
32
- end
33
-
53
+ return page.output if !page.data || is_ignored?(page)
34
54
  # convert HTML entities back to characters
35
55
  post = HTMLEntities.new.decode(page.output.to_s)
36
56
  # render inline expressions
37
- post = post.gsub(/(\\\()((.|\n)*?)(?<!\\)\\\)/) { |m| escape_method($1, $2, page.path) }
38
- # render display expressions
39
- post = post.gsub(/(\\\[)((.|\n)*?)(?<!\\)\\\]/) { |m| escape_method($1, $2, page.path) }
57
+ post = post.gsub(/(\\\()((.|\n)*?)(?<!\\)\\\)/) { |m| escape_method($1, $2, page.relative_path) }
58
+ # render display mode expressions
59
+ post = post.gsub(/(\\\[)((.|\n)*?)(?<!\\)\\\]/) { |m| escape_method($1, $2, page.relative_path) }
40
60
  return post
41
61
  end
42
62
 
43
- def escape_method( type, string, doc_path )
44
- @display = false
45
-
46
- # detect if expression is display view
47
- case type.downcase
48
- when /\(/
49
- @display = false
50
- else /\[/
51
- @display = true
52
- end
63
+ def escape_method( type, expression, doc_path )
64
+ # detect if expression is in display mode
65
+ is_in_display_mode? = type.downcase =~ /\[/
53
66
 
54
67
  # generate a hash from the math expression
55
- @expression_hash = Digest::SHA2.hexdigest(string) + @display.to_s
68
+ expression_hash = Digest::SHA2.hexdigest(string) + is_in_display_mode?.to_s
56
69
 
57
70
  # use it if it exists
58
- if($cache.has_key?(@expression_hash))
71
+ if($cache.has_key?(expression_hash) && !contains_updated_global_macro?(string))
72
+ # check if expressin conains updated macro
59
73
  $count_newly_generated_expressions += 1
60
74
  print_stats
61
- return $cache[@expression_hash]
75
+ return $cache[expression_hash]
62
76
 
63
77
  # else generate one and store it
64
78
  else
65
79
  # create the cache directory, if it doesn't exist
66
80
  begin
67
81
  # render using ExecJS
68
- @result = KATEX.call("katex.renderToString", string,
69
- {displayMode: @display, macros: $global_macros})
82
+ result = KATEX.call("katex.renderToString", expression,
83
+ {is_in_display_mode?Mode: is_in_display_mode?, macros: $global_macros})
70
84
  rescue SystemExit, Interrupt
71
85
  # save cache to disk
72
86
  File.open($path_to_cache, "w"){|to_file| Marshal.dump($cache, to_file)}
73
87
  # this stops jekyll being immune to interrupts and kill command
74
88
  raise
75
- rescue Exception => e
89
+ rescue ExecJS::ProgramError => pe
76
90
  # catch parse error
77
- puts "\e[31m " + e.message.gsub("ParseError: ", "") + "\n\t" + doc_path + "\e[0m"
91
+ puts "\e[31m " + pe.message.gsub("ParseError: ", "") + "\n\t" + doc_path + "\e[0m"
78
92
  return PARSE_ERROR_PLACEHOLDER
79
93
  end
80
94
  # save to cache
81
- $cache[@expression_hash] = @result
95
+ $cache[expression_hash] = @result
82
96
  # update count of newly generated expressions
83
97
  $count_newly_generated_expressions += 1
84
98
  print_stats
85
- return @result
99
+ return result
86
100
  end
87
101
  end
88
102
 
89
- def print_stats
90
- print " LaTeX: " +
91
- ($count_newly_generated_expressions).to_s +
92
- " expressions rendered (" + $cache.size.to_s +
93
- " already cached) \r"
94
- $stdout.flush
95
- end
96
-
97
103
  Jekyll::Hooks.register :pages, :post_render do |page|
98
104
  page.output = render(page)
99
105
  end
@@ -103,50 +109,42 @@ Jekyll::Hooks.register :documents, :post_render do |doc|
103
109
  end
104
110
 
105
111
  Jekyll::Hooks.register :site, :after_init do |site|
106
- if site.config["jektex"] == nil then
107
- # if no config is defined make empty one
108
- config = Hash.new
112
+ # load jektex config from config file and if no config is defined make empty one
113
+ config = site.config["jektex"] || Hash.new
114
+
115
+ # check if there is defined custom cache location in config
116
+ $path_to_cache = File.join(config["cache_dir"].to_s, CACHE_FILE) if config.has_key?("cache_dir")
117
+
118
+ # load content of cache file if it exists
119
+ if File.exist?($path_to_cache)
120
+ $cache = File.open($path_to_cache, "r"){ |from_file| Marshal.load(from_file)}
109
121
  else
110
- # load jektex config from config file
111
- config = site.config["jektex"]
122
+ $cache = Hash.new
112
123
  end
124
+
125
+ # check if cache is disable in config
126
+ $disable_disk_cache = site.config["disable_disk_cache"] if site.config.has_key?("disable_disk_cache")
127
+
113
128
  # load macros
114
- if config["macros"] != nil then
129
+ if config.has_key?("macros")
115
130
  for macro_definition in config["macros"]
116
131
  $global_macros[macro_definition[0]] = macro_definition[1]
117
132
  end
118
133
  end
119
134
 
135
+ # make list of updated macros
136
+ $updated_global_macros = get_list_of_updated_global_macros($global_macros, $cache["cached_global_macros"])
120
137
  # print macro information
121
- if $global_macros.size == 0 then
122
- puts " LaTeX: no macros loaded"
138
+ if $global_macros.empty?
139
+ puts "#{INDENT}LaTeX: no macros loaded"
123
140
  else
124
- puts " LaTeX: " + $global_macros.size.to_s + " macro" +
125
- ($global_macros.size == 1 ? "" : "s") + " loaded"
126
- end
127
-
128
- # check if there is defined custom cache location in config
129
- if config["cache_dir"] != nil then
130
- $path_to_cache = File.join(config["cache_dir"].to_s, CACHE_FILE)
141
+ puts "#{INDENT}LaTeX: #{$global_macros.size} macro" +
142
+ ($global_macros.size == 1 ? "" : "s") + " loaded" +
143
+ ($updated_global_macros.empty? ? "" : " (#{$updated_global_macros.size} updated)")
131
144
  end
132
145
 
133
146
  # load list of ignored files
134
- if config["ignore"] != nil then
135
- $ignored = config["ignore"]
136
- end
137
-
138
- # load content of cache file if it exists
139
- if(File.exist?($path_to_cache)) then
140
- $cache = File.open($path_to_cache, "r"){|from_file| Marshal.load(from_file)}
141
- else
142
- $cache = Hash.new
143
- end
144
-
145
- # check if cache is disable in config
146
- if site.config["disable_disk_cache"] != nil then
147
- $disable_disk_cache = site.config["disable_disk_cache"]
148
- end
149
-
147
+ $ignored = config["ignore"] if config.has_key?("ignore")
150
148
  end
151
149
 
152
150
  Jekyll::Hooks.register :site, :after_reset do
@@ -158,9 +156,13 @@ Jekyll::Hooks.register :site, :post_write do
158
156
  # print new line to prevent overwriting previous output
159
157
  print "\n"
160
158
  # check if caching is enabled
161
- if $disable_disk_cache == false
159
+ if !$disable_disk_cache
160
+ # save global macros to cache
161
+ $cache["cached_global_macros"] = $global_macros
162
+ # create cache path
163
+ Pathname.new($path_to_cache).dirname.mkpath
162
164
  # save cache to disk
163
- Dir.mkdir(File.dirname($path_to_cache)) unless File.exists?(File.dirname($path_to_cache))
164
165
  File.open($path_to_cache, "w"){|to_file| Marshal.dump($cache, to_file)}
165
166
  end
166
167
  end
168
+
@@ -1,3 +1,3 @@
1
1
  module Jektex
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jektex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Černý
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-22 00:00:00.000000000 Z
11
+ date: 2022-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs
@@ -108,7 +108,7 @@ licenses:
108
108
  - GPL-3.0-or-later
109
109
  metadata:
110
110
  bug_tracker_uri: https://github.com/yagarea/jektex/issues
111
- documentation_uri: https://github.com/yagarea/jektex
111
+ documentation_uri: https://github.com/yagarea/jektex/blob/master/README.md
112
112
  homepage_uri: https://github.com/yagarea/jektex
113
113
  source_code_uri: https://github.com/yagarea/jektex
114
114
  changelog_uri: https://github.com/yagarea/jektex/blob/master/changelog.md