Improve class handling in PDF

* Update phar
* Fix several sniff errors
* Remove unused converter file
* Update README with better quickstart information
This commit is contained in:
Craig Davis 2014-01-12 14:33:43 -07:00
parent d225525927
commit b87c193db5
6 changed files with 58 additions and 749 deletions

View File

@ -16,17 +16,19 @@ at the [blog post for the project][blog].
## Features ## Features
* Three styles to choose from: modern, blockish, unstyled * Three styles to choose from: modern, blockish, unstyled (Fork and add more!)
* PDF generation via [wkhtmltopdf][wkhtmltopdf] * PDF generation via [wkhtmltopdf][wkhtmltopdf]
* Responsive design for multiple device viewport sizes * Responsive design for multiple device viewport sizes
* Simple Markdown formatting * Simple Markdown formatting
* Single file deployment * Single file deployment (no external stylesheets)
* You can now version control and branch your resume. * You can now version control and branch your resume.
## Quickstart ## Quickstart
php ./bin/resume.php --source resume/sample.md There is no installation or need to run composer. Just run the phar file:
php ./bin/resume.php --source resume/sample.md --pdf
./bin/md2resume html examples/source/sample.md examples/output/
./bin/md2resume pdf examples/source/sample.md examples/output/
## Help ## Help
@ -57,45 +59,56 @@ at the [blog post for the project][blog].
Choose a template with the -t option. Choose a template with the -t option.
php ./bin/resume.php --source resume/sample.md -t blockish ./bin/md2resume html --template blockish examples/source/sample.md examples/output/
If you want to edit your markdown resume in your editor while watching it If you want to edit your markdown resume in your editor while watching it
update in your browser, run this command: update in your browser, run this command:
watch php ./bin/resume.php -s resume/sample.md -r watch ./bin/md2resume html --refresh examples/source/sample.md examples/output/
This makes the build script run periodically, and html document will refresh This makes the build script run periodically, and html document will refresh
every two seconds via a meta tag. Open the `./ouput/sample.html` file in every two seconds via a meta tag. Open the `./examples/ouput/sample.html` file
your browser, and then just save your markdown document when you want to see in your browser, and then just save your markdown document when you want to see
a fresh preview. a fresh preview.
## Development ## Authoring Your Resume
Markdown is limited to basic html markup. Follow the `resume/sample.md` file Markdown is limited to basic html markup. Follow the `examples/source/sample.md`
as a guideline. This file includes various headers and several nested elements. file as a guideline. This file includes various headers and several nested
This allows us to construct a semantic HTML document for the resume, and then elements. This allows us to construct a semantic HTML document for the resume,
use a CSS rules to display a very nice resume. Note that because we have very and then use a CSS rules to display a very nice resume. Note that because we
few ways to nest or identify elements that many of the css rules are based have very few ways to nest or identify elements that many of the css rules are
on descendant and adjacent selectors. based on descendant and adjacent selectors.
## Development Dependencies ## Feature Development
* composer install The application is deployed as a compiled phar file. In order to add new
* pear install PHP_CodeSniffer commands, you'll need to first install the dependencies:
* `composer install`
* `pear install PHP_CodeSniffer`
* [install pake][pake] * [install pake][pake]
After that, you can run the `md2resume_dev.php` file from the command line.
Check out the pake tooling for more information about the build.
## TODO ## TODO
* Google Analytics include * Google Analytics include
* CDN for fonts
## Acknowledgments ## Acknowledgments
The initial inspiration is from the [Sample Resume Template][srt]. The initial inspiration is from the [Sample Resume Template][srt].
However, no HTML from that project has been used in this. General layout has been reused, and media queries However, no HTML from that project has been used in this. General layout has
have been added. It's a nice template, and if you are a more comfortable with html than markdown, you should use it. been reused, and media queries have been added. It's a nice template, and if you
are a more comfortable with html than markdown, you should use it.
## Changelog ## Changelog
* __2.0.0__ : Complete rewrite with the [symfony console component][console].
Deployment is no done with a compiled phar file, and development dependencies
are managed with composer.
* __0.9.0__ : Add composer and update README with new changelog * __0.9.0__ : Add composer and update README with new changelog
* __0.8.8__ : Add Chinese text example (@ishitcno1) * __0.8.8__ : Add Chinese text example (@ishitcno1)
* __0.8.7__ : Update pdf formatting of the modern template (@roleary) * __0.8.7__ : Update pdf formatting of the modern template (@roleary)
@ -110,3 +123,4 @@ have been added. It's a nice template, and if you are a more comfortable with ht
[blog]: http://there4development.com/blog/2012/12/31/markdown-resume-builder/ [blog]: http://there4development.com/blog/2012/12/31/markdown-resume-builder/
[pake]: https://github.com/indeyets/pake/wiki/Installing-Pake [pake]: https://github.com/indeyets/pake/wiki/Installing-Pake
[wkhtmltopdf]: https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF [wkhtmltopdf]: https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF
[console]: http://symfony.com/doc/current/components/console/introduction.html

