mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2025-05-10 15:57:07 +01:00
Finish HackMyCore reshaping.
Reintroduce HackMyCore, dropping the interim submodule, and reorganize and improve tests.
This commit is contained in:
72
src/utils/class.js
Normal file
72
src/utils/class.js
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
Definition of John Resig's `Class` class.
|
||||
@module class.js
|
||||
*/
|
||||
|
||||
/* Simple JavaScript Inheritance
|
||||
* By John Resig http://ejohn.org/
|
||||
* MIT Licensed.
|
||||
* http://ejohn.org/blog/simple-javascript-inheritance/
|
||||
*/
|
||||
// Inspired by base2 and Prototype
|
||||
(function(){
|
||||
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||
|
||||
// The base Class implementation (does nothing)
|
||||
this.Class = function(){};
|
||||
module.exports = Class;
|
||||
|
||||
// Create a new Class that inherits from this class
|
||||
Class.extend = function(prop) {
|
||||
var _super = this.prototype;
|
||||
|
||||
// Instantiate a base class (but only create the instance,
|
||||
// don't run the init constructor)
|
||||
initializing = true;
|
||||
var prototype = new this();
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
for (var name in prop) {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == "function" &&
|
||||
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
|
||||
(function(name, fn){
|
||||
return function() {
|
||||
var tmp = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same method
|
||||
// but on the super-class
|
||||
this._super = _super[name];
|
||||
|
||||
// The method only need to be bound temporarily, so we
|
||||
// remove it when we're done executing
|
||||
var ret = fn.apply(this, arguments);
|
||||
this._super = tmp;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]) : // jshint ignore:line
|
||||
prop[name];
|
||||
}
|
||||
|
||||
// The dummy class constructor
|
||||
function Class() {
|
||||
// All construction is actually done in the init method
|
||||
if ( !initializing && this.init )
|
||||
this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Populate our constructed prototype object
|
||||
Class.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
Class.prototype.constructor = Class;
|
||||
|
||||
// And make this class extendable
|
||||
Class.extend = arguments.callee;
|
||||
|
||||
return Class;
|
||||
};
|
||||
|
||||
})();
|
7
src/utils/file-contains.coffee
Normal file
7
src/utils/file-contains.coffee
Normal file
@ -0,0 +1,7 @@
|
||||
###*
|
||||
Definition of the SyntaxErrorEx class.
|
||||
@module file-contains.js
|
||||
###
|
||||
|
||||
module.exports = ( file, needle ) ->
|
||||
require('fs').readFileSync(file,'utf-8').indexOf( needle ) > -1
|
49
src/utils/html-to-wpml.coffee
Normal file
49
src/utils/html-to-wpml.coffee
Normal file
@ -0,0 +1,49 @@
|
||||
###*
|
||||
Definition of the Markdown to WordProcessingML conversion routine.
|
||||
@license MIT. Copyright (c) 2015 James Devlin / FluentDesk.
|
||||
@module utils/html-to-wpml
|
||||
###
|
||||
|
||||
|
||||
_ = require 'underscore'
|
||||
HTML5Tokenizer = require 'simple-html-tokenizer'
|
||||
|
||||
module.exports = ( html ) ->
|
||||
|
||||
# Tokenize the HTML stream.
|
||||
tokens = HTML5Tokenizer.tokenize( html )
|
||||
final = is_bold = is_italic = is_link = link_url = ''
|
||||
|
||||
# Process <em>, <strong>, and <a> elements in the HTML stream, producing
|
||||
# equivalent WordProcessingML that can be dumped into a <w:p> or other
|
||||
# text container element.
|
||||
_.each tokens, ( tok ) ->
|
||||
|
||||
switch tok.type
|
||||
|
||||
when 'StartTag'
|
||||
switch tok.tagName
|
||||
when 'p' then final += '<w:p>'
|
||||
when 'strong' then is_bold = true
|
||||
when 'em' then is_italic = true
|
||||
when 'a'
|
||||
is_link = true;
|
||||
link_url = tok.attributes.filter((attr) -> attr[0] == 'href' )[0][1];
|
||||
|
||||
when 'EndTag'
|
||||
switch tok.tagName
|
||||
when 'p' then final += '</w:p>'
|
||||
when 'strong' then is_bold = false
|
||||
when 'em' then is_italic = false
|
||||
when 'a' then is_link = false
|
||||
|
||||
when 'Chars'
|
||||
if( tok.chars.trim().length )
|
||||
style = if is_bold then '<w:b/>' else ''
|
||||
style += if is_italic then '<w:i/>' else ''
|
||||
style += if is_link then '<w:rStyle w:val="Hyperlink"/>' else ''
|
||||
final +=
|
||||
(if is_link then ('<w:hlink w:dest="' + link_url + '">') else '') +
|
||||
'<w:r><w:rPr>' + style + '</w:rPr><w:t>' + tok.chars +
|
||||
'</w:t></w:r>' + (if is_link then '</w:hlink>' else '')
|
||||
final
|
15
src/utils/md2chalk.coffee
Normal file
15
src/utils/md2chalk.coffee
Normal file
@ -0,0 +1,15 @@
|
||||
###*
|
||||
Inline Markdown-to-Chalk conversion routines.
|
||||
@license MIT. See LICENSE.md for details.
|
||||
@module utils/md2chalk
|
||||
###
|
||||
|
||||
|
||||
MD = require 'marked'
|
||||
CHALK = require 'chalk'
|
||||
LO = require 'lodash'
|
||||
|
||||
module.exports = ( v, style, boldStyle ) ->
|
||||
boldStyle = boldStyle || 'bold'
|
||||
temp = v.replace(/\*\*(.*?)\*\*/g, LO.get( CHALK, boldStyle )('$1'))
|
||||
if style then LO.get( CHALK, style )(temp) else temp
|
58
src/utils/rasterize.coffee
Normal file
58
src/utils/rasterize.coffee
Normal file
@ -0,0 +1,58 @@
|
||||
# Exemplar script for generating documents with Phantom.js.
|
||||
# https://raw.githubusercontent.com/ariya/phantomjs/master/examples/rasterize.js
|
||||
# Converted to CoffeeScript by hacksalot
|
||||
|
||||
"use strict";
|
||||
page = require('webpage').create()
|
||||
system = require('system')
|
||||
address = output = size = null
|
||||
|
||||
if system.args.length < 3 || system.args.length > 5
|
||||
|
||||
console.log 'Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]'
|
||||
console.log ' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'
|
||||
console.log ' image (png/jpg output) examples: "1920px" entire page, window width 1920px'
|
||||
console.log ' "800px*600px" window, clipped to 800x600'
|
||||
phantom.exit 1
|
||||
|
||||
else
|
||||
|
||||
address = system.args[1]
|
||||
output = system.args[2]
|
||||
page.viewportSize = width: 600, height: 600
|
||||
|
||||
if system.args.length > 3 and system.args[2].substr(-4) == ".pdf"
|
||||
|
||||
size = system.args[3].split('*')
|
||||
page.paperSize =
|
||||
if size.length == 2 then width: size[0], height: size[1], margin: '0px'
|
||||
else format: system.args[3], orientation: 'portrait', margin: '1cm'
|
||||
|
||||
else if system.args.length > 3 && system.args[3].substr(-2) == "px"
|
||||
size = system.args[3].split '*'
|
||||
if size.length == 2
|
||||
pageWidth = parseInt size[0], 10
|
||||
pageHeight = parseInt size[1], 10
|
||||
page.viewportSize = width: pageWidth, height: pageHeight
|
||||
page.clipRect = top: 0, left: 0, width: pageWidth, height: pageHeight
|
||||
else
|
||||
console.log "size:", system.args[3]
|
||||
pageWidth = parseInt system.args[3], 10
|
||||
pageHeight = parseInt pageWidth * 3/4, 10 # it's as good an assumption as any
|
||||
console.log "pageHeight:", pageHeight
|
||||
page.viewportSize = width: pageWidth, height: pageHeight
|
||||
|
||||
if system.args.length > 4
|
||||
page.zoomFactor = system.args[4]
|
||||
|
||||
page.open address, (status) ->
|
||||
if status != 'success'
|
||||
console.log 'Unable to load the address!'
|
||||
phantom.exit(1)
|
||||
return
|
||||
else
|
||||
window.setTimeout () ->
|
||||
page.render(output)
|
||||
phantom.exit()
|
||||
return
|
||||
, 200
|
26
src/utils/safe-json-loader.coffee
Normal file
26
src/utils/safe-json-loader.coffee
Normal file
@ -0,0 +1,26 @@
|
||||
###*
|
||||
Definition of the SafeJsonLoader class.
|
||||
@module utils/safe-json-loader
|
||||
@license MIT. See LICENSE.md for details.
|
||||
###
|
||||
|
||||
FS = require('fs')
|
||||
SyntaxErrorEx = require('./syntax-error-ex')
|
||||
|
||||
module.exports = ( file ) ->
|
||||
ret = { }
|
||||
try
|
||||
ret.raw = FS.readFileSync( file, 'utf8' );
|
||||
ret.json = JSON.parse( ret.raw );
|
||||
catch
|
||||
# If we get here, either FS.readFileSync or JSON.parse failed.
|
||||
# We'll return HMSTATUS.readError or HMSTATUS.parseError.
|
||||
retRaw = ret.raw && ret.raw.trim()
|
||||
ret.ex =
|
||||
operation: if retRaw then 'parse' else 'read'
|
||||
inner:
|
||||
if SyntaxErrorEx.is( _error )
|
||||
then (new SyntaxErrorEx( _error, retRaw ))
|
||||
else _error
|
||||
file: file
|
||||
ret
|
28
src/utils/safe-spawn.coffee
Normal file
28
src/utils/safe-spawn.coffee
Normal file
@ -0,0 +1,28 @@
|
||||
###*
|
||||
Safe spawn utility for HackMyResume / FluentCV.
|
||||
@module utils/safe-spawn
|
||||
@license MIT. See LICENSE.md for details.
|
||||
###
|
||||
|
||||
module.exports = ( cmd, args, isSync, callback ) ->
|
||||
|
||||
try
|
||||
|
||||
# .spawnSync not available on earlier Node.js, so default to .spawn
|
||||
spawn = require('child_process')[ if isSync then 'spawnSync' else 'spawn'];
|
||||
info = spawn cmd, args
|
||||
|
||||
# Check for error depending on whether we're sync or async
|
||||
if !isSync
|
||||
info.on 'error', (err) ->
|
||||
if callback? then callback err; return
|
||||
else throw cmd: cmd, inner: err
|
||||
return
|
||||
else
|
||||
if info.error
|
||||
if callback? then callback err; return
|
||||
else throw cmd: cmd, inner: info.error
|
||||
|
||||
catch
|
||||
if callback? then callback _error
|
||||
else throw _error
|
43
src/utils/string-transformer.coffee
Normal file
43
src/utils/string-transformer.coffee
Normal file
@ -0,0 +1,43 @@
|
||||
###*
|
||||
Object string transformation.
|
||||
@module utils/string-transformer
|
||||
@license MIT. See LICENSE.md for details.
|
||||
###
|
||||
|
||||
_ = require 'underscore'
|
||||
moment = require 'moment'
|
||||
|
||||
###*
|
||||
Create a copy of this object in which all string fields have been run through
|
||||
a transformation function (such as a Markdown filter or XML encoder).
|
||||
###
|
||||
|
||||
module.exports = ( ret, filt, transformer ) ->
|
||||
|
||||
that = @
|
||||
|
||||
# TODO: refactor recursion
|
||||
transformStringsInObject = ( obj, filters ) ->
|
||||
return if !obj
|
||||
return if moment.isMoment obj
|
||||
|
||||
if _.isArray( obj )
|
||||
obj.forEach (elem, idx, ar) ->
|
||||
if typeof elem == 'string' || elem instanceof String
|
||||
ar[idx] = transformer( null, elem )
|
||||
else if _.isObject(elem)
|
||||
transformStringsInObject( elem, filters )
|
||||
else if _.isObject( obj )
|
||||
Object.keys( obj ).forEach (k) ->
|
||||
if filters.length && _.contains(filters, k)
|
||||
return
|
||||
sub = obj[k]
|
||||
if typeof sub == 'string' || sub instanceof String
|
||||
obj[k] = transformer( k, sub )
|
||||
else if _.isObject( sub )
|
||||
transformStringsInObject( sub, filters )
|
||||
|
||||
Object.keys( ret ).forEach (member) ->
|
||||
if !filt || !filt.length || !_.contains(filt, member)
|
||||
transformStringsInObject( ret[ member ], filt || [] )
|
||||
ret
|
15
src/utils/string.coffee
Normal file
15
src/utils/string.coffee
Normal file
@ -0,0 +1,15 @@
|
||||
###*
|
||||
Definitions of string utility functions.
|
||||
@module utils/string
|
||||
###
|
||||
|
||||
###*
|
||||
Determine if the string is null, empty, or whitespace.
|
||||
See: http://stackoverflow.com/a/32800728/4942583
|
||||
@method isNullOrWhitespace
|
||||
###
|
||||
|
||||
|
||||
String.isNullOrWhitespace = ( input ) -> !input || !input.trim()
|
||||
String.prototype.endsWith = (suffix) -> @indexOf(suffix, this.length - suffix.length) != -1
|
||||
String.is = ( val ) -> typeof val == 'string' || val instanceof String
|
25
src/utils/syntax-error-ex.coffee
Normal file
25
src/utils/syntax-error-ex.coffee
Normal file
@ -0,0 +1,25 @@
|
||||
###*
|
||||
Definition of the SyntaxErrorEx class.
|
||||
@module utils/syntax-error-ex
|
||||
@license MIT. See LICENSE.md for details.
|
||||
###
|
||||
|
||||
###*
|
||||
Represents a SyntaxError exception with line and column info.
|
||||
Collect syntax error information from the provided exception object. The
|
||||
JavaScript `SyntaxError` exception isn't interpreted uniformly across environ-
|
||||
ments, so we reparse on error to grab the line and column.
|
||||
See: http://stackoverflow.com/q/13323356
|
||||
@class SyntaxErrorEx
|
||||
###
|
||||
|
||||
SyntaxErrorEx = ( ex, rawData ) ->
|
||||
lineNum = null
|
||||
colNum = null
|
||||
JSONLint = require 'json-lint'
|
||||
lint = JSONLint rawData, { comments: false }
|
||||
this.line = if lint.error then lint.line else '???'
|
||||
this.col = if lint.error then lint.character else '???'
|
||||
|
||||
SyntaxErrorEx.is = ( ex ) -> ex instanceof SyntaxError
|
||||
module.exports = SyntaxErrorEx;
|
Reference in New Issue
Block a user