1
0
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:
hacksalot
2016-01-29 15:23:57 -05:00
parent e9971eb882
commit 0f65e4c9f3
130 changed files with 5384 additions and 337 deletions

72
src/utils/class.js Normal file
View 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;
};
})();

View 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

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

View 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

View 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

View 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

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

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