{"action":"created","comment":{"url":"https://api.github.com/repos/Financial-Times/next-article/pulls/comments/34573352","id":34573352,"diff_hunk":"@@ -1,29 +1,58 @@\n 'use strict';\n \n-var denodeify = require('denodeify');\n-var libxslt = require('bbc-xslt');\n+var fs = require('fs');\n+var tempWrite = require('temp-write');\n+var spawn = require('child_process').spawn;\n \n-// HACK: Body transforms have already unwrapped the document at this point.\n-function wrap(article) {\n-\treturn '<root>' + article + '</root>';\n-}\n+module.exports = function(content, stylesheet, params) {\n+\treturn new Promise(function(resolve, reject) {\n \n-function unwrap(article) {\n-\treturn article.replace(/<\\/?root>/g, '');\n-}\n+\t\ttempWrite(content, 'article.xml', function(err, tmpFile) {\n+\t\t\tif (err) {\n+\t\t\t\treturn reject(err);\n+\t\t\t}\n \n-module.exports = function bigReadTransform(article, opts) {\n-\tvar stylesheet = (opts && opts.stylesheet) || 'main';\n-\tvar parseFile = denodeify(libxslt.parseFile);\n+\t\t\tvar output = [];\n+\t\t\tvar errors = [];\n+\t\t\tvar options = [\n+\t\t\t\t'--html',\n+\t\t\t\t'--novalid',\n+\t\t\t\t'--encoding', 'utf-8'\n+\t\t\t];\n \n-\t// If you pass in an XML document you get an XML document\n-\tvar articleXML = libxslt.libxmljs.parseXml(opts && opts.wrap ? wrap(article) : article);\n+\t\t\tparams && Object.keys(params).forEach(function(param) {\n+\t\t\t\tvar string = typeof params[param] === 'string';\n+\t\t\t\toptions = options.concat(string ? '--stringparam' : '--param', param, params[param]);\n+\t\t\t});\n \n-\treturn parseFile(__dirname + '/../stylesheets/' + stylesheet + '.xsl').then(function(stylesheet) {\n-\t\tvar transformedXML = stylesheet.apply(articleXML, opts && opts.params);\n+\t\t\tvar xsltproc = spawn('xsltproc', options.concat(\n+\t\t\t\tprocess.cwd() + '/server/stylesheets/' + stylesheet + '.xsl',\n+\t\t\t\ttmpFile\n+\t\t\t));","path":"server/transforms/article-xslt.js","position":47,"original_position":47,"commit_id":"8db627c69489a60d7a5817fe32ea32d14cd72873","original_commit_id":"8db627c69489a60d7a5817fe32ea32d14cd72873","user":{"login":"matthew-andrews","id":825088,"avatar_url":"https://avatars.githubusercontent.com/u/825088?v=3","gravatar_id":"","url":"https://api.github.com/users/matthew-andrews","html_url":"https://github.com/matthew-andrews","followers_url":"https://api.github.com/users/matthew-andrews/followers","following_url":"https://api.github.com/users/matthew-andrews/following{/other_user}","gists_url":"https://api.github.com/users/matthew-andrews/gists{/gist_id}","starred_url":"https://api.github.com/users/matthew-andrews/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthew-andrews/subscriptions","organizations_url":"https://api.github.com/users/matthew-andrews/orgs","repos_url":"https://api.github.com/users/matthew-andrews/repos","events_url":"https://api.github.com/users/matthew-andrews/events{/privacy}","received_events_url":"https://api.github.com/users/matthew-andrews/received_events","type":"User","site_admin":false},"body":"`))` => `), { env: process.env })`","created_at":"2015-07-14T14:28:18Z","updated_at":"2015-07-14T14:28:18Z","html_url":"https://github.com/Financial-Times/next-article/pull/671#discussion_r34573352","pull_request_url":"https://api.github.com/repos/Financial-Times/next-article/pulls/671","_links":{"self":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/comments/34573352"},"html":{"href":"https://github.com/Financial-Times/next-article/pull/671#discussion_r34573352"},"pull_request":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/671"}}},"pull_request":{"url":"https://api.github.com/repos/Financial-Times/next-article/pulls/671","id":39693249,"html_url":"https://github.com/Financial-Times/next-article/pull/671","diff_url":"https://github.com/Financial-Times/next-article/pull/671.diff","patch_url":"https://github.com/Financial-Times/next-article/pull/671.patch","issue_url":"https://api.github.com/repos/Financial-Times/next-article/issues/671","number":671,"state":"open","locked":false,"title":"Spawn xsltproc","user":{"login":"i-like-robots","id":271645,"avatar_url":"https://avatars.githubusercontent.com/u/271645?v=3","gravatar_id":"","url":"https://api.github.com/users/i-like-robots","html_url":"https://github.com/i-like-robots","followers_url":"https://api.github.com/users/i-like-robots/followers","following_url":"https://api.github.com/users/i-like-robots/following{/other_user}","gists_url":"https://api.github.com/users/i-like-robots/gists{/gist_id}","starred_url":"https://api.github.com/users/i-like-robots/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/i-like-robots/subscriptions","organizations_url":"https://api.github.com/users/i-like-robots/orgs","repos_url":"https://api.github.com/users/i-like-robots/repos","events_url":"https://api.github.com/users/i-like-robots/events{/privacy}","received_events_url":"https://api.github.com/users/i-like-robots/received_events","type":"User","site_admin":false},"body":"This swaps out the dependency on Node bindings for libxml2 and libxslt and instead shells out to a precompiled [xsltproc](http://xmlsoft.org/XSLT/xsltproc2.html). This is stored within the repo in the `libxslt/` folder.\r\n\r\nOur Heroku instances are already equipped with libxml2-dev and libxslt-dev so compiling xsltproc is actually straightforward:\r\n\r\n```sh\r\nheroku run bash\r\n$ curl http://xmlsoft.org/sources/libxslt-1.1.28.tar.gz -o /tmp/libxslt.tar.gz\r\n$ mkdir /tmp/libxslt && tar -C /tmp/libxslt -xvf /tmp/libxslt.tar.gz\r\n$ cd /tmp/libxslt/libxslt-1.1.28 && ./configure --prefix=/app/libxslt && make && make install\r\n```\r\n\r\nTravis compiles it's own version too, see `.travis.yml`\r\n\r\nTo run locally just install libxslt with brew or aptitude or whatever.\r\n\r\n| Good points | Bad points |\r\n|---|---|\r\n| It works :ok: | Writing to a temp file is :-1: |\r\n| It supports HTML input/output properly :trophy: | Have we _really_ come to this? :confounded:  |\r\n| Avoids Node managing memory for C bindings and :boom: | |\r\n\r\n__Do not merge__, this needs battle testing on Heroku.","created_at":"2015-07-10T15:09:43Z","updated_at":"2015-07-14T14:28:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b46ddb12699bf8920a9889f200c2d5c6a1fe002e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Financial-Times/next-article/pulls/671/commits","review_comments_url":"https://api.github.com/repos/Financial-Times/next-article/pulls/671/comments","review_comment_url":"https://api.github.com/repos/Financial-Times/next-article/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Financial-Times/next-article/issues/671/comments","statuses_url":"https://api.github.com/repos/Financial-Times/next-article/statuses/8db627c69489a60d7a5817fe32ea32d14cd72873","head":{"label":"Financial-Times:matth/spawn-xsltproc","ref":"matth/spawn-xsltproc","sha":"8db627c69489a60d7a5817fe32ea32d14cd72873","user":{"login":"Financial-Times","id":3502508,"avatar_url":"https://avatars.githubusercontent.com/u/3502508?v=3","gravatar_id":"","url":"https://api.github.com/users/Financial-Times","html_url":"https://github.com/Financial-Times","followers_url":"https://api.github.com/users/Financial-Times/followers","following_url":"https://api.github.com/users/Financial-Times/following{/other_user}","gists_url":"https://api.github.com/users/Financial-Times/gists{/gist_id}","starred_url":"https://api.github.com/users/Financial-Times/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Financial-Times/subscriptions","organizations_url":"https://api.github.com/users/Financial-Times/orgs","repos_url":"https://api.github.com/users/Financial-Times/repos","events_url":"https://api.github.com/users/Financial-Times/events{/privacy}","received_events_url":"https://api.github.com/users/Financial-Times/received_events","type":"Organization","site_admin":false},"repo":{"id":26121818,"name":"next-article","full_name":"Financial-Times/next-article","owner":{"login":"Financial-Times","id":3502508,"avatar_url":"https://avatars.githubusercontent.com/u/3502508?v=3","gravatar_id":"","url":"https://api.github.com/users/Financial-Times","html_url":"https://github.com/Financial-Times","followers_url":"https://api.github.com/users/Financial-Times/followers","following_url":"https://api.github.com/users/Financial-Times/following{/other_user}","gists_url":"https://api.github.com/users/Financial-Times/gists{/gist_id}","starred_url":"https://api.github.com/users/Financial-Times/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Financial-Times/subscriptions","organizations_url":"https://api.github.com/users/Financial-Times/orgs","repos_url":"https://api.github.com/users/Financial-Times/repos","events_url":"https://api.github.com/users/Financial-Times/events{/privacy}","received_events_url":"https://api.github.com/users/Financial-Times/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Financial-Times/next-article","description":"Articles","fork":false,"url":"https://api.github.com/repos/Financial-Times/next-article","forks_url":"https://api.github.com/repos/Financial-Times/next-article/forks","keys_url":"https://api.github.com/repos/Financial-Times/next-article/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Financial-Times/next-article/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Financial-Times/next-article/teams","hooks_url":"https://api.github.com/repos/Financial-Times/next-article/hooks","issue_events_url":"https://api.github.com/repos/Financial-Times/next-article/issues/events{/number}","events_url":"https://api.github.com/repos/Financial-Times/next-article/events","assignees_url":"https://api.github.com/repos/Financial-Times/next-article/assignees{/user}","branches_url":"https://api.github.com/repos/Financial-Times/next-article/branches{/branch}","tags_url":"https://api.github.com/repos/Financial-Times/next-article/tags","blobs_url":"https://api.github.com/repos/Financial-Times/next-article/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Financial-Times/next-article/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Financial-Times/next-article/git/refs{/sha}","trees_url":"https://api.github.com/repos/Financial-Times/next-article/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Financial-Times/next-article/statuses/{sha}","languages_url":"https://api.github.com/repos/Financial-Times/next-article/languages","stargazers_url":"https://api.github.com/repos/Financial-Times/next-article/stargazers","contributors_url":"https://api.github.com/repos/Financial-Times/next-article/contributors","subscribers_url":"https://api.github.com/repos/Financial-Times/next-article/subscribers","subscription_url":"https://api.github.com/repos/Financial-Times/next-article/subscription","commits_url":"https://api.github.com/repos/Financial-Times/next-article/commits{/sha}","git_commits_url":"https://api.github.com/repos/Financial-Times/next-article/git/commits{/sha}","comments_url":"https://api.github.com/repos/Financial-Times/next-article/comments{/number}","issue_comment_url":"https://api.github.com/repos/Financial-Times/next-article/issues/comments{/number}","contents_url":"https://api.github.com/repos/Financial-Times/next-article/contents/{+path}","compare_url":"https://api.github.com/repos/Financial-Times/next-article/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Financial-Times/next-article/merges","archive_url":"https://api.github.com/repos/Financial-Times/next-article/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Financial-Times/next-article/downloads","issues_url":"https://api.github.com/repos/Financial-Times/next-article/issues{/number}","pulls_url":"https://api.github.com/repos/Financial-Times/next-article/pulls{/number}","milestones_url":"https://api.github.com/repos/Financial-Times/next-article/milestones{/number}","notifications_url":"https://api.github.com/repos/Financial-Times/next-article/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Financial-Times/next-article/labels{/name}","releases_url":"https://api.github.com/repos/Financial-Times/next-article/releases{/id}","created_at":"2014-11-03T14:22:04Z","updated_at":"2015-06-16T08:39:25Z","pushed_at":"2015-07-14T14:00:44Z","git_url":"git://github.com/Financial-Times/next-article.git","ssh_url":"git@github.com:Financial-Times/next-article.git","clone_url":"https://github.com/Financial-Times/next-article.git","svn_url":"https://github.com/Financial-Times/next-article","homepage":"","size":14796,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":18,"forks":2,"open_issues":18,"watchers":1,"default_branch":"master"}},"base":{"label":"Financial-Times:master","ref":"master","sha":"148847d1b0329bda973eed49f29f2354b695ea55","user":{"login":"Financial-Times","id":3502508,"avatar_url":"https://avatars.githubusercontent.com/u/3502508?v=3","gravatar_id":"","url":"https://api.github.com/users/Financial-Times","html_url":"https://github.com/Financial-Times","followers_url":"https://api.github.com/users/Financial-Times/followers","following_url":"https://api.github.com/users/Financial-Times/following{/other_user}","gists_url":"https://api.github.com/users/Financial-Times/gists{/gist_id}","starred_url":"https://api.github.com/users/Financial-Times/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Financial-Times/subscriptions","organizations_url":"https://api.github.com/users/Financial-Times/orgs","repos_url":"https://api.github.com/users/Financial-Times/repos","events_url":"https://api.github.com/users/Financial-Times/events{/privacy}","received_events_url":"https://api.github.com/users/Financial-Times/received_events","type":"Organization","site_admin":false},"repo":{"id":26121818,"name":"next-article","full_name":"Financial-Times/next-article","owner":{"login":"Financial-Times","id":3502508,"avatar_url":"https://avatars.githubusercontent.com/u/3502508?v=3","gravatar_id":"","url":"https://api.github.com/users/Financial-Times","html_url":"https://github.com/Financial-Times","followers_url":"https://api.github.com/users/Financial-Times/followers","following_url":"https://api.github.com/users/Financial-Times/following{/other_user}","gists_url":"https://api.github.com/users/Financial-Times/gists{/gist_id}","starred_url":"https://api.github.com/users/Financial-Times/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Financial-Times/subscriptions","organizations_url":"https://api.github.com/users/Financial-Times/orgs","repos_url":"https://api.github.com/users/Financial-Times/repos","events_url":"https://api.github.com/users/Financial-Times/events{/privacy}","received_events_url":"https://api.github.com/users/Financial-Times/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Financial-Times/next-article","description":"Articles","fork":false,"url":"https://api.github.com/repos/Financial-Times/next-article","forks_url":"https://api.github.com/repos/Financial-Times/next-article/forks","keys_url":"https://api.github.com/repos/Financial-Times/next-article/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Financial-Times/next-article/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Financial-Times/next-article/teams","hooks_url":"https://api.github.com/repos/Financial-Times/next-article/hooks","issue_events_url":"https://api.github.com/repos/Financial-Times/next-article/issues/events{/number}","events_url":"https://api.github.com/repos/Financial-Times/next-article/events","assignees_url":"https://api.github.com/repos/Financial-Times/next-article/assignees{/user}","branches_url":"https://api.github.com/repos/Financial-Times/next-article/branches{/branch}","tags_url":"https://api.github.com/repos/Financial-Times/next-article/tags","blobs_url":"https://api.github.com/repos/Financial-Times/next-article/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Financial-Times/next-article/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Financial-Times/next-article/git/refs{/sha}","trees_url":"https://api.github.com/repos/Financial-Times/next-article/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Financial-Times/next-article/statuses/{sha}","languages_url":"https://api.github.com/repos/Financial-Times/next-article/languages","stargazers_url":"https://api.github.com/repos/Financial-Times/next-article/stargazers","contributors_url":"https://api.github.com/repos/Financial-Times/next-article/contributors","subscribers_url":"https://api.github.com/repos/Financial-Times/next-article/subscribers","subscription_url":"https://api.github.com/repos/Financial-Times/next-article/subscription","commits_url":"https://api.github.com/repos/Financial-Times/next-article/commits{/sha}","git_commits_url":"https://api.github.com/repos/Financial-Times/next-article/git/commits{/sha}","comments_url":"https://api.github.com/repos/Financial-Times/next-article/comments{/number}","issue_comment_url":"https://api.github.com/repos/Financial-Times/next-article/issues/comments{/number}","contents_url":"https://api.github.com/repos/Financial-Times/next-article/contents/{+path}","compare_url":"https://api.github.com/repos/Financial-Times/next-article/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Financial-Times/next-article/merges","archive_url":"https://api.github.com/repos/Financial-Times/next-article/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Financial-Times/next-article/downloads","issues_url":"https://api.github.com/repos/Financial-Times/next-article/issues{/number}","pulls_url":"https://api.github.com/repos/Financial-Times/next-article/pulls{/number}","milestones_url":"https://api.github.com/repos/Financial-Times/next-article/milestones{/number}","notifications_url":"https://api.github.com/repos/Financial-Times/next-article/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Financial-Times/next-article/labels{/name}","releases_url":"https://api.github.com/repos/Financial-Times/next-article/releases{/id}","created_at":"2014-11-03T14:22:04Z","updated_at":"2015-06-16T08:39:25Z","pushed_at":"2015-07-14T14:00:44Z","git_url":"git://github.com/Financial-Times/next-article.git","ssh_url":"git@github.com:Financial-Times/next-article.git","clone_url":"https://github.com/Financial-Times/next-article.git","svn_url":"https://github.com/Financial-Times/next-article","homepage":"","size":14796,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":18,"forks":2,"open_issues":18,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/671"},"html":{"href":"https://github.com/Financial-Times/next-article/pull/671"},"issue":{"href":"https://api.github.com/repos/Financial-Times/next-article/issues/671"},"comments":{"href":"https://api.github.com/repos/Financial-Times/next-article/issues/671/comments"},"review_comments":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/671/comments"},"review_comment":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Financial-Times/next-article/pulls/671/commits"},"statuses":{"href":"https://api.github.com/repos/Financial-Times/next-article/statuses/8db627c69489a60d7a5817fe32ea32d14cd72873"}}}}