Binary file not shown.

View File

@ -1,691 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Craig Davis | Senior PHP Developer, UX Director</title>
<style type="text/css">
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section,
summary {
display: block;
}
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
audio:not([controls]) {
display: none;
}
[hidden] {
display: none;
}
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
button,
input,
select,
textarea {
font-family: sans-serif;
}
body {
margin: 0;
}
a:focus {
outline: thin dotted;
}
a:hover,
a:active {
outline: 0;
}
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;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
blockquote {
margin: 1em 40px;
}
dfn {
font-style: italic;
}
mark {
background: #ff0;
color: #000;
}
p,
pre {
margin: 1em 0;
}
pre,
code,
kbd,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
}
q {
quotes: none;
}
q:before,
q:after {
content: '';
content: none;
}
small {
font-size: 75%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
dl,
menu,
ol,
ul {
margin: 1em 0;
}
dd {
margin: 0 0 0 40px;
}
menu,
ol,
ul {
padding: 0 0 0 40px;
}
nav ul,
nav ol {
list-style: none;
list-style-image: none;
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 0;
}
form {
margin: 0;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
border: 0;
padding: 0;
white-space: normal;
*margin-left: -7px;
}
button,
input,
select,
textarea {
font-size: 100%;
margin: 0;
vertical-align: baseline;
*vertical-align: middle;
}
button,
input {
line-height: normal;
}
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer;
-webkit-appearance: button;
*overflow: visible;
}
button[disabled],
input[disabled] {
cursor: default;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
*height: 13px;
*width: 13px;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
vertical-align: top;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body.pdf {
color: black;
}
body.pdf a {
text-decoration: none;
color: black;
}
body.pdf .container {
width: 1000px;
margin: 0 auto;
padding: 0;
background: none;
border: none;
border-width: 8px 0 2px 0;
text-align: left;
}
body.pdf .resume {
position: relative;
padding: 40px 80px;
}
body.pdf a[href$='.pdf'] {
display: none;
}
body.pdf h1 {
letter-spacing: 0;
margin-top: 0;
font-size: 48px;
text-transform: uppercase;
font-weight: normal;
}
body.pdf h2 {
letter-spacing: 0;
text-transform: uppercase;
font-style: italic;
font-weight: normal;
}
body.pdf h3 {
float: left;
width: 16%;
font-style: normal;
}
body.pdf h3+p {
float: left;
width: 84%;
}
body.pdf blockquote {
top: 40px;
right: 50px;
position: absolute;
}
body.pdf ul li {
width: 28%;
float: left;
}
body.pdf ul dl {
margin: 0;
padding: 0.3em 0 0;
}
body.pdf ul dl dt {
font-size: 122%;
font-weight: normal;
margin: 0 0 .75em;
}
body.pdf ul dl dd {
padding: 0 4em 0 0;
}
body.pdf ol {
float: left;
width: 84%;
margin: .7em 0 0;
}
body.pdf ol li {
width: 33%;
margin: 0;
}
body.pdf ol li:nth-child(3n) {
width: 34%;
}
body.pdf ol li:nth-child(1),
body.pdf ol li:nth-child(2),
body.pdf ol li:nth-child(3) {
border-top: none;
}
body.pdf dl {
margin: .7em 0 0;
page-break-inside: avoid !important;
display: block;
width: 84%;
float: left;
}
body.pdf dl strong {
float: right;
margin-top: -2em;
}
body.pdf dl em {
font-size: 130%;
font-style: normal;
}
.clearfix {
zoom: 1;
}
.clearfix:after {
display: block;
visibility: hidden;
height: 0;
clear: both;
content: ".";
}
body {
font-family: 'Hoefler Text', Times New Roman, Times, 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 {
color: #990003;
}
a[href$='.pdf'] {
display: inline-block;
background: #666;
color: white;
padding: 6px 12px;
margin-bottom: 6px;
text-decoration: none;
}
blockquote {
margin: 0;
padding: 0;
line-height: 1.4em;
}
hr {
display: block;
position: relative;
padding: 0;
margin: 18px auto;
width: 100%;
clear: both;
border: none;
border-top: 1px solid #CCC;
font-size: 1px;
line-height: 0;
overflow: visible;
page-break-after: avoid;
}
h1 {
margin: 0;
padding: 0;
font-size: 36px;
letter-spacing: -1px;
font-weight: normal;
}
h2 {
margin: 0;
padding: 0;
font-size: 18px;
font-style: italic;
letter-spacing: -1px;
font-weight: normal;
}
h3 {
margin: 0;
padding: 0 0 .5em;
font-size: 150%;
font-style: italic;
font-weight: normal;
}
h3+p {
margin: .6em 0 16px;
padding: 0;
display: block;
font-size: 104%;
line-height: 24px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
ul li {
margin: 0;
padding: 0;
}
ul dl {
margin: .3em 0 0;
padding: 0;
width: 100%;
}
ul dl dt {
font-size: 100%;
}
ul dl dd {
margin: 0 0 1em;
padding: 0 2em 0 0;
font-size: .8em;
line-height: 1.5em;
}
ol {
margin: 0;
padding: 0 0 .75em;
width: 84%;
display: inline-block;
}
ol li {
margin: 0 0 0 1em;
padding: 0;
border-top: 1px solid #CCCCCC;
width: 100%;
float: left;
list-style: none;
line-height: 24px;
font-size: 14px;
}
ol li:nth-child(1) {
border-top: none;
}
dl {
display: inline-block;
width: 75%;
margin: 0;
padding: 0;
}
dl dt {
margin: 0;
padding: 0;
font-size: 140%;
}
dl dd {
margin: 0 0 1.5em;
padding: 0;
font-size: 80%;
line-height: 1.4em;
}
dl strong {
display: block;
}
dl em {
display: block;
font-size: 110%;
margin: .15em 0 .5em;
font-style: bold;
}
#footer {
display: none;
}
#footer + p {
width: 100%;
font-size: 11px;
text-align: center;
}
@media screen and (min-width: 37.5em) {
body {
padding: 2em 0;
}
blockquote {
top: 10px;
right: 50px;
position: absolute;
}
h1 {
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;
}
}
@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;
}
ul dl 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;
}
dl strong {
float: right;
margin-top: -2em;
}
dl em {
font-size: 130%;
font-style: normal;
}
}
</style>
</head>
<body class="">
<div class="container">
<div class="resume">
<h1>Craig Davis</h1>
<h2>Senior PHP Developer, UX Director</h2>
<blockquote>
<p><a href="resume.pdf">Download PDF</a><br />
<a href="craig@there4development.com">craig@there4development.com</a><br />
(999) 888-7777</p>
</blockquote>
<hr />
<h3 id="profile">Profile</h3>
<p>Progressively evolve cross-platform ideas before impactful infomediaries. Energistically visualize tactical initiatives before cross-media catalysts for change.</p>
<hr />
<h3 id="skills">Skills</h3>
<ul>
<li><dl>
<dt>Web Design</dt>
<dd>Assertively exploit wireless initiatives rather than synergistic core competencies.</dd>
</dl></li>
<li><dl>
<dt>Interface Design</dt>
<dd>Credibly streamline mission-critical value with multifunctional functionalities.</dd>
</dl></li>
<li><dl>
<dt>Project Direction</dt>
<dd>Proven ability to lead and manage a wide variety of design and development projects in team and independent situations.</dd>
</dl></li>
</ul>
<hr />
<h3 id="technical">Technical</h3>
<ol>
<li>XHTML</li>
<li>CSS</li>
<li>Javascript</li>
<li>Jquery</li>
<li>PHP</li>
<li>CVS / Subversion</li>
<li>OS X</li>
<li>Windows XP/Vista</li>
<li>Linux</li>
</ol>
<hr />
<h3 id="experience">Experience</h3>
<dl>
<dt>Initrode Conglomerated</dt>
<dd><em>Principal and Creative Lead</em>
<strong>2004-2005</strong>
Intrinsicly transform flexible manufactured products without excellent intellectual capital. Energistically evisculate orthogonal architectures through covalent action items. Assertively incentivize sticky platforms without synergistic materials.</dd>
<dt>Gizmonic Institute Company (GIM)</dt>
<dd><em>Lead Web Designer</em>
<strong>2001-2004</strong>
Globally re-engineer cross-media schemas through viral methods of empowerment. Proactively grow long-term high-impact human capital and highly efficient innovation. Intrinsicly iterate excellent e-tailers with timely e-markets.</dd>
</dl>
<hr />
<h3 id="footer">Footer</h3>
<p>Craig Davis &#8212; <a href="craig@there4development.com">craig@there4development.com</a> &#8212; (999) 888-7777</p>
<hr />
</div>
</div>
</body>
</html>

