Merge pull request #1 from there4/master

Pulling upstream master
This commit is contained in:
Sabree Blackmon 2018-03-13 15:49:38 -05:00 committed by GitHub
commit 46842f5712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 3138 additions and 1690 deletions

2
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea
vendor
examples/resume/_*.md
examples/output/*.html
@ -16,3 +17,4 @@ Icon
# Files that might appear on external disk
.Spotlight-V100
.Trashes
*.sublime*

View File

@ -1,9 +1,12 @@
language: php
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
php:
- 5.3
- 5.4
- '7.1'
- '7.2'
install:
- travis_retry composer self-update
- travis_retry composer install --prefer-source --no-interaction --dev
script:
- composer test

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Craig Davis
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.

View File

@ -3,7 +3,7 @@
Turn a simple Markdown document into an elegant resume with both a perfect
pdf printable format, and a responsive css3 html5 file. You can view a sample
at the [blog post for the project][blog].
at the [blog post for the project][blog], or look in examples/output to see sample PDFs.
## Features
@ -14,9 +14,29 @@ at the [blog post for the project][blog].
* Single file deployment (no external stylesheets)
* You can now version control and branch your resume.
## Quickstart
## Install
There is no installation or need to run composer. Just download and [run the phar file](https://github.com/there4/markdown-resume/raw/master/bin/md2resume):
#### OSX
1. The simplest installation of the PDF to HTML conversion tool is via [Homebrew Cask](https://caskroom.github.io/)
```bash
brew cask install wkhtmltopdf
```
2. Download as .zip (cloning has [an issue as of Dec 2017](https://github.com/there4/markdown-resume/issues/65)) and unzip.
3. [Install PHP 7](https://jason.pureconcepts.net/2016/09/upgrade-php-mac-os-x/) and be sure to update your PATH variable.
4. [Install 'composer'](https://getcomposer.org/download/), a per-project package installer to setup the rest of the requirements. You may need to run './composer.phar update' to get the correct versions of dependencies.
5. Now you should be ready to continue down in Quickstart.
#### Debian
```bash
sudo apt install php7.0-mbstring wkhtmltopdf
```
#### Fedora
```bash
sudo dnf install php-mbstring wkhtmltopdf
```
## Quickstart
```
./bin/md2resume html examples/source/sample.md examples/output/
@ -25,7 +45,7 @@ at the [blog post for the project][blog].
## Help
```
Markdown Resume Generator version 2.0.10 by Craig Davis
Markdown Resume Generator version 2.2.1 by Craig Davis
Usage:
[options] command [arguments]
@ -44,7 +64,6 @@ Available commands:
html Generate an HTML resume from a markdown file
list Lists commands
pdf Generate a PDF from a markdown file
selfupdate Updates md2resume.phar to the latest version.
stats Generate a word frequency analysis of your resume
templates List available templates
version Show current version information
@ -78,15 +97,8 @@ and then use CSS rules to display a nicely formatted resume. Note that because
we have very few ways to nest or identify elements that many of the css rules
are based on descendant and adjacent selectors.
__PLEASE NOTE__: The templates are compiled into the phar archive in the `./bin`
folder. If you intend to edit the templates or add new ones, you'll need to run
this application in the dev mode. See below for more information about doing
this.
## Feature Development
The application is deployed as a compiled phar file. In order to add new
commands, you'll need to first install the dependencies:
In order to add new commands, you'll need to first install the dependencies:
* `composer install`
@ -94,16 +106,10 @@ After that, you can run the `md2resume_dev.php` file from the command line.
## Building a Release
1. Tag the repo with the new build number. This will be picked up for both
the `version` file used by the self update command and placed into the
phar file.
2. Run `pake build`.
1. Tag the repo with the new build number.
2. Run `composer build`.
3. Push both the tag and the code.
Check out the pake tooling for more information about the build. Pake will be
installed to `./vendor/bin/pake`. So for instance a complete phar file build
looks like `./vendor/bin/pake build`.
## Acknowledgments
The initial inspiration is from the [Sample Resume Template][srt].
@ -113,6 +119,9 @@ are a more comfortable with html than markdown, you should use it.
## Changelog
* __2.2.0__ : Dropped phar file distribution, removed Pake and migrated to composer commands
* __2.1.0__ : Dropped PHP5 support
* __2.0.12__ : Added new `Roboto` template from [@ejwaibel](https://github.com/ejwaibel)
* __2.0.10__ : Updated spacing in moder template with commites from [@501st-alpha1](https://github.com/501st-alpha1)
* __2.0.9__ : Updated Modern template with improved spacing. Update parsing of
`--template` option to close [issue #7](https://github.com/there4/markdown-resume/issues/7)
@ -144,3 +153,4 @@ are a more comfortable with html than markdown, you should use it.
[pake]: https://github.com/indeyets/pake/wiki/Installing-Pake
[wkhtmltopdf]: https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF
[console]: http://symfony.com/doc/current/components/console/introduction.html
HELLO

Binary file not shown.

View File

@ -1,496 +0,0 @@
#!/usr/bin/env php
<?php
/*
* Empir
*
Copyright (c) 2010 Jeremy Perret <j.perret.27@gmail.com>
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.
*/
//if colors make any damages on your terminal deactivate them by setting to false this option
define('ACTIVATE_COLORS', true);
//only run Empir automatically when this file is called directly from the command line
if (isset($argv[0])) {
if (version_compare(phpversion(), '5.3.0', '<')) {
echo "ERROR: Empir require php >= 5.3.0 (Your PHP version: ".phpversion().")\n";
exit(1);
}
$empir = new Empir($argv);
exit($empir->run());
}
/**
* Command line interface Helper.
*
* @package Empir
* @author Jeremy Perret <j.perret.27@gmail.com>
*/
class CLI_Interface
{
protected function execCommand()
{
if (isset($this->commands[$this->command])) {
$method = $this->commands[$this->command];
$rcode = $this->$method();
}else
$rcode = $this->error("Command <$this->command> doesn't exist. Try <help>");
return ($rcode == null) ? 0 : $rcode;
}
protected function gopt($no)
{
if(isset($this->options[$no]))
return $this->options[$no];
return null;
}
protected function glopt($opt)
{
foreach ($this->options as $option) {
if(strpos($option, "--$opt=") !== false)
return trim(end(explode('=', $option)), '"');
}
return null;
}
protected function reqopt($no, $name)
{
if($this->gopt($no) == null)
exit($this->error("Param $name is required. Try <help>"));
return $this->gopt($no);
}
protected function error($message = '', $errno = 1)
{
if($message != '')
echo Color::str("ERROR: $message\n", Empir::ERR_COLOR);
return $errno;
}
protected function success($message)
{
echo Color::str("$message\n", Empir::SUCCESS_COLOR);
}
protected function makeAbsolut($path='')
{
$current = getcwd().'/';
if($path == "" || $path == false)
$absolut_path = $current;
elseif(substr($path, 0, 2) == './')
$absolut_path = $current.substr($path,2);
elseif(strpos($path, ':') !== false || substr($path, 0, 2) == '\\\\' || substr($path, 0, 1) == '/')
$absolut_path = $path;
else
$absolut_path = $current.$path;
$absolut_path = str_replace('\\', '/', $absolut_path);
$absolut_path = rtrim($absolut_path, '/');
return $absolut_path;
}
private function find_opt($opt)
{
}
}
/**
* Manage phar
*
* @package Empir
* @author Jeremy Perret <j.perret.27@gmail.com>
*/
class Empir extends CLI_Interface
{
const VERSION = '1.0.0';
const ERR_COLOR = 'red';
const HELP_COLOR = 'green';
const PARAM_COLOR = 'purple';
const SUCCESS_COLOR = 'green';
public $options = array();
public $command;
public $commands = array(
'help' => 'help',
'?' => 'help',
'-h' => 'help',
'make' => 'make',
'convert' => 'convert',
'extract' => 'extract'
);
public $compression_types = array('gz', 'bz2', 'no');
public $format_types = array('phar', 'tar', 'zip');
public function __construct($argv)
{
$this->options = array_slice($argv, 1);
$vars = array(
'gz' => array(
'name' => 'gz',
'extension' => 'zlib',
'mime' => '.gz',
'int_value' => Phar::GZ,
),
'bz2' => array(
'name' => 'bz2',
'extension' => 'bzip2',
'mime' => '.bz2',
'int_value' => Phar::BZ2,
),
'no' => array(
'name' => 'no',
'extension' => 'not',
'mime' => '',
'int_value' => Phar::NONE,
),
'phar' => array(
'name' => 'phar',
'mime' => '.phar',
'int_value' => Phar::PHAR,
'compression' => true
),
'tar' => array(
'name' => 'tar',
'mime' => '.tar',
'int_value' => Phar::TAR,
'compression' => true
),
'zip' => array(
'name' => 'zip',
'mime' => '.zip',
'int_value' => Phar::ZIP,
'compression' => false
)
);
foreach($vars as $name => $attrs)
$this->$name = $this->array_to_object($attrs);
}
public function run()
{
$this->command = ($this->gopt(0) != null) ? $this->gopt(0) : 'help';
$this->options = array_slice($this->options, 1);
return $this->execCommand();
}
public function make()
{
$this->_is_phar_writable();
$phar = $this->makeAbsolut($this->reqopt(0, 'phar filename'));
$phar_name = end(explode('/', $phar));
$stub_file = trim($this->reqopt(1, 'stub file'), '/');
$root_app = $this->makeAbsolut($this->reqopt(2, 'root dir of your app'));
$_compression = $this->glopt('compress') ?: 'no';
$_format = $this->glopt('format') ?: 'phar';
$_exclude = $this->glopt('exclude');
$_fexclude = $this->glopt('fexclude');
if(!file_exists($root_app)) return $this->error("Root dir of your app doesn't exist.");
if(!empty($_compression) && !in_array($_compression, $this->compression_types)) return $this->error("Unrecognized compression: $_compression");
if(!empty($_format) && !in_array($_format, $this->format_types)) return $this->error("Unrecognized format: $_format");
if (!empty($_fexclude)) {
$_fexclude = $this->makeAbsolut($_fexclude);
if(!file_exists($_fexclude)) return $this->error("Exclude file: $_fexclude not found.");
$_fexclude = file_get_contents($_fexclude);
}
$shell_masks = explode('|', $_exclude);
$shell_masks = array_merge($shell_masks, explode("\n", $_fexclude));
$c = $this->get_var($_compression);
$f = $this->get_var($_format);
if (file_exists($phar)) {
unlink($phar);
}
try {
$p = new Phar($phar, Phar::CURRENT_AS_FILEINFO | Phar::KEY_AS_FILENAME, $phar_name);
echo "Make $phar_name : \n===================\n";
$project = json_decode(file_get_contents('composer.json'));
$p->setStub(
"#!/usr/bin/env php \n"
. "<?php\n"
. 'define("IN_PHAR", true);' . "\n"
. '$project = (object) array(' . "\n"
. " 'description' => '$project->description', " . "\n"
. " 'version' => '$project->version'," . "\n"
. " 'selfupdatepath' => '$project->selfupdatepath'," . "\n"
. " 'selfupdateversion' => '$project->selfupdateversion'," . "\n"
. ");" . "\n"
. "Phar::mapPhar(); " . "\n"
. "include 'phar://".$phar_name."/".$stub_file."'; " . "\n"
. "__HALT_COMPILER(); " . "\n"
. "?>" . "\n"
);
$files = $this->_scandir($root_app);
$i=0;
foreach ($files as $file) {
$file_buff = $file;
$file = str_replace('\\', '/', $file);
$file = str_replace($root_app.'/', '', $file);
if (!$this->_exclude($file, $shell_masks) && !$this->_exclude($file, array('*/'.$phar_name, $phar_name))) {
echo "add $file\n";
//$p[$file] = php_strip_whitespace($file_buff);
$p[$file] = file_get_contents($file_buff);
$i++;
}
}
echo "\nTotal: $i files added\n";
if ($f->name == 'phar' && $c->name='no') {
$this->success("CREATE $phar");
return;
}
if(!Phar::canCompress($c->int_value)) return $this->error("Unable to compress the phar with $c->name, extension $c->extension not found. But $phar is created.");
if(!$f->compression) $c->int_value = Phar::NONE;
$phar_copy = $phar.$f->mime.$c->mime;
@unlink($phar_copy);
$p = $p->convertToExecutable($f->int_value, $c->int_value);
$this->success("CREATE $phar_copy");
@unlink($phar);
} catch (Exception $e) {
return $this->error($e->getMessage());
}
}
public function help()
{
$help = new Help();
$command = $this->gopt(0);
if(empty($command)) return $help->main();
switch ($command) {
case 'make': $help->make(); break;
default: return $this->error("Command: $command doesn't exist."); break;
}
}
private function _is_phar_writable()
{
if(!Phar::canWrite()) exit($this->error("Unable to write phar, phar.readonly must be set to zero in your php.ini otherwise use: $ php -dphar.readonly=0 empir <command> ..."));
}
private function get_var($var)
{
if (is_string($var)) {
if(isset($this->$var))
return $this->$var;
} else {
foreach (array_merge($this->compression_types, $this->format_types) as $v) {
if($this->$v->int_value == $var)
return $this->$v;
}
}
}
private function _exclude($file, $shell_masks)
{
if (!empty($shell_masks)) {
foreach ($shell_masks as $mask) {
if(fnmatch(trim($mask), $file))
return true;
}
}
return false;
}
private function _scandir($path)
{
$items = array();
$path = rtrim($path, '/');
if (!$current_dir = opendir($path))
return $items;
while (false !== ($filename = readdir($current_dir))) {
if ($filename != "." && $filename != "..") {
if (is_dir($path.'/'.$filename)) {
$items = array_merge($items, $this->_scandir($path.'/'.$filename));
} else
$items[] = $path.'/'.$filename;
}
}
closedir($current_dir);
return $items;
}
private function array_to_object($array)
{
$object = new stdClass();
foreach ($array as $name => $value) {
$name = strtolower(trim($name));
if (!empty($name))
$object->$name = $value;
}
return $object;
}
}
/**
* Colorizer
*
* @package Empir
* @author Jeremy Perret <j.perret.27@gmail.com>
*/
class Color
{
public static $foreground_colors = array(
'black' => '0;30',
'dark_gray' => '1;30',
'blue' => '0;34',
'light_blue' => '1;34',
'green' => '0;32',
'light_green' => '1;32',
'cyan' => '0;36',
'light_cyan' => '1;36',
'red' => '0;31',
'light_red' => '1;31',
'purple' => '0;35',
'light_purple' => '1;35',
'brown' => '0;33',
'yellow' => '1;33',
'light_gray' => '0;37',
'white' => '1;37'
);
public static $background_colors = array(
'black' => '40',
'red' => '41',
'green' => '42',
'yellow' => '43',
'blue' => '44',
'magenta' => '45',
'cyan' => '46',
'light_gray' => '47'
);
public static function str($string, $foreground_color = null, $background_color = null)
{
if(!self::isTermSupportColor()) return $string;
$colored_string = "";
if (isset(self::$foreground_colors[$foreground_color])) {
$colored_string .= "\033[".self::$foreground_colors[$foreground_color]."m";
}
if (isset(self::$background_colors[$background_color])) {
$colored_string .= "\033[".self::$background_colors[$background_color]."m";
}
$colored_string .= $string."\033[0m";
return $colored_string;
}
public static function random($string)
{
$index_foreground = array_rand(self::$foreground_colors, 1);
$index_background= array_rand(self::$background_colors, 1);
return self::str($string, $index_foreground, $index_background);
}
public static function isTermSupportColor()
{
$term = getenv('TERM');
if($term && ACTIVATE_COLORS) return true;
return false;
}
}
/**
* All differents helps.
*
* @package Empir
* @author Jeremy Perret <j.perret.27@gmail.com>
*/
class Help
{
public function main()
{
echo "Empir v".Empir::VERSION." 2010 (c) Jeremy Perret <j.perret.27@gmail.com>
Empir is a php tool to manage phar.
The setting phar.readonly must be 0 in your php.ini,
otherwise use $ php -dphar.readonly=0 empir <command> ...
If you use Empir from PEAR installation don't care about this php option,
it used directly in the executable file.
".Color::str('Usage', Empir::HELP_COLOR).":
$ php empir <command> <parameters> [options]
".Color::str('Commands', Empir::HELP_COLOR).":
".Color::str('make', Empir::PARAM_COLOR)." Create a phar from an entire php application.
For more help on a command use 'empir help <command>'
";
}
public function make()
{
echo "Command make allows to create a phar file from an entire php application from its root directory.
".Color::str('Usage', Empir::HELP_COLOR).":
$ php empir make <phar_file> <stub_file> <root_app> [options]
".Color::str('Parameters', Empir::HELP_COLOR).":
".Color::str('phar_file', Empir::PARAM_COLOR)." Phar file that will be created, accept absolute or relative path.
".Color::str('stub_file', Empir::PARAM_COLOR)." Bootstrap file of your application, from your root app folder.
".Color::str('root_app', Empir::PARAM_COLOR)." Root folder of your application, accept absolute or relative path.
".Color::str('Options', Empir::HELP_COLOR).":
".Color::str('--exclude=PATTERN', Empir::PARAM_COLOR)." Exclude files match PATTERN, seperate several patterns with a pipe.
".Color::str('--fexclude=FILE', Empir::PARAM_COLOR)." Exclude patterns listed in FILE. One pattern per line.
".Color::str('--format=FORMAT', Empir::PARAM_COLOR)." Special phar format, FORMAT can be tar or zip. Don't specify format to keep normal phar.
".Color::str('--compress=TYPE', Empir::PARAM_COLOR)." Specify the phar compression type. TYPE can be gz or bz2.
";
}
}

