nanoc3 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # nanoc news
2
2
 
3
- ## 3.1.3 (???)
3
+ ## 3.1.4 (2010-07-25)
4
+
5
+ * Made INT and TERM signals always quit the CLI
6
+ * Allowed relative imports in LESS
7
+ * Made sure modification times are unchanged for identical recompiled items
8
+ * Improved link validator error handling
9
+ * Made pygmentize not output extra divs and pres
10
+ * Allowed colorizers to be specified using symbols instead of strings
11
+ * Added scss to the default list of text extensions
12
+
13
+ ## 3.1.3 (2010-04-25)
4
14
 
5
15
  * Removed annoying win32console warning [Eric Sunshine]
6
16
  * Removed color codes when not writing to a terminal, or when writing to
data/README.md CHANGED
@@ -52,10 +52,17 @@ you want to explore nanoc from a technical perspective.
52
52
 
53
53
  ## Dependencies
54
54
 
55
- nanoc itself can be used without installing any dependencies. Some
56
- components, however, do have dependencies:
55
+ nanoc has few dependencies. It is possible to use nanoc programmatically
56
+ without any dependencies at all, but if you want to use nanoc in a proper way,
57
+ you’ll likely need some dependencies:
57
58
 
59
+ * The **commandline frontend** depends on `cli`.
58
60
  * The **autocompiler** depends on `mime-types` and `rack`.
61
+ * Filters and helpers likely have dependencies on their own too.
62
+
63
+ If you’re developing for nanoc, such as writing custom filters or helpers, you
64
+ may be interested in the development dependencies:
65
+
59
66
  * For **documentation generation** you’ll need `yard`.
60
67
  * For **packaging** you’ll need `rubygems` (1.3 or newer).
61
68
  * For **testing** you’ll need `mocha` and `minitest`.
@@ -13,6 +13,16 @@ module Nanoc3
13
13
  # @return [Hash] This item's attributes
14
14
  attr_accessor :attributes
15
15
 
16
+ # A string that uniquely identifies an item in a site.
17
+ #
18
+ # Identifiers start and end with a slash. They are comparable to paths on
19
+ # the filesystem, with the difference that file system paths usually do
20
+ # not have a trailing slash. The item hierarchy (parent and children of
21
+ # items) is determined by the item identifier.
22
+ #
23
+ # The root page (the home page) has the identifier “/”, which means
24
+ # that it is the ancestor of all other items.
25
+ #
16
26
  # @return [String] This item's identifier
17
27
  attr_accessor :identifier
18
28
 
@@ -357,15 +357,17 @@ module Nanoc3
357
357
  hash_old = hash_for_file(self.raw_path)
358
358
  size_old = File.size(self.raw_path)
359
359
  end
360
-
361
- # Copy
362
- FileUtils.cp(@filenames[:last], self.raw_path)
363
- @written = true
360
+ size_new = File.size(@filenames[:last])
361
+ hash_new = hash_for_file(@filenames[:last]) if size_old == size_new
364
362
 
365
363
  # Check if file was modified
366
- size_new = File.size(self.raw_path)
367
- hash_new = hash_for_file(self.raw_path) if size_old == size_new
368
364
  @modified = (size_old != size_new || hash_old != hash_new)
365
+
366
+ # Copy
367
+ if @modified
368
+ FileUtils.cp(@filenames[:last], self.raw_path)
369
+ end
370
+ @written = true
369
371
  else
370
372
  # Remember old content
371
373
  if File.file?(self.raw_path)
@@ -373,7 +375,10 @@ module Nanoc3
373
375
  end
374
376
 
375
377
  # Write
376
- File.open(self.raw_path, 'w') { |io| io.write(@content[:last]) }
378
+ new_content = @content[:last]
379
+ if @old_content != new_content
380
+ File.open(self.raw_path, 'w') { |io| io.write(new_content) }
381
+ end
377
382
  @written = true
