polytexnic 0.6.8 → 0.6.9

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
  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