View File

@ -1,150 +0,0 @@
#!/usr/bin/php
<?php
// ===========
// = Globals =
// ===========
$count = 0; // total files checked
$errors = array();
$options = setOptions(array(
'quiet' => false,
'recurse' => false,
));
if ($options['quiet']) {
ob_start();
}
// =============
// = Scan path =
// =============
$files = getPipedFiles();
$path = $_SERVER['PWD']; // Default to execution directory
// Piped files present
if ($files) {
foreach ($files as $file) {
checkFile("$path/$file");
}
}
// Use arguments
else {
if ($_SERVER['argc'] > 1) {
$last = end($_SERVER['argv']);
if (substr($last, 0, 1) != '-') {
$path = $last; // snag last argument, if it wasn't an option switch
}
}
if (is_dir($path)) {
checkDirectoryContents($path);
}
elseif (is_file($path)) {
checkFile($path);
}
else {
echo "$path is not a file or directory.\n";
showHelp() AND exit(1);
}
}
if ($options['quiet']) {
ob_end_clean();
}
echo "\n$count files checked, " . count($errors) . ' errors.';
echo "\n", implode($errors,'');
function checkDirectoryContents($dir) {
global $options, $i, $errors, $count;
$contents = scandir($dir);
foreach($contents as $content) {
if ($content == '.' || $content == '..') {
continue;
}
$path = "$dir/$content";
// Recurse into directories
if (is_dir($path) && $options['recurse']) {
checkDirectoryContents($path);
} // if is_dir
else {
checkFile($path);
} // !is_dir
} // foreach
} // function checkDirectoryContents
function checkFile($path) {
global $count, $errors;
// echo "$path\n";
// Skip non-php files
if (substr($path, -4) != '.php') {
return false;
}
if (($count % 60 == 0)) {
echo "\n";
}
$error = `php -l $path 2>&1 1> /dev/null`;
if ($error) {
$errors[] = $error;
echo 'E';
}
else {
echo '.';
}
$count++;
}
function getPipedFiles() {
$files = array();
stream_set_blocking(STDIN,FALSE);
while ($line = trim(fgets(STDIN))) {
$files[] = $line;
}
return $files;
}
function setOptions($options) {
$args = array_keys(getopt('qRh', array('quiet', 'recursive', 'help')));
foreach ($args as $arg) {
switch ($arg) {
case 'q':
case 'quiet':
$options['quiet'] = true;
break;
case 'R':
case 'recursive':
$options['recurse'] = true;
break;
case 'h':
case 'help':
default:
showHelp() AND exit(0);
} // Switch
} // Foreach args
return $options;
} // function setOptions
function showHelp() {
echo <<<HELP
usage: lint [-qR] [path]
options:
-q, --quiet: disable verbose output
-R, --recursive: recurse into subdirectories
-h, --help: display this help screen
HELP;
return true;
}