378
383
 
379
384
  # Generate diff
@@ -14,7 +14,7 @@ module Nanoc3
14
14
  # * `layouts` ({Array}<{Nanoc3::Layout}>) - A list of all layouts
15
15
  class RuleContext < Context
16
16
 
17
- # Creates a new rule context for the given iterm representation.
17
+ # Creates a new rule context for the given item representation.
18
18
  #
19
19
  # @param [Nanoc3::ItemRep] rep The item representation for which to create
20
20
  # a new rule context.
@@ -39,7 +39,7 @@ module Nanoc3
39
39
  # that lacks some options, the default value will be taken from
40
40
  # `DEFAULT_CONFIG`.
41
41
  DEFAULT_CONFIG = {
42
- :text_extensions => %w( css erb haml htm html js less markdown md php rb sass txt xhtml xml ),
42
+ :text_extensions => %w( css erb haml htm html js less markdown md php rb sass scss txt xhtml xml ),
43
43
  :output_dir => 'output',
44
44
  :data_sources => [ {} ],
45
45
  :index_filenames => [ 'index.html' ],
@@ -54,6 +54,14 @@ module Nanoc3::CLI
54
54
 
55
55
  # Inherited from ::Cri::Base
56
56
  def run(args)
57
+ # Set exit handler
58
+ [ 'INT', 'TERM' ].each do |signal|
59
+ Signal.trap(signal) do
60
+ puts
61
+ exit!(0)
62
+ end
63
+ end
64
+
57
65
  super(args)
58
66
  rescue Interrupt => e
59
67
  exit(1)
@@ -106,6 +106,7 @@ module Nanoc3::Extra::Deployers
106
106
  # Runs the given shell command. This is a simple wrapper around Kernel#system.
107
107
  def run_shell_cmd(args)
108
108
  system(*args)
109
+ raise "command exited with a nonzero status code #{$?.exitstatus} (command: #{args.join(' ')})" if !$?.success?
109
110
  end
110
111
 
111
112
  end
@@ -48,6 +48,36 @@ module Nanoc3::Extra::Validators
48
48
 
49
49
  private
50
50
 
51
+ # Enumerates all key-value pairs of a given hash in a thread-safe way.
52
+ #
53
+ # This class is a helper class, which means that it is not used directly
54
+ # by nanoc. Future versions of nanoc may no longer contain this class. Do
55
+ # not depend on this class to be available.
56
+ class ThreadsafeHashEnumerator
57
+
58
+ # Creates a new enumerator for the given hash.
59
+ #
60
+ # @param [Hash] hash The hash for which the enumerator should return
61
+ # key-value pairs
62
+ def initialize(hash)
63
+ @hash = hash
64
+ @unprocessed_keys = @hash.keys.dup
65
+ @mutex = Mutex.new
66
+ end
67
+
68
+ # Returns the next key-value pair in the hash.
69
+ #
70
+ # @return [Array] An array containing the key and the corresponding
71
+ # value of teh next key-value pair
72
+ def next_pair
73
+ @mutex.synchronize do
74
+ key = @unprocessed_keys.shift
75
+ return (key ? [ key, @hash[key] ] : nil)
76
+ end
77
+ end
78
+
79
+ end
80
+
51
81
  def all_broken_hrefs
52
82
  broken_hrefs = {}
53
83
 
@@ -127,17 +157,23 @@ module Nanoc3::Extra::Validators
127
157
  require 'uri'
128
158
 
129
159
  # Parse
130
- uri = URI.parse(href)
160
+ uri = nil
161
+ begin
162
+ uri = URI.parse(href)
163
+ rescue URI::InvalidURIError
164
+ @delegate && @delegate.send(:external_href_validated, href, false)
165
+ return false
166
+ end
131
167
 
132
168
  # Skip non-HTTP URLs
133
169
  return true if uri.scheme != 'http'
134
170
 
135
171
  # Get status
136
172
  status = fetch_http_status_for(uri)
137
- is_valid = (status && status >= 200 && status <= 299)
173
+ is_valid = !!(status && status >= 200 && status <= 299)
138
174
 
139
175
  # Notify
140
- @delegate.send(:external_href_validated, href, is_valid)
176
+ @delegate && @delegate.send(:external_href_validated, href, is_valid)
141
177
 
142
178
  # Done
143
179
  is_valid
@@ -153,30 +189,10 @@ module Nanoc3::Extra::Validators
153
189
  end
154
190
  end
155
191
 
156
- # This class is a helper class, which means that it is not used directly
157
- # by nanoc. Future versions of nanoc may no longer contain this class. Do
158
- # not depend on this class to be available.
159
- class EachPairEnumerator
160
-
161
- def initialize(hash)
162
- @hash = hash
163
- @unprocessed_keys = @hash.keys.dup
164
- @mutex = Mutex.new
165
- end
166
-
167
- def next_pair
168
- @mutex.synchronize do
169
- key = @unprocessed_keys.shift
170
- return (key ? [ key, @hash[key] ] : nil)
171
- end
172
- end
173
-
174
- end
175
-
176
192
  def validate_external_hrefs(hrefs, broken_hrefs)
177
193
  @mutex = Mutex.new
178
194
 
179
- enum = EachPairEnumerator.new(hrefs)
195
+ enum = ThreadsafeHashEnumerator.new(hrefs)
180
196
 
181
197
  threads = []
182
198
  10.times do
@@ -202,7 +218,10 @@ module Nanoc3::Extra::Validators
202
218
  def fetch_http_status_for(url, params={})
203
219
  5.times do |i|
204
220
  begin
205
- res = request_url_once(url)
221
+ res = nil
222
+ Timeout::timeout(10) do
223
+ res = request_url_once(url)
224
+ end
206
225
 
207
226
  if res.code =~ /^3..$/
208
227
  url = URI.parse(res['location'])
@@ -211,7 +230,7 @@ module Nanoc3::Extra::Validators
211
230
  return res.code.to_i
212
231
  end
213
232
  rescue
214
- nil
233
+ return nil
215
234
  end
216
235
  end
217
236
  end
@@ -71,7 +71,7 @@ module Nanoc3::Filters
71
71
  KNOWN_COLORIZERS = [ :coderay, :dummy, :pygmentize ]
72
72
 
73
73
  def highlight(code, language, params={})
74
- colorizer = @colorizers[language]
74
+ colorizer = @colorizers[language.to_sym]
75
75
  if KNOWN_COLORIZERS.include?(colorizer)
76
76
  send(colorizer, code, language, params[colorizer] || {})
77
77
  else
@@ -93,7 +93,10 @@ module Nanoc3::Filters
93
93
  IO.popen("pygmentize -l #{language} -f html", "r+") do |io|
94
94
  io.write(code)
95
95
  io.close_write
96
- return io.read
96
+ highlighted_code = io.read
97
+
98
+ doc = Nokogiri::HTML.fragment(highlighted_code)
99
+ return doc.xpath('./div[@class="highlight"]/pre').inner_html
97
100
  end
98
101
  end
99
102
 
@@ -12,7 +12,13 @@ module Nanoc3::Filters
12
12
  def run(content, params={})
13
13
  require 'less'
14
14
 
15
+ # Add filename to load path
16
+ $LESS_LOAD_PATH << File.dirname(@item[:content_filename])
17
+
15
18
  ::Less::Engine.new(content).to_css
19
+ ensure
20
+ # Restore load path
21
+ $LESS_LOAD_PATH.delete_at(-1)
16
22
  end
17
23
 
18
24
  end
@@ -47,7 +47,12 @@ module Nanoc3::Helpers
47
47
  # # => '<a title="My super cool blog" href="/blog/">Blog</a>'
48
48
  def link_to(text, target, attributes={})
49
49
  # Find path
50
- path = target.is_a?(String) ? target : target.path
50
+ if target.is_a?(String)
51
+ path = target
52
+ else
53
+ path = target.path
54
+ raise RuntimeError, "Cannot create a link to #{target.inspect} because this target is not outputted (its routing rule returns nil)" if path.nil?
55
+ end
51
56
 
52
57
  # Join attributes
53
58
  attributes = attributes.inject('') do |memo, (key, value)|
@@ -112,14 +117,20 @@ module Nanoc3::Helpers
112
117
  require 'pathname'
113
118
 
114
119
  # Find path
115
- path = target.is_a?(String) ? target : target.path
120
+ if target.is_a?(String)
121
+ path = target
122
+ else
123
+ path = target.path
124
+ raise RuntimeError, "Cannot get the relative path to #{target.inspect} because this target is not outputted (its routing rule returns nil)" if path.nil?
125
+ end
116
126
 
117
127
  # Get source and destination paths
118
128
  dst_path = Pathname.new(path)
129
+ raise RuntimeError, "Cannot get the relative path to #{path} because the current item representation, #{@item_rep.inspect}, is not outputted (its routing rule returns nil)" if @item_rep.path.nil?
119
130
  src_path = Pathname.new(@item_rep.path)
120
131
 
121
- # Calculate elative path (method depends on whether destination is a
122
- # directory or not).
132
+ # Calculate the relative path (method depends on whether destination is
133
+ # a directory or not).
123
134
  if src_path.to_s[-1,1] != '/'
124
135
  relative_path = dst_path.relative_path_from(src_path.dirname).to_s
125
136
  else
data/lib/nanoc3.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Nanoc3
4
4
 
5
5
  # The current nanoc version.
6
- VERSION = '3.1.3'
6
+ VERSION = '3.1.4'
7
7
 
8
8
  end
9
9
 
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc3
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 11
4
5
  prerelease: false
5
6
  segments:
6
7
  - 3
7
8
  - 1
8
- - 3
9
- version: 3.1.3
9
+ - 4
10
+ version: 3.1.4
10
11
  platform: ruby
11
12
  authors:
12
13
  - Denis Defreyne
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-25 00:00:00 +02:00
18
+ date: 2010-07-25 00:00:00 +02:00
18
19
  default_executable: nanoc3
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: cri
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 23
27
30
  segments:
28
31
  - 1
29
32
  - 0
@@ -147,6 +150,7 @@ files:
147
150
  - lib/nanoc3/tasks/validate.rake
148
151
  - lib/nanoc3/tasks.rb
149
152
  - lib/nanoc3.rb
153
+ - bin/nanoc3
150
154
  has_rdoc: yard
151
155
  homepage: http://nanoc.stoneship.org/
152
156
  licenses: []
@@ -172,23 +176,27 @@ rdoc_options:
172
176
  require_paths:
173
177
  - lib
174
178
  required_ruby_version: !ruby/object:Gem::Requirement
179
+ none: false
175
180
  requirements:
176
181
  - - ">="
177
182
  - !ruby/object:Gem::Version
183
+ hash: 3
178
184
  segments:
179
185
  - 0
180
186
  version: "0"
181
187
  required_rubygems_version: !ruby/object:Gem::Requirement
188
+ none: false
182
189
  requirements:
183
190
  - - ">="
184
191
  - !ruby/object:Gem::Version
192
+ hash: 3
185
193
  segments:
186
194
  - 0
187
195
  version: "0"
188
196
  requirements: []
189
197
 
190
198
  rubyforge_project:
191
- rubygems_version: 1.3.6
199
+ rubygems_version: 1.3.7
192
200
  signing_key:
193
201
  specification_version: 3
194
202
  summary: a web publishing system written in Ruby for building small to medium-sized websites.