Module: Polytexnic::Utils
Instance Method Summary collapse
-
#add_font_info(string) ⇒ Object
Adds some verbatim font info (including size).
-
#cache_hrefs(doc, latex = false) ⇒ Object
Caches URLs for href commands.
-
#debug? ⇒ Boolean
Returns true if we are debugging, false otherwise.
-
#digest(string, options = {}) ⇒ Object
Returns a salted hash digest of the string.
-
#escape_backslashes(string) ⇒ Object
Escapes backslashes.
-
#framed(code) ⇒ Object
Puts a frame around code.
-
#highlight(key, content, language, formatter) ⇒ Object
Highlights a code sample.
-
#highlight_source_code(document) ⇒ Object
Highlights source code.
-
#horrible_backslash_kludge(string) ⇒ Object
Does something horrible with backslashes.
-
#pipeline_digest(element) ⇒ Object
Returns a digest for passing things through the pipeline.
-
#profiling? ⇒ Boolean
Returns true if we are profiling the code, false otherwise.
- #set_test_mode! ⇒ Object
- #test? ⇒ Boolean
-
#tralics ⇒ Object
Returns the executable for the Tralics LaTeX-to-XML converter.
-
#tralics_commands ⇒ Object
Returns some commands for Tralics.
-
#underscore_digest ⇒ Object
Returns a digest for use in labels.
-
#xmlelement(name, skip = false) ⇒ Object
Returns a Tralics pseudo-LaTeX XML element.
Instance Method Details
#add_font_info(string) ⇒ Object
Adds some verbatim font info (including size). We prepend rather than replace the styles because the Pygments output includes a required override of the default commandchars. Since the substitution is only important in the context of a PDF book, it only gets made if there’s a style in ‘softcover.sty’ in the current directory
128 129 130 131 132 133 134 135 136 |
# File 'lib/polytexnic/utils.rb', line 128 def add_font_info(string) if File.exist?('softcover.sty') regex = '{code}{Verbatim}{(.*)}' styles = File.read('softcover.sty').scan(/#{regex}/).flatten.first string.gsub!("\\begin{Verbatim}[", "\\begin{Verbatim}[#{styles},") end string end |
#cache_hrefs(doc, latex = false) ⇒ Object
Caches URLs for href commands.
41 42 43 44 45 46 47 48 49 |
# File 'lib/polytexnic/utils.rb', line 41 def cache_hrefs(doc, latex=false) doc.tap do |text| text.gsub!(/\\href{(.*?)}/) do key = digest($1) literal_cache[key] = $1 "\\href{#{key}}" end end end |
#debug? ⇒ Boolean
Returns true if we are debugging, false otherwise. Manually change to ‘true` on an as-needed basis.
157 158 159 |
# File 'lib/polytexnic/utils.rb', line 157 def debug? false end |
#digest(string, options = {}) ⇒ Object
Returns a salted hash digest of the string.
14 15 16 17 |
# File 'lib/polytexnic/utils.rb', line 14 def digest(string, = {}) salt = [:salt] || SecureRandom.base64 Digest::SHA1.hexdigest("#{salt}--#{string}") end |
#escape_backslashes(string) ⇒ Object
Escapes backslashes. Interpolated backslashes need extra escaping. We only escape ‘\’ by itself, i.e., a backslash followed by spaces or the end of line.
36 37 38 |
# File 'lib/polytexnic/utils.rb', line 36 def escape_backslashes(string) string.gsub(/\\(\s+|$)/) { '\\\\' + $1.to_s } end |
#framed(code) ⇒ Object
Puts a frame around code.
111 112 113 |
# File 'lib/polytexnic/utils.rb', line 111 def framed(code) "\\begin{framed_shaded}\n#{code}\n\\end{framed_shaded}" end |
#highlight(key, content, language, formatter) ⇒ Object
Highlights a code sample.
116 117 118 119 120 |
# File 'lib/polytexnic/utils.rb', line 116 def highlight(key, content, language, formatter) highlight_cache[key] ||= Pygments.highlight(content, lexer: language, formatter: formatter) end |
#highlight_source_code(document) ⇒ Object
Highlights source code.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/polytexnic/utils.rb', line 87 def highlight_source_code(document) if document.is_a?(String) # LaTeX substitutions = {} document.tap do code_cache.each do |key, (content, language, in_codelisting)| code = highlight(key, content, language, 'latex') output = code.split("\n") horrible_backslash_kludge(add_font_info(output.first)) code = output.join("\n") substitutions[key] = in_codelisting ? code : framed(code) end document.gsub!(Regexp.union(substitutions.keys), substitutions) end else # HTML document.css('div.code').each do |code_block| key = code_block.content next unless (value = code_cache[key]) content, language = value code_block.inner_html = highlight(key, content, language, 'html') end end end |
#horrible_backslash_kludge(string) ⇒ Object
Does something horrible with backslashes. OK, so the deal is that code highlighted for LaTeX contains the line beginVerbatim Oh crap, there are backslashes in there. This means we have no chance of getting things to work after interpolating, gsubbing, and so on, because in Ruby ‘\foo’ is the same as ‘\\foo’, ‘}’ is ‘}’, etc. I thought I escaped (heh) this problem with the ‘escape_backslashes` method, but here the problem is extremely specific. In particular, \{} is really \ and { and }, but Ruby doensn’t know WTF to do with it, and thinks that it’s “\{}”, which is the same as ‘{}’. The solution is to replace ‘\\’ with some number of backslashes. How many? I literally had to just keep adding backslashes until the output was correct when running ‘poly build:pdf`.
151 152 153 |
# File 'lib/polytexnic/utils.rb', line 151 def horrible_backslash_kludge(string) string.gsub!(/commandchars=\\\\/, 'commandchars=\\\\\\\\') end |
#pipeline_digest(element) ⇒ Object
Returns a digest for passing things through the pipeline.
20 21 22 23 |
# File 'lib/polytexnic/utils.rb', line 20 def pipeline_digest(element) value = digest("#{Time.now.to_s}::#{element}") @literal_cache[element.to_s] ||= value end |
#profiling? ⇒ Boolean
Returns true if we are profiling the code, false otherwise. Manually change to ‘true` on an as-needed basis.
163 164 165 166 |
# File 'lib/polytexnic/utils.rb', line 163 def profiling? return false if test? false end |
#set_test_mode! ⇒ Object
168 169 170 |
# File 'lib/polytexnic/utils.rb', line 168 def set_test_mode! @@test_mode = true end |
#test? ⇒ Boolean
172 173 174 |
# File 'lib/polytexnic/utils.rb', line 172 def test? defined?(@@test_mode) && @@test_mode end |
#tralics ⇒ Object
Returns the executable for the Tralics LaTeX-to-XML converter.
8 9 10 11 |
# File 'lib/polytexnic/utils.rb', line 8 def tralics File.join(File.dirname(__FILE__), '..', '..', 'precompiled_binaries', 'tralics') end |
#tralics_commands ⇒ Object
Returns some commands for Tralics. For various reasons, we don’t actually want to include these in the style file that gets passed to LaTeX. For example, the commands with ‘xmlelt’ aren’t even valid LaTeX; they’re actually pseudo-LaTeX that has special meaning to the Tralics processor.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/polytexnic/utils.rb', line 66 def tralics_commands <<-'EOS' % Commands specific to Tralics \def\hyperref[#1]#2{\xmlelt{a}{\XMLaddatt{target}{#1}#2}} \newcommand{\heading}[1]{\xmlelt{heading}{#1}} \newcommand{\codecaption}[1]{\xmlelt{heading}{#1}} \newcommand{\sout}[1]{\xmlelt{sout}{#1}} \newcommand{\kode}[1]{\xmlelt{kode}{#1}} \newcommand{\filepath}[1]{\xmlelt{filepath}{#1}} \newcommand{\image}[1]{\xmlelt{image}{#1}} \newcommand{\imagebox}[1]{\xmlelt{imagebox}{#1}} % Code listings \usepackage{amsthm} \theoremstyle{definition} \newtheorem{codelisting}{Listing}[chapter] \newtheorem{aside}{Box}[chapter] EOS end |
#underscore_digest ⇒ Object
Returns a digest for use in labels. I like to use labels of the form cha:foo_bar, but for some reason Tralics removes the underscore in this case.
28 29 30 |
# File 'lib/polytexnic/utils.rb', line 28 def underscore_digest pipeline_digest('_') end |
#xmlelement(name, skip = false) ⇒ Object
Returns a Tralics pseudo-LaTeX XML element. The use of the ‘skip’ flag is a hack to be able to use xmlelement even when generating, e.g., LaTeX, where we simply want to yield the block.
55 56 57 58 59 |
# File 'lib/polytexnic/utils.rb', line 55 def xmlelement(name, skip = false) output = (skip ? "" : "\\begin{xmlelement}{#{name}}") output << yield if block_given? output << (skip ? "" : "\\end{xmlelement}") end |