polytexnic 0.6.8 → 0.6.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de6a446d78432685757904722522835e26505704
4
- data.tar.gz: 3a39439ee2a40bcf52f9ca967332feaa65af4941
3
+ metadata.gz: 0f50dc640b0a38892e9baa3045a4fee09d384b8e
4
+ data.tar.gz: 0a407157700ee14b3178cf40db2429aa2d5dbbce
5
5
  SHA512:
6
- metadata.gz: a587872ddd1612030e5e3ccbe006daa6cf0782a07762e496858f05b556d62db003a0cec403f3239b66baa19fc533e4b44ef1b164ce1a38727142f64d6ad78661
7
- data.tar.gz: 982fd0d2bcf7d04e92b69a06f805e58cf5dd321a793bb3c7eee8e8e6eb061f0a999499705ab840083b82b925d4fcb2ddb84caef0d65b1ca568a5f41ae9f991b1
6
+ metadata.gz: e0cd5456e8dd7e9bbb97272cce76a44d1b4030704e55256608e40dd35dc3dc7c20def048565ffe2025aa020606ccebccbbe939cf5a5a2aa90c8180389526a12e
7
+ data.tar.gz: d4c3ec0365163f7616e58e2c74f6fd883dc6252c489b3aa31207f23d730eb9bbb6c5ce84983b3c4f3e7392b2f835d5955d601e52b6aa22fbf6723428cb5f38ba
File without changes
File without changes
@@ -6,7 +6,6 @@ require "polytexnic/preprocessor"
6
6
  require 'tempfile'
7
7
  require 'nokogiri'
8
8
  require 'digest/sha1'
9
- require 'pygments'
10
9
  require 'msgpack'
11
10
 
12
11
  module Polytexnic
@@ -3,14 +3,15 @@ module Polytexnic
3
3
  extend self
4
4
 
5
5
  # Matches the line for syntax highlighting.
6
- # %= lang:<language>
7
- LANG_REGEX = /^\s*%=\s+lang:\s*(\w+)/
6
+ # %= lang: <language>[, options: ...]
7
+ LANG_REGEX = /^\s*%=\s+lang:\s*(\w+)(?:,\s*options:(.*))?/
8
8
 
9
9
  # Matches the line for code inclusion.
10
10
  # %= <</path/to/code.ext
11
11
  CODE_INCLUSION_REGEX = /^\s*%=\s+<<\s*\( # opening
12
- \s*([\w\/-]+\.?(\w*)) # path
12
+ \s*([\w\/-]+\.?(\w*)) # path
13
13
  (?:,\s*lang:\s*(\w+))? # optional lang
14
+ (,\s*options:\s*.*)? # optional options
14
15
  \s*\) # closing paren
15
16
  /x
16
17
 
@@ -65,6 +66,7 @@ module Polytexnic
65
66
  while (line = lines.shift)
66
67
  if line =~ LANG_REGEX && !in_verbatim
67
68
  language = $1
69
+ highlight_options = $2
68
70
  elsif line =~ /\s*\\begin\{codelisting\}/ && !in_verbatim
69
71
  in_codelisting = true
70
72
  output << line
@@ -84,7 +86,9 @@ module Polytexnic
84
86
  filename = $1
85
87
  if File.exist?(filename)
86
88
  language = $3 || $2 || 'text'
89
+ highlight_options = $4
87
90
  code = ["%= lang:#{language}"]
91
+ code << highlight_options unless highlight_options.nil?
88
92
  code << '\begin{code}'
89
93
  code.concat(File.read($1).split("\n"))
90
94
  code << '\end{code}'
@@ -131,9 +135,9 @@ module Polytexnic
131
135
  tag = 'literal'
132
136
  else
133
137
  format = latex ? 'latex' : 'html'
134
- id = "#{content}--#{language}--#{format}--#{in_codelisting}"
138
+ id = "#{content}--#{language}--#{format}--#{in_codelisting}--#{highlight_options}"
135
139
  key = digest(id, salt: code_salt)
136
- code_cache[key] = [content, language, in_codelisting]
140
+ code_cache[key] = [content, language, in_codelisting, highlight_options]
137
141
  tag = 'code'
138
142
  end
139
143
  if latex || tag == 'code' || math
@@ -34,8 +34,9 @@ module Polytexnic
34
34
  # \end{code}
