beautiful-code

格式化并高亮代码块

  1. // ==UserScript==
  2. // @name beautiful-code
  3. // @description 格式化并高亮代码块
  4. // @namespace github.com/backtolife2021
  5. // @include http*://*
  6. // @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2
  7. // @require https://unpkg.com/@vscode/vscode-languagedetection@1.0.21
  8. // @require https://unpkg.com/shiki@0.9.15/dist/index.unpkg.iife.js
  9. // @require https://unpkg.com/prettier@2.5.1/standalone.js
  10. // @require https://unpkg.com/prettier@2.5.1/parser-typescript.js
  11. // @require https://unpkg.com/prettier@2.5.1/parser-babel.js
  12. // @version 1.0.1
  13. // @homepage https://github.com/backtolife2021/beautiful-code
  14. // @author backtolife
  15. // @license MIT
  16. // @grant none
  17. // ==/UserScript==
  18.  
  19. /*
  20. MIT License
  21.  
  22. Copyright (c) 2022 backtolife2021
  23.  
  24. Permission is hereby granted, free of charge, to any person obtaining a copy
  25. of this software and associated documentation files (the "Software"), to deal
  26. in the Software without restriction, including without limitation the rights
  27. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  28. copies of the Software, and to permit persons to whom the Software is
  29. furnished to do so, subject to the following conditions:
  30.  
  31. The above copyright notice and this permission notice shall be included in all
  32. copies or substantial portions of the Software.
  33.  
  34. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  35. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  36. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  37. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  38. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  39. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  40. SOFTWARE.
  41. */
  42.  
  43. /* globals VM shiki prettier globalThis["vscode-languagedetection"]*/
  44. (function (VM, vscodeLanguagedetection, prettier, shiki) {
  45. 'use strict';
  46.  
  47. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  48.  
  49. var VM__default = /*#__PURE__*/_interopDefaultLegacy(VM);
  50. var prettier__default = /*#__PURE__*/_interopDefaultLegacy(prettier);
  51. var shiki__default = /*#__PURE__*/_interopDefaultLegacy(shiki);
  52.  
  53. /**
  54. * @see https://github.com/microsoft/vscode-languagedetection#usage
  55. * @see https://github.com/microsoft/vscode/blob/3a1cf8e51e3797a2d9ccb12d207378de364596c4/src/vs/workbench/services/languageDetection/browser/languageDetectionService.ts#L59
  56. * @see https://unpkg.com/browse/@vscode/vscode-languagedetection@1.0.21/model/
  57. */
  58. const modulOperations = new vscodeLanguagedetection.ModelOperations({
  59. async modelJsonLoaderFunc() {
  60. const response = await fetch('https://unpkg.com/@vscode/vscode-languagedetection@1.0.21/model/model.json');
  61. const modelJSON = (await response.json());
  62. return modelJSON;
  63. },
  64. async weightsLoaderFunc() {
  65. const response = await fetch('https://unpkg.com/@vscode/vscode-languagedetection@1.0.21/model/group1-shard1of1.bin');
  66. const buffer = await response.arrayBuffer();
  67. return buffer;
  68. },
  69. });
  70. /**
  71. * @see https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
  72. * [
  73. {
  74. "languageId": "js",
  75. "confidence": 0.24262011051177979
  76. },
  77. {
  78. "languageId": "groovy",
  79. "confidence": 0.2068355679512024
  80. },
  81. {
  82. "languageId": "coffee",
  83. "confidence": 0.08538007736206055
  84. },
  85. {
  86. "languageId": "ts",
  87. "confidence": 0.07805327326059341
  88. },
  89. {
  90. "languageId": "lua",
  91. "confidence": 0.04159870371222496
  92. },
  93. {
  94. "languageId": "rb",
  95. "confidence": 0.03658360242843628
  96. },
  97. {
  98. "languageId": "r",
  99. "confidence": 0.03136871010065079
  100. },
  101. {
  102. "languageId": "swift",
  103. "confidence": 0.02843020297586918
  104. },
  105. {
  106. "languageId": "dart",
  107. "confidence": 0.025191379711031914
  108. },
  109. {
  110. "languageId": "php",
  111. "confidence": 0.02489558607339859
  112. },
  113. {
  114. "languageId": "scala",
  115. "confidence": 0.016375916078686714
  116. },
  117. {
  118. "languageId": "py",
  119. "confidence": 0.01570715941488743
  120. },
  121. {
  122. "languageId": "kt",
  123. "confidence": 0.014793860726058483
  124. },
  125. {
  126. "languageId": "cs",
  127. "confidence": 0.010329823940992355
  128. },
  129. {
  130. "languageId": "ps1",
  131. "confidence": 0.009833300486207008
  132. },
  133. {
  134. "languageId": "html",
  135. "confidence": 0.009663671255111694
  136. },
  137. {
  138. "languageId": "f90",
  139. "confidence": 0.00893926527351141
  140. },
  141. {
  142. "languageId": "json",
  143. "confidence": 0.008335321210324764
  144. },
  145. {
  146. "languageId": "mm",
  147. "confidence": 0.008064116351306438
  148. },
  149. {
  150. "languageId": "matlab",
  151. "confidence": 0.0077512627467513084
  152. },
  153. {
  154. "languageId": "md",
  155. "confidence": 0.007669923361390829
  156. },
  157. {
  158. "languageId": "java",
  159. "confidence": 0.006278263870626688
  160. },
  161. {
  162. "languageId": "clj",
  163. "confidence": 0.00619084807112813
  164. },
  165. {
  166. "languageId": "cpp",
  167. "confidence": 0.005193199031054974
  168. },
  169. {
  170. "languageId": "ex",
  171. "confidence": 0.004912080243229866
  172. },
  173. {
  174. "languageId": "cmake",
  175. "confidence": 0.004895167890936136
  176. },
  177. {
  178. "languageId": "rs",
  179. "confidence": 0.004293493460863829
  180. },
  181. {
  182. "languageId": "tex",
  183. "confidence": 0.0040983883664011955
  184. },
  185. {
  186. "languageId": "prolog",
  187. "confidence": 0.003859680611640215
  188. },
  189. {
  190. "languageId": "csv",
  191. "confidence": 0.0037101071793586016
  192. },
  193. {
  194. "languageId": "dm",
  195. "confidence": 0.003579826094210148
  196. },
  197. {
  198. "languageId": "c",
  199. "confidence": 0.003512203460559249
  200. },
  201. {
  202. "languageId": "jl",
  203. "confidence": 0.003408814314752817
  204. },
  205. {
  206. "languageId": "sql",
  207. "confidence": 0.002867681672796607
  208. },
  209. {
  210. "languageId": "css",
  211. "confidence": 0.002399126533418894
  212. },
  213. {
  214. "languageId": "bat",
  215. "confidence": 0.002297078724950552
  216. },
  217. {
  218. "languageId": "vba",
  219. "confidence": 0.002262661000713706
  220. },
  221. {
  222. "languageId": "go",
  223. "confidence": 0.002190779196098447
  224. },
  225. {
  226. "languageId": "ini",
  227. "confidence": 0.002004046691581607
  228. },
  229. {
  230. "languageId": "ml",
  231. "confidence": 0.001782393315806985
  232. },
  233. {
  234. "languageId": "erl",
  235. "confidence": 0.0016315156826749444
  236. },
  237. {
  238. "languageId": "xml",
  239. "confidence": 0.0015882366569712758
  240. },
  241. {
  242. "languageId": "pas",
  243. "confidence": 0.001484898617491126
  244. },
  245. {
  246. "languageId": "pm",
  247. "confidence": 0.0014668531948700547
  248. },
  249. {
  250. "languageId": "hs",
  251. "confidence": 0.0009900418808683753
  252. },
  253. {
  254. "languageId": "yaml",
  255. "confidence": 0.0007946646073833108
  256. },
  257. {
  258. "languageId": "asm",
  259. "confidence": 0.000721517251804471
  260. },
  261. {
  262. "languageId": "sh",
  263. "confidence": 0.0007181295077316463
  264. },
  265. {
  266. "languageId": "lisp",
  267. "confidence": 0.0006713239708915353
  268. },
  269. {
  270. "languageId": "cbl",
  271. "confidence": 0.0005515082157216966
  272. },
  273. {
  274. "languageId": "dockerfile",
  275. "confidence": 0.0005290511180646718
  276. },
  277. {
  278. "languageId": "makefile",
  279. "confidence": 0.0002923230640590191
  280. },
  281. {
  282. "languageId": "v",
  283. "confidence": 0.00028496066806837916
  284. },
  285. {
  286. "languageId": "toml",
  287. "confidence": 0.000118325486255344
  288. }
  289. ]
  290. */
  291. const langMap = new Map([['kt', 'kotlin']]);
  292. /**
  293. * @see https://github.com/shikijs/shiki#usage
  294. * @see https://github.com/shikijs/shiki/blob/main/docs/languages.md#all-languages
  295. */
  296. const highlight = () => {
  297. void shiki__default["default"]
  298. .getHighlighter({
  299. langs: [...shiki__default["default"].BUNDLED_LANGUAGES],
  300. theme: 'dracula',
  301. })
  302. .then((highlighter) => {
  303. // eslint-disable-next-line promise/no-nesting
  304. void Promise.all(Array.from(document.querySelectorAll('pre')).map(async (pre) => {
  305. if (pre.dataset.isHighlighted === 'true')
  306. return void 0;
  307. const rawCodeText = pre.textContent ?? '';
  308. const result = await modulOperations.runModel(rawCodeText);
  309. const lang = result.at(0)?.languageId ?? 'tsx';
  310. const code = highlighter.codeToHtml((() => {
  311. try {
  312. /**
  313. * @see https://prettier.io/docs/en/browser.html#global
  314. */
  315. return prettier__default["default"].format(rawCodeText, {
  316. parser: 'babel-ts',
  317. plugins: window.prettierPlugins,
  318. semi: false,
  319. trailingComma: 'all',
  320. singleQuote: true,
  321. arrowParens: 'always',
  322. endOfLine: 'lf',
  323. });
  324. }
  325. catch {
  326. return rawCodeText;
  327. }
  328. })(), { lang: langMap.get(lang) ?? lang });
  329. /**
  330. * @see https://stackoverflow.com/a/67571022/11791657
  331. */
  332. const range = document.createRange();
  333. const fragment = range.createContextualFragment(code
  334. .replace('class="shiki"', () => 'class="shiki notranslate" data-is-highlighted="true"')
  335. .replace('<code>', () => '<code style="background-color: transparent">'));
  336. pre.replaceWith(fragment);
  337. })).catch((err) => {
  338. console.error(err);
  339. });
  340. });
  341. };
  342. /**
  343. * @see https://violentmonkey.github.io/guide/observing-dom/
  344. */
  345. VM__default["default"].observe(document.body, () => {
  346. highlight();
  347. return false;
  348. });
  349.  
  350. })(VM, window["vscode-languagedetection"], prettier, shiki);
  351. //# sourceMappingURL=production.user.js.map