Skip to content

Commit

Permalink
Implemented encoding dep for iconv light. So hopefully we can move aw…
Browse files Browse the repository at this point in the history
…ay from the slow and windows only iconv dep for encoding. Ref #596. Possible fix to #627
  • Loading branch information
balupton committed Sep 2, 2013
1 parent edce54e commit d11890c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -104,6 +104,7 @@
"extract-opts": "~2.2.0",
"getmac": "~1.0.5",
"jschardet": "~1.0.2",
"encoding": "~0.1.6",
"lazy-require": "~1.0.0",
"lodash": "~1.3.1",
"mime": "~1.2.9",
Expand Down
7 changes: 4 additions & 3 deletions src/lib/docpad.coffee
Expand Up @@ -931,7 +931,6 @@ class DocPad extends EventEmitterGrouped
# Detect Encoding
# Should we attempt to auto detect the encoding of our files?
# Useful when you are using foreign encoding (e.g. GBK) for your files
# Only works on unix systems currently (limit of iconv module)
detectEncoding: false

# Render Single Extensions
Expand Down Expand Up @@ -1487,12 +1486,14 @@ class DocPad extends EventEmitterGrouped
postTasks = new TaskGroup().once 'complete', (err) =>
return next(err, @config)

# Lazy Dependencies: Iconv
###
# Lazy Dependencies: Encoding
postTasks.addTask (complete) =>
return complete() unless @config.detectEncoding
return lazyRequire 'iconv', {cwd:corePath}, (err) ->
return lazyRequire 'encoding', {cwd:corePath}, (err) ->
docpad.warn(locale.encodingLoadFailed) if err
return complete()
###

# Load Plugins
postTasks.addTask (complete) ->
Expand Down
48 changes: 31 additions & 17 deletions src/lib/models/file.coffee
Expand Up @@ -10,7 +10,8 @@ extendr = require('extendr')

# Import: Optional
jschardet = null
Iconv = null
encodingUtil = null
#Iconv = null

# Local
{Backbone,Model} = require('../base')
Expand Down Expand Up @@ -597,34 +598,38 @@ class FileModel extends Model
if isText is true
# Detect source encoding if not manually specified
if @detectEncoding
# Import
jschardet ?= require('jschardet')
try
Iconv ?= require('iconv').Iconv
catch err
Iconv = null
encoding ?= jschardet.detect(buffer)?.encoding

# Detect
encoding ?= jschardet.detect(buffer)?.encoding or 'utf8'
else
encoding ?= 'utf8'
# Default the encoding
encoding or= 'utf8'

# Convert into utf8
if encoding.toLowerCase() not in ['ascii','utf8','utf-8']
if docpadUtil.isStandardEncoding(encoding) is false
# Import optional dependencies
try
#Iconv ?= require('iconv').Iconv
encodingUtil ?= require('encoding')
# ^ when we prove encoding/iconv-lite works better than iconv
# we can move this out of the try catch and make detectEncoding standard
catch err
# ignore

# Can convert?
if Iconv?
if encodingUtil?
@log('info', "Converting encoding #{encoding} to UTF-8 on #{relativePath}")

# Convert
d = require('domain').create()
d.on 'error', =>
@log('warn', "Encoding conversion failed, therefore we cannot convert the encoding #{encoding} to UTF-8 on #{relativePath}")
d.run ->
buffer = new Iconv(encoding, 'utf8').convert(buffer)
#buffer = new Iconv(encoding, 'utf8').convert(buffer)
buffer = encodingUtil.convert(buffer, 'utf8', encoding) # content, to, from

# Can't convert
else
@log('warn', "Iconv did not load, therefore we cannot convert the encoding #{encoding} to UTF-8 on #{relativePath}")
@log('warn', "Encoding utilities did not load, therefore we cannot convert the encoding #{encoding} to UTF-8 on #{relativePath}")

# Apply
changes.encoding = encoding
Expand Down Expand Up @@ -856,14 +861,23 @@ class FileModel extends Model

# Convert utf8 to original encoding
unless opts.encoding.toLowerCase() in ['ascii','utf8','utf-8','binary']
if Iconv?
# Import optional dependencies
try
#Iconv ?= require('iconv').Iconv
encodingUtil ?= require('encoding')
catch err
# ignore

# Convert
if encodingUtil?
@log('info', "Converting encoding UTF-8 to #{opts.encoding} on #{opts.path}")
try
opts.content = new Iconv('utf8',opts.encoding).convert(opts.content)
#opts.content = new Iconv('utf8',opts.encoding).convert(opts.content)
opts.content = encodingUtil.convert(opts.content, opts.encoding, 'utf8') # content, to, from
catch err
@log('warn', "Encoding conversion failed, therefore we cannot convert the encoding UTF-8 to #{opts.encoding} on #{opts.path}")
else
@log('warn', "Iconv did not load, therefore we cannot convert the encoding UTF-8 to #{opts.encoding} on #{opts.path}")
@log('warn', "Encoding utilities did not load, therefore we cannot convert the encoding UTF-8 to #{opts.encoding} on #{opts.path}")

# Log
file.log 'debug', "Writing the #{opts.type}: #{opts.path} #{opts.encoding}"
Expand Down
4 changes: 4 additions & 0 deletions src/lib/util.coffee
Expand Up @@ -3,6 +3,10 @@ pathUtil = require('path')

# Export
module.exports = docpadUtil =
# Standard Encodings
isStandardEncoding: (encoding) ->
return encoding.toLowerCase() in ['ascii', 'utf8', 'utf-8']

# Get Local DocPad Installation Executable
getLocalDocPadExecutable: ->
return pathUtil.join(process.cwd(), 'node_modules', 'docpad', 'bin', 'docpad')
Expand Down

0 comments on commit d11890c

Please sign in to comment.