View File

@ -1,9 +0,0 @@
<?php
namespace Resume\Cli;
class Converter
{
}
/* End of file Converter.php */

View File

@ -31,17 +31,17 @@ class HtmlCommand extends Command
'Output destination folder' 'Output destination folder'
) )
->addOption( ->addOption(
'template', 'template',
't', 't',
InputOption::VALUE_OPTIONAL, InputOption::VALUE_OPTIONAL,
'Which of the templates to use' 'Which of the templates to use'
) )
->addOption( ->addOption(
'refresh', 'refresh',
'r', 'r',
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'If set, the html will include a meta command to refresh the ' . 'If set, the html will include a meta command to refresh the ' .
'document every 5 seconds.' 'document every 5 seconds.'
); );
} }
@ -86,12 +86,8 @@ class HtmlCommand extends Command
if (!$template) { if (!$template) {
$template = $this->app->defaultTemplate; $template = $this->app->defaultTemplate;
} }
$templatePath = join(DIRECTORY_SEPARATOR, array( $templatePath = join(DIRECTORY_SEPARATOR, array($this->app->templatePath, basename($template)));
$this->app->templatePath, basename($template) $templateIndexPath = join(DIRECTORY_SEPARATOR, array($templatePath, 'index.html'));
));
$templateIndexPath = join(DIRECTORY_SEPARATOR, array(
$templatePath, 'index.html'
));
if (!file_exists($templateIndexPath)) { if (!file_exists($templateIndexPath)) {
$output->writeln( $output->writeln(
sprintf( sprintf(

View File

@ -26,10 +26,10 @@ class PdfCommand extends HtmlCommand
'Output destination folder' 'Output destination folder'
) )
->addOption( ->addOption(
'template', 'template',
't', 't',
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'Which of the templates to use' 'Which of the templates to use'
); );
} }
@ -46,13 +46,10 @@ class PdfCommand extends HtmlCommand
exec('wkhtmltopdf -V', $results, $returnVal); exec('wkhtmltopdf -V', $results, $returnVal);
if ($returnVal) { if ($returnVal) {
$output->writeln( $output->writeln(
sprintf( "\n<error>Error:</error> Unable to locate wkhtmltopdf.\n" .
"\n<error>Error:</error> Unable to locate wkhtmltopdf.\n" . " Please make sure that it is installed and available in " .
" Please make sure that it is installed and available in " . "your path. \n For installation help, please read: " .
"your path. \n For installation help, please read: " . "https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF \n\n",
"https://github.com/pdfkit/pdfkit/wiki/Installing-WKHTMLTOPDF \n\n",
$destination
),
$this->app->outputFormat $this->app->outputFormat
); );
@ -63,8 +60,10 @@ class PdfCommand extends HtmlCommand
// The pdf needs some extra css rules, and so we'll add them here // The pdf needs some extra css rules, and so we'll add them here
// to our html document // to our html document
// TODO: Update this with the simple DOM to add class $simpleDom = new \simple_html_dom($rendered);
$rendered = str_replace('body class=""', 'body class="pdf"', $rendered); $body = $simpleDom->find('body', 0);
$body->class = $body->class . ' pdf';
$rendered = (string) $simpleDom;
// Save to a temp destination for the pdf renderer to use // Save to a temp destination for the pdf renderer to use
file_put_contents($pdfSource, $rendered); file_put_contents($pdfSource, $rendered);
@ -78,7 +77,7 @@ class PdfCommand extends HtmlCommand
$output->writeln( $output->writeln(
sprintf( sprintf(
"Wrote pdf resume to: <info>%s</info>", "Wrote pdf resume to: <info>%s</info>",
$destination $destFilename
), ),
$this->app->outputFormat $this->app->outputFormat
); );