Skip to content

Commit 1a1e8ad

Browse files
committed
Add problem statement cloning to Grunt init task
1 parent 18f203e commit 1a1e8ad

File tree

6 files changed

+178
-8
lines changed

6 files changed

+178
-8
lines changed

gruntfile.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ module.exports = function(grunt)
2525
sourcePath: './src/',
2626
problemListPath: './storage/problems.json',
2727
problemUrlFormat: 'https://www.codeeval.com/browse/%s/',
28+
problemUrlFormatAlt: 'https://www.codeeval.com/public_sc/%s/',
2829
files:
2930
{
3031
meta: 'meta.yaml',
3132
input: 'input.txt',
3233
readme: 'readme.md',
34+
mirror: 'readme.pdf',
3335
languages:
3436
{
3537
c:

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"js-yaml": "~3.2.6",
1313
"slug": "~0.8.0",
1414
"word-wrap": "~1.0.2",
15-
"clui": "~0.3.1"
15+
"clui": "~0.3.1",
16+
"phantomjs-prebuilt": "2.1.12"
1617
}
1718
}

readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ Running "init-solution:1" (init-solution) task
106106
>> Created "solutions" directory in: src/easy/fizz-buzz
107107
>> Created meta.yaml in: src/easy/fizz-buzz
108108
>> Created readme.md in: src/easy/fizz-buzz
109+
>> Created readme.pdf in: src/easy/fizz-buzz
109110
>> Created input.txt in: src/easy/fizz-buzz
110111
>> Created solution.c in: src/easy/fizz-buzz/solutions/c
111112
>> Created solution.cpp in: src/easy/fizz-buzz/solutions/c++

tasks/init-solution.js

+43-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ module.exports = function(grunt)
22
{
33
'use strict';
44

5-
var path = require('path');
6-
var util = require('util');
7-
var request = require('request');
8-
var cheerio = require('cheerio');
9-
var yaml = require('js-yaml');
10-
var slug = require('slug');
11-
var wrap = require('word-wrap');
5+
var path = require('path');
6+
var util = require('util');
7+
var execFile = require('child_process').execFileSync;
8+
var request = require('request');
9+
var cheerio = require('cheerio');
10+
var phantom = require('phantomjs-prebuilt').path;
11+
var yaml = require('js-yaml');
12+
var slug = require('slug');
13+
var wrap = require('word-wrap');
1214

1315
require('array.prototype.find');
1416
require('./lib/to-title-case');
@@ -23,6 +25,7 @@ module.exports = function(grunt)
2325
this.requiresConfig([this.name, 'config', 'files', 'input']);
2426
this.requiresConfig([this.name, 'config', 'files', 'meta']);
2527
this.requiresConfig([this.name, 'config', 'files', 'readme']);
28+
this.requiresConfig([this.name, 'config', 'files', 'mirror']);
2629

2730
var config = grunt.config([this.name, 'config']);
2831

@@ -75,6 +78,7 @@ module.exports = function(grunt)
7578
{
7679
meta: path.join(solutionDir, config.files.meta),
7780
readme: path.join(solutionDir, config.files.readme),
81+
mirror: path.join(solutionDir, config.files.mirror),
7882
input: path.join(solutionDir, config.files.input),
7983
solutions: path.join(solutionDir, 'solutions')
8084
};
@@ -153,6 +157,38 @@ module.exports = function(grunt)
153157
grunt.log.ok('Created ' + config.files.readme + ' in: ' + solutionDir);
154158
})();
155159