35
35
  # which reduces syntax highlighting to a previously solved problem.
36
36
  def write_polytex_code
37
- code_cache.each do |key, (code, lang, in_codelisting)|
38
- latex = "%= lang:#{lang}\n\\begin{code}\n#{code}\n\\end{code}"
37
+ code_cache.each do |key, (code, lang, in_codelisting, options)|
38
+ latex = "%= lang:#{lang}#{options}\n" +
39
+ "\\begin{code}\n#{code}\n\\end{code}"
39
40
  @source.gsub!(key, latex)
40
41
  end
41
42
  end
@@ -41,6 +41,7 @@ module Polytexnic
41
41
  kramdown = Kramdown::Document.new(cleaned_markdown, latex_headers: lh)
42
42
  @source = kramdown.to_latex.tap do |polytex|
43
43
  remove_comments(polytex)
44
+ convert_includegraphics(polytex)
44
45
  convert_tt(polytex)
45
46
  restore_math(polytex, math_cache)
46
47
  restore_hashed_content(polytex, cache)
@@ -134,15 +135,17 @@ module Polytexnic
134
135
  output << indentation + line
135
136
  end
136
137
  output << "\n"
137
- elsif line =~ /^```(\w+)\s*$/ # syntax-highlighted code fences
138
+ elsif line =~ /^```(\w+)(,\s*options:.*)?$/ # highlighted fences
138
139
  language = $1
140
+ options = $2
139
141
  code = []