20
build/update_readme.php Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env php
<?php
/**
* Run the markdown resume and update the readme with the generated help
*/
$baseDir = dirname(__DIR__);
$startPoint = '## Help';
$endPoint = '## Examples';
$readme = file_get_contents('README.md');
$help = shell_exec('php '.$baseDir.'/bin/md2resume list --no-interaction');
$output = preg_replace(
'/('.preg_quote($startPoint).')(.*)('.preg_quote($endPoint).')/si',
"$1\n```\n" . $help . "\n```\n$3",
$readme
);
file_put_contents($baseDir.'/README.md', $output);
/* End of file updated_readme.php */

View File

@ -8,13 +8,10 @@
"html5"
],
"license": "MIT",
"version": "2.0.10",
"selfupdatepath": "://github.com/there4/markdown-resume/raw/master/bin/md2resume",
"selfupdateversion": "://github.com/there4/markdown-resume/raw/master/version",
"authors": [
{
"name": "Craig Davis",
"email": "craig@there4development.com",
"email": "craig@there4.io",
"role": "Developer"
},
{
@ -34,6 +31,11 @@
"name": "Abhishek Kandoi",
"email": "abhikandoi2000@gmail.com",
"role": "Contributor"
},
{
"name": "Erik Waibel",
"email": "ejwaibel@gmail.com",
"role": "Contributor"
}
],
"support": {
@ -41,22 +43,41 @@
},
"minimum-stability": "dev",
"require": {
"fabpot/php-cs-fixer": "0.4.0",
"indeyets/pake": "~1.99",
"php": ">=7.1",
"kriswallsmith/assetic": "1.1.2",
"leafo/lessphp": "v0.4.0",
"michelf/php-markdown": "1.4.0",
"michelf/php-smartypants": "1.6.0-beta1",
"michelf/php-smartypants": "^1.8",
"mustache/mustache": "2.5.1",
"phpunit/phpunit": "3.7.*",
"squizlabs/php_codesniffer": "1.*",
"sunra/php-simple-html-dom-parser": "v1.5.0",
"symfony/config": "v2.3.4",
"symfony/console": "v2.3.4",
"symfony/yaml": "v2.3.4",
"twig/twig": "v1.13.2"
"twig/twig": "v1.13.2",
"symfony/event-dispatcher": "^4.0@dev",
"leafo/scssphp": "dev-master"
},
"bin": [
"bin/md2resume"
]
],
"require-dev": {
"phpunit/phpunit": "^6.2",
"squizlabs/php_codesniffer": "^3.0@dev",
"jakub-onderka/php-parallel-lint": "dev-master",
"jakub-onderka/php-console-highlighter": "dev-master"
},
"scripts": {
"build": [
"@lint",
"@format",
"@sniff",
"@test",
"@readme"
],
"lint": "vendor/bin/parallel-lint --exclude app --exclude vendor .",
"sniff": "vendor/bin/phpcs --standard=PSR2 -n --extensions=php src",
"format": "vendor/bin/phpcbf --standard=PSR2 --extensions=php src",
"readme": "build/update_readme.php",
"test": "vendor/bin/phpunit"
}
}