160+
// Mirror problem statement.
161+
(function()
162+
{
163+
if(!grunt.option('overwrite') && grunt.file.isFile(paths.mirror))
164+
{
165+
grunt.log.writeln('Skipped ' + config.files.mirror +
166+
' -- already exists in: ' + solutionDir);
167+
168+
return;
169+
}
170+
171+
try
172+
{
173+
var job =
174+
[
175+
'./tools/mirror-problem-statement/rasterize.js',
176+
util.format(config.problemUrlFormatAlt, problemId),
177+
path.resolve(paths.mirror)
178+
];
179+
180+
execFile(phantom, job);
181+
182+
grunt.log.ok('Created ' + config.files.mirror + ' in: ' + solutionDir);
183+
}
184+
185+
catch(error)
186+
{
187+
grunt.fatal('Failed to mirror problem statement; ' +
188+
'rasterizer return code -> ' + error.status);
189+
}
190+
})();
191+
156192
// Make solution templates.
157193
function makeSolutionTemplates(problemHasInput)
158194
{
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
html, body
2+
{
3+
zoom: 0.78125;
4+
background: transparent;
5+
}
6+
7+
#main-navigation,
8+
#header,
9+
#fdbk_tab,
10+
#footer,
11+
#main header,
12+
.backtolist,
13+
h3 + img,
14+
#map-canvas,
15+
[title="Login"]
16+
{
17+
display: none;
18+
}
19+
20+
#container
21+
{
22+
margin: 0;
23+
border: none;
24+
background: transparent;
25+
}
26+
27+
.browse-challenge-page .inner
28+
{
29+
width: auto;
30+
}
31+
32+
#ce-content
33+
{
34+
padding: 0;
35+
}
36+
37+
.public_content
38+
{
39+
width: 100%;
40+
}
41+
42+
h3
43+
{
44+
margin-top: 2em;
45+
}
46+
47+
p
48+
{
49+
margin-bottom: 1.5em;
50+
}
51+
52+
pre
53+
{
54+
padding: 15px;
55+
border: 1px solid #ccc;
56+
background: transparent;
57+
page-break-inside: avoid;
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
var fs = require('fs'),
4+
sys = require('system'),
5+
page = require('webpage').create();
6+
7+
function die()
8+
{
9+
sys.stderr.write(Array.prototype.join.call(arguments, ' ') + '\n');
10+
phantom.exit(1);
11+
}
12+
13+
if(sys.args.length < 3)
14+
{
15+
die(['Usage:', sys.args[0], 'URL', 'file'].join(' '));
16+
}
17+
18+
page.paperSize =
19+
{
20+
format: 'Letter',
21+
orientation: 'portrait',
22+
margin: '10mm'
23+
};
24+
25+
page.onError = function() {};
26+
27+
page.onResourceRequested = function(data, request)
28+
{
29+
// Intercept and discard the Ace editor library since
30+
// it renders code blocks as garbage in the PDF.
31+
if(/ace_editor/i.test(data.url)) request.abort();
32+
};
33+
34+
page.open(sys.args[1], function(status)
35+
{
36+
if(status !== 'success')
37+
{
38+
die('Failed to load remote target.');
39+
}
40+
41+
var styles = fs.read(fs.absolute(phantom.libraryPath +
42+
fs.separator +
43+
'patch.css'));
44+
45+
page.evaluate(function(css)
46+
{
47+
// Inject override stylesheet.
48+
$('<style>').text(css.replace(/;/g, '!important;')).appendTo('head');
49+
50+
// Remove empty elements that mess with vertical flow from some pages.
51+
$('body *').filter(function()
52+
{
53+
var isEmpty = (this.innerHTML.trim() === ''),
54+
isTarget = (this.tagName.toLowerCase() in {h3: true, p: true});
55+
56+
return (isEmpty && isTarget);
57+
}).remove();
58+
59+
// Remove challenge sponsor branding.
60+
$('h3:contains("Sponsoring") + p').remove();
61+
$('h3:contains("Sponsoring")').remove();
62+
63+
// Patch I/O sample blocks since we're not using Ace.
64+
$('.description-input-output').contents().unwrap().wrap('<pre/>');
65+
}, styles);
66+
67+
window.setTimeout(function()
68+
{
69+
page.render(sys.args[2]);
70+
phantom.exit();
71+
}, 1e3);
72+
});

0 commit comments

Comments
 (0)