140
142
  while (line = lines.shift) && !line.match(/^```\s*$/) do
141
143
  code << line
142
144
  end
143
145
  code = code.join("\n")
144
- key = digest(code)
145
- code_cache[key] = [code, language]
146
+ data = [code, language, false, options]
147
+ key = digest(data.join("--"))
148
+ code_cache[key] = data
146
149
  output << key
147
150
  else
148
151
  output << line
@@ -151,13 +154,13 @@ module Polytexnic
151
154
  output.join("\n")
152
155
  end
153
156
 
154
- # # Removes comments.
155
- # # The main reason for doing this is so that commented-out cached objects,
156
- # # such as '% <hash of a code sample>', get removed.
157
- # # Code like '%= lang:ruby' gets preserved.
158
- # def strip_comments(text)
159
- # text.gsub!(/^%.*$/, '')
160
- # end
157
+ # Converts \includegraphics to \image.
158
+ # The reason is that raw \includegraphics is almost always too wide
159
+ # in the PDF. Instead, we use the custom-defined \image command, which
160
+ # is specifically designed to fix this issue.
161
+ def convert_includegraphics(text)
162
+ text.gsub!('\includegraphics', '\image')
163
+ end
161
164
 
162
165
  # Converts {tt ...} to \kode{...}
163
166
  # This effectively converts `inline code`, which kramdown sets as
@@ -88,10 +88,11 @@ module Polytexnic
88
88
  if document.is_a?(String) # LaTeX
89
89
  substitutions = {}
90
90
  document.tap do
91
- code_cache.each do |key, (content, language, in_codelisting)|
92
- code = highlight(key, content, language, 'latex')
91
+ code_cache.each do |key, (content, language, in_codelisting, options)|
92
+ code = highlight(key, content, language, 'latex', options)
93
93
  output = code.split("\n")
94
94
  horrible_backslash_kludge(add_font_info(output.first))
95
+ highlight_lines(output, options)
95
96
  code = output.join("\n")
96
97
  substitutions[key] = in_codelisting ? code : framed(code)
97
98
  end
@@ -101,22 +102,44 @@ module Polytexnic
101
102
  document.css('div.code').each do |code_block|
102
103
  key = code_block.content
103
104
  next unless (value = code_cache[key])
104
- content, language = value
105
- code_block.inner_html = highlight(key, content, language, 'html')
105
+ content, language, _, options = value
106
+ code_block.inner_html = highlight(key, content, language, 'html',
107
+ options)
106
108
  end
107
109
  end
108
110
  end
109
111
 
112
+ # Highlight lines (i.e., with a yellow backgroun).
113
+ # This is needed due to a Pygments bug that fails to highlight lines
114
+ # in the LaTeX output.
115
+ def highlight_lines(output, options)
116
+ highlighted_lines(options).each do |i|
117
+ output[i] = '\colorbox{hilightyellow}{' + output[i] + '}'
118
+ end
119
+ end
120
+
121
+ # Returns an array with the highlighted lines.
122
+ def highlighted_lines(options)
123
+ ActiveSupport::JSON.decode('{' + options.to_s + '}')['hl_lines'] || []
124
+ end
125
+
110
126
  # Puts a frame around code.
111
127
  def framed(code)
112
128
  "\\begin{framed_shaded}\n#{code}\n\\end{framed_shaded}"
113
129
  end
114
130
 
115
131
  # Highlights a code sample.
116
- def highlight(key, content, language, formatter)
117
- highlight_cache[key] ||= Pygments.highlight(content,
118
- lexer: language,
119
- formatter: formatter)
132
+ def highlight(key, content, language, formatter, options)
133
+ require 'pygments'
134
+ require 'active_support'
135
+ options = ActiveSupport::JSON.decode('{' + options.to_s + '}')
136
+ if options['linenos'] && formatter == 'html'
137
+ # Inline numbers look much better in HTML but are invalid in LaTeX.
138
+ options['linenos'] = 'inline'
139
+ end
140
+ highlight_cache[key] ||= Pygments.highlight(content, lexer: language,
141
+ formatter: formatter,
142
+ options: options)
120
143
  end
121
144
 
122
145
  # Adds some verbatim font info (including size).
@@ -1,3 +1,3 @@
1
1
  module Polytexnic
2
- VERSION = "0.6.8"
2
+ VERSION = "0.6.9"
3
3
  end
@@ -22,6 +22,7 @@ Gem::Specification.new do |gem|
22
22
  gem.add_dependency 'pygments.rb', '~> 0.4.2'
23
23
  gem.add_dependency 'msgpack', '~> 0.4.2'
24
24
  gem.add_dependency 'kramdown'
25
+ gem.add_dependency 'active_support'
25
26
 
26
27
  gem.add_development_dependency 'rspec'
27
28
  gem.add_development_dependency 'simplecov'
@@ -91,8 +91,6 @@ x^2
91
91
  end
92
92
  end
93
93
 
94
-
95
-
96
94
  describe "footnotes" do
97
95
  subject do
98
96
  Polytexnic::Pipeline.new(markdown, source: :markdown).polytex
@@ -119,6 +117,24 @@ That is it. You can keep writing your text after the footnote content.
119
117
  end
120
118
  end
121
119
 
120
+ describe "images" do
121
+ subject do
122
+ Polytexnic::Pipeline.new(markdown, source: :markdown).polytex
123
+ end
124
+
125
+ context "inclusion with a caption and a label" do
126
+ let(:markdown) do <<-'EOS'
127
+ ![Running the Softcover server in a separate tab.\label{fig:softcover_server}](images/figures/softcover_server.png)
128
+ EOS
129
+ end
130
+
131
+ it { should include '\caption{Running the Softcover server in a separate tab.\label{fig:softcover_server}}' }
132
+ it { should include '\image' }
133
+ it { should_not include '\includegraphics' }
134
+ end
135
+
136
+ end
137
+
122
138
  context "with LaTeX containing" do
123
139
 
124
140
  context "a normal command" do
@@ -298,9 +314,9 @@ lorem
298
314
  let(:source) { '<<(/path/to/code)' }
299
315
  it { should resemble '%= <<(/path/to/code)' }
300
316
 
301
- context "with an alternate lang" do
302
- let(:source) { '<<(/path/to/code.md, lang: text)' }
303
- it { should resemble '%= <<(/path/to/code.md, lang: text)' }
317
+ context "with an alternate lang and options" do
318
+ let(:source) { '<<(/path/to/code.md, lang: text, options: "hl_lines": [1, 2], "linenos": true)' }
319
+ it { should resemble '%= <<(/path/to/code.md, lang: text, options: "hl_lines": [1, 2], "linenos": true)' }
304
320
  end
305
321
  end
306
322
 
@@ -329,9 +345,9 @@ lorem
329
345
  it { should resemble output }
330
346
  end
331
347
 
332
- context "with highlighting" do
348
+ context "with highlighting and options" do
333
349
  let(:source) do <<-EOS
334
- ```ruby
350
+ ```ruby, options: "hl_lines": [1, 2], "linenos": true
335
351
  def foo
336
352
  "bar"
337
353
  end
@@ -341,7 +357,7 @@ lorem
341
357
  end
342
358
 
343
359
  let(:output) do <<-'EOS'
344
- %= lang:ruby
360
+ %= lang:ruby, options: "hl_lines": [1, 2], "linenos": true
345
361
  \begin{code}
346
362
  def foo
347
363
  "bar"
@@ -45,7 +45,7 @@ $ subl .gemrc
45
45
  end
46
46
 
47
47
  context "with an empty caption" do
48
- let(:polytex) do <<-'EOS'
48
+ let(:polytex) do <<-'EOS'
49
49
  \chapter{Foo bar}
50
50
 
51
51
  \begin{codelisting}
@@ -63,6 +63,27 @@ $ subl .gemrc
63
63
  it { should include 'Listing 1.1' }
64
64
  it { should_not include 'Listing 1.1:' }
65
65
  end
66
+
67
+ context "containing code inclusion with a hyphen" do
68
+ before do
69
+ File.write(File.join('spec', 'fixtures', 'name-with-hyphens.txt'), '')
70
+ end
71
+ after do
72
+ FileUtils.rm(File.join('spec', 'fixtures', 'name-with-hyphens.txt'))
73
+ end
74
+ let(:polytex) do <<-'EOS'
75
+ \begin{codelisting}
76
+ \codecaption{Foo}
77
+ \label{code:foo}
78
+ %= <<(spec/fixtures/name-with-hyphens.txt, lang: text)
79
+ \end{codelisting}
80
+ EOS
81
+ end
82
+
83
+ it "should not raise an error" do
84
+ expect { processed_text }.not_to raise_error
85
+ end
86
+ end
66
87
  end
67
88
 
68
89
  describe "metacode listings" do
@@ -87,25 +108,4 @@ $ subl .gemrc
87
108
  expect { processed_text }.not_to raise_error
88
109
  end
89
110
  end
90
-
91
- describe "containing code inclusion with a hyphen" do
92
- before do
93
- File.write(File.join('spec', 'fixtures', 'name-with-hyphens.txt'), '')
94
- end
95
- after do
96
- FileUtils.rm(File.join('spec', 'fixtures', 'name-with-hyphens.txt'))
97
- end
98
- let(:polytex) do <<-'EOS'
99
- \begin{codelisting}
100
- \codecaption{Foo}
101
- \label{code:foo}
102
- %= <<(spec/fixtures/name-with-hyphens.txt, lang: text)
103
- \end{codelisting}
104
- EOS
105
- end
106
-
107
- it "should not raise an error" do
108
- expect { processed_text }.not_to raise_error
109
- end
110
- end
111
111
  end
@@ -84,6 +84,39 @@ describe Polytexnic::Pipeline do
84
84
  end
85
85
  end
86
86
 
87
+ context "with highlight and line numbering options" do
88
+ let(:polytex) do <<-'EOS'
89
+ %= lang:ruby, options: "hl_lines": [1, 2], "linenos": true
90
+ \begin{code}
91
+ def foo
92
+ "bar"
93
+ end
94
+ \end{code}
95
+ EOS
96
+ end
97
+
98
+ it do
99
+ should resemble <<-'EOS'
100
+ <div class="code">
101
+ <div class="highlight">
102
+ <pre>
103
+ <span class="lineno">1</span>
104
+ <span class="hll">
105
+ <span class="k">def</span> <span class="nf">foo</span>
106
+ </span>
107
+ <span class="lineno">2</span>
108
+ <span class="hll">
109
+ <span class="s2">"bar"</span>
110
+ </span>
111
+ <span class="lineno">3</span>
112
+ <span class="k">end</span>
113
+ </pre>
114
+ </div>
115
+ </div>
116
+ EOS
117
+ end
118
+ end
119
+
87
120
  describe "code inclusion" do
88
121
  context "for an existing file" do
89
122
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polytexnic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.8
4
+ version: 0.6.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Hartl
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-28 00:00:00.000000000 Z
12
+ date: 2013-11-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: active_support
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: rspec
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +183,8 @@ files:
169
183
  - .pull_requests/1384811507
170
184
  - .pull_requests/1385061501
171
185
  - .pull_requests/1385598040
186
+ - .pull_requests/1385601533
187
+ - .pull_requests/1385778060
172
188
  - .rspec
173
189
  - .ruby-gemset
174
190
  - .ruby-version