index.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. var Prism = require('prismjs');
  2. var languages = require('prismjs').languages;
  3. var path = require('path');
  4. const cheerio = require('cheerio');
  5. var DEFAULT_LANGUAGE = 'markup';
  6. var MAP_LANGUAGES = {
  7. 'py': 'python',
  8. 'js': 'javascript',
  9. 'rb': 'ruby',
  10. 'csharp': 'cs',
  11. 'html': 'markup'
  12. };
  13. function getAssets() {
  14. var cssFiles = this.config.get('pluginsConfig.prism.css', []);
  15. var cssFolder = null;
  16. var cssNames = [];
  17. var cssName = null;
  18. if (cssFiles.length === 0) {
  19. cssFiles.push('prismjs/themes/prism.css');
  20. }
  21. cssFiles.forEach(function(cssFile) {
  22. var cssPath = require.resolve(cssFile);
  23. cssFolder = path.dirname(cssPath);
  24. cssName = path.basename(cssPath);
  25. cssNames.push(cssName);
  26. });
  27. var assets = {
  28. assets: cssFolder,
  29. css: cssNames
  30. };
  31. return assets;
  32. }
  33. module.exports = {
  34. book: getAssets,
  35. ebook: getAssets,
  36. blocks: {
  37. code: function(block) {
  38. var highlighted = '';
  39. // Normalize language id
  40. var lang = block.kwargs.language || DEFAULT_LANGUAGE;
  41. lang = MAP_LANGUAGES[lang] || lang;
  42. // Try and find the language definition in components folder
  43. if (!languages[lang]) {
  44. try {
  45. require('prismjs/components/prism-' + lang + '.js');
  46. } catch (e) {
  47. console.warn('Failed to load prism syntax: ' + lang);
  48. console.warn(e);
  49. }
  50. }
  51. if (!languages[lang]) lang = DEFAULT_LANGUAGE;
  52. // Check against html, prism "markup" works for this
  53. if (lang === 'html') {
  54. lang = 'markup';
  55. }
  56. try {
  57. // The process can fail (failed to parse)
  58. highlighted = Prism.highlight(block.body, languages[lang]);
  59. } catch (e) {
  60. console.warn('Failed to highlight:');
  61. console.warn(e);
  62. highlighted = block.body;
  63. }
  64. return highlighted;
  65. }
  66. },
  67. hooks: {
  68. 'page': function(page) {
  69. var highlighted = false;
  70. var $ = cheerio.load(page.content);
  71. // Prism css styles target the <code> and <pre> blocks using
  72. // a substring CSS selector:
  73. //
  74. // code[class*="language-"], pre[class*="language-"]
  75. //
  76. // Adding "language-" to each element should be sufficient to trigger
  77. // correct color theme.
  78. $('code, pre').each(function() {
  79. highlighted = true;
  80. const $this = $(this);
  81. $this.addClass('language-');
  82. });
  83. if (highlighted) {
  84. page.content = $.html();
  85. }
  86. return page;
  87. }
  88. }
  89. };