plugin.js 126 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655
  1. /**
  2. * TinyMCE version 8.0.2 (2025-08-14)
  3. */
  4. (function () {
  5. 'use strict';
  6. var global$2 = tinymce.util.Tools.resolve('tinymce.PluginManager');
  7. /* eslint-disable @typescript-eslint/no-wrapper-object-types */
  8. const isNullable = (a) => a === null || a === undefined;
  9. const isNonNullable = (a) => !isNullable(a);
  10. const noop = () => { };
  11. const constant = (value) => {
  12. return () => {
  13. return value;
  14. };
  15. };
  16. /**
  17. * The `Optional` type represents a value (of any type) that potentially does
  18. * not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
  19. * value does exist) or a `None` (in which case the value does not exist). This
  20. * module defines a whole lot of FP-inspired utility functions for dealing with
  21. * `Optional` objects.
  22. *
  23. * Comparison with null or undefined:
  24. * - We don't get fancy null coalescing operators with `Optional`
  25. * - We do get fancy helper functions with `Optional`
  26. * - `Optional` support nesting, and allow for the type to still be nullable (or
  27. * another `Optional`)
  28. * - There is no option to turn off strict-optional-checks like there is for
  29. * strict-null-checks
  30. */
  31. class Optional {
  32. // The internal representation has a `tag` and a `value`, but both are
  33. // private: able to be console.logged, but not able to be accessed by code
  34. constructor(tag, value) {
  35. this.tag = tag;
  36. this.value = value;
  37. }
  38. // --- Identities ---
  39. /**
  40. * Creates a new `Optional<T>` that **does** contain a value.
  41. */
  42. static some(value) {
  43. return new Optional(true, value);
  44. }
  45. /**
  46. * Create a new `Optional<T>` that **does not** contain a value. `T` can be
  47. * any type because we don't actually have a `T`.
  48. */
  49. static none() {
  50. return Optional.singletonNone;
  51. }
  52. /**
  53. * Perform a transform on an `Optional` type. Regardless of whether this
  54. * `Optional` contains a value or not, `fold` will return a value of type `U`.
  55. * If this `Optional` does not contain a value, the `U` will be created by
  56. * calling `onNone`. If this `Optional` does contain a value, the `U` will be
  57. * created by calling `onSome`.
  58. *
  59. * For the FP enthusiasts in the room, this function:
  60. * 1. Could be used to implement all of the functions below
  61. * 2. Forms a catamorphism
  62. */
  63. fold(onNone, onSome) {
  64. if (this.tag) {
  65. return onSome(this.value);
  66. }
  67. else {
  68. return onNone();
  69. }
  70. }
  71. /**
  72. * Determine if this `Optional` object contains a value.
  73. */
  74. isSome() {
  75. return this.tag;
  76. }
  77. /**
  78. * Determine if this `Optional` object **does not** contain a value.
  79. */
  80. isNone() {
  81. return !this.tag;
  82. }
  83. // --- Functor (name stolen from Haskell / maths) ---
  84. /**
  85. * Perform a transform on an `Optional` object, **if** there is a value. If
  86. * you provide a function to turn a T into a U, this is the function you use
  87. * to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
  88. * a value then the output will also contain a value (that value being the
  89. * output of `mapper(this.value)`), and if this **does not** contain a value
  90. * then neither will the output.
  91. */
  92. map(mapper) {
  93. if (this.tag) {
  94. return Optional.some(mapper(this.value));
  95. }
  96. else {
  97. return Optional.none();
  98. }
  99. }
  100. // --- Monad (name stolen from Haskell / maths) ---
  101. /**
  102. * Perform a transform on an `Optional` object, **if** there is a value.
  103. * Unlike `map`, here the transform itself also returns an `Optional`.
  104. */
  105. bind(binder) {
  106. if (this.tag) {
  107. return binder(this.value);
  108. }
  109. else {
  110. return Optional.none();
  111. }
  112. }
  113. // --- Traversable (name stolen from Haskell / maths) ---
  114. /**
  115. * For a given predicate, this function finds out if there **exists** a value
  116. * inside this `Optional` object that meets the predicate. In practice, this
  117. * means that for `Optional`s that do not contain a value it returns false (as
  118. * no predicate-meeting value exists).
  119. */
  120. exists(predicate) {
  121. return this.tag && predicate(this.value);
  122. }
  123. /**
  124. * For a given predicate, this function finds out if **all** the values inside
  125. * this `Optional` object meet the predicate. In practice, this means that
  126. * for `Optional`s that do not contain a value it returns true (as all 0
  127. * objects do meet the predicate).
  128. */
  129. forall(predicate) {
  130. return !this.tag || predicate(this.value);
  131. }
  132. filter(predicate) {
  133. if (!this.tag || predicate(this.value)) {
  134. return this;
  135. }
  136. else {
  137. return Optional.none();
  138. }
  139. }
  140. // --- Getters ---
  141. /**
  142. * Get the value out of the inside of the `Optional` object, using a default
  143. * `replacement` value if the provided `Optional` object does not contain a
  144. * value.
  145. */
  146. getOr(replacement) {
  147. return this.tag ? this.value : replacement;
  148. }
  149. /**
  150. * Get the value out of the inside of the `Optional` object, using a default
  151. * `replacement` value if the provided `Optional` object does not contain a
  152. * value. Unlike `getOr`, in this method the `replacement` object is also
  153. * `Optional` - meaning that this method will always return an `Optional`.
  154. */
  155. or(replacement) {
  156. return this.tag ? this : replacement;
  157. }
  158. /**
  159. * Get the value out of the inside of the `Optional` object, using a default
  160. * `replacement` value if the provided `Optional` object does not contain a
  161. * value. Unlike `getOr`, in this method the `replacement` value is
  162. * "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
  163. * pass a function which (if called) will **return** the `value` you want to
  164. * use.
  165. */
  166. getOrThunk(thunk) {
  167. return this.tag ? this.value : thunk();
  168. }
  169. /**
  170. * Get the value out of the inside of the `Optional` object, using a default
  171. * `replacement` value if the provided Optional object does not contain a
  172. * value.
  173. *
  174. * Unlike `or`, in this method the `replacement` value is "thunked" - that is
  175. * to say that you don't pass a value to `orThunk`, you pass a function which
  176. * (if called) will **return** the `value` you want to use.
  177. *
  178. * Unlike `getOrThunk`, in this method the `replacement` value is also
  179. * `Optional`, meaning that this method will always return an `Optional`.
  180. */
  181. orThunk(thunk) {
  182. return this.tag ? this : thunk();
  183. }
  184. /**
  185. * Get the value out of the inside of the `Optional` object, throwing an
  186. * exception if the provided `Optional` object does not contain a value.
  187. *
  188. * WARNING:
  189. * You should only be using this function if you know that the `Optional`
  190. * object **is not** empty (otherwise you're throwing exceptions in production
  191. * code, which is bad).
  192. *
  193. * In tests this is more acceptable.
  194. *
  195. * Prefer other methods to this, such as `.each`.
  196. */
  197. getOrDie(message) {
  198. if (!this.tag) {
  199. throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
  200. }
  201. else {
  202. return this.value;
  203. }
  204. }
  205. // --- Interop with null and undefined ---
  206. /**
  207. * Creates an `Optional` value from a nullable (or undefined-able) input.
  208. * Null, or undefined, is converted to `None`, and anything else is converted
  209. * to `Some`.
  210. */
  211. static from(value) {
  212. return isNonNullable(value) ? Optional.some(value) : Optional.none();
  213. }
  214. /**
  215. * Converts an `Optional` to a nullable type, by getting the value if it
  216. * exists, or returning `null` if it does not.
  217. */
  218. getOrNull() {
  219. return this.tag ? this.value : null;
  220. }
  221. /**
  222. * Converts an `Optional` to an undefined-able type, by getting the value if
  223. * it exists, or returning `undefined` if it does not.
  224. */
  225. getOrUndefined() {
  226. return this.value;
  227. }
  228. // --- Utilities ---
  229. /**
  230. * If the `Optional` contains a value, perform an action on that value.
  231. * Unlike the rest of the methods on this type, `.each` has side-effects. If
  232. * you want to transform an `Optional<T>` **into** something, then this is not
  233. * the method for you. If you want to use an `Optional<T>` to **do**
  234. * something, then this is the method for you - provided you're okay with not
  235. * doing anything in the case where the `Optional` doesn't have a value inside
  236. * it. If you're not sure whether your use-case fits into transforming
  237. * **into** something or **doing** something, check whether it has a return
  238. * value. If it does, you should be performing a transform.
  239. */
  240. each(worker) {
  241. if (this.tag) {
  242. worker(this.value);
  243. }
  244. }
  245. /**
  246. * Turn the `Optional` object into an array that contains all of the values
  247. * stored inside the `Optional`. In practice, this means the output will have
  248. * either 0 or 1 elements.
  249. */
  250. toArray() {
  251. return this.tag ? [this.value] : [];
  252. }
  253. /**
  254. * Turn the `Optional` object into a string for debugging or printing. Not
  255. * recommended for production code, but good for debugging. Also note that
  256. * these days an `Optional` object can be logged to the console directly, and
  257. * its inner value (if it exists) will be visible.
  258. */
  259. toString() {
  260. return this.tag ? `some(${this.value})` : 'none()';
  261. }
  262. }
  263. // Sneaky optimisation: every instance of Optional.none is identical, so just
  264. // reuse the same object
  265. Optional.singletonNone = new Optional(false);
  266. const get$1 = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
  267. const head = (xs) => get$1(xs, 0);
  268. // Use window object as the global if it's available since CSP will block script evals
  269. // eslint-disable-next-line @typescript-eslint/no-implied-eval
  270. const Global = typeof window !== 'undefined' ? window : Function('return this;')();
  271. const blank = (r) => (s) => s.replace(r, '');
  272. /** removes all leading and trailing spaces */
  273. const trim = blank(/^\s+|\s+$/g);
  274. var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  275. const prismjs = function(global, module, exports) {
  276. // preserve the global if it has already been loaded
  277. const oldprism = window.Prism;
  278. window.Prism = { manual: true };
  279. /// <reference lib="WebWorker"/>
  280. var _self = (typeof window !== 'undefined')
  281. ? window // if in browser
  282. : (
  283. (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
  284. ? self // if in worker
  285. : {} // if in node js
  286. );
  287. /**
  288. * Prism: Lightweight, robust, elegant syntax highlighting
  289. *
  290. * @license MIT <https://opensource.org/licenses/MIT>
  291. * @author Lea Verou <https://lea.verou.me>
  292. * @namespace
  293. * @public
  294. */
  295. var Prism = (function (_self) {
  296. // Private helper vars
  297. var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
  298. var uniqueId = 0;
  299. // The grammar object for plaintext
  300. var plainTextGrammar = {};
  301. var _ = {
  302. /**
  303. * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
  304. * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
  305. * additional languages or plugins yourself.
  306. *
  307. * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
  308. *
  309. * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
  310. * empty Prism object into the global scope before loading the Prism script like this:
  311. *
  312. * ```js
  313. * window.Prism = window.Prism || {};
  314. * Prism.manual = true;
  315. * // add a new <script> to load Prism's script
  316. * ```
  317. *
  318. * @default false
  319. * @type {boolean}
  320. * @memberof Prism
  321. * @public
  322. */
  323. manual: _self.Prism && _self.Prism.manual,
  324. /**
  325. * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
  326. * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
  327. * own worker, you don't want it to do this.
  328. *
  329. * By setting this value to `true`, Prism will not add its own listeners to the worker.
  330. *
  331. * You obviously have to change this value before Prism executes. To do this, you can add an
  332. * empty Prism object into the global scope before loading the Prism script like this:
  333. *
  334. * ```js
  335. * window.Prism = window.Prism || {};
  336. * Prism.disableWorkerMessageHandler = true;
  337. * // Load Prism's script
  338. * ```
  339. *
  340. * @default false
  341. * @type {boolean}
  342. * @memberof Prism
  343. * @public
  344. */
  345. disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
  346. /**
  347. * A namespace for utility methods.
  348. *
  349. * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
  350. * change or disappear at any time.
  351. *
  352. * @namespace
  353. * @memberof Prism
  354. */
  355. util: {
  356. encode: function encode(tokens) {
  357. if (tokens instanceof Token) {
  358. return new Token(tokens.type, encode(tokens.content), tokens.alias);
  359. } else if (Array.isArray(tokens)) {
  360. return tokens.map(encode);
  361. } else {
  362. return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
  363. }
  364. },
  365. /**
  366. * Returns the name of the type of the given value.
  367. *
  368. * @param {any} o
  369. * @returns {string}
  370. * @example
  371. * type(null) === 'Null'
  372. * type(undefined) === 'Undefined'
  373. * type(123) === 'Number'
  374. * type('foo') === 'String'
  375. * type(true) === 'Boolean'
  376. * type([1, 2]) === 'Array'
  377. * type({}) === 'Object'
  378. * type(String) === 'Function'
  379. * type(/abc+/) === 'RegExp'
  380. */
  381. type: function (o) {
  382. return Object.prototype.toString.call(o).slice(8, -1);
  383. },
  384. /**
  385. * Returns a unique number for the given object. Later calls will still return the same number.
  386. *
  387. * @param {Object} obj
  388. * @returns {number}
  389. */
  390. objId: function (obj) {
  391. if (!obj['__id']) {
  392. Object.defineProperty(obj, '__id', { value: ++uniqueId });
  393. }
  394. return obj['__id'];
  395. },
  396. /**
  397. * Creates a deep clone of the given object.
  398. *
  399. * The main intended use of this function is to clone language definitions.
  400. *
  401. * @param {T} o
  402. * @param {Record<number, any>} [visited]
  403. * @returns {T}
  404. * @template T
  405. */
  406. clone: function deepClone(o, visited) {
  407. visited = visited || {};
  408. var clone; var id;
  409. switch (_.util.type(o)) {
  410. case 'Object':
  411. id = _.util.objId(o);
  412. if (visited[id]) {
  413. return visited[id];
  414. }
  415. clone = /** @type {Record<string, any>} */ ({});
  416. visited[id] = clone;
  417. for (var key in o) {
  418. if (o.hasOwnProperty(key)) {
  419. clone[key] = deepClone(o[key], visited);
  420. }
  421. }
  422. return /** @type {any} */ (clone);
  423. case 'Array':
  424. id = _.util.objId(o);
  425. if (visited[id]) {
  426. return visited[id];
  427. }
  428. clone = [];
  429. visited[id] = clone;
  430. (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
  431. clone[i] = deepClone(v, visited);
  432. });
  433. return /** @type {any} */ (clone);
  434. default:
  435. return o;
  436. }
  437. },
  438. /**
  439. * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
  440. *
  441. * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
  442. *
  443. * @param {Element} element
  444. * @returns {string}
  445. */
  446. getLanguage: function (element) {
  447. while (element) {
  448. var m = lang.exec(element.className);
  449. if (m) {
  450. return m[1].toLowerCase();
  451. }
  452. element = element.parentElement;
  453. }
  454. return 'none';
  455. },
  456. /**
  457. * Sets the Prism `language-xxxx` class of the given element.
  458. *
  459. * @param {Element} element
  460. * @param {string} language
  461. * @returns {void}
  462. */
  463. setLanguage: function (element, language) {
  464. // remove all `language-xxxx` classes
  465. // (this might leave behind a leading space)
  466. element.className = element.className.replace(RegExp(lang, 'gi'), '');
  467. // add the new `language-xxxx` class
  468. // (using `classList` will automatically clean up spaces for us)
  469. element.classList.add('language-' + language);
  470. },
  471. /**
  472. * Returns the script element that is currently executing.
  473. *
  474. * This does __not__ work for line script element.
  475. *
  476. * @returns {HTMLScriptElement | null}
  477. */
  478. currentScript: function () {
  479. if (typeof document === 'undefined') {
  480. return null;
  481. }
  482. if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
  483. return /** @type {any} */ (document.currentScript);
  484. }
  485. // IE11 workaround
  486. // we'll get the src of the current script by parsing IE11's error stack trace
  487. // this will not work for inline scripts
  488. try {
  489. throw new Error();
  490. } catch (err) {
  491. // Get file src url from stack. Specifically works with the format of stack traces in IE.
  492. // A stack will look like this:
  493. //
  494. // Error
  495. // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
  496. // at Global code (http://localhost/components/prism-core.js:606:1)
  497. var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
  498. if (src) {
  499. var scripts = document.getElementsByTagName('script');
  500. for (var i in scripts) {
  501. if (scripts[i].src == src) {
  502. return scripts[i];
  503. }
  504. }
  505. }
  506. return null;
  507. }
  508. },
  509. /**
  510. * Returns whether a given class is active for `element`.
  511. *
  512. * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
  513. * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
  514. * given class is just the given class with a `no-` prefix.
  515. *
  516. * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
  517. * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
  518. * ancestors have the given class or the negated version of it, then the default activation will be returned.
  519. *
  520. * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
  521. * version of it, the class is considered active.
  522. *
  523. * @param {Element} element
  524. * @param {string} className
  525. * @param {boolean} [defaultActivation=false]
  526. * @returns {boolean}
  527. */
  528. isActive: function (element, className, defaultActivation) {
  529. var no = 'no-' + className;
  530. while (element) {
  531. var classList = element.classList;
  532. if (classList.contains(className)) {
  533. return true;
  534. }
  535. if (classList.contains(no)) {
  536. return false;
  537. }
  538. element = element.parentElement;
  539. }
  540. return !!defaultActivation;
  541. }
  542. },
  543. /**
  544. * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
  545. *
  546. * @namespace
  547. * @memberof Prism
  548. * @public
  549. */
  550. languages: {
  551. /**
  552. * The grammar for plain, unformatted text.
  553. */
  554. plain: plainTextGrammar,
  555. plaintext: plainTextGrammar,
  556. text: plainTextGrammar,
  557. txt: plainTextGrammar,
  558. /**
  559. * Creates a deep copy of the language with the given id and appends the given tokens.
  560. *
  561. * If a token in `redef` also appears in the copied language, then the existing token in the copied language
  562. * will be overwritten at its original position.
  563. *
  564. * ## Best practices
  565. *
  566. * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
  567. * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
  568. * understand the language definition because, normally, the order of tokens matters in Prism grammars.
  569. *
  570. * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
  571. * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
  572. *
  573. * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
  574. * @param {Grammar} redef The new tokens to append.
  575. * @returns {Grammar} The new language created.
  576. * @public
  577. * @example
  578. * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
  579. * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
  580. * // at its original position
  581. * 'comment': { ... },
  582. * // CSS doesn't have a 'color' token, so this token will be appended
  583. * 'color': /\b(?:red|green|blue)\b/
  584. * });
  585. */
  586. extend: function (id, redef) {
  587. var lang = _.util.clone(_.languages[id]);
  588. for (var key in redef) {
  589. lang[key] = redef[key];
  590. }
  591. return lang;
  592. },
  593. /**
  594. * Inserts tokens _before_ another token in a language definition or any other grammar.
  595. *
  596. * ## Usage
  597. *
  598. * This helper method makes it easy to modify existing languages. For example, the CSS language definition
  599. * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
  600. * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
  601. * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
  602. * this:
  603. *
  604. * ```js
  605. * Prism.languages.markup.style = {
  606. * // token
  607. * };
  608. * ```
  609. *
  610. * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
  611. * before existing tokens. For the CSS example above, you would use it like this:
  612. *
  613. * ```js
  614. * Prism.languages.insertBefore('markup', 'cdata', {
  615. * 'style': {
  616. * // token
  617. * }
  618. * });
  619. * ```
  620. *
  621. * ## Special cases
  622. *
  623. * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
  624. * will be ignored.
  625. *
  626. * This behavior can be used to insert tokens after `before`:
  627. *
  628. * ```js
  629. * Prism.languages.insertBefore('markup', 'comment', {
  630. * 'comment': Prism.languages.markup.comment,
  631. * // tokens after 'comment'
  632. * });
  633. * ```
  634. *
  635. * ## Limitations
  636. *
  637. * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
  638. * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
  639. * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
  640. * deleting properties which is necessary to insert at arbitrary positions.
  641. *
  642. * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
  643. * Instead, it will create a new object and replace all references to the target object with the new one. This
  644. * can be done without temporarily deleting properties, so the iteration order is well-defined.
  645. *
  646. * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
  647. * you hold the target object in a variable, then the value of the variable will not change.
  648. *
  649. * ```js
  650. * var oldMarkup = Prism.languages.markup;
  651. * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
  652. *
  653. * assert(oldMarkup !== Prism.languages.markup);
  654. * assert(newMarkup === Prism.languages.markup);
  655. * ```
  656. *
  657. * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
  658. * object to be modified.
  659. * @param {string} before The key to insert before.
  660. * @param {Grammar} insert An object containing the key-value pairs to be inserted.
  661. * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
  662. * object to be modified.
  663. *
  664. * Defaults to `Prism.languages`.
  665. * @returns {Grammar} The new grammar object.
  666. * @public
  667. */
  668. insertBefore: function (inside, before, insert, root) {
  669. root = root || /** @type {any} */ (_.languages);
  670. var grammar = root[inside];
  671. /** @type {Grammar} */
  672. var ret = {};
  673. for (var token in grammar) {
  674. if (grammar.hasOwnProperty(token)) {
  675. if (token == before) {
  676. for (var newToken in insert) {
  677. if (insert.hasOwnProperty(newToken)) {
  678. ret[newToken] = insert[newToken];
  679. }
  680. }
  681. }
  682. // Do not insert token which also occur in insert. See #1525
  683. if (!insert.hasOwnProperty(token)) {
  684. ret[token] = grammar[token];
  685. }
  686. }
  687. }
  688. var old = root[inside];
  689. root[inside] = ret;
  690. // Update references in other language definitions
  691. _.languages.DFS(_.languages, function (key, value) {
  692. if (value === old && key != inside) {
  693. this[key] = ret;
  694. }
  695. });
  696. return ret;
  697. },
  698. // Traverse a language definition with Depth First Search
  699. DFS: function DFS(o, callback, type, visited) {
  700. visited = visited || {};
  701. var objId = _.util.objId;
  702. for (var i in o) {
  703. if (o.hasOwnProperty(i)) {
  704. callback.call(o, i, o[i], type || i);
  705. var property = o[i];
  706. var propertyType = _.util.type(property);
  707. if (propertyType === 'Object' && !visited[objId(property)]) {
  708. visited[objId(property)] = true;
  709. DFS(property, callback, null, visited);
  710. } else if (propertyType === 'Array' && !visited[objId(property)]) {
  711. visited[objId(property)] = true;
  712. DFS(property, callback, i, visited);
  713. }
  714. }
  715. }
  716. }
  717. },
  718. plugins: {},
  719. /**
  720. * This is the most high-level function in Prism’s API.
  721. * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
  722. * each one of them.
  723. *
  724. * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
  725. *
  726. * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
  727. * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
  728. * @memberof Prism
  729. * @public
  730. */
  731. highlightAll: function (async, callback) {
  732. _.highlightAllUnder(document, async, callback);
  733. },
  734. /**
  735. * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
  736. * {@link Prism.highlightElement} on each one of them.
  737. *
  738. * The following hooks will be run:
  739. * 1. `before-highlightall`
  740. * 2. `before-all-elements-highlight`
  741. * 3. All hooks of {@link Prism.highlightElement} for each element.
  742. *
  743. * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
  744. * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
  745. * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
  746. * @memberof Prism
  747. * @public
  748. */
  749. highlightAllUnder: function (container, async, callback) {
  750. var env = {
  751. callback: callback,
  752. container: container,
  753. selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
  754. };
  755. _.hooks.run('before-highlightall', env);
  756. env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
  757. _.hooks.run('before-all-elements-highlight', env);
  758. for (var i = 0, element; (element = env.elements[i++]);) {
  759. _.highlightElement(element, async === true, env.callback);
  760. }
  761. },
  762. /**
  763. * Highlights the code inside a single element.
  764. *
  765. * The following hooks will be run:
  766. * 1. `before-sanity-check`
  767. * 2. `before-highlight`
  768. * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
  769. * 4. `before-insert`
  770. * 5. `after-highlight`
  771. * 6. `complete`
  772. *
  773. * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
  774. * the element's language.
  775. *
  776. * @param {Element} element The element containing the code.
  777. * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
  778. * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
  779. * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
  780. * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
  781. *
  782. * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
  783. * asynchronous highlighting to work. You can build your own bundle on the
  784. * [Download page](https://prismjs.com/download.html).
  785. * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
  786. * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
  787. * @memberof Prism
  788. * @public
  789. */
  790. highlightElement: function (element, async, callback) {
  791. // Find language
  792. var language = _.util.getLanguage(element);
  793. var grammar = _.languages[language];
  794. // Set language on the element, if not present
  795. _.util.setLanguage(element, language);
  796. // Set language on the parent, for styling
  797. var parent = element.parentElement;
  798. if (parent && parent.nodeName.toLowerCase() === 'pre') {
  799. _.util.setLanguage(parent, language);
  800. }
  801. var code = element.textContent;
  802. var env = {
  803. element: element,
  804. language: language,
  805. grammar: grammar,
  806. code: code
  807. };
  808. function insertHighlightedCode(highlightedCode) {
  809. env.highlightedCode = highlightedCode;
  810. _.hooks.run('before-insert', env);
  811. env.element.innerHTML = env.highlightedCode;
  812. _.hooks.run('after-highlight', env);
  813. _.hooks.run('complete', env);
  814. callback && callback.call(env.element);
  815. }
  816. _.hooks.run('before-sanity-check', env);
  817. // plugins may change/add the parent/element
  818. parent = env.element.parentElement;
  819. if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
  820. parent.setAttribute('tabindex', '0');
  821. }
  822. if (!env.code) {
  823. _.hooks.run('complete', env);
  824. callback && callback.call(env.element);
  825. return;
  826. }
  827. _.hooks.run('before-highlight', env);
  828. if (!env.grammar) {
  829. insertHighlightedCode(_.util.encode(env.code));
  830. return;
  831. }
  832. if (async && _self.Worker) {
  833. var worker = new Worker(_.filename);
  834. worker.onmessage = function (evt) {
  835. insertHighlightedCode(evt.data);
  836. };
  837. worker.postMessage(JSON.stringify({
  838. language: env.language,
  839. code: env.code,
  840. immediateClose: true
  841. }));
  842. } else {
  843. insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
  844. }
  845. },
  846. /**
  847. * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
  848. * and the language definitions to use, and returns a string with the HTML produced.
  849. *
  850. * The following hooks will be run:
  851. * 1. `before-tokenize`
  852. * 2. `after-tokenize`
  853. * 3. `wrap`: On each {@link Token}.
  854. *
  855. * @param {string} text A string with the code to be highlighted.
  856. * @param {Grammar} grammar An object containing the tokens to use.
  857. *
  858. * Usually a language definition like `Prism.languages.markup`.
  859. * @param {string} language The name of the language definition passed to `grammar`.
  860. * @returns {string} The highlighted HTML.
  861. * @memberof Prism
  862. * @public
  863. * @example
  864. * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
  865. */
  866. highlight: function (text, grammar, language) {
  867. var env = {
  868. code: text,
  869. grammar: grammar,
  870. language: language
  871. };
  872. _.hooks.run('before-tokenize', env);
  873. if (!env.grammar) {
  874. throw new Error('The language "' + env.language + '" has no grammar.');
  875. }
  876. env.tokens = _.tokenize(env.code, env.grammar);
  877. _.hooks.run('after-tokenize', env);
  878. return Token.stringify(_.util.encode(env.tokens), env.language);
  879. },
  880. /**
  881. * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
  882. * and the language definitions to use, and returns an array with the tokenized code.
  883. *
  884. * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
  885. *
  886. * This method could be useful in other contexts as well, as a very crude parser.
  887. *
  888. * @param {string} text A string with the code to be highlighted.
  889. * @param {Grammar} grammar An object containing the tokens to use.
  890. *
  891. * Usually a language definition like `Prism.languages.markup`.
  892. * @returns {TokenStream} An array of strings and tokens, a token stream.
  893. * @memberof Prism
  894. * @public
  895. * @example
  896. * let code = `var foo = 0;`;
  897. * let tokens = Prism.tokenize(code, Prism.languages.javascript);
  898. * tokens.forEach(token => {
  899. * if (token instanceof Prism.Token && token.type === 'number') {
  900. * console.log(`Found numeric literal: ${token.content}`);
  901. * }
  902. * });
  903. */
  904. tokenize: function (text, grammar) {
  905. var rest = grammar.rest;
  906. if (rest) {
  907. for (var token in rest) {
  908. grammar[token] = rest[token];
  909. }
  910. delete grammar.rest;
  911. }
  912. var tokenList = new LinkedList();
  913. addAfter(tokenList, tokenList.head, text);
  914. matchGrammar(text, tokenList, grammar, tokenList.head, 0);
  915. return toArray(tokenList);
  916. },
  917. /**
  918. * @namespace
  919. * @memberof Prism
  920. * @public
  921. */
  922. hooks: {
  923. all: {},
  924. /**
  925. * Adds the given callback to the list of callbacks for the given hook.
  926. *
  927. * The callback will be invoked when the hook it is registered for is run.
  928. * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
  929. *
  930. * One callback function can be registered to multiple hooks and the same hook multiple times.
  931. *
  932. * @param {string} name The name of the hook.
  933. * @param {HookCallback} callback The callback function which is given environment variables.
  934. * @public
  935. */
  936. add: function (name, callback) {
  937. var hooks = _.hooks.all;
  938. hooks[name] = hooks[name] || [];
  939. hooks[name].push(callback);
  940. },
  941. /**
  942. * Runs a hook invoking all registered callbacks with the given environment variables.
  943. *
  944. * Callbacks will be invoked synchronously and in the order in which they were registered.
  945. *
  946. * @param {string} name The name of the hook.
  947. * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
  948. * @public
  949. */
  950. run: function (name, env) {
  951. var callbacks = _.hooks.all[name];
  952. if (!callbacks || !callbacks.length) {
  953. return;
  954. }
  955. for (var i = 0, callback; (callback = callbacks[i++]);) {
  956. callback(env);
  957. }
  958. }
  959. },
  960. Token: Token
  961. };
  962. _self.Prism = _;
  963. // Typescript note:
  964. // The following can be used to import the Token type in JSDoc:
  965. //
  966. // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
  967. /**
  968. * Creates a new token.
  969. *
  970. * @param {string} type See {@link Token#type type}
  971. * @param {string | TokenStream} content See {@link Token#content content}
  972. * @param {string|string[]} [alias] The alias(es) of the token.
  973. * @param {string} [matchedStr=""] A copy of the full string this token was created from.
  974. * @class
  975. * @global
  976. * @public
  977. */
  978. function Token(type, content, alias, matchedStr) {
  979. /**
  980. * The type of the token.
  981. *
  982. * This is usually the key of a pattern in a {@link Grammar}.
  983. *
  984. * @type {string}
  985. * @see GrammarToken
  986. * @public
  987. */
  988. this.type = type;
  989. /**
  990. * The strings or tokens contained by this token.
  991. *
  992. * This will be a token stream if the pattern matched also defined an `inside` grammar.
  993. *
  994. * @type {string | TokenStream}
  995. * @public
  996. */
  997. this.content = content;
  998. /**
  999. * The alias(es) of the token.
  1000. *
  1001. * @type {string|string[]}
  1002. * @see GrammarToken
  1003. * @public
  1004. */
  1005. this.alias = alias;
  1006. // Copy of the full string this token was created from
  1007. this.length = (matchedStr || '').length | 0;
  1008. }
  1009. /**
  1010. * A token stream is an array of strings and {@link Token Token} objects.
  1011. *
  1012. * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
  1013. * them.
  1014. *
  1015. * 1. No adjacent strings.
  1016. * 2. No empty strings.
  1017. *
  1018. * The only exception here is the token stream that only contains the empty string and nothing else.
  1019. *
  1020. * @typedef {Array<string | Token>} TokenStream
  1021. * @global
  1022. * @public
  1023. */
  1024. /**
  1025. * Converts the given token or token stream to an HTML representation.
  1026. *
  1027. * The following hooks will be run:
  1028. * 1. `wrap`: On each {@link Token}.
  1029. *
  1030. * @param {string | Token | TokenStream} o The token or token stream to be converted.
  1031. * @param {string} language The name of current language.
  1032. * @returns {string} The HTML representation of the token or token stream.
  1033. * @memberof Token
  1034. * @static
  1035. */
  1036. Token.stringify = function stringify(o, language) {
  1037. if (typeof o == 'string') {
  1038. return o;
  1039. }
  1040. if (Array.isArray(o)) {
  1041. var s = '';
  1042. o.forEach(function (e) {
  1043. s += stringify(e, language);
  1044. });
  1045. return s;
  1046. }
  1047. var env = {
  1048. type: o.type,
  1049. content: stringify(o.content, language),
  1050. tag: 'span',
  1051. classes: ['token', o.type],
  1052. attributes: {},
  1053. language: language
  1054. };
  1055. var aliases = o.alias;
  1056. if (aliases) {
  1057. if (Array.isArray(aliases)) {
  1058. Array.prototype.push.apply(env.classes, aliases);
  1059. } else {
  1060. env.classes.push(aliases);
  1061. }
  1062. }
  1063. _.hooks.run('wrap', env);
  1064. var attributes = '';
  1065. for (var name in env.attributes) {
  1066. attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
  1067. }
  1068. return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
  1069. };
  1070. /**
  1071. * @param {RegExp} pattern
  1072. * @param {number} pos
  1073. * @param {string} text
  1074. * @param {boolean} lookbehind
  1075. * @returns {RegExpExecArray | null}
  1076. */
  1077. function matchPattern(pattern, pos, text, lookbehind) {
  1078. pattern.lastIndex = pos;
  1079. var match = pattern.exec(text);
  1080. if (match && lookbehind && match[1]) {
  1081. // change the match to remove the text matched by the Prism lookbehind group
  1082. var lookbehindLength = match[1].length;
  1083. match.index += lookbehindLength;
  1084. match[0] = match[0].slice(lookbehindLength);
  1085. }
  1086. return match;
  1087. }
  1088. /**
  1089. * @param {string} text
  1090. * @param {LinkedList<string | Token>} tokenList
  1091. * @param {any} grammar
  1092. * @param {LinkedListNode<string | Token>} startNode
  1093. * @param {number} startPos
  1094. * @param {RematchOptions} [rematch]
  1095. * @returns {void}
  1096. * @private
  1097. *
  1098. * @typedef RematchOptions
  1099. * @property {string} cause
  1100. * @property {number} reach
  1101. */
  1102. function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
  1103. for (var token in grammar) {
  1104. if (!grammar.hasOwnProperty(token) || !grammar[token]) {
  1105. continue;
  1106. }
  1107. var patterns = grammar[token];
  1108. patterns = Array.isArray(patterns) ? patterns : [patterns];
  1109. for (var j = 0; j < patterns.length; ++j) {
  1110. if (rematch && rematch.cause == token + ',' + j) {
  1111. return;
  1112. }
  1113. var patternObj = patterns[j];
  1114. var inside = patternObj.inside;
  1115. var lookbehind = !!patternObj.lookbehind;
  1116. var greedy = !!patternObj.greedy;
  1117. var alias = patternObj.alias;
  1118. if (greedy && !patternObj.pattern.global) {
  1119. // Without the global flag, lastIndex won't work
  1120. var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
  1121. patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
  1122. }
  1123. /** @type {RegExp} */
  1124. var pattern = patternObj.pattern || patternObj;
  1125. for ( // iterate the token list and keep track of the current token/string position
  1126. var currentNode = startNode.next, pos = startPos;
  1127. currentNode !== tokenList.tail;
  1128. pos += currentNode.value.length, currentNode = currentNode.next
  1129. ) {
  1130. if (rematch && pos >= rematch.reach) {
  1131. break;
  1132. }
  1133. var str = currentNode.value;
  1134. if (tokenList.length > text.length) {
  1135. // Something went terribly wrong, ABORT, ABORT!
  1136. return;
  1137. }
  1138. if (str instanceof Token) {
  1139. continue;
  1140. }
  1141. var removeCount = 1; // this is the to parameter of removeBetween
  1142. var match;
  1143. if (greedy) {
  1144. match = matchPattern(pattern, pos, text, lookbehind);
  1145. if (!match || match.index >= text.length) {
  1146. break;
  1147. }
  1148. var from = match.index;
  1149. var to = match.index + match[0].length;
  1150. var p = pos;
  1151. // find the node that contains the match
  1152. p += currentNode.value.length;
  1153. while (from >= p) {
  1154. currentNode = currentNode.next;
  1155. p += currentNode.value.length;
  1156. }
  1157. // adjust pos (and p)
  1158. p -= currentNode.value.length;
  1159. pos = p;
  1160. // the current node is a Token, then the match starts inside another Token, which is invalid
  1161. if (currentNode.value instanceof Token) {
  1162. continue;
  1163. }
  1164. // find the last node which is affected by this match
  1165. for (
  1166. var k = currentNode;
  1167. k !== tokenList.tail && (p < to || typeof k.value === 'string');
  1168. k = k.next
  1169. ) {
  1170. removeCount++;
  1171. p += k.value.length;
  1172. }
  1173. removeCount--;
  1174. // replace with the new match
  1175. str = text.slice(pos, p);
  1176. match.index -= pos;
  1177. } else {
  1178. match = matchPattern(pattern, 0, str, lookbehind);
  1179. if (!match) {
  1180. continue;
  1181. }
  1182. }
  1183. // eslint-disable-next-line no-redeclare
  1184. var from = match.index;
  1185. var matchStr = match[0];
  1186. var before = str.slice(0, from);
  1187. var after = str.slice(from + matchStr.length);
  1188. var reach = pos + str.length;
  1189. if (rematch && reach > rematch.reach) {
  1190. rematch.reach = reach;
  1191. }
  1192. var removeFrom = currentNode.prev;
  1193. if (before) {
  1194. removeFrom = addAfter(tokenList, removeFrom, before);
  1195. pos += before.length;
  1196. }
  1197. removeRange(tokenList, removeFrom, removeCount);
  1198. var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
  1199. currentNode = addAfter(tokenList, removeFrom, wrapped);
  1200. if (after) {
  1201. addAfter(tokenList, currentNode, after);
  1202. }
  1203. if (removeCount > 1) {
  1204. // at least one Token object was removed, so we have to do some rematching
  1205. // this can only happen if the current pattern is greedy
  1206. /** @type {RematchOptions} */
  1207. var nestedRematch = {
  1208. cause: token + ',' + j,
  1209. reach: reach
  1210. };
  1211. matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
  1212. // the reach might have been extended because of the rematching
  1213. if (rematch && nestedRematch.reach > rematch.reach) {
  1214. rematch.reach = nestedRematch.reach;
  1215. }
  1216. }
  1217. }
  1218. }
  1219. }
  1220. }
  1221. /**
  1222. * @typedef LinkedListNode
  1223. * @property {T} value
  1224. * @property {LinkedListNode<T> | null} prev The previous node.
  1225. * @property {LinkedListNode<T> | null} next The next node.
  1226. * @template T
  1227. * @private
  1228. */
  1229. /**
  1230. * @template T
  1231. * @private
  1232. */
  1233. function LinkedList() {
  1234. /** @type {LinkedListNode<T>} */
  1235. var head = { value: null, prev: null, next: null };
  1236. /** @type {LinkedListNode<T>} */
  1237. var tail = { value: null, prev: head, next: null };
  1238. head.next = tail;
  1239. /** @type {LinkedListNode<T>} */
  1240. this.head = head;
  1241. /** @type {LinkedListNode<T>} */
  1242. this.tail = tail;
  1243. this.length = 0;
  1244. }
  1245. /**
  1246. * Adds a new node with the given value to the list.
  1247. *
  1248. * @param {LinkedList<T>} list
  1249. * @param {LinkedListNode<T>} node
  1250. * @param {T} value
  1251. * @returns {LinkedListNode<T>} The added node.
  1252. * @template T
  1253. */
  1254. function addAfter(list, node, value) {
  1255. // assumes that node != list.tail && values.length >= 0
  1256. var next = node.next;
  1257. var newNode = { value: value, prev: node, next: next };
  1258. node.next = newNode;
  1259. next.prev = newNode;
  1260. list.length++;
  1261. return newNode;
  1262. }
  1263. /**
  1264. * Removes `count` nodes after the given node. The given node will not be removed.
  1265. *
  1266. * @param {LinkedList<T>} list
  1267. * @param {LinkedListNode<T>} node
  1268. * @param {number} count
  1269. * @template T
  1270. */
  1271. function removeRange(list, node, count) {
  1272. var next = node.next;
  1273. for (var i = 0; i < count && next !== list.tail; i++) {
  1274. next = next.next;
  1275. }
  1276. node.next = next;
  1277. next.prev = node;
  1278. list.length -= i;
  1279. }
  1280. /**
  1281. * @param {LinkedList<T>} list
  1282. * @returns {T[]}
  1283. * @template T
  1284. */
  1285. function toArray(list) {
  1286. var array = [];
  1287. var node = list.head.next;
  1288. while (node !== list.tail) {
  1289. array.push(node.value);
  1290. node = node.next;
  1291. }
  1292. return array;
  1293. }
  1294. if (!_self.document) {
  1295. if (!_self.addEventListener) {
  1296. // in Node.js
  1297. return _;
  1298. }
  1299. if (!_.disableWorkerMessageHandler) {
  1300. // In worker
  1301. _self.addEventListener('message', function (evt) {
  1302. var message = JSON.parse(evt.data);
  1303. var lang = message.language;
  1304. var code = message.code;
  1305. var immediateClose = message.immediateClose;
  1306. _self.postMessage(_.highlight(code, _.languages[lang], lang));
  1307. if (immediateClose) {
  1308. _self.close();
  1309. }
  1310. }, false);
  1311. }
  1312. return _;
  1313. }
  1314. // Get current script and highlight
  1315. var script = _.util.currentScript();
  1316. if (script) {
  1317. _.filename = script.src;
  1318. if (script.hasAttribute('data-manual')) {
  1319. _.manual = true;
  1320. }
  1321. }
  1322. function highlightAutomaticallyCallback() {
  1323. if (!_.manual) {
  1324. _.highlightAll();
  1325. }
  1326. }
  1327. if (!_.manual) {
  1328. // If the document state is "loading", then we'll use DOMContentLoaded.
  1329. // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
  1330. // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
  1331. // might take longer one animation frame to execute which can create a race condition where only some plugins have
  1332. // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
  1333. // See https://github.com/PrismJS/prism/issues/2102
  1334. var readyState = document.readyState;
  1335. if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
  1336. document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
  1337. } else {
  1338. if (window.requestAnimationFrame) {
  1339. window.requestAnimationFrame(highlightAutomaticallyCallback);
  1340. } else {
  1341. window.setTimeout(highlightAutomaticallyCallback, 16);
  1342. }
  1343. }
  1344. }
  1345. return _;
  1346. }(_self));
  1347. if (typeof module !== 'undefined' && module.exports) {
  1348. module.exports = Prism;
  1349. }
  1350. // hack for components to work correctly in node.js
  1351. if (typeof global !== 'undefined') {
  1352. global.Prism = Prism;
  1353. }
  1354. // some additional documentation/types
  1355. /**
  1356. * The expansion of a simple `RegExp` literal to support additional properties.
  1357. *
  1358. * @typedef GrammarToken
  1359. * @property {RegExp} pattern The regular expression of the token.
  1360. * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
  1361. * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
  1362. * @property {boolean} [greedy=false] Whether the token is greedy.
  1363. * @property {string|string[]} [alias] An optional alias or list of aliases.
  1364. * @property {Grammar} [inside] The nested grammar of this token.
  1365. *
  1366. * The `inside` grammar will be used to tokenize the text value of each token of this kind.
  1367. *
  1368. * This can be used to make nested and even recursive language definitions.
  1369. *
  1370. * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
  1371. * each another.
  1372. * @global
  1373. * @public
  1374. */
  1375. /**
  1376. * @typedef Grammar
  1377. * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
  1378. * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
  1379. * @global
  1380. * @public
  1381. */
  1382. /**
  1383. * A function which will invoked after an element was successfully highlighted.
  1384. *
  1385. * @callback HighlightCallback
  1386. * @param {Element} element The element successfully highlighted.
  1387. * @returns {void}
  1388. * @global
  1389. * @public
  1390. */
  1391. /**
  1392. * @callback HookCallback
  1393. * @param {Object<string, any>} env The environment variables of the hook.
  1394. * @returns {void}
  1395. * @global
  1396. * @public
  1397. */
  1398. Prism.languages.clike = {
  1399. 'comment': [
  1400. {
  1401. pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
  1402. lookbehind: true,
  1403. greedy: true
  1404. },
  1405. {
  1406. pattern: /(^|[^\\:])\/\/.*/,
  1407. lookbehind: true,
  1408. greedy: true
  1409. }
  1410. ],
  1411. 'string': {
  1412. pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
  1413. greedy: true
  1414. },
  1415. 'class-name': {
  1416. pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
  1417. lookbehind: true,
  1418. inside: {
  1419. 'punctuation': /[.\\]/
  1420. }
  1421. },
  1422. 'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
  1423. 'boolean': /\b(?:false|true)\b/,
  1424. 'function': /\b\w+(?=\()/,
  1425. 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
  1426. 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
  1427. 'punctuation': /[{}[\];(),.:]/
  1428. };
  1429. (function (Prism) {
  1430. /**
  1431. * Returns the placeholder for the given language id and index.
  1432. *
  1433. * @param {string} language
  1434. * @param {string|number} index
  1435. * @returns {string}
  1436. */
  1437. function getPlaceholder(language, index) {
  1438. return '___' + language.toUpperCase() + index + '___';
  1439. }
  1440. Object.defineProperties(Prism.languages['markup-templating'] = {}, {
  1441. buildPlaceholders: {
  1442. /**
  1443. * Tokenize all inline templating expressions matching `placeholderPattern`.
  1444. *
  1445. * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns
  1446. * `true` will be replaced.
  1447. *
  1448. * @param {object} env The environment of the `before-tokenize` hook.
  1449. * @param {string} language The language id.
  1450. * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders.
  1451. * @param {(match: string) => boolean} [replaceFilter]
  1452. */
  1453. value: function (env, language, placeholderPattern, replaceFilter) {
  1454. if (env.language !== language) {
  1455. return;
  1456. }
  1457. var tokenStack = env.tokenStack = [];
  1458. env.code = env.code.replace(placeholderPattern, function (match) {
  1459. if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
  1460. return match;
  1461. }
  1462. var i = tokenStack.length;
  1463. var placeholder;
  1464. // Check for existing strings
  1465. while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1) {
  1466. ++i;
  1467. }
  1468. // Create a sparse array
  1469. tokenStack[i] = match;
  1470. return placeholder;
  1471. });
  1472. // Switch the grammar to markup
  1473. env.grammar = Prism.languages.markup;
  1474. }
  1475. },
  1476. tokenizePlaceholders: {
  1477. /**
  1478. * Replace placeholders with proper tokens after tokenizing.
  1479. *
  1480. * @param {object} env The environment of the `after-tokenize` hook.
  1481. * @param {string} language The language id.
  1482. */
  1483. value: function (env, language) {
  1484. if (env.language !== language || !env.tokenStack) {
  1485. return;
  1486. }
  1487. // Switch the grammar back
  1488. env.grammar = Prism.languages[language];
  1489. var j = 0;
  1490. var keys = Object.keys(env.tokenStack);
  1491. function walkTokens(tokens) {
  1492. for (var i = 0; i < tokens.length; i++) {
  1493. // all placeholders are replaced already
  1494. if (j >= keys.length) {
  1495. break;
  1496. }
  1497. var token = tokens[i];
  1498. if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
  1499. var k = keys[j];
  1500. var t = env.tokenStack[k];
  1501. var s = typeof token === 'string' ? token : token.content;
  1502. var placeholder = getPlaceholder(language, k);
  1503. var index = s.indexOf(placeholder);
  1504. if (index > -1) {
  1505. ++j;
  1506. var before = s.substring(0, index);
  1507. var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t);
  1508. var after = s.substring(index + placeholder.length);
  1509. var replacement = [];
  1510. if (before) {
  1511. replacement.push.apply(replacement, walkTokens([before]));
  1512. }
  1513. replacement.push(middle);
  1514. if (after) {
  1515. replacement.push.apply(replacement, walkTokens([after]));
  1516. }
  1517. if (typeof token === 'string') {
  1518. tokens.splice.apply(tokens, [i, 1].concat(replacement));
  1519. } else {
  1520. token.content = replacement;
  1521. }
  1522. }
  1523. } else if (token.content /* && typeof token.content !== 'string' */) {
  1524. walkTokens(token.content);
  1525. }
  1526. }
  1527. return tokens;
  1528. }
  1529. walkTokens(env.tokens);
  1530. }
  1531. }
  1532. });
  1533. }(Prism));
  1534. Prism.languages.c = Prism.languages.extend('clike', {
  1535. 'comment': {
  1536. pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
  1537. greedy: true
  1538. },
  1539. 'string': {
  1540. // https://en.cppreference.com/w/c/language/string_literal
  1541. pattern: /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
  1542. greedy: true
  1543. },
  1544. 'class-name': {
  1545. pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,
  1546. lookbehind: true
  1547. },
  1548. 'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,
  1549. 'function': /\b[a-z_]\w*(?=\s*\()/i,
  1550. 'number': /(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,
  1551. 'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/
  1552. });
  1553. Prism.languages.insertBefore('c', 'string', {
  1554. 'char': {
  1555. // https://en.cppreference.com/w/c/language/character_constant
  1556. pattern: /'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,
  1557. greedy: true
  1558. }
  1559. });
  1560. Prism.languages.insertBefore('c', 'string', {
  1561. 'macro': {
  1562. // allow for multiline macro definitions
  1563. // spaces after the # character compile fine with gcc
  1564. pattern: /(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,
  1565. lookbehind: true,
  1566. greedy: true,
  1567. alias: 'property',
  1568. inside: {
  1569. 'string': [
  1570. {
  1571. // highlight the path of the include statement as a string
  1572. pattern: /^(#\s*include\s*)<[^>]+>/,
  1573. lookbehind: true
  1574. },
  1575. Prism.languages.c['string']
  1576. ],
  1577. 'char': Prism.languages.c['char'],
  1578. 'comment': Prism.languages.c['comment'],
  1579. 'macro-name': [
  1580. {
  1581. pattern: /(^#\s*define\s+)\w+\b(?!\()/i,
  1582. lookbehind: true
  1583. },
  1584. {
  1585. pattern: /(^#\s*define\s+)\w+\b(?=\()/i,
  1586. lookbehind: true,
  1587. alias: 'function'
  1588. }
  1589. ],
  1590. // highlight macro directives as keywords
  1591. 'directive': {
  1592. pattern: /^(#\s*)[a-z]+/,
  1593. lookbehind: true,
  1594. alias: 'keyword'
  1595. },
  1596. 'directive-hash': /^#/,
  1597. 'punctuation': /##|\\(?=[\r\n])/,
  1598. 'expression': {
  1599. pattern: /\S[\s\S]*/,
  1600. inside: Prism.languages.c
  1601. }
  1602. }
  1603. }
  1604. });
  1605. Prism.languages.insertBefore('c', 'function', {
  1606. // highlight predefined macros as constants
  1607. 'constant': /\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/
  1608. });
  1609. delete Prism.languages.c['boolean'];
  1610. (function (Prism) {
  1611. var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;
  1612. var modName = /\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g, function () { return keyword.source; });
  1613. Prism.languages.cpp = Prism.languages.extend('c', {
  1614. 'class-name': [
  1615. {
  1616. pattern: RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source
  1617. .replace(/<keyword>/g, function () { return keyword.source; })),
  1618. lookbehind: true
  1619. },
  1620. // This is intended to capture the class name of method implementations like:
  1621. // void foo::bar() const {}
  1622. // However! The `foo` in the above example could also be a namespace, so we only capture the class name if
  1623. // it starts with an uppercase letter. This approximation should give decent results.
  1624. /\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,
  1625. // This will capture the class name before destructors like:
  1626. // Foo::~Foo() {}
  1627. /\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,
  1628. // This also intends to capture the class name of method implementations but here the class has template
  1629. // parameters, so it can't be a namespace (until C++ adds generic namespaces).
  1630. /\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/
  1631. ],
  1632. 'keyword': keyword,
  1633. 'number': {
  1634. pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,
  1635. greedy: true
  1636. },
  1637. 'operator': />>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
  1638. 'boolean': /\b(?:false|true)\b/
  1639. });
  1640. Prism.languages.insertBefore('cpp', 'string', {
  1641. 'module': {
  1642. // https://en.cppreference.com/w/cpp/language/modules
  1643. pattern: RegExp(
  1644. /(\b(?:import|module)\s+)/.source +
  1645. '(?:' +
  1646. // header-name
  1647. /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source +
  1648. '|' +
  1649. // module name or partition or both
  1650. /<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g, function () { return modName; }) +
  1651. ')'
  1652. ),
  1653. lookbehind: true,
  1654. greedy: true,
  1655. inside: {
  1656. 'string': /^[<"][\s\S]+/,
  1657. 'operator': /:/,
  1658. 'punctuation': /\./
  1659. }
  1660. },
  1661. 'raw-string': {
  1662. pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
  1663. alias: 'string',
  1664. greedy: true
  1665. }
  1666. });
  1667. Prism.languages.insertBefore('cpp', 'keyword', {
  1668. 'generic-function': {
  1669. pattern: /\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,
  1670. inside: {
  1671. 'function': /^\w+/,
  1672. 'generic': {
  1673. pattern: /<[\s\S]+/,
  1674. alias: 'class-name',
  1675. inside: Prism.languages.cpp
  1676. }
  1677. }
  1678. }
  1679. });
  1680. Prism.languages.insertBefore('cpp', 'operator', {
  1681. 'double-colon': {
  1682. pattern: /::/,
  1683. alias: 'punctuation'
  1684. }
  1685. });
  1686. Prism.languages.insertBefore('cpp', 'class-name', {
  1687. // the base clause is an optional list of parent classes
  1688. // https://en.cppreference.com/w/cpp/language/class
  1689. 'base-clause': {
  1690. pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,
  1691. lookbehind: true,
  1692. greedy: true,
  1693. inside: Prism.languages.extend('cpp', {})
  1694. }
  1695. });
  1696. Prism.languages.insertBefore('inside', 'double-colon', {
  1697. // All untokenized words that are not namespaces should be class names
  1698. 'class-name': /\b[a-z_]\w*\b(?!\s*::)/i
  1699. }, Prism.languages.cpp['base-clause']);
  1700. }(Prism));
  1701. (function (Prism) {
  1702. /**
  1703. * Replaces all placeholders "<<n>>" of given pattern with the n-th replacement (zero based).
  1704. *
  1705. * Note: This is a simple text based replacement. Be careful when using backreferences!
  1706. *
  1707. * @param {string} pattern the given pattern.
  1708. * @param {string[]} replacements a list of replacement which can be inserted into the given pattern.
  1709. * @returns {string} the pattern with all placeholders replaced with their corresponding replacements.
  1710. * @example replace(/a<<0>>a/.source, [/b+/.source]) === /a(?:b+)a/.source
  1711. */
  1712. function replace(pattern, replacements) {
  1713. return pattern.replace(/<<(\d+)>>/g, function (m, index) {
  1714. return '(?:' + replacements[+index] + ')';
  1715. });
  1716. }
  1717. /**
  1718. * @param {string} pattern
  1719. * @param {string[]} replacements
  1720. * @param {string} [flags]
  1721. * @returns {RegExp}
  1722. */
  1723. function re(pattern, replacements, flags) {
  1724. return RegExp(replace(pattern, replacements), flags || '');
  1725. }
  1726. /**
  1727. * Creates a nested pattern where all occurrences of the string `<<self>>` are replaced with the pattern itself.
  1728. *
  1729. * @param {string} pattern
  1730. * @param {number} depthLog2
  1731. * @returns {string}
  1732. */
  1733. function nested(pattern, depthLog2) {
  1734. for (var i = 0; i < depthLog2; i++) {
  1735. pattern = pattern.replace(/<<self>>/g, function () { return '(?:' + pattern + ')'; });
  1736. }
  1737. return pattern.replace(/<<self>>/g, '[^\\s\\S]');
  1738. }
  1739. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
  1740. var keywordKinds = {
  1741. // keywords which represent a return or variable type
  1742. type: 'bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void',
  1743. // keywords which are used to declare a type
  1744. typeDeclaration: 'class enum interface record struct',
  1745. // contextual keywords
  1746. // ("var" and "dynamic" are missing because they are used like types)
  1747. contextual: 'add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)',
  1748. // all other keywords
  1749. other: 'abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield'
  1750. };
  1751. // keywords
  1752. function keywordsToPattern(words) {
  1753. return '\\b(?:' + words.trim().replace(/ /g, '|') + ')\\b';
  1754. }
  1755. var typeDeclarationKeywords = keywordsToPattern(keywordKinds.typeDeclaration);
  1756. var keywords = RegExp(keywordsToPattern(keywordKinds.type + ' ' + keywordKinds.typeDeclaration + ' ' + keywordKinds.contextual + ' ' + keywordKinds.other));
  1757. var nonTypeKeywords = keywordsToPattern(keywordKinds.typeDeclaration + ' ' + keywordKinds.contextual + ' ' + keywordKinds.other);
  1758. var nonContextualKeywords = keywordsToPattern(keywordKinds.type + ' ' + keywordKinds.typeDeclaration + ' ' + keywordKinds.other);
  1759. // types
  1760. var generic = nested(/<(?:[^<>;=+\-*/%&|^]|<<self>>)*>/.source, 2); // the idea behind the other forbidden characters is to prevent false positives. Same for tupleElement.
  1761. var nestedRound = nested(/\((?:[^()]|<<self>>)*\)/.source, 2);
  1762. var name = /@?\b[A-Za-z_]\w*\b/.source;
  1763. var genericName = replace(/<<0>>(?:\s*<<1>>)?/.source, [name, generic]);
  1764. var identifier = replace(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source, [nonTypeKeywords, genericName]);
  1765. var array = /\[\s*(?:,\s*)*\]/.source;
  1766. var typeExpressionWithoutTuple = replace(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source, [identifier, array]);
  1767. var tupleElement = replace(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source, [generic, nestedRound, array]);
  1768. var tuple = replace(/\(<<0>>+(?:,<<0>>+)+\)/.source, [tupleElement]);
  1769. var typeExpression = replace(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source, [tuple, identifier, array]);
  1770. var typeInside = {
  1771. 'keyword': keywords,
  1772. 'punctuation': /[<>()?,.:[\]]/
  1773. };
  1774. // strings & characters
  1775. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#character-literals
  1776. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#string-literals
  1777. var character = /'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source; // simplified pattern
  1778. var regularString = /"(?:\\.|[^\\"\r\n])*"/.source;
  1779. var verbatimString = /@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;
  1780. Prism.languages.csharp = Prism.languages.extend('clike', {
  1781. 'string': [
  1782. {
  1783. pattern: re(/(^|[^$\\])<<0>>/.source, [verbatimString]),
  1784. lookbehind: true,
  1785. greedy: true
  1786. },
  1787. {
  1788. pattern: re(/(^|[^@$\\])<<0>>/.source, [regularString]),
  1789. lookbehind: true,
  1790. greedy: true
  1791. }
  1792. ],
  1793. 'class-name': [
  1794. {
  1795. // Using static
  1796. // using static System.Math;
  1797. pattern: re(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source, [identifier]),
  1798. lookbehind: true,
  1799. inside: typeInside
  1800. },
  1801. {
  1802. // Using alias (type)
  1803. // using Project = PC.MyCompany.Project;
  1804. pattern: re(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source, [name, typeExpression]),
  1805. lookbehind: true,
  1806. inside: typeInside
  1807. },
  1808. {
  1809. // Using alias (alias)
  1810. // using Project = PC.MyCompany.Project;
  1811. pattern: re(/(\busing\s+)<<0>>(?=\s*=)/.source, [name]),
  1812. lookbehind: true
  1813. },
  1814. {
  1815. // Type declarations
  1816. // class Foo<A, B>
  1817. // interface Foo<out A, B>
  1818. pattern: re(/(\b<<0>>\s+)<<1>>/.source, [typeDeclarationKeywords, genericName]),
  1819. lookbehind: true,
  1820. inside: typeInside
  1821. },
  1822. {
  1823. // Single catch exception declaration
  1824. // catch(Foo)
  1825. // (things like catch(Foo e) is covered by variable declaration)
  1826. pattern: re(/(\bcatch\s*\(\s*)<<0>>/.source, [identifier]),
  1827. lookbehind: true,
  1828. inside: typeInside
  1829. },
  1830. {
  1831. // Name of the type parameter of generic constraints
  1832. // where Foo : class
  1833. pattern: re(/(\bwhere\s+)<<0>>/.source, [name]),
  1834. lookbehind: true
  1835. },
  1836. {
  1837. // Casts and checks via as and is.
  1838. // as Foo<A>, is Bar<B>
  1839. // (things like if(a is Foo b) is covered by variable declaration)
  1840. pattern: re(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source, [typeExpressionWithoutTuple]),
  1841. lookbehind: true,
  1842. inside: typeInside
  1843. },
  1844. {
  1845. // Variable, field and parameter declaration
  1846. // (Foo bar, Bar baz, Foo[,,] bay, Foo<Bar, FooBar<Bar>> bax)
  1847. pattern: re(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source, [typeExpression, nonContextualKeywords, name]),
  1848. inside: typeInside
  1849. }
  1850. ],
  1851. 'keyword': keywords,
  1852. // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#literals
  1853. 'number': /(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,
  1854. 'operator': />>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,
  1855. 'punctuation': /\?\.?|::|[{}[\];(),.:]/
  1856. });
  1857. Prism.languages.insertBefore('csharp', 'number', {
  1858. 'range': {
  1859. pattern: /\.\./,
  1860. alias: 'operator'
  1861. }
  1862. });
  1863. Prism.languages.insertBefore('csharp', 'punctuation', {
  1864. 'named-parameter': {
  1865. pattern: re(/([(,]\s*)<<0>>(?=\s*:)/.source, [name]),
  1866. lookbehind: true,
  1867. alias: 'punctuation'
  1868. }
  1869. });
  1870. Prism.languages.insertBefore('csharp', 'class-name', {
  1871. 'namespace': {
  1872. // namespace Foo.Bar {}
  1873. // using Foo.Bar;
  1874. pattern: re(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source, [name]),
  1875. lookbehind: true,
  1876. inside: {
  1877. 'punctuation': /\./
  1878. }
  1879. },
  1880. 'type-expression': {
  1881. // default(Foo), typeof(Foo<Bar>), sizeof(int)
  1882. pattern: re(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source, [nestedRound]),
  1883. lookbehind: true,
  1884. alias: 'class-name',
  1885. inside: typeInside
  1886. },
  1887. 'return-type': {
  1888. // Foo<Bar> ForBar(); Foo IFoo.Bar() => 0
  1889. // int this[int index] => 0; T IReadOnlyList<T>.this[int index] => this[index];
  1890. // int Foo => 0; int Foo { get; set } = 0;
  1891. pattern: re(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source, [typeExpression, identifier]),
  1892. inside: typeInside,
  1893. alias: 'class-name'
  1894. },
  1895. 'constructor-invocation': {
  1896. // new List<Foo<Bar[]>> { }
  1897. pattern: re(/(\bnew\s+)<<0>>(?=\s*[[({])/.source, [typeExpression]),
  1898. lookbehind: true,
  1899. inside: typeInside,
  1900. alias: 'class-name'
  1901. },
  1902. /*'explicit-implementation': {
  1903. // int IFoo<Foo>.Bar => 0; void IFoo<Foo<Foo>>.Foo<T>();
  1904. pattern: replace(/\b<<0>>(?=\.<<1>>)/, className, methodOrPropertyDeclaration),
  1905. inside: classNameInside,
  1906. alias: 'class-name'
  1907. },*/
  1908. 'generic-method': {
  1909. // foo<Bar>()
  1910. pattern: re(/<<0>>\s*<<1>>(?=\s*\()/.source, [name, generic]),
  1911. inside: {
  1912. 'function': re(/^<<0>>/.source, [name]),
  1913. 'generic': {
  1914. pattern: RegExp(generic),
  1915. alias: 'class-name',
  1916. inside: typeInside
  1917. }
  1918. }
  1919. },
  1920. 'type-list': {
  1921. // The list of types inherited or of generic constraints
  1922. // class Foo<F> : Bar, IList<FooBar>
  1923. // where F : Bar, IList<int>
  1924. pattern: re(
  1925. /\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,
  1926. [typeDeclarationKeywords, genericName, name, typeExpression, keywords.source, nestedRound, /\bnew\s*\(\s*\)/.source]
  1927. ),
  1928. lookbehind: true,
  1929. inside: {
  1930. 'record-arguments': {
  1931. pattern: re(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source, [genericName, nestedRound]),
  1932. lookbehind: true,
  1933. greedy: true,
  1934. inside: Prism.languages.csharp
  1935. },
  1936. 'keyword': keywords,
  1937. 'class-name': {
  1938. pattern: RegExp(typeExpression),
  1939. greedy: true,
  1940. inside: typeInside
  1941. },
  1942. 'punctuation': /[,()]/
  1943. }
  1944. },
  1945. 'preprocessor': {
  1946. pattern: /(^[\t ]*)#.*/m,
  1947. lookbehind: true,
  1948. alias: 'property',
  1949. inside: {
  1950. // highlight preprocessor directives as keywords
  1951. 'directive': {
  1952. pattern: /(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,
  1953. lookbehind: true,
  1954. alias: 'keyword'
  1955. }
  1956. }
  1957. }
  1958. });
  1959. // attributes
  1960. var regularStringOrCharacter = regularString + '|' + character;
  1961. var regularStringCharacterOrComment = replace(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source, [regularStringOrCharacter]);
  1962. var roundExpression = nested(replace(/[^"'/()]|<<0>>|\(<<self>>*\)/.source, [regularStringCharacterOrComment]), 2);
  1963. // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/#attribute-targets
  1964. var attrTarget = /\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source;
  1965. var attr = replace(/<<0>>(?:\s*\(<<1>>*\))?/.source, [identifier, roundExpression]);
  1966. Prism.languages.insertBefore('csharp', 'class-name', {
  1967. 'attribute': {
  1968. // Attributes
  1969. // [Foo], [Foo(1), Bar(2, Prop = "foo")], [return: Foo(1), Bar(2)], [assembly: Foo(Bar)]
  1970. pattern: re(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source, [attrTarget, attr]),
  1971. lookbehind: true,
  1972. greedy: true,
  1973. inside: {
  1974. 'target': {
  1975. pattern: re(/^<<0>>(?=\s*:)/.source, [attrTarget]),
  1976. alias: 'keyword'
  1977. },
  1978. 'attribute-arguments': {
  1979. pattern: re(/\(<<0>>*\)/.source, [roundExpression]),
  1980. inside: Prism.languages.csharp
  1981. },
  1982. 'class-name': {
  1983. pattern: RegExp(identifier),
  1984. inside: {
  1985. 'punctuation': /\./
  1986. }
  1987. },
  1988. 'punctuation': /[:,]/
  1989. }
  1990. }
  1991. });
  1992. // string interpolation
  1993. var formatString = /:[^}\r\n]+/.source;
  1994. // multi line
  1995. var mInterpolationRound = nested(replace(/[^"'/()]|<<0>>|\(<<self>>*\)/.source, [regularStringCharacterOrComment]), 2);
  1996. var mInterpolation = replace(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [mInterpolationRound, formatString]);
  1997. // single line
  1998. var sInterpolationRound = nested(replace(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<<self>>*\)/.source, [regularStringOrCharacter]), 2);
  1999. var sInterpolation = replace(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [sInterpolationRound, formatString]);
  2000. function createInterpolationInside(interpolation, interpolationRound) {
  2001. return {
  2002. 'interpolation': {
  2003. pattern: re(/((?:^|[^{])(?:\{\{)*)<<0>>/.source, [interpolation]),
  2004. lookbehind: true,
  2005. inside: {
  2006. 'format-string': {
  2007. pattern: re(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source, [interpolationRound, formatString]),
  2008. lookbehind: true,
  2009. inside: {
  2010. 'punctuation': /^:/
  2011. }
  2012. },
  2013. 'punctuation': /^\{|\}$/,
  2014. 'expression': {
  2015. pattern: /[\s\S]+/,
  2016. alias: 'language-csharp',
  2017. inside: Prism.languages.csharp
  2018. }
  2019. }
  2020. },
  2021. 'string': /[\s\S]+/
  2022. };
  2023. }
  2024. Prism.languages.insertBefore('csharp', 'string', {
  2025. 'interpolation-string': [
  2026. {
  2027. pattern: re(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source, [mInterpolation]),
  2028. lookbehind: true,
  2029. greedy: true,
  2030. inside: createInterpolationInside(mInterpolation, mInterpolationRound),
  2031. },
  2032. {
  2033. pattern: re(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source, [sInterpolation]),
  2034. lookbehind: true,
  2035. greedy: true,
  2036. inside: createInterpolationInside(sInterpolation, sInterpolationRound),
  2037. }
  2038. ],
  2039. 'char': {
  2040. pattern: RegExp(character),
  2041. greedy: true
  2042. }
  2043. });
  2044. Prism.languages.dotnet = Prism.languages.cs = Prism.languages.csharp;
  2045. }(Prism));
  2046. (function (Prism) {
  2047. var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
  2048. Prism.languages.css = {
  2049. 'comment': /\/\*[\s\S]*?\*\//,
  2050. 'atrule': {
  2051. pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
  2052. inside: {
  2053. 'rule': /^@[\w-]+/,
  2054. 'selector-function-argument': {
  2055. pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
  2056. lookbehind: true,
  2057. alias: 'selector'
  2058. },
  2059. 'keyword': {
  2060. pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
  2061. lookbehind: true
  2062. }
  2063. // See rest below
  2064. }
  2065. },
  2066. 'url': {
  2067. // https://drafts.csswg.org/css-values-3/#urls
  2068. pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
  2069. greedy: true,
  2070. inside: {
  2071. 'function': /^url/i,
  2072. 'punctuation': /^\(|\)$/,
  2073. 'string': {
  2074. pattern: RegExp('^' + string.source + '$'),
  2075. alias: 'url'
  2076. }
  2077. }
  2078. },
  2079. 'selector': {
  2080. pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
  2081. lookbehind: true
  2082. },
  2083. 'string': {
  2084. pattern: string,
  2085. greedy: true
  2086. },
  2087. 'property': {
  2088. pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
  2089. lookbehind: true
  2090. },
  2091. 'important': /!important\b/i,
  2092. 'function': {
  2093. pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
  2094. lookbehind: true
  2095. },
  2096. 'punctuation': /[(){};:,]/
  2097. };
  2098. Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
  2099. var markup = Prism.languages.markup;
  2100. if (markup) {
  2101. markup.tag.addInlined('style', 'css');
  2102. markup.tag.addAttribute('style', 'css');
  2103. }
  2104. }(Prism));
  2105. (function (Prism) {
  2106. var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/;
  2107. // full package (optional) + parent classes (optional)
  2108. var classNamePrefix = /(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source;
  2109. // based on the java naming conventions
  2110. var className = {
  2111. pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),
  2112. lookbehind: true,
  2113. inside: {
  2114. 'namespace': {
  2115. pattern: /^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,
  2116. inside: {
  2117. 'punctuation': /\./
  2118. }
  2119. },
  2120. 'punctuation': /\./
  2121. }
  2122. };
  2123. Prism.languages.java = Prism.languages.extend('clike', {
  2124. 'string': {
  2125. pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,
  2126. lookbehind: true,
  2127. greedy: true
  2128. },
  2129. 'class-name': [
  2130. className,
  2131. {
  2132. // variables, parameters, and constructor references
  2133. // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
  2134. pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),
  2135. lookbehind: true,
  2136. inside: className.inside
  2137. },
  2138. {
  2139. // class names based on keyword
  2140. // this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
  2141. pattern: RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source + classNamePrefix + /[A-Z]\w*\b/.source),
  2142. lookbehind: true,
  2143. inside: className.inside
  2144. }
  2145. ],
  2146. 'keyword': keywords,
  2147. 'function': [
  2148. Prism.languages.clike.function,
  2149. {
  2150. pattern: /(::\s*)[a-z_]\w*/,
  2151. lookbehind: true
  2152. }
  2153. ],
  2154. 'number': /\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,
  2155. 'operator': {
  2156. pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
  2157. lookbehind: true
  2158. },
  2159. 'constant': /\b[A-Z][A-Z_\d]+\b/
  2160. });
  2161. Prism.languages.insertBefore('java', 'string', {
  2162. 'triple-quoted-string': {
  2163. // http://openjdk.java.net/jeps/355#Description
  2164. pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
  2165. greedy: true,
  2166. alias: 'string'
  2167. },
  2168. 'char': {
  2169. pattern: /'(?:\\.|[^'\\\r\n]){1,6}'/,
  2170. greedy: true
  2171. }
  2172. });
  2173. Prism.languages.insertBefore('java', 'class-name', {
  2174. 'annotation': {
  2175. pattern: /(^|[^.])@\w+(?:\s*\.\s*\w+)*/,
  2176. lookbehind: true,
  2177. alias: 'punctuation'
  2178. },
  2179. 'generics': {
  2180. pattern: /<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,
  2181. inside: {
  2182. 'class-name': className,
  2183. 'keyword': keywords,
  2184. 'punctuation': /[<>(),.:]/,
  2185. 'operator': /[?&|]/
  2186. }
  2187. },
  2188. 'import': [
  2189. {
  2190. pattern: RegExp(/(\bimport\s+)/.source + classNamePrefix + /(?:[A-Z]\w*|\*)(?=\s*;)/.source),
  2191. lookbehind: true,
  2192. inside: {
  2193. 'namespace': className.inside.namespace,
  2194. 'punctuation': /\./,
  2195. 'operator': /\*/,
  2196. 'class-name': /\w+/
  2197. }
  2198. },
  2199. {
  2200. pattern: RegExp(/(\bimport\s+static\s+)/.source + classNamePrefix + /(?:\w+|\*)(?=\s*;)/.source),
  2201. lookbehind: true,
  2202. alias: 'static',
  2203. inside: {
  2204. 'namespace': className.inside.namespace,
  2205. 'static': /\b\w+$/,
  2206. 'punctuation': /\./,
  2207. 'operator': /\*/,
  2208. 'class-name': /\w+/
  2209. }
  2210. }
  2211. ],
  2212. 'namespace': {
  2213. pattern: RegExp(
  2214. /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/
  2215. .source.replace(/<keyword>/g, function () { return keywords.source; })),
  2216. lookbehind: true,
  2217. inside: {
  2218. 'punctuation': /\./,
  2219. }
  2220. }
  2221. });
  2222. }(Prism));
  2223. Prism.languages.javascript = Prism.languages.extend('clike', {
  2224. 'class-name': [
  2225. Prism.languages.clike['class-name'],
  2226. {
  2227. pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
  2228. lookbehind: true
  2229. }
  2230. ],
  2231. 'keyword': [
  2232. {
  2233. pattern: /((?:^|\})\s*)catch\b/,
  2234. lookbehind: true
  2235. },
  2236. {
  2237. pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
  2238. lookbehind: true
  2239. },
  2240. ],
  2241. // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
  2242. 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
  2243. 'number': {
  2244. pattern: RegExp(
  2245. /(^|[^\w$])/.source +
  2246. '(?:' +
  2247. (
  2248. // constant
  2249. /NaN|Infinity/.source +
  2250. '|' +
  2251. // binary integer
  2252. /0[bB][01]+(?:_[01]+)*n?/.source +
  2253. '|' +
  2254. // octal integer
  2255. /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
  2256. '|' +
  2257. // hexadecimal integer
  2258. /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
  2259. '|' +
  2260. // decimal bigint
  2261. /\d+(?:_\d+)*n/.source +
  2262. '|' +
  2263. // decimal number (integer or float) but no bigint
  2264. /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
  2265. ) +
  2266. ')' +
  2267. /(?![\w$])/.source
  2268. ),
  2269. lookbehind: true
  2270. },
  2271. 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
  2272. });
  2273. Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
  2274. Prism.languages.insertBefore('javascript', 'keyword', {
  2275. 'regex': {
  2276. pattern: RegExp(
  2277. // lookbehind
  2278. // eslint-disable-next-line regexp/no-dupe-characters-character-class
  2279. /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
  2280. // Regex pattern:
  2281. // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
  2282. // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
  2283. // with the only syntax, so we have to define 2 different regex patterns.
  2284. /\//.source +
  2285. '(?:' +
  2286. /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
  2287. '|' +
  2288. // `v` flag syntax. This supports 3 levels of nested character classes.
  2289. /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
  2290. ')' +
  2291. // lookahead
  2292. /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
  2293. ),
  2294. lookbehind: true,
  2295. greedy: true,
  2296. inside: {
  2297. 'regex-source': {
  2298. pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
  2299. lookbehind: true,
  2300. alias: 'language-regex',
  2301. inside: Prism.languages.regex
  2302. },
  2303. 'regex-delimiter': /^\/|\/$/,
  2304. 'regex-flags': /^[a-z]+$/,
  2305. }
  2306. },
  2307. // This must be declared before keyword because we use "function" inside the look-forward
  2308. 'function-variable': {
  2309. pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
  2310. alias: 'function'
  2311. },
  2312. 'parameter': [
  2313. {
  2314. pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
  2315. lookbehind: true,
  2316. inside: Prism.languages.javascript
  2317. },
  2318. {
  2319. pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
  2320. lookbehind: true,
  2321. inside: Prism.languages.javascript
  2322. },
  2323. {
  2324. pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
  2325. lookbehind: true,
  2326. inside: Prism.languages.javascript
  2327. },
  2328. {
  2329. pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
  2330. lookbehind: true,
  2331. inside: Prism.languages.javascript
  2332. }
  2333. ],
  2334. 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
  2335. });
  2336. Prism.languages.insertBefore('javascript', 'string', {
  2337. 'hashbang': {
  2338. pattern: /^#!.*/,
  2339. greedy: true,
  2340. alias: 'comment'
  2341. },
  2342. 'template-string': {
  2343. pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
  2344. greedy: true,
  2345. inside: {
  2346. 'template-punctuation': {
  2347. pattern: /^`|`$/,
  2348. alias: 'string'
  2349. },
  2350. 'interpolation': {
  2351. pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
  2352. lookbehind: true,
  2353. inside: {
  2354. 'interpolation-punctuation': {
  2355. pattern: /^\$\{|\}$/,
  2356. alias: 'punctuation'
  2357. },
  2358. rest: Prism.languages.javascript
  2359. }
  2360. },
  2361. 'string': /[\s\S]+/
  2362. }
  2363. },
  2364. 'string-property': {
  2365. pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
  2366. lookbehind: true,
  2367. greedy: true,
  2368. alias: 'property'
  2369. }
  2370. });
  2371. Prism.languages.insertBefore('javascript', 'operator', {
  2372. 'literal-property': {
  2373. pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
  2374. lookbehind: true,
  2375. alias: 'property'
  2376. },
  2377. });
  2378. if (Prism.languages.markup) {
  2379. Prism.languages.markup.tag.addInlined('script', 'javascript');
  2380. // add attribute support for all DOM events.
  2381. // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
  2382. Prism.languages.markup.tag.addAttribute(
  2383. /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
  2384. 'javascript'
  2385. );
  2386. }
  2387. Prism.languages.js = Prism.languages.javascript;
  2388. Prism.languages.markup = {
  2389. 'comment': {
  2390. pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
  2391. greedy: true
  2392. },
  2393. 'prolog': {
  2394. pattern: /<\?[\s\S]+?\?>/,
  2395. greedy: true
  2396. },
  2397. 'doctype': {
  2398. // https://www.w3.org/TR/xml/#NT-doctypedecl
  2399. pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
  2400. greedy: true,
  2401. inside: {
  2402. 'internal-subset': {
  2403. pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
  2404. lookbehind: true,
  2405. greedy: true,
  2406. inside: null // see below
  2407. },
  2408. 'string': {
  2409. pattern: /"[^"]*"|'[^']*'/,
  2410. greedy: true
  2411. },
  2412. 'punctuation': /^<!|>$|[[\]]/,
  2413. 'doctype-tag': /^DOCTYPE/i,
  2414. 'name': /[^\s<>'"]+/
  2415. }
  2416. },
  2417. 'cdata': {
  2418. pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
  2419. greedy: true
  2420. },
  2421. 'tag': {
  2422. pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
  2423. greedy: true,
  2424. inside: {
  2425. 'tag': {
  2426. pattern: /^<\/?[^\s>\/]+/,
  2427. inside: {
  2428. 'punctuation': /^<\/?/,
  2429. 'namespace': /^[^\s>\/:]+:/
  2430. }
  2431. },
  2432. 'special-attr': [],
  2433. 'attr-value': {
  2434. pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
  2435. inside: {
  2436. 'punctuation': [
  2437. {
  2438. pattern: /^=/,
  2439. alias: 'attr-equals'
  2440. },
  2441. {
  2442. pattern: /^(\s*)["']|["']$/,
  2443. lookbehind: true
  2444. }
  2445. ]
  2446. }
  2447. },
  2448. 'punctuation': /\/?>/,
  2449. 'attr-name': {
  2450. pattern: /[^\s>\/]+/,
  2451. inside: {
  2452. 'namespace': /^[^\s>\/:]+:/
  2453. }
  2454. }
  2455. }
  2456. },
  2457. 'entity': [
  2458. {
  2459. pattern: /&[\da-z]{1,8};/i,
  2460. alias: 'named-entity'
  2461. },
  2462. /&#x?[\da-f]{1,8};/i
  2463. ]
  2464. };
  2465. Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
  2466. Prism.languages.markup['entity'];
  2467. Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
  2468. // Plugin to make entity title show the real entity, idea by Roman Komarov
  2469. Prism.hooks.add('wrap', function (env) {
  2470. if (env.type === 'entity') {
  2471. env.attributes['title'] = env.content.replace(/&amp;/, '&');
  2472. }
  2473. });
  2474. Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
  2475. /**
  2476. * Adds an inlined language to markup.
  2477. *
  2478. * An example of an inlined language is CSS with `<style>` tags.
  2479. *
  2480. * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
  2481. * case insensitive.
  2482. * @param {string} lang The language key.
  2483. * @example
  2484. * addInlined('style', 'css');
  2485. */
  2486. value: function addInlined(tagName, lang) {
  2487. var includedCdataInside = {};
  2488. includedCdataInside['language-' + lang] = {
  2489. pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
  2490. lookbehind: true,
  2491. inside: Prism.languages[lang]
  2492. };
  2493. includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
  2494. var inside = {
  2495. 'included-cdata': {
  2496. pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
  2497. inside: includedCdataInside
  2498. }
  2499. };
  2500. inside['language-' + lang] = {
  2501. pattern: /[\s\S]+/,
  2502. inside: Prism.languages[lang]
  2503. };
  2504. var def = {};
  2505. def[tagName] = {
  2506. pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
  2507. lookbehind: true,
  2508. greedy: true,
  2509. inside: inside
  2510. };
  2511. Prism.languages.insertBefore('markup', 'cdata', def);
  2512. }
  2513. });
  2514. Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
  2515. /**
  2516. * Adds an pattern to highlight languages embedded in HTML attributes.
  2517. *
  2518. * An example of an inlined language is CSS with `style` attributes.
  2519. *
  2520. * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
  2521. * case insensitive.
  2522. * @param {string} lang The language key.
  2523. * @example
  2524. * addAttribute('style', 'css');
  2525. */
  2526. value: function (attrName, lang) {
  2527. Prism.languages.markup.tag.inside['special-attr'].push({
  2528. pattern: RegExp(
  2529. /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
  2530. 'i'
  2531. ),
  2532. lookbehind: true,
  2533. inside: {
  2534. 'attr-name': /^[^\s=]+/,
  2535. 'attr-value': {
  2536. pattern: /=[\s\S]+/,
  2537. inside: {
  2538. 'value': {
  2539. pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
  2540. lookbehind: true,
  2541. alias: [lang, 'language-' + lang],
  2542. inside: Prism.languages[lang]
  2543. },
  2544. 'punctuation': [
  2545. {
  2546. pattern: /^=/,
  2547. alias: 'attr-equals'
  2548. },
  2549. /"|'/
  2550. ]
  2551. }
  2552. }
  2553. }
  2554. });
  2555. }
  2556. });
  2557. Prism.languages.html = Prism.languages.markup;
  2558. Prism.languages.mathml = Prism.languages.markup;
  2559. Prism.languages.svg = Prism.languages.markup;
  2560. Prism.languages.xml = Prism.languages.extend('markup', {});
  2561. Prism.languages.ssml = Prism.languages.xml;
  2562. Prism.languages.atom = Prism.languages.xml;
  2563. Prism.languages.rss = Prism.languages.xml;
  2564. /**
  2565. * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/
  2566. * Modified by Miles Johnson: http://milesj.me
  2567. * Rewritten by Tom Pavelec
  2568. *
  2569. * Supports PHP 5.3 - 8.0
  2570. */
  2571. (function (Prism) {
  2572. var comment = /\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/;
  2573. var constant = [
  2574. {
  2575. pattern: /\b(?:false|true)\b/i,
  2576. alias: 'boolean'
  2577. },
  2578. {
  2579. pattern: /(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,
  2580. greedy: true,
  2581. lookbehind: true,
  2582. },
  2583. {
  2584. pattern: /(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,
  2585. greedy: true,
  2586. lookbehind: true,
  2587. },
  2588. /\b(?:null)\b/i,
  2589. /\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/,
  2590. ];
  2591. var number = /\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i;
  2592. var operator = /<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/;
  2593. var punctuation = /[{}\[\](),:;]/;
  2594. Prism.languages.php = {
  2595. 'delimiter': {
  2596. pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
  2597. alias: 'important'
  2598. },
  2599. 'comment': comment,
  2600. 'variable': /\$+(?:\w+\b|(?=\{))/,
  2601. 'package': {
  2602. pattern: /(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
  2603. lookbehind: true,
  2604. inside: {
  2605. 'punctuation': /\\/
  2606. }
  2607. },
  2608. 'class-name-definition': {
  2609. pattern: /(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,
  2610. lookbehind: true,
  2611. alias: 'class-name'
  2612. },
  2613. 'function-definition': {
  2614. pattern: /(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,
  2615. lookbehind: true,
  2616. alias: 'function'
  2617. },
  2618. 'keyword': [
  2619. {
  2620. pattern: /(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,
  2621. alias: 'type-casting',
  2622. greedy: true,
  2623. lookbehind: true
  2624. },
  2625. {
  2626. pattern: /([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,
  2627. alias: 'type-hint',
  2628. greedy: true,
  2629. lookbehind: true
  2630. },
  2631. {
  2632. pattern: /(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,
  2633. alias: 'return-type',
  2634. greedy: true,
  2635. lookbehind: true
  2636. },
  2637. {
  2638. pattern: /\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,
  2639. alias: 'type-declaration',
  2640. greedy: true
  2641. },
  2642. {
  2643. pattern: /(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,
  2644. alias: 'type-declaration',
  2645. greedy: true,
  2646. lookbehind: true
  2647. },
  2648. {
  2649. pattern: /\b(?:parent|self|static)(?=\s*::)/i,
  2650. alias: 'static-context',
  2651. greedy: true
  2652. },
  2653. {
  2654. // yield from
  2655. pattern: /(\byield\s+)from\b/i,
  2656. lookbehind: true
  2657. },
  2658. // `class` is always a keyword unlike other keywords
  2659. /\bclass\b/i,
  2660. {
  2661. // https://www.php.net/manual/en/reserved.keywords.php
  2662. //
  2663. // keywords cannot be preceded by "->"
  2664. // the complex lookbehind means `(?<!(?:->|::)\s*)`
  2665. pattern: /((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,
  2666. lookbehind: true
  2667. }
  2668. ],
  2669. 'argument-name': {
  2670. pattern: /([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,
  2671. lookbehind: true
  2672. },
  2673. 'class-name': [
  2674. {
  2675. pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,
  2676. greedy: true,
  2677. lookbehind: true
  2678. },
  2679. {
  2680. pattern: /(\|\s*)\b[a-z_]\w*(?!\\)\b/i,
  2681. greedy: true,
  2682. lookbehind: true
  2683. },
  2684. {
  2685. pattern: /\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,
  2686. greedy: true
  2687. },
  2688. {
  2689. pattern: /(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,
  2690. alias: 'class-name-fully-qualified',
  2691. greedy: true,
  2692. lookbehind: true,
  2693. inside: {
  2694. 'punctuation': /\\/
  2695. }
  2696. },
  2697. {
  2698. pattern: /(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,
  2699. alias: 'class-name-fully-qualified',
  2700. greedy: true,
  2701. inside: {
  2702. 'punctuation': /\\/
  2703. }
  2704. },
  2705. {
  2706. pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
  2707. alias: 'class-name-fully-qualified',
  2708. greedy: true,
  2709. lookbehind: true,
  2710. inside: {
  2711. 'punctuation': /\\/
  2712. }
  2713. },
  2714. {
  2715. pattern: /\b[a-z_]\w*(?=\s*\$)/i,
  2716. alias: 'type-declaration',
  2717. greedy: true
  2718. },
  2719. {
  2720. pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,
  2721. alias: ['class-name-fully-qualified', 'type-declaration'],
  2722. greedy: true,
  2723. inside: {
  2724. 'punctuation': /\\/
  2725. }
  2726. },
  2727. {
  2728. pattern: /\b[a-z_]\w*(?=\s*::)/i,
  2729. alias: 'static-context',
  2730. greedy: true
  2731. },
  2732. {
  2733. pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,
  2734. alias: ['class-name-fully-qualified', 'static-context'],
  2735. greedy: true,
  2736. inside: {
  2737. 'punctuation': /\\/
  2738. }
  2739. },
  2740. {
  2741. pattern: /([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,
  2742. alias: 'type-hint',
  2743. greedy: true,
  2744. lookbehind: true
  2745. },
  2746. {
  2747. pattern: /([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,
  2748. alias: ['class-name-fully-qualified', 'type-hint'],
  2749. greedy: true,
  2750. lookbehind: true,
  2751. inside: {
  2752. 'punctuation': /\\/
  2753. }
  2754. },
  2755. {
  2756. pattern: /(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,
  2757. alias: 'return-type',
  2758. greedy: true,
  2759. lookbehind: true
  2760. },
  2761. {
  2762. pattern: /(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
  2763. alias: ['class-name-fully-qualified', 'return-type'],
  2764. greedy: true,
  2765. lookbehind: true,
  2766. inside: {
  2767. 'punctuation': /\\/
  2768. }
  2769. }
  2770. ],
  2771. 'constant': constant,
  2772. 'function': {
  2773. pattern: /(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,
  2774. lookbehind: true,
  2775. inside: {
  2776. 'punctuation': /\\/
  2777. }
  2778. },
  2779. 'property': {
  2780. pattern: /(->\s*)\w+/,
  2781. lookbehind: true
  2782. },
  2783. 'number': number,
  2784. 'operator': operator,
  2785. 'punctuation': punctuation
  2786. };
  2787. var string_interpolation = {
  2788. pattern: /\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,
  2789. lookbehind: true,
  2790. inside: Prism.languages.php
  2791. };
  2792. var string = [
  2793. {
  2794. pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,
  2795. alias: 'nowdoc-string',
  2796. greedy: true,
  2797. inside: {
  2798. 'delimiter': {
  2799. pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
  2800. alias: 'symbol',
  2801. inside: {
  2802. 'punctuation': /^<<<'?|[';]$/
  2803. }
  2804. }
  2805. }
  2806. },
  2807. {
  2808. pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,
  2809. alias: 'heredoc-string',
  2810. greedy: true,
  2811. inside: {
  2812. 'delimiter': {
  2813. pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
  2814. alias: 'symbol',
  2815. inside: {
  2816. 'punctuation': /^<<<"?|[";]$/
  2817. }
  2818. },
  2819. 'interpolation': string_interpolation
  2820. }
  2821. },
  2822. {
  2823. pattern: /`(?:\\[\s\S]|[^\\`])*`/,
  2824. alias: 'backtick-quoted-string',
  2825. greedy: true
  2826. },
  2827. {
  2828. pattern: /'(?:\\[\s\S]|[^\\'])*'/,
  2829. alias: 'single-quoted-string',
  2830. greedy: true
  2831. },
  2832. {
  2833. pattern: /"(?:\\[\s\S]|[^\\"])*"/,
  2834. alias: 'double-quoted-string',
  2835. greedy: true,
  2836. inside: {
  2837. 'interpolation': string_interpolation
  2838. }
  2839. }
  2840. ];
  2841. Prism.languages.insertBefore('php', 'variable', {
  2842. 'string': string,
  2843. 'attribute': {
  2844. pattern: /#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,
  2845. greedy: true,
  2846. inside: {
  2847. 'attribute-content': {
  2848. pattern: /^(#\[)[\s\S]+(?=\]$)/,
  2849. lookbehind: true,
  2850. // inside can appear subset of php
  2851. inside: {
  2852. 'comment': comment,
  2853. 'string': string,
  2854. 'attribute-class-name': [
  2855. {
  2856. pattern: /([^:]|^)\b[a-z_]\w*(?!\\)\b/i,
  2857. alias: 'class-name',
  2858. greedy: true,
  2859. lookbehind: true
  2860. },
  2861. {
  2862. pattern: /([^:]|^)(?:\\?\b[a-z_]\w*)+/i,
  2863. alias: [
  2864. 'class-name',
  2865. 'class-name-fully-qualified'
  2866. ],
  2867. greedy: true,
  2868. lookbehind: true,
  2869. inside: {
  2870. 'punctuation': /\\/
  2871. }
  2872. }
  2873. ],
  2874. 'constant': constant,
  2875. 'number': number,
  2876. 'operator': operator,
  2877. 'punctuation': punctuation
  2878. }
  2879. },
  2880. 'delimiter': {
  2881. pattern: /^#\[|\]$/,
  2882. alias: 'punctuation'
  2883. }
  2884. }
  2885. },
  2886. });
  2887. Prism.hooks.add('before-tokenize', function (env) {
  2888. if (!/<\?/.test(env.code)) {
  2889. return;
  2890. }
  2891. var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;
  2892. Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
  2893. });
  2894. Prism.hooks.add('after-tokenize', function (env) {
  2895. Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
  2896. });
  2897. }(Prism));
  2898. Prism.languages.python = {
  2899. 'comment': {
  2900. pattern: /(^|[^\\])#.*/,
  2901. lookbehind: true,
  2902. greedy: true
  2903. },
  2904. 'string-interpolation': {
  2905. pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
  2906. greedy: true,
  2907. inside: {
  2908. 'interpolation': {
  2909. // "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
  2910. pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
  2911. lookbehind: true,
  2912. inside: {
  2913. 'format-spec': {
  2914. pattern: /(:)[^:(){}]+(?=\}$)/,
  2915. lookbehind: true
  2916. },
  2917. 'conversion-option': {
  2918. pattern: /![sra](?=[:}]$)/,
  2919. alias: 'punctuation'
  2920. },
  2921. rest: null
  2922. }
  2923. },
  2924. 'string': /[\s\S]+/
  2925. }
  2926. },
  2927. 'triple-quoted-string': {
  2928. pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
  2929. greedy: true,
  2930. alias: 'string'
  2931. },
  2932. 'string': {
  2933. pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
  2934. greedy: true
  2935. },
  2936. 'function': {
  2937. pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
  2938. lookbehind: true
  2939. },
  2940. 'class-name': {
  2941. pattern: /(\bclass\s+)\w+/i,
  2942. lookbehind: true
  2943. },
  2944. 'decorator': {
  2945. pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
  2946. lookbehind: true,
  2947. alias: ['annotation', 'punctuation'],
  2948. inside: {
  2949. 'punctuation': /\./
  2950. }
  2951. },
  2952. 'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
  2953. 'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
  2954. 'boolean': /\b(?:False|None|True)\b/,
  2955. 'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
  2956. 'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
  2957. 'punctuation': /[{}[\];(),.:]/
  2958. };
  2959. Prism.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism.languages.python;
  2960. Prism.languages.py = Prism.languages.python;
  2961. /**
  2962. * Original by Samuel Flores
  2963. *
  2964. * Adds the following new token classes:
  2965. * constant, builtin, variable, symbol, regex
  2966. */
  2967. (function (Prism) {
  2968. Prism.languages.ruby = Prism.languages.extend('clike', {
  2969. 'comment': {
  2970. pattern: /#.*|^=begin\s[\s\S]*?^=end/m,
  2971. greedy: true
  2972. },
  2973. 'class-name': {
  2974. pattern: /(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,
  2975. lookbehind: true,
  2976. inside: {
  2977. 'punctuation': /[.\\]/
  2978. }
  2979. },
  2980. 'keyword': /\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,
  2981. 'operator': /\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,
  2982. 'punctuation': /[(){}[\].,;]/,
  2983. });
  2984. Prism.languages.insertBefore('ruby', 'operator', {
  2985. 'double-colon': {
  2986. pattern: /::/,
  2987. alias: 'punctuation'
  2988. },
  2989. });
  2990. var interpolation = {
  2991. pattern: /((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,
  2992. lookbehind: true,
  2993. inside: {
  2994. 'content': {
  2995. pattern: /^(#\{)[\s\S]+(?=\}$)/,
  2996. lookbehind: true,
  2997. inside: Prism.languages.ruby
  2998. },
  2999. 'delimiter': {
  3000. pattern: /^#\{|\}$/,
  3001. alias: 'punctuation'
  3002. }
  3003. }
  3004. };
  3005. delete Prism.languages.ruby.function;
  3006. var percentExpression = '(?:' + [
  3007. /([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
  3008. /\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,
  3009. /\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,
  3010. /\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,
  3011. /<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source
  3012. ].join('|') + ')';
  3013. var symbolName = /(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;
  3014. Prism.languages.insertBefore('ruby', 'keyword', {
  3015. 'regex-literal': [
  3016. {
  3017. pattern: RegExp(/%r/.source + percentExpression + /[egimnosux]{0,6}/.source),
  3018. greedy: true,
  3019. inside: {
  3020. 'interpolation': interpolation,
  3021. 'regex': /[\s\S]+/
  3022. }
  3023. },
  3024. {
  3025. pattern: /(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,
  3026. lookbehind: true,
  3027. greedy: true,
  3028. inside: {
  3029. 'interpolation': interpolation,
  3030. 'regex': /[\s\S]+/
  3031. }
  3032. }
  3033. ],
  3034. 'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
  3035. 'symbol': [
  3036. {
  3037. pattern: RegExp(/(^|[^:]):/.source + symbolName),
  3038. lookbehind: true,
  3039. greedy: true
  3040. },
  3041. {
  3042. pattern: RegExp(/([\r\n{(,][ \t]*)/.source + symbolName + /(?=:(?!:))/.source),
  3043. lookbehind: true,
  3044. greedy: true
  3045. },
  3046. ],
  3047. 'method-definition': {
  3048. pattern: /(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,
  3049. lookbehind: true,
  3050. inside: {
  3051. 'function': /\b\w+$/,
  3052. 'keyword': /^self\b/,
  3053. 'class-name': /^\w+/,
  3054. 'punctuation': /\./
  3055. }
  3056. }
  3057. });
  3058. Prism.languages.insertBefore('ruby', 'string', {
  3059. 'string-literal': [
  3060. {
  3061. pattern: RegExp(/%[qQiIwWs]?/.source + percentExpression),
  3062. greedy: true,
  3063. inside: {
  3064. 'interpolation': interpolation,
  3065. 'string': /[\s\S]+/
  3066. }
  3067. },
  3068. {
  3069. pattern: /("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,
  3070. greedy: true,
  3071. inside: {
  3072. 'interpolation': interpolation,
  3073. 'string': /[\s\S]+/
  3074. }
  3075. },
  3076. {
  3077. pattern: /<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
  3078. alias: 'heredoc-string',
  3079. greedy: true,
  3080. inside: {
  3081. 'delimiter': {
  3082. pattern: /^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,
  3083. inside: {
  3084. 'symbol': /\b\w+/,
  3085. 'punctuation': /^<<[-~]?/
  3086. }
  3087. },
  3088. 'interpolation': interpolation,
  3089. 'string': /[\s\S]+/
  3090. }
  3091. },
  3092. {
  3093. pattern: /<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
  3094. alias: 'heredoc-string',
  3095. greedy: true,
  3096. inside: {
  3097. 'delimiter': {
  3098. pattern: /^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,
  3099. inside: {
  3100. 'symbol': /\b\w+/,
  3101. 'punctuation': /^<<[-~]?'|'$/,
  3102. }
  3103. },
  3104. 'string': /[\s\S]+/
  3105. }
  3106. }
  3107. ],
  3108. 'command-literal': [
  3109. {
  3110. pattern: RegExp(/%x/.source + percentExpression),
  3111. greedy: true,
  3112. inside: {
  3113. 'interpolation': interpolation,
  3114. 'command': {
  3115. pattern: /[\s\S]+/,
  3116. alias: 'string'
  3117. }
  3118. }
  3119. },
  3120. {
  3121. pattern: /`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,
  3122. greedy: true,
  3123. inside: {
  3124. 'interpolation': interpolation,
  3125. 'command': {
  3126. pattern: /[\s\S]+/,
  3127. alias: 'string'
  3128. }
  3129. }
  3130. }
  3131. ]
  3132. });
  3133. delete Prism.languages.ruby.string;
  3134. Prism.languages.insertBefore('ruby', 'number', {
  3135. 'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,
  3136. 'constant': /\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/
  3137. });
  3138. Prism.languages.rb = Prism.languages.ruby;
  3139. }(Prism));
  3140. // restore the original Prism reference
  3141. window.Prism = oldprism;
  3142. return Prism;
  3143. }(undefined, undefined);
  3144. const option = (name) => (editor) => editor.options.get(name);
  3145. const register$2 = (editor) => {
  3146. const registerOption = editor.options.register;
  3147. registerOption('codesample_languages', {
  3148. processor: 'object[]'
  3149. });
  3150. registerOption('codesample_global_prismjs', {
  3151. processor: 'boolean',
  3152. default: false
  3153. });
  3154. };
  3155. const getLanguages$1 = option('codesample_languages');
  3156. const useGlobalPrismJS = option('codesample_global_prismjs');
  3157. const get = (editor) => Global.Prism && useGlobalPrismJS(editor) ? Global.Prism : prismjs;
  3158. const isCodeSample = (elm) => {
  3159. return isNonNullable(elm) && elm.nodeName === 'PRE' && elm.className.indexOf('language-') !== -1;
  3160. };
  3161. const getSelectedCodeSample = (editor) => {
  3162. const node = editor.selection ? editor.selection.getNode() : null;
  3163. return isCodeSample(node) ? Optional.some(node) : Optional.none();
  3164. };
  3165. const insertCodeSample = (editor, language, code) => {
  3166. const dom = editor.dom;
  3167. editor.undoManager.transact(() => {
  3168. const node = getSelectedCodeSample(editor);
  3169. code = global$1.DOM.encode(code);
  3170. return node.fold(() => {
  3171. editor.insertContent('<pre id="__new" class="language-' + language + '">' + code + '</pre>');
  3172. const newPre = dom.select('#__new')[0];
  3173. dom.setAttrib(newPre, 'id', null);
  3174. editor.selection.select(newPre);
  3175. }, (n) => {
  3176. dom.setAttrib(n, 'class', 'language-' + language);
  3177. n.innerHTML = code;
  3178. get(editor).highlightElement(n);
  3179. editor.selection.select(n);
  3180. });
  3181. });
  3182. };
  3183. const getCurrentCode = (editor) => {
  3184. const node = getSelectedCodeSample(editor);
  3185. return node.bind((n) => Optional.from(n.textContent)).getOr('');
  3186. };
  3187. const getLanguages = (editor) => {
  3188. const defaultLanguages = [
  3189. { text: 'HTML/XML', value: 'markup' },
  3190. { text: 'JavaScript', value: 'javascript' },
  3191. { text: 'CSS', value: 'css' },
  3192. { text: 'PHP', value: 'php' },
  3193. { text: 'Ruby', value: 'ruby' },
  3194. { text: 'Python', value: 'python' },
  3195. { text: 'Java', value: 'java' },
  3196. { text: 'C', value: 'c' },
  3197. { text: 'C#', value: 'csharp' },
  3198. { text: 'C++', value: 'cpp' }
  3199. ];
  3200. const customLanguages = getLanguages$1(editor);
  3201. return customLanguages ? customLanguages : defaultLanguages;
  3202. };
  3203. const getCurrentLanguage = (editor, fallback) => {
  3204. const node = getSelectedCodeSample(editor);
  3205. return node.fold(() => fallback, (n) => {
  3206. const matches = n.className.match(/language-(\w+)/);
  3207. return matches ? matches[1] : fallback;
  3208. });
  3209. };
  3210. const open = (editor) => {
  3211. const languages = getLanguages(editor);
  3212. const defaultLanguage = head(languages).fold(constant(''), (l) => l.value);
  3213. const currentLanguage = getCurrentLanguage(editor, defaultLanguage);
  3214. const currentCode = getCurrentCode(editor);
  3215. editor.windowManager.open({
  3216. title: 'Insert/Edit Code Sample',
  3217. size: 'large',
  3218. body: {
  3219. type: 'panel',
  3220. items: [
  3221. {
  3222. type: 'listbox',
  3223. name: 'language',
  3224. label: 'Language',
  3225. items: languages
  3226. },
  3227. {
  3228. type: 'textarea',
  3229. name: 'code',
  3230. label: 'Code view',
  3231. spellcheck: false,
  3232. }
  3233. ]
  3234. },
  3235. buttons: [
  3236. {
  3237. type: 'cancel',
  3238. name: 'cancel',
  3239. text: 'Cancel'
  3240. },
  3241. {
  3242. type: 'submit',
  3243. name: 'save',
  3244. text: 'Save',
  3245. primary: true
  3246. }
  3247. ],
  3248. initialData: {
  3249. language: currentLanguage,
  3250. code: currentCode
  3251. },
  3252. onSubmit: (api) => {
  3253. const data = api.getData();
  3254. insertCodeSample(editor, data.language, data.code);
  3255. api.close();
  3256. }
  3257. });
  3258. };
  3259. const register$1 = (editor) => {
  3260. editor.addCommand('codesample', () => {
  3261. const node = editor.selection.getNode();
  3262. if (editor.selection.isCollapsed() || isCodeSample(node)) {
  3263. open(editor);
  3264. }
  3265. else {
  3266. editor.formatter.toggle('code');
  3267. }
  3268. });
  3269. };
  3270. var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
  3271. const setup = (editor) => {
  3272. editor.on('PreProcess', (e) => {
  3273. const dom = editor.dom;
  3274. const pres = dom.select('pre[contenteditable=false]', e.node);
  3275. global.each(global.grep(pres, isCodeSample), (elm) => {
  3276. const code = elm.textContent;
  3277. dom.setAttrib(elm, 'class', trim(dom.getAttrib(elm, 'class')));
  3278. dom.setAttrib(elm, 'contentEditable', null);
  3279. dom.setAttrib(elm, 'data-mce-highlighted', null);
  3280. // Empty the pre element
  3281. let child;
  3282. while ((child = elm.firstChild)) {
  3283. elm.removeChild(child);
  3284. }
  3285. const codeElm = dom.add(elm, 'code');
  3286. // Needs to be textContent since innerText produces BR:s
  3287. codeElm.textContent = code;
  3288. });
  3289. });
  3290. editor.on('SetContent', () => {
  3291. const dom = editor.dom;
  3292. const unprocessedCodeSamples = global.grep(dom.select('pre'), (elm) => {
  3293. return isCodeSample(elm) && dom.getAttrib(elm, 'data-mce-highlighted') !== 'true';
  3294. });
  3295. if (unprocessedCodeSamples.length) {
  3296. editor.undoManager.transact(() => {
  3297. global.each(unprocessedCodeSamples, (elm) => {
  3298. var _a;
  3299. global.each(dom.select('br', elm), (elm) => {
  3300. dom.replace(editor.getDoc().createTextNode('\n'), elm);
  3301. });
  3302. elm.innerHTML = dom.encode((_a = elm.textContent) !== null && _a !== void 0 ? _a : '');
  3303. get(editor).highlightElement(elm);
  3304. dom.setAttrib(elm, 'data-mce-highlighted', true);
  3305. elm.className = trim(elm.className);
  3306. });
  3307. });
  3308. }
  3309. });
  3310. editor.on('PreInit', () => {
  3311. editor.parser.addNodeFilter('pre', (nodes) => {
  3312. var _a;
  3313. for (let i = 0, l = nodes.length; i < l; i++) {
  3314. const node = nodes[i];
  3315. const isCodeSample = ((_a = node.attr('class')) !== null && _a !== void 0 ? _a : '').indexOf('language-') !== -1;
  3316. if (isCodeSample) {
  3317. node.attr('contenteditable', 'false');
  3318. node.attr('data-mce-highlighted', 'false');
  3319. }
  3320. }
  3321. });
  3322. });
  3323. };
  3324. const onSetupEditable = (editor, onChanged = noop) => (api) => {
  3325. const nodeChanged = () => {
  3326. api.setEnabled(editor.selection.isEditable());
  3327. onChanged(api);
  3328. };
  3329. editor.on('NodeChange', nodeChanged);
  3330. nodeChanged();
  3331. return () => {
  3332. editor.off('NodeChange', nodeChanged);
  3333. };
  3334. };
  3335. const isCodeSampleSelection = (editor) => {
  3336. const node = editor.selection.getStart();
  3337. return editor.dom.is(node, 'pre[class*="language-"]');
  3338. };
  3339. const register = (editor) => {
  3340. const onAction = () => editor.execCommand('codesample');
  3341. editor.ui.registry.addToggleButton('codesample', {
  3342. icon: 'code-sample',
  3343. tooltip: 'Insert/edit code sample',
  3344. onAction,
  3345. onSetup: onSetupEditable(editor, (api) => {
  3346. api.setActive(isCodeSampleSelection(editor));
  3347. })
  3348. });
  3349. editor.ui.registry.addMenuItem('codesample', {
  3350. text: 'Code sample...',
  3351. icon: 'code-sample',
  3352. onAction,
  3353. onSetup: onSetupEditable(editor)
  3354. });
  3355. };
  3356. var Plugin = () => {
  3357. global$2.add('codesample', (editor) => {
  3358. register$2(editor);
  3359. setup(editor);
  3360. register(editor);
  3361. register$1(editor);
  3362. editor.on('dblclick', (ev) => {
  3363. if (isCodeSample(ev.target)) {
  3364. open(editor);
  3365. }
  3366. });
  3367. });
  3368. };
  3369. Plugin();
  3370. /** *****
  3371. * DO NOT EXPORT ANYTHING
  3372. *
  3373. * IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
  3374. *******/
  3375. })();