Skip to content

Commit

Permalink
Update README. Allow to specify custom executable
Browse files Browse the repository at this point in the history
  • Loading branch information
Yaroslav Konoplov committed Sep 1, 2016
1 parent f1d78a2 commit 8e5dfc7
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 14 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ruby on Rails integration with Jade
# Ruby on Rails integration with Pug (ex. Jade)

## How it works
This gem compiles Jade templates with [command line tool](http://jade-lang.com/command-line).
Expand All @@ -11,19 +11,19 @@ There are support of all basic features including advanced:
Jade template can be alternatively compiled using [command line](http://jade-lang.com/command-line). This method is impemented in this fork.

## Installing
Install Jade globally via npm:
Install Pug globally via npm:
```bash
npm install -g jade
npm install -g pug-cli
```

Add to your Gemfile:
```ruby
gem 'pug-rails', '~> 1.0'
```

Require Jade runtime.js:
Require Pug runtime.js:
```js
//= require jade/runtime
//= require pug/runtime
```

## Running Tests
Expand All @@ -32,4 +32,4 @@ bundle exec rake test
```

## Versioning
Gem version always reflects the version of Jade it contains.
Gem version always reflects the version of Pug it contains.
17 changes: 13 additions & 4 deletions lib/pug-rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
require 'open3'
require 'tilt'
require 'json'
require 'pug/template'
require 'pug/railtie' if defined?(Rails)

module Pug
class << self
Expand All @@ -12,20 +10,31 @@ def compile(source, options = {})

# Command line arguments take precedence over json options in Jade binary
# @link https://github.com/jadejs/jade/blob/master/bin/jade.js
cmd = %w( jade )
# @link https://github.com/pugjs/pug-cli/blob/master/index.js
cmd = [ options.fetch(:executable) ]
cmd.push('--client')
cmd.push('--path', options[:filename]) if options[:filename]
cmd.push('--pretty') if options[:pretty]
cmd.push('--no-debug') unless options[:debug]
cmd.push('--obj', JSON.generate(options))
cmd.push('--obj', JSON.generate(options))

stdout, stderr, exit_status = Open3.capture3(*cmd, stdin_data: source)
raise CompileError.new(stderr) unless exit_status.success?
stdout
end

def find_executable
%w( pug jade ).find do |name|
`which #{name}`
$?.success?
end
end
end

class CompileError < ::StandardError
end
end

require 'pug/template'
require 'pug/railtie' if defined?(Rails)

1 change: 1 addition & 0 deletions lib/pug/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module Pug
class Railtie < Rails::Engine
config.pug = ActiveSupport::OrderedOptions.new
config.pug.executable = Pug.find_executable
config.pug.pretty = Rails.env.development?
config.pug.self = false
config.pug.compile_debug = Rails.env.development?
Expand Down
4 changes: 1 addition & 3 deletions lib/pug/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ def prepare
end

def evaluate(context, locals, &block)
options = { }
options[:filename] = file
jade_config = Rails.application.config.pug.merge(options)
jade_config = Rails.application.config.pug.merge(filename: file)
Pug.compile(data, jade_config)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/pug/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true
module Pug
VERSION = '1.11.0'
VERSION = '1.11.0.1'
end
22 changes: 22 additions & 0 deletions vendor/assets/javascripts/jade/LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(The MIT License)

Copyright (c) 2009-2014 TJ Holowaychuk <tj@vision-media.ca>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
252 changes: 252 additions & 0 deletions vendor/assets/javascripts/jade/runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jade = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

/**
* Merge two attribute objects giving precedence
* to values in object `b`. Classes are special-cased
* allowing for arrays and merging/joining appropriately
* resulting in a string.
*
* @param {Object} a
* @param {Object} b
* @return {Object} a
* @api private
*/

exports.merge = function merge(a, b) {
if (arguments.length === 1) {
var attrs = a[0];
for (var i = 1; i < a.length; i++) {
attrs = merge(attrs, a[i]);
}
return attrs;
}
var ac = a['class'];
var bc = b['class'];

if (ac || bc) {
ac = ac || [];
bc = bc || [];
if (!Array.isArray(ac)) ac = [ac];
if (!Array.isArray(bc)) bc = [bc];
a['class'] = ac.concat(bc).filter(nulls);
}

for (var key in b) {
if (key != 'class') {
a[key] = b[key];
}
}

return a;
};

/**
* Filter null `val`s.
*
* @param {*} val
* @return {Boolean}
* @api private
*/

function nulls(val) {
return val != null && val !== '';
}

/**
* join array as classes.
*
* @param {*} val
* @return {String}
*/
exports.joinClasses = joinClasses;
function joinClasses(val) {
return (Array.isArray(val) ? val.map(joinClasses) :
(val && typeof val === 'object') ? Object.keys(val).filter(function (key) { return val[key]; }) :
[val]).filter(nulls).join(' ');
}

/**
* Render the given classes.
*
* @param {Array} classes
* @param {Array.<Boolean>} escaped
* @return {String}
*/
exports.cls = function cls(classes, escaped) {
var buf = [];
for (var i = 0; i < classes.length; i++) {
if (escaped && escaped[i]) {
buf.push(exports.escape(joinClasses([classes[i]])));
} else {
buf.push(joinClasses(classes[i]));
}
}
var text = joinClasses(buf);
if (text.length) {
return ' class="' + text + '"';
} else {
return '';
}
};


exports.style = function (val) {
if (val && typeof val === 'object') {
return Object.keys(val).map(function (style) {
return style + ':' + val[style];
}).join(';');
} else {
return val;
}
};
/**
* Render the given attribute.
*
* @param {String} key
* @param {String} val
* @param {Boolean} escaped
* @param {Boolean} terse
* @return {String}
*/
exports.attr = function attr(key, val, escaped, terse) {
if (key === 'style') {
val = exports.style(val);
}
if ('boolean' == typeof val || null == val) {
if (val) {
return ' ' + (terse ? key : key + '="' + key + '"');
} else {
return '';
}
} else if (0 == key.indexOf('data') && 'string' != typeof val) {
if (JSON.stringify(val).indexOf('&') !== -1) {
console.warn('Since Jade 2.0.0, ampersands (`&`) in data attributes ' +
'will be escaped to `&amp;`');
};
if (val && typeof val.toISOString === 'function') {
console.warn('Jade will eliminate the double quotes around dates in ' +
'ISO form after 2.0.0');
}
return ' ' + key + "='" + JSON.stringify(val).replace(/'/g, '&apos;') + "'";
} else if (escaped) {
if (val && typeof val.toISOString === 'function') {
console.warn('Jade will stringify dates in ISO form after 2.0.0');
}
return ' ' + key + '="' + exports.escape(val) + '"';
} else {
if (val && typeof val.toISOString === 'function') {
console.warn('Jade will stringify dates in ISO form after 2.0.0');
}
return ' ' + key + '="' + val + '"';
}
};

/**
* Render the given attributes object.
*
* @param {Object} obj
* @param {Object} escaped
* @return {String}
*/
exports.attrs = function attrs(obj, terse){
var buf = [];

var keys = Object.keys(obj);

if (keys.length) {
for (var i = 0; i < keys.length; ++i) {
var key = keys[i]
, val = obj[key];

if ('class' == key) {
if (val = joinClasses(val)) {
buf.push(' ' + key + '="' + val + '"');
}
} else {
buf.push(exports.attr(key, val, false, terse));
}
}
}

return buf.join('');
};

/**
* Escape the given string of `html`.
*
* @param {String} html
* @return {String}
* @api private
*/

var jade_encode_html_rules = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;'
};
var jade_match_html = /[&<>"]/g;

function jade_encode_char(c) {
return jade_encode_html_rules[c] || c;
}

exports.escape = jade_escape;
function jade_escape(html){
var result = String(html).replace(jade_match_html, jade_encode_char);
if (result === '' + html) return html;
else return result;
};

/**
* Re-throw the given `err` in context to the
* the jade in `filename` at the given `lineno`.
*
* @param {Error} err
* @param {String} filename
* @param {String} lineno
* @api private
*/

exports.rethrow = function rethrow(err, filename, lineno, str){
if (!(err instanceof Error)) throw err;
if ((typeof window != 'undefined' || !filename) && !str) {
err.message += ' on line ' + lineno;
throw err;
}
try {
str = str || require('fs').readFileSync(filename, 'utf8')
} catch (ex) {
rethrow(err, null, lineno)
}
var context = 3
, lines = str.split('\n')
, start = Math.max(lineno - context, 0)
, end = Math.min(lines.length, lineno + context);

// Error context
var context = lines.slice(start, end).map(function(line, i){
var curr = i + start + 1;
return (curr == lineno ? ' > ' : ' ')
+ curr
+ '| '
+ line;
}).join('\n');

// Alter exception message
err.path = filename;
err.message = (filename || 'Jade') + ':' + lineno
+ '\n' + context + '\n\n' + err.message;
throw err;
};

exports.DebugItem = function DebugItem(lineno, filename) {
this.lineno = lineno;
this.filename = filename;
}

},{"fs":2}],2:[function(require,module,exports){

},{}]},{},[1])(1)
});

0 comments on commit 8e5dfc7

Please sign in to comment.