Browse Source

Remove ::selection background color from code block in PDFs. Fixes #11.

Prism themes contain a ::selection selector that was being applied to <code> blocks in PDFs and causing them not to render properly.
Robert McGuinness 8 years ago
parent
commit
f64ba3a787
4 changed files with 62 additions and 13 deletions
  1. 39 8
      index.js
  2. 5 4
      package.json
  3. 17 0
      prism-pdf.css
  4. 1 1
      test.js

+ 39 - 8
index.js

@@ -1,7 +1,9 @@
 var Prism = require('prismjs');
 var languages = require('prismjs').languages;
 var path = require('path');
-const cheerio = require('cheerio');
+var fs = require('fs');
+var cheerio = require('cheerio');
+var mkdirp = require('mkdirp');
 
 var DEFAULT_LANGUAGE = 'markup';
 var MAP_LANGUAGES = {
@@ -30,17 +32,23 @@ function getAssets() {
     cssNames.push(cssName);
   });
 
-  var assets = {
+  return {
     assets: cssFolder,
     css: cssNames
   };
-
-  return assets;
 }
 
 module.exports = {
   book: getAssets,
-  ebook: getAssets,
+  ebook: function() {
+
+    // Adding prism-pdf.css to the CSS collection forces Gitbook  to add a reference to it in the html
+    // markup that is converted into a PDF.
+    var assets = getAssets.call(this);
+    assets.css.push('prism-pdf.css');
+    return assets;
+
+  },
   blocks: {
     code: function(block) {
 
@@ -77,10 +85,34 @@ module.exports = {
       }
 
       return highlighted;
+
     }
   },
   hooks: {
-    'page': function(page) {
+
+    // Copy prism-pdf.css into the temporary directory that Gitbook uses for inlining
+    // styles from this plugin.  This is done manually because prism-pdf.css lives outside
+    // the asset folder referenced above in getAssets().
+    //
+    // Inspired by https://github.com/GitbookIO/plugin-styles-less/blob/master/index.js#L8
+    init: function() {
+
+      var book = this;
+
+      var outputDirectory = book.output.root() + '/gitbook/gitbook-plugin-prism';
+      var outputFile = path.resolve(outputDirectory, 'prism-pdf.css');
+      var inputFile = path.resolve(__dirname, './prism-pdf.css');
+      mkdirp.sync(outputDirectory + 'gitbook/gitbook-plugin-prism');
+
+      try {
+        fs.writeFileSync(outputFile, fs.readFileSync(inputFile));
+      } catch (e) {
+        console.warn('Failed to write prism-pdf.css. See https://git.io/v1LHY for side effects.');
+        console.warn(e);
+      }
+
+    },
+    page: function(page) {
 
       var highlighted = false;
 
@@ -91,13 +123,12 @@ module.exports = {
       //
       //    code[class*="language-"], pre[class*="language-"]
       //
-      // Adding "language-" to each element should be sufficient to trigger
+      // Adding "language-" to <pre> element should be sufficient to trigger
       // correct color theme.
       $('pre').each(function() {
         highlighted = true;
         const $this = $(this);
         $this.addClass('language-');
-
       });
 
       if (highlighted) {

+ 5 - 4
package.json

@@ -20,17 +20,18 @@
     "url": "https://github.com/gaearon/gitbook-plugin-prism/issues"
   },
   "dependencies": {
-    "prismjs": "1.5.1",
-    "cheerio": "0.22.0"
+    "cheerio": "0.22.0",
+    "mkdirp": "0.5.1",
+    "prismjs": "1.5.1"
   },
   "devDependencies": {
-    "eslint": "3.10.2",
+    "eslint": "3.11.1",
     "eslint-config-semistandard": "7.0.0",
     "eslint-config-standard": "6.2.1",
     "eslint-plugin-promise": "3.4.0",
     "eslint-plugin-react": "6.7.1",
     "eslint-plugin-standard": "2.0.1",
     "gitbook-tester": "1.4.3",
-    "tape": "4.6.2"
+    "tape": "4.6.3"
   }
 }

+ 17 - 0
prism-pdf.css

@@ -0,0 +1,17 @@
+/*
+ * Prism themes contain a ::selection selector that was being applied to <code>
+ * blocks in PDFs.
+ *
+ * @See https://github.com/gaearon/gitbook-plugin-prism/issues/11
+*/
+pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
+code[class*="language-"]::selection, code[class*="language-"] ::selection {
+  background: none;
+}
+
+/*
+ * @See https://github.com/gaearon/gitbook-plugin-prism/issues/11#issuecomment-262058733
+*/
+.page .section code {
+    background-color: none;
+}

+ 1 - 1
test.js

@@ -16,7 +16,7 @@ test('should highlight javascript code block', function (t) {
     })
     .create()
     .then(function(result) {
-      var expected = '<pre class="language-"><code class="lang-js language-"><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>';
+      var expected = '<pre class="language-"><code class="lang-js"><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>\n</code></pre>';
       t.equal(result[0].content, expected);
     })
     .done();