Unity Docs Syntax Highlighter

Adds syntax highlighting to the Unity Documentation. Forked from hyblocker.

  1. // ==UserScript==
  2. // @name Unity Docs Syntax Highlighter
  3. // @namespace https://github.com/Maoyeedy
  4. // @version 1.3.1
  5. // @author Yidi Mao, hyblocker
  6. // @license MIT
  7. // @description Adds syntax highlighting to the Unity Documentation. Forked from hyblocker.
  8. // @icon https://unity.com/favicon.ico
  9. //
  10. // @match https://docs.unity3d.com/Manual/*
  11. // @match https://docs.unity3d.com/ScriptReference/*
  12. // @match https://docs.unity3d.com/*/Manual/*
  13. // @match https://docs.unity3d.com/*/ScriptReference/*
  14. //
  15. // @grant GM_getResourceText
  16. // @grant GM_addStyle
  17. //
  18. // @require https://cdn.jsdelivr.net/npm/prismjs@1/prism.min.js
  19. // @require https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-c.min.js
  20. // @require https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-clike.min.js
  21. // @require https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-csharp.min.js
  22. // @require https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-hlsl.min.js
  23. // @require https://cdn.jsdelivr.net/npm/prismjs@1/plugins/keep-markup/prism-keep-markup.min.js
  24. //
  25. //
  26. // @resource PRISM_THEME_LIGHT https://cdn.jsdelivr.net/gh/PrismJS/prism-themes/themes/prism-one-light.min.css
  27. // @resource PRISM_THEME_DARK https://cdn.jsdelivr.net/gh/PrismJS/prism-themes/themes/prism-one-dark.min.css
  28. //
  29. // Recommended Light Themes
  30. // https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism.min.css
  31. //
  32. // Recommended Dark Themes
  33. // https://cdn.jsdelivr.net/gh/PrismJS/prism-themes/themes/prism-xonokai.min.css
  34. // https://cdn.jsdelivr.net/gh/PrismJS/prism-themes/themes/prism-duotone-dark.min.css
  35. //
  36. // Extra Themes
  37. // https://github.com/PrismJS/prism-themes
  38.  
  39. //
  40. // ==/UserScript==
  41.  
  42. (function () {
  43. "use strict"
  44. GM_addStyle(`#ot-sdk-btn-floating { display: none !important; }`)
  45. /* Create Button */
  46. const switchButton = document.createElement("button")
  47. switchButton.style.cursor = "pointer"
  48. switchButton.style.position = "fixed"
  49. switchButton.style.bottom = "15px"
  50. switchButton.style.right = "15px"
  51. switchButton.style.width = "32px"
  52. switchButton.style.height = "32px"
  53. switchButton.style.borderRadius = "16px"
  54. switchButton.style.border = "1px solid"
  55. switchButton.style.fontSize = "16px"
  56. switchButton.style.paddingBottom = "2px"
  57.  
  58. /* Switch between dark and light themes */
  59. function SetLightTheme () {
  60. GM_addStyle(GM_getResourceText("PRISM_THEME_LIGHT"))
  61. switchButton.style.backgroundColor = "#f9f9f9"
  62. switchButton.style.borderColor = "#272b33"
  63. switchButton.textContent = "🌞"
  64. }
  65.  
  66. function SetDarkTheme () {
  67. GM_addStyle(GM_getResourceText("PRISM_THEME_DARK"))
  68. switchButton.style.backgroundColor = "#272b33"
  69. switchButton.style.borderColor = "#fae3a2"
  70. switchButton.textContent = "🌙"
  71. }
  72.  
  73. function SetTheme () {
  74. isLightTheme ? SetLightTheme() : SetDarkTheme()
  75. }
  76.  
  77. let isLightTheme = true
  78. SetTheme()
  79.  
  80. document.body.appendChild(switchButton)
  81. switchButton.addEventListener("click", () => {
  82. isLightTheme = !isLightTheme
  83. SetTheme()
  84. })
  85.  
  86. /* InjectCustomCSS */
  87. const customCSS = `
  88. code[class*="language-"],
  89. pre[class*="language-"] {
  90. border-radius: .5em;
  91. font-family: 'Jetbrains Mono', monospace !important;
  92. font-size: 0.875em !important;
  93. line-height: 1.5 !important;
  94. text-shadow: none !important;
  95. }
  96. .token.keyword,
  97. .token.bold {
  98. font-weight: normal !important;
  99. }
  100. .token.comment {
  101. font-style: italic !important;
  102. }
  103. .token.operator,
  104. .token.entity,
  105. .token.url,
  106. .style .token.string {
  107. background: transparent !important;
  108. }
  109. `
  110. GM_addStyle(customCSS)
  111. })()
  112.  
  113. const CSHARP = 0
  114. const HLSL = 1
  115.  
  116. var waitForGlobal = function (key, callback) {
  117. if (window[key]) {
  118. callback()
  119. } else {
  120. setTimeout(function () {
  121. waitForGlobal(key, callback)
  122. }, 100)
  123. }
  124. }
  125. function waitForLangLoad (lang, callback) {
  126. if (Prism.util.getLanguage(lang) != null) {
  127. callback()
  128. } else {
  129. setTimeout(function () {
  130. waitForLangLoad(lang, callback)
  131. }, 100)
  132. }
  133. }
  134.  
  135. function detectCodeLanguage (elem) {
  136. if (elem.classList.contains("codeExampleCS")) {
  137. return CSHARP
  138. }
  139.  
  140. if (
  141. elem.innerHTML.match(/CGPROGRAM|ENDCG|CGINCLUDE|#pragma|SubShader \"/g) !=
  142. null
  143. ) {
  144. return HLSL
  145. }
  146.  
  147. return CSHARP
  148. }
  149.  
  150. waitForGlobal("Prism", () => {
  151. waitForLangLoad("csharp", () => {
  152. waitForLangLoad("hlsl", () => {
  153. document.querySelectorAll(".content-wrap pre").forEach((el) => {
  154. // Replace <br> tags with newlines
  155. el.innerHTML = el.innerHTML.replace(/\<br\>/g, "\n")
  156.  
  157. // Add language class
  158. el.classList.add(
  159. detectCodeLanguage(el) === CSHARP
  160. ? "language-csharp"
  161. : "language-hlsl"
  162. )
  163.  
  164. // Wrap in <code> if needed
  165. if (el.firstChild.nodeName != "CODE") {
  166. el.innerHTML = `<code data-keep-markup="true">${el.innerHTML}</code>`
  167. } else {
  168. el.firstChild.setAttribute("data-keep-markup", "true")
  169. }
  170. })
  171.  
  172. // Apply syntax highlighting after DOM modifications
  173. Prism.highlightAllUnder(document.body)
  174. })
  175. })
  176. })