website.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import glob = require('glob');
  6. import path = require('path');
  7. import fs = require('fs');
  8. import cp = require('child_process');
  9. import CleanCSS from 'clean-css';
  10. import { REPO_ROOT, readFiles, writeFiles } from './utils';
  11. import { removeDir } from './fs';
  12. const MONACO_EDITOR_VERSION: string = (() => {
  13. const output = cp.execSync(`npm show monaco-editor version`).toString();
  14. const version = output.split(/\r\n|\r|\n/g)[0];
  15. if (!/\d+\.\d+\.\d+/.test(version)) {
  16. console.log('unrecognized package.json version: ' + version);
  17. process.exit(1);
  18. }
  19. return version;
  20. })();
  21. removeDir(`../monaco-editor-website`);
  22. checkSamples();
  23. generateWebsite();
  24. /**
  25. * Check that there are samples for all available languages
  26. */
  27. function checkSamples() {
  28. let languages = glob
  29. .sync('src/basic-languages/*/*.contribution.ts', { cwd: REPO_ROOT })
  30. .map((f) => path.dirname(f))
  31. .map((f) => f.substring('src/basic-languages/'.length));
  32. languages.push('css');
  33. languages.push('html');
  34. languages.push('json');
  35. languages.push('typescript');
  36. // some languages have a different id than their folder
  37. languages = languages.map((l) => {
  38. switch (l) {
  39. case 'coffee':
  40. return 'coffeescript';
  41. case 'protobuf':
  42. return 'proto';
  43. case 'solidity':
  44. return 'sol';
  45. case 'sophia':
  46. return 'aes';
  47. default:
  48. return l;
  49. }
  50. });
  51. let fail = false;
  52. for (const language of languages) {
  53. const expectedSamplePath = path.join(REPO_ROOT, `website/index/samples/sample.${language}.txt`);
  54. if (!fs.existsSync(expectedSamplePath)) {
  55. console.error(`Missing sample for ${language} at ${expectedSamplePath}`);
  56. fail = true;
  57. }
  58. }
  59. if (fail) {
  60. process.exit(1);
  61. }
  62. }
  63. function replaceWithRelativeResource(
  64. dataPath: string,
  65. contents: string,
  66. regex: RegExp,
  67. callback: (match: string, fileContents: Buffer) => string
  68. ): string {
  69. return contents.replace(regex, function (_, m0) {
  70. const filePath = path.join(REPO_ROOT, 'website', path.dirname(dataPath), m0);
  71. return callback(m0, fs.readFileSync(filePath));
  72. });
  73. }
  74. function generateWebsite() {
  75. const files = readFiles('website/**/*', {
  76. base: 'website',
  77. ignore: ['website/typedoc/**/*'],
  78. dot: true
  79. });
  80. for (const file of files) {
  81. if (!file.contents || !/\.(html)$/.test(file.path) || /new-samples/.test(file.path)) {
  82. continue;
  83. }
  84. let contents = file.contents.toString();
  85. contents = contents.replace(/\.\.\/release\/dev/g, 'node_modules/monaco-editor/min');
  86. // contents = contents.replace(/\.\.\/\.\.\/release\/dev/g, '../monaco-editor/release/dev');
  87. contents = contents.replace(/{{version}}/g, MONACO_EDITOR_VERSION);
  88. contents = contents.replace(/{{year}}/g, String(new Date().getFullYear()));
  89. // Preload xhr contents
  90. contents = replaceWithRelativeResource(
  91. file.path,
  92. contents,
  93. /<pre data-preload="([^"]+)".*/g,
  94. function (m0, fileContents) {
  95. return (
  96. '<pre data-preload="' +
  97. m0 +
  98. '" style="display:none">' +
  99. fileContents
  100. .toString('utf8')
  101. .replace(/&/g, '&amp;')
  102. .replace(/</g, '&lt;')
  103. .replace(/>/g, '&gt;') +
  104. '</pre>'
  105. );
  106. }
  107. );
  108. // Inline fork.png
  109. contents = replaceWithRelativeResource(
  110. file.path,
  111. contents,
  112. /src="(\.\/fork.png)"/g,
  113. function (m0, fileContents) {
  114. return 'src="data:image/png;base64,' + fileContents.toString('base64') + '"';
  115. }
  116. );
  117. // let allCSS = '';
  118. contents = replaceWithRelativeResource(
  119. file.path,
  120. contents,
  121. /<link data-inline="yes-please" href="([^"]+)".*/g,
  122. function (m0, fileContents) {
  123. const minifiedCSS = (new CleanCSS() as any).minify(fileContents.toString('utf8')).styles;
  124. return `<style>${minifiedCSS}</style>`;
  125. }
  126. );
  127. // Inline javascript
  128. contents = replaceWithRelativeResource(
  129. file.path,
  130. contents,
  131. /<script data-inline="yes-please" src="([^"]+)".*/g,
  132. function (m0, fileContents) {
  133. return '<script>' + fileContents.toString('utf8') + '</script>';
  134. }
  135. );
  136. file.contents = Buffer.from(contents.split(/\r\n|\r|\n/).join('\n'));
  137. }
  138. writeFiles(files, `../monaco-editor-website`);
  139. // temporarily create package.json so that npm install doesn't bark
  140. fs.writeFileSync(path.join(REPO_ROOT, '../monaco-editor-website/package.json'), '{}');
  141. fs.writeFileSync(path.join(REPO_ROOT, '../monaco-editor-website/.nojekyll'), '');
  142. cp.execSync('npm install monaco-editor', {
  143. cwd: path.join(REPO_ROOT, '../monaco-editor-website')
  144. });
  145. fs.unlinkSync(path.join(REPO_ROOT, '../monaco-editor-website/package.json'));
  146. }