2585
composer.lock generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
examples/output/modern.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
examples/output/swissen.pdf Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,32 +0,0 @@
<?php
error_reporting(E_ALL | E_STRICT);
// If the dependencies aren't installed, we have to bail and offer some help.
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
exit("\nPlease run `composer install` to install dependencies.\n\n");
}
// Bootstrap our application with the Composer autoloader
$app = require __DIR__ . '/vendor/autoload.php';
// Setup the namespace for our own namespace
$app->add('Resume', __DIR__ . '/src');
// Instantiate our Console application
$console = new Resume\Cli\Resume();
// If we're running from phar, we get these values from the stub
if (!defined('IN_PHAR')) {
$project = json_decode(file_get_contents(__DIR__ . '/composer.json'));
}
$templatePath = __DIR__ . '/templates';
$consoleTemplatePath = __DIR__ . '/src/Resume/Templates';
// Init the app with these params
$console->initialize($templatePath, $consoleTemplatePath, $project);
// Execute the console app.
$console->run();
/* End of resume.php */

121
pakefile
View File

@ -1,121 +0,0 @@
<?php
pake_desc('Run the unit tests');
pake_task('test');
pake_desc('Check the code for psr2 standards');
pake_task('sniff');
pake_desc('Run php-cs-fixer on the src directory');
pake_task('fixer');
pake_desc('Update the README with the latest command output');
pake_task('readme');
pake_desc('Build phar file');
pake_task('phar');
pake_desc('PHP Lint the src folder');
pake_task('lint');
pake_desc('Display the version');
pake_task('version');
pake_desc('Create the selfupdate version file');
pake_task('version_file');
pake_desc('Copy to ~/bin');
pake_task('mv');
pake_desc('Build the app for deployment');
pake_task('build', 'version', 'version_file', 'readme', 'lint', 'fixer', 'sniff', 'phar');
pake_alias('default', 'build');
function run_build()
{
// Used only for naming a string of dependencies.
}
function run_test()
{
pake_sh('./vendor/bin/phpunit', true);
}
function run_version()
{
$composer = json_decode(file_get_contents('composer.json'));
pake_echo_comment("Building Markdown Resume Builder version " . $composer->version);
}
function run_version_file()
{
// Find the latest tag
$version = trim(shell_exec('git describe --abbrev=0 --tags'));
// Write it to the version file for the self update command
file_put_contents('./version', $version);
// Write it to the composer.json file as well
$config = json_decode(file_get_contents('composer.json'));
$config->version = $version;
file_put_contents('composer.json', json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
function run_lint()
{
pake_echo_comment('Linting files');
pake_sh('./build/lint -R ./src', true);
}
function run_phar()
{
pake_echo_comment('Construction phar and moving to ./bin/md2resume');
$command =
'rm -f ./bin/md2resume && rm -f ./bin/md2resume.phar &&'
. 'php -dphar.readonly=0 build/empir make ./bin/md2resume.phar md2resume_dev.php . --exclude="'
. '*.git/*|*.gitignore|*test*|*Tests*|*.md|*/doc/*|*.lock|*token.txt|pakefile'
. '|.*|build/*|*.markdown|*.phar|*LICENSE|*AUTHORS|*CHANGELOG|*.dist|*.tpl|.travis.yml'
. '|*squizlabs*|*fabpot*'
. '" && chmod a+x ./bin/md2resume.phar'
. ' && mv ./bin/md2resume.phar ./bin/md2resume';
pake_sh($command, true);
}
function run_sniff()
{
pake_echo_comment('Checking files for PSR2');
pake_sh('./vendor/bin/phpcs -p --standard=PSR2 ./src/ ./md2resume_dev.php', true);
}
function run_fixer()
{
pake_echo_comment('Running php-cs-fixer');
pake_sh(
'./vendor/bin/php-cs-fixer fix ./md2resume_dev.php'
. ' && ./vendor/bin/php-cs-fixer fix ./src/Resume/Cli/'
. ' && ./vendor/bin/php-cs-fixer fix ./src/Resume/Command/',
true
);
}
function run_readme()
{
pake_echo_comment('Updating README documentation');
$startPoint = '## Help';
$endPoint = '## Examples';
$readme = file_get_contents('README.md');
$help = shell_exec('php ./md2resume_dev.php list --no-interaction');
$output = preg_replace(
'/('.preg_quote($startPoint).')(.*)('.preg_quote($endPoint).')/si',
"$1\n```\n" . $help . "\n```\n$3",
$readme
);
file_put_contents('README.md', $output);
}
function run_mv()
{
pake_sh('cp ./bin/md2resume ~/bin/md2resume', true);
}
/* End of pakefile */

View File

@ -18,8 +18,6 @@ class Resume extends Application
public function initialize($templatePath, $consoleTemplatePath, $project)
{
$runSetup = false;
// Add the composer information for use in version info and such.
$this->project = $project;
@ -40,7 +38,6 @@ class Resume extends Application
// Load our commands into the application
$this->add(new Command\HtmlCommand());
$this->add(new Command\PdfCommand());
$this->add(new Command\SelfUpdateCommand());
$this->add(new Command\StatsCommand());
$this->add(new Command\TemplatesCommand());
$this->add(new Command\VersionCommand());

View File

@ -83,7 +83,7 @@ class PdfCommand extends HtmlCommand
file_put_contents($pdfSource, $rendered);
// Process the document with wkhtmltopdf
exec('wkhtmltopdf ' . $pdfSource .' ' . $destFilename);
exec('wkhtmltopdf --dpi 300 ' . $pdfSource .' ' . $destFilename);
// Unlink the temporary file
unlink($pdfSource);

View File

@ -1,86 +0,0 @@
<?php
namespace Resume\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SelfUpdateCommand extends Command
{
protected function configure()
{
$this
->setName('selfupdate')
->setDescription('Updates md2resume.phar to the latest version.')
->setHelp(
<<<EOT
The <info>self-update</info> command checks github for newer
versions of the command line client and if found, installs the latest.
EOT
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->app = $this->getApplication();
$localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
$tempFilename = dirname($localFilename) . '/' . basename($localFilename, '.phar').'-temp.phar';
if (substr($localFilename, -4) === '.php') {
throw new \Exception('You must run this from the compiled phar file.');
}
// check for permissions in local filesystem before start connection process
if (!is_writable($tempDirectory = dirname($tempFilename))) {
throw new \Exception(
'Self update failed: the "' . $tempDirectory
. '" directory used to download the temp file could not be written'
);
}
if (!is_writable($localFilename)) {
throw new \Exception(
'Self update failed: the "' . $localFilename . '" file could not be written'
);
}
$protocol = extension_loaded('openssl') ? 'https' : 'http';
$latest = trim(file_get_contents($protocol . $this->app->project->selfupdateversion, false));
if ($this->app->project->version !== $latest) {
$output->writeln(sprintf("Updating to version <info>%s</info>.", $latest));
$remoteFilename = $protocol . $this->app->project->selfupdatepath;
$phar = file_get_contents($remoteFilename);
file_put_contents($tempFilename, $phar);
if (!file_exists($tempFilename)) {
$output->writeln('<error>The download of the new version failed for an unexpected reason</error>');
return 1;
}
try {
@chmod($tempFilename, 0777 & ~umask());
// test the phar validity
$phar = new \Phar($tempFilename);
// free the variable to unlock the file
unset($phar);
rename($tempFilename, $localFilename);
} catch (\Exception $e) {
@unlink($tempFilename);
if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
throw $e;
}
$output->writeln('<error>The download is corrupted ('.$e->getMessage().').</error>');
$output->writeln('<error>Please re-run the self-update command to try again.</error>');
}
} else {
$output->writeln("<info>You are using the latest version.</info>");
}
}
}
/* End of file SelfUpdateCommand.php */

View File

@ -0,0 +1,136 @@
/*---------------------------------------------------
LESS Elements 0.6
---------------------------------------------------
A set of useful LESS mixins by Dmitry Fadeyev
Special thanks for mixin suggestions to:
Kris Van Herzeele,
Benoit Adam,
Portenart Emile-Victor,
Ryan Faerman
More info at: http://lesselements.com
-----------------------------------------------------*/
.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) {
background: @color;
background: -webkit-gradient(linear,
left bottom,
left top,
color-stop(0, @start),
color-stop(1, @stop));
background: -ms-linear-gradient(bottom,
@start,
@stop);
background: -moz-linear-gradient(center bottom,
@start 0%,
@stop 100%);
}
.bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) {
background: @color;
background: -webkit-gradient(linear,
left bottom,
left top,
color-stop(0, rgb(@start,@start,@start)),
color-stop(1, rgb(@stop,@stop,@stop)));
background: -ms-linear-gradient(bottom,
rgb(@start,@start,@start) 0%,
rgb(@start,@start,@start) 100%);
background: -moz-linear-gradient(center bottom,
rgb(@start,@start,@start) 0%,
rgb(@stop,@stop,@stop) 100%);
}
.bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) {
border-top: solid 1px @top-color;
border-left: solid 1px @left-color;
border-right: solid 1px @right-color;
border-bottom: solid 1px @bottom-color;
}
.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {
-webkit-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
-moz-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
}
.rounded(@radius: 2px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
-moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;
}
.border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
-webkit-border-top-right-radius: @topright;
-webkit-border-bottom-right-radius: @bottomright;
-webkit-border-bottom-left-radius: @bottomleft;
-webkit-border-top-left-radius: @topleft;
-moz-border-radius-topright: @topright;
-moz-border-radius-bottomright: @bottomright;
-moz-border-radius-bottomleft: @bottomleft;
-moz-border-radius-topleft: @topleft;
border-top-right-radius: @topright;
border-bottom-right-radius: @bottomright;
border-bottom-left-radius: @bottomleft;
border-top-left-radius: @topleft;
-moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;
}
.opacity(@opacity: 0.5) {
-moz-opacity: @opacity;
-khtml-opacity: @opacity;
-webkit-opacity: @opacity;
opacity: @opacity;
}
.transition-duration(@duration: 0.2s) {
-moz-transition-duration: @duration;
-webkit-transition-duration: @duration;
transition-duration: @duration;
}
.rotation(@deg:5deg){
-webkit-transform: rotate(@deg);
-moz-transform: rotate(@deg);
transform: rotate(@deg);
}
.scale(@ratio:1.5){
-webkit-transform:scale(@ratio);
-moz-transform:scale(@ratio);
transform:scale(@ratio);
}
.transition(@duration:0.2s, @ease:ease-out) {
-webkit-transition: all @duration @ease;
-moz-transition: all @duration @ease;
transition: all @duration @ease;
}
.inner-shadow(@horizontal:0, @vertical:1px, @blur:2px, @alpha: 0.4) {
-webkit-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
-moz-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
}
.box-shadow(@arguments) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) {
-moz-column-width: @colwidth;
-moz-column-count: @colcount;
-moz-column-gap: @colgap;
-moz-column-rule-color: @columnRuleColor;
-moz-column-rule-style: @columnRuleStyle;
-moz-column-rule-width: @columnRuleWidth;
-webkit-column-width: @colwidth;
-webkit-column-count: @colcount;
-webkit-column-gap: @colgap;
-webkit-column-rule-color: @columnRuleColor;
-webkit-column-rule-style: @columnRuleStyle;
-webkit-column-rule-width: @columnRuleWidth;
column-width: @colwidth;
column-count: @colcount;
column-gap: @colgap;
column-rule-color: @columnRuleColor;
column-rule-style: @columnRuleStyle;
column-rule-width: @columnRuleWidth;
}
.translate(@x:0, @y:0) {
-moz-transform: translate(@x, @y);
-webkit-transform: translate(@x, @y);
-o-transform: translate(@x, @y);
-ms-transform: translate(@x, @y);
transform: translate(@x, @y);
}

502
templates/roboto/css/normalize.css vendored Normal file
View File

@ -0,0 +1,502 @@
/*! normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */
/* =============================================================================
HTML5 display definitions
========================================================================== */
/*
* Corrects block display not defined in IE6/7/8/9 & FF3
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
/*
* Corrects inline-block display not defined in IE6/7/8/9 & FF3
*/
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
/*
* Prevents modern browsers from displaying 'audio' without controls
*/
audio:not([controls]) {
display: none;
}
/*
* Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
* Known issue: no IE6 support
*/
[hidden] {
display: none;
}
/* =============================================================================
Base
========================================================================== */
/*
* 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
* http://clagnut.com/blog/348/#c790
* 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
* www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
*/
html {
font-size: 100%; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-ms-text-size-adjust: 100%; /* 2 */
}
/*
* Addresses font-family inconsistency between 'textarea' and other form elements.
*/
html,
button,
input,
select,
textarea {
font-family: sans-serif;
}
/*
* Addresses margins handled incorrectly in IE6/7
*/
body {
margin: 0;
}
/* =============================================================================
Links
========================================================================== */
/*
* Addresses outline displayed oddly in Chrome
*/
a:focus {
outline: thin dotted;
}
/*
* Improves readability when focused and also mouse hovered in all browsers
* people.opera.com/patrickl/experiments/keyboard/test
*/
a:hover,
a:active {
outline: 0;
}
/* =============================================================================
Typography
========================================================================== */
/*
* Addresses font sizes and margins set differently in IE6/7
* Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
h2 {
font-size: 1.5em;
margin: 0.83em 0;
}
h3 {
font-size: 1.17em;
margin: 1em 0;
}
h4 {
font-size: 1em;
margin: 1.33em 0;
}
h5 {
font-size: 0.83em;
margin: 1.67em 0;
}
h6 {
font-size: 0.75em;
margin: 2.33em 0;
}
/*
* Addresses styling not present in IE7/8/9, S5, Chrome
*/
abbr[title] {
border-bottom: 1px dotted;
}
/*
* Addresses style set to 'bolder' in FF3+, S4/5, Chrome
*/
b,
strong {
font-weight: bold;
}
blockquote {
margin: 1em 40px;
}
/*
* Addresses styling not present in S5, Chrome
*/
dfn {
font-style: italic;
}
/*
* Addresses styling not present in IE6/7/8/9
*/
mark {
background: #ff0;
color: #000;
}
/*
* Addresses margins set differently in IE6/7
*/
p,
pre {
margin: 1em 0;
}
/*
* Corrects font family set oddly in IE6, S4/5, Chrome
* en.wikipedia.org/wiki/User:Davidgothberg/Test59
*/
pre,
code,
kbd,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}
/*
* Improves readability of pre-formatted text in all browsers
*/
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
/*
* 1. Addresses CSS quotes not supported in IE6/7
* 2. Addresses quote property not supported in S4
*/
/* 1 */
q {
quotes: none;
}
/* 2 */
q:before,
q:after {
content: '';
content: none;
}
small {
font-size: 75%;
}
/*
* Prevents sub and sup affecting line-height in all browsers
* gist.github.com/413930
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* =============================================================================
Lists
========================================================================== */
/*
* Addresses margins set differently in IE6/7
*/
dl,
menu,
ol,
ul {
margin: 1em 0;
}
dd {
margin: 0 0 0 40px;
}
/*
* Addresses paddings set differently in IE6/7
*/
menu,
ol,
ul {
padding: 0 0 0 40px;
}
/*
* Corrects list images handled incorrectly in IE7
*/
nav ul,
nav ol {
list-style: none;
list-style-image: none;
}
/* =============================================================================
Embedded content
========================================================================== */
/*
* 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
* 2. Improves image quality when scaled in IE7
* code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
*/
img {
border: 0; /* 1 */
-ms-interpolation-mode: bicubic; /* 2 */
}
/*
* Corrects overflow displayed oddly in IE9
*/
svg:not(:root) {
overflow: hidden;
}
/* =============================================================================
Figures
========================================================================== */
/*
* Addresses margin not present in IE6/7/8/9, S5, O11
*/
figure {
margin: 0;
}
/* =============================================================================
Forms
========================================================================== */
/*
* Corrects margin displayed oddly in IE6/7
*/
form {
margin: 0;
}
/*
* Define consistent border, margin, and padding
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/*
* 1. Corrects color not being inherited in IE6/7/8/9
* 2. Corrects text not wrapping in FF3
* 3. Corrects alignment displayed oddly in IE6/7
*/
legend {
border: 0; /* 1 */
padding: 0;
white-space: normal; /* 2 */
*margin-left: -7px; /* 3 */
}
/*
* 1. Corrects font size not being inherited in all browsers
* 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
* 3. Improves appearance and consistency in all browsers
*/
button,
input,
select,
textarea {
font-size: 100%; /* 1 */
margin: 0; /* 2 */
vertical-align: baseline; /* 3 */
*vertical-align: middle; /* 3 */
}
/*
* Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
*/
button,
input {
line-height: normal; /* 1 */
}
/*
* 1. Improves usability and consistency of cursor style between image-type 'input' and others
* 2. Corrects inability to style clickable 'input' types in iOS
* 3. Removes inner spacing in IE7 without affecting normal text inputs
* Known issue: inner spacing remains in IE6
*/
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer; /* 1 */
-webkit-appearance: button; /* 2 */
*overflow: visible; /* 3 */
}
/*
* Re-set default cursor for disabled elements
*/
button[disabled],
input[disabled] {
cursor: default;
}
/*
* 1. Addresses box sizing set to content-box in IE8/9
* 2. Removes excess padding in IE8/9
* 3. Removes excess padding in IE7
Known issue: excess padding remains in IE6
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
*height: 13px; /* 3 */
*width: 13px; /* 3 */
}
/*
* 1. Addresses appearance set to searchfield in S5, Chrome
* 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/*
* Removes inner padding and search cancel button in S5, Chrome on OS X
*/
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
/*
* Removes inner padding and border in FF3+
* www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/*
* 1. Removes default vertical scrollbar in IE6/7/8/9
* 2. Improves readability and alignment in all browsers
*/
textarea {
overflow: auto; /* 1 */
vertical-align: top; /* 2 */
}
/* =============================================================================
Tables
========================================================================== */
/*
* Remove most spacing between table cells
*/
table {
border-collapse: collapse;
border-spacing: 0;
}

View File

@ -0,0 +1,96 @@
body.pdf {
color: black;
a {
text-decoration: none;
color: black;
&[href$='.pdf'],
&[href*='github'] {
display: none;
}
}
.container {
width: 1080px;
margin: 0 auto;
padding: 0;
background: none;
border: 0;
text-align: left;
}
.resume {
position:relative;
padding: 40px 80px;
}
h1 {
letter-spacing: 0;
margin-top: 0;
text-transform: uppercase;
font-weight: normal;
}
h2 {
letter-spacing: 0;
text-transform: uppercase;
font-style: italic;
font-weight: normal;
}
h3 {
font-style: normal;
+ p {
}
}
blockquote {
top: 40px;
right: 50px;
position: absolute;
}
ul {
}
ul li {
}
// ul dl {
// margin: 0;
// padding: 0.3em 0 0;
// dt {
// font-size: 122%;
// font-weight: normal;
// margin: 0 0 .75em;
// }
// dd {
// padding: 0 4em 0 0;
// }
// }
// ol {
// margin: .7em 0 0;
// }
// ol li {
// margin: 0;
// }
// dl {
// margin: .7em 0 0;
// page-break-inside: avoid !important;
// display: block;
// // width:90%;
// em {
// font-size: 130%;
// font-style: normal;
// }
// }
}

View File

@ -0,0 +1,250 @@
.clearfix {
zoom: 1;
&:after {
display: block;
visibility: hidden;
height: 0;
clear: both;
content: ".";
}
}
body {
/*font: 12px normal 'Hoefler Text', Times New Roman, Times, serif;*/
/*font-family: 'Roboto', sans-serif;*/
color: #444;
}
h1, h2, h3, h4, ul dl dt {
/*font-family: Futura, "Century Gothic", AppleGothic, sans-serif;*/
}
.container {
margin: 0 auto;
padding: 0;
background: whiteSmoke;
border: solid #666;
border-width: 8px 0 2px 0;
text-align: left;
}
.resume {
position:relative;
padding: 10px 20px;
}
a[href$='.pdf'] {
background: #666;
color: white;
padding: 6px 12px;
margin-bottom: 6px;
text-decoration: none;
position: absolute;
top: 15px;
right: 25px;
}
a[href*='github'] {
background: #000;
color: white;
padding: 6px 12px;
margin-bottom: 6px;
text-decoration: none;
position: absolute;
top: 45px;
right: 25px;
&:hover {
background: white;
color: #000;
}
}
/*p {
font-size: 1em;
}*/
blockquote {
margin: 0;
padding: 0;
line-height: 1.4em;
}
blockquote a {
color: #990003;
display: block;
}
hr {
display: block;
position: relative;
padding: 0;
margin: 18px auto;
width: 100%;
clear: both;
border: 0;
border-top: 1px solid #CCC;
font-size: 1px;
line-height: 0;
overflow: visible;
page-break-after: avoid;
}
ul {
margin: 0;
padding: 0;
}
h1 {
margin: 0;
padding: 0;
font-size: 3em;
letter-spacing: -1px;
font-weight: normal;
}
h2 {
margin: 0;
padding: 0;
font-size: 2em;
font-style: italic;
letter-spacing: -1px;
font-weight: normal;
}
h3 {
border-bottom: 5px solid #000;
margin: 0;
padding: .25em 0 .25em .3em;
font-size: 2em;
font-style: italic;
font-weight: normal;
}
h3+p,
h3~ul {
margin: .2em 0 1.2em;
padding: 0;
display: block;
font-size: 1em;
line-height: 1.5;
}
h3~ul {
padding-left: 1.5em;
}
h4 {
font-size: 1.5em;
margin: 0;
}
ul li {
margin: 0;
padding: 0;
/*font-size: 1.2em;*/
}
ul,
ol {
li ul li {
font-style: italic;
margin: 0 0 0 1.5em;
width: 80%;
}
}
ul dl {
margin: .3em 0 0;
padding: 0;
width: 100%;
dt {
/*font-size: 1em;*/
}
dd {
margin: 0 0 1em;
padding: 0 2em 0 0;
font-size: .8em;
line-height: 1.5em;
}
}
ol {
margin: 0;
margin-left: 1em;
padding: 0 0 .75em;
width: 84%;
display: inline-block;
}
ol li {
margin: 0 0 0 .5em;
padding: 0;
border-top: 1px solid #CCCCCC;
width: 100%;
/*float: left;*/
/*list-style: none;*/
line-height: 1.5em;
font-size: 1em;
}
ol li:nth-child(1) {
border-top: 0;
}
dl {
display: inline-block;
width: 95%;
margin: 0;
padding: 0;
dt {
margin: 0;
padding: 0;
/*font-size: 1.4em;*/
}
dd {
padding: 0;
font-size: 0.8em;
}
strong {
display: block;
font-size: 1.2em;
}
em {
display: block;
font-size: 1.2em;
margin: .15em 0 .5em;
}
}
#experience {
~ dl {
dt {
float: left;
margin-top: 1em;
}
dd {
float: right;
text-align: right;
width: 45%;
}
}
~ p {
width: 85%;
}
~ ul {
width: 85%;
}
~ ol li {
border: 0;
font-size: 1em;
}
}
#footer {
display: none;
+ p {
width: 100%;
font-size: 0.8em;
text-align: center;
}
}

View File

@ -0,0 +1,159 @@
/*
Mobile layout
240479 px
Zoomed out below 320 px
*/
@media screen and (min-width: 15em) {
}
/*
Wide mobile layout
480-767 px
Zoomed in above 480 px
*/
@media screen and (min-width: 30em) {
}
/*
Tablet layout
600-911 px
Zoomed in above 600 px
*/
@media screen and (min-width: 37.5em) {
body {
padding: 2em 0;
}
blockquote {
top: 10px;
right: 50px;
position: absolute;
}
h1 { /* Open up the top section height so we don't collapse on the blockquote */
margin-top: .5em;
}
ol {
margin: 0 0 0 1em;
}
ol li {
width: 50%;
margin: 0;
}
ol li:nth-child(1), ol li:nth-child(2) {
border-top: none;
}
}
/*
Widescreen layout
912-1887 px
Zoomed in above 912 px
*/
/*@media screen and (min-width: 57em) {
.container {
width: 912px;
}
.resume {
position:relative;
padding: 40px 50px;
}
blockquote {
top: 40px;
right: 50px;
position: absolute;
}
h1 {
margin-top: 0;
font-size: 48px;
text-transform: uppercase;
letter-spacing: 3px;
font-weight: normal;
}
h2 {
text-transform: uppercase;
font-style: italic;
letter-spacing: 2px;
font-weight: normal;
}
h3 {
float: left;
width: 16%;
}
h3+p {
float: left;
width: 84%;
}
ul li {
width: 28%;
float: left;
}
ul dl {
dt {
font-size: 122%;
font-weight: normal;
margin-bottom: .75em;
}
dd {
padding: 0 4em 0 0;
}
}
ol {
float: left;
width: 84%;
margin: .6em 0 0;
}
ol li {
width: 33%;
margin: 0;
}
ol li:nth-child(3n) {
width: 34%;
}
ol li:nth-child(1), ol li:nth-child(2), ol li:nth-child(3) {
border-top: none;
}
dl {
margin: .5em 0 0;
dt {
}
dd {
}
strong {
float: right;
margin-top: -2em;
}
em {
font-size: 130%;
font-style: normal;
}
}
}*/
/*
Huge-screen layout
1888-2520 px
Zoomed in above 1920 px
*/
@media screen and (min-width: 118em) {
}

View File

@ -0,0 +1 @@
Layout with static header, format for GitHub link, and Google Roboto font.

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
{{#reload}}
<meta http-equiv="refresh" content="{{refresh_rate}}">
{{/reload}}
<title>{{title}}</title>
<style type="text/css">
{{{style}}}
</style>
</head>
<body class="">
<div class="container">
<header>{{{header}}}</header>
<div class="resume">
{{{resume}}}
</div>
<footer>{{{footer}}}</footer>
</div>
</body>
</html>

View File

@ -3,9 +3,10 @@
$app = require __DIR__ . '/../vendor/autoload.php';
$app->add('Resume', __DIR__ . '/../src');
use PHPUnit\Framework\TestCase;
use Resume\Cli\Resume;
class ResumeTest extends \PHPUnit_Framework_TestCase
class ResumeTest extends TestCase
{
public $console;
@ -14,6 +15,8 @@ class ResumeTest extends \PHPUnit_Framework_TestCase
$templatePath = realpath(__DIR__ . '/../templates/');
$consoleTemplatePath = realpath(__DIR__ . '/../src/Resume/Templates');
$project = json_decode(file_get_contents(__DIR__ . '/../composer.json'));
$project->version = 0;
$this->console = new Resume();
$this->console->initialize($templatePath, $consoleTemplatePath, $project);
}

View File

@ -1 +0,0 @@
2.0.10