ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç thirdpartylibs.xml000064400000000737152266604540010353 0ustar00 amd/src/prism.js PrismJS Prism is a lightweight, robust, and elegant syntax highlighting library. It's a spin-off project from Dabblet. 1.29.0 MIT https://github.com/PrismJS/prism 2012 Lea Verou styles.css000064400000004060152266604540006613 0ustar00/** * prism.js default theme for JavaScript, CSS and HTML * Based on dabblet (http://dabblet.com) * @author Lea Verou */ pre[class*="language-"] { color: black; background: none; text-shadow: 0 1px white; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 1em; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; word-wrap: normal; line-height: 1.5; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection { text-shadow: none; background: #b3d4fc; } pre[class*="language-"]::selection, pre[class*="language-"] ::selection { text-shadow: none; background: #b3d4fc; } @media print { pre[class*="language-"] { text-shadow: none; } } /* Code blocks */ pre[class*="language-"] { padding: 1em; margin: .5em 0; overflow: auto; } pre[class*="language-"] { background: #f5f2f0; } .token.comment, .token.prolog, .token.doctype, .token.cdata { color: slategray; } .token.punctuation { color: #999; } .token.namespace { opacity: .7; } .token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted { color: #905; } .token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted { color: #690; } .token.operator, .token.entity, .token.url, .language-css .token.string, .style .token.string { color: #9a6e3a; /* This background color was intended by the author of this theme. */ background: hsla(0, 0%, 100%, .5); } .token.atrule, .token.attr-value, .token.keyword { color: #07a; } .token.function, .token.class-name { color: #dd4a68; } .token.regex, .token.important, .token.variable { color: #e90; } .token.important, .token.bold { font-weight: bold; } .token.italic { font-style: italic; } .token.entity { cursor: help; } db/renamedclasses.php000064400000002027152266604540010646 0ustar00. /** * Renamed classes for the filter_codehighlighter plugin. * * @package filter_codehighlighter * @copyright Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die; $renamedclasses = [ 'filter_codehighlighter' => \filter_codehighlighter\text_filter::class, ]; lang/en/filter_codehighlighter.php000064400000002070152266604540013307 0ustar00. /** * Strings for filter_codehighlighter * * @package filter_codehighlighter * @copyright 2023 Meirza * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $string['filtername'] = 'Code highlighter'; $string['privacy:metadata'] = 'The code highlighter plugin does not store any personal data.'; version.php000064400000002223152266604540006753 0ustar00. /** * Version information * * @package filter_codehighlighter * @copyright 2023 Meirza * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->version = 2025041400; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2025040800; // Requires this Moodle version. $plugin->component = 'filter_codehighlighter'; // Full name of the plugin (used for diagnostics). filter.php000064400000002313152266604540006553 0ustar00. /** * File only retained to prevent fatal errors in code that tries to require/include this. * * @todo MDL-82708 delete this file as part of Moodle 6.0 development. * @deprecated This file is no longer required in Moodle 4.5+. * @package filter_codehighlighter * @copyright Meirza * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); debugging('This file is no longer required in Moodle 4.5+. Please do not include/require it.', DEBUG_DEVELOPER); readme_moodle.txt000064400000006072152266604540010120 0ustar00Description of Code Highlighter Filter in Moodle ==================================================== Code highlighter uses PrismJS. Why PrismJS? --------------------------------------------------- One of the editors in Moodle is TinyMCE, and the Code Sample plugin makes use of PrismJS. Hence, the code-highlighter filter likewise uses PrismJS to get the same behavior and look. As a result, when we need to upgrade the PrismJS version in this filter, We must take into account the PrismJS version that TinyMCE is currently using. Upgrading steps: --------------------------------------------------- Prerequisite: Make sure the grunt watcher is running during the below process: 1. In yourmoodle directory, run "npm install && grunt watch -f". It will generate minified js files automatically if there is a change in all JS files in the amd folder. 2. Download PrismJS See the lib/editor/tiny/thirdpartylibs.xml to get the current TinyMCE version (X.Y.Z). Download the ZIP file at https://github.com/tinymce/tinymce/tree/X.Y.Z and extract the ZIP file. For instance, if TinyMCE version is 6.3.2, the file to download should be https://github.com/tinymce/tinymce/tree/6.3.2. 3. In the extracted folder, run "yarn". 4. Update the PrismJS version in filter/codehighlighter/thirdpartylibs.xml according to the PrismJS version in the extracted folder in the file node_modules/prismjs/package.json. 5. Copy the node_modules/prismjs/themes/prism.css to yourmoodle/filter/codehighlighter/styles.css 6. Edit the styles.css to make sure the indentation is made using spaces, not tabs, and remove trailing spaces. 7. To avoid conflict with the theme code tag style. Remove all the lines that contain 'code[class*="language-"]' text in the styles.css, and also remove the comma character after the text if necessary to make sure that the CSS structure is correct. Please see the examples below: * code[class*="language-"], * :not(pre) > code[class*="language-"], * code[class*="language-"]::-moz-selection, * code[class*="language-"] ::-moz-selection * code[class*="language-"]::selection, * code[class*="language-"] ::selection * code[class*="language-"] 8. See if the grunt watch is reporting problems. If yes, follow the instructions to fix it. e.g: Before: ``` pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection { pre[class*="language-"]::selection, pre[class*="language-"] ::selection { ``` After: ``` pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection { pre[class*="language-"]::selection, pre[class*="language-"] ::selection { ``` And remove the warning from color-hex-case by renaming "#DD4A68" to lowercase "#dd4a68". 9. In the extracted folder, run "./bin/build-prism.js" 10. Copy the node_modules/prismjs/prism.js to yourmoodle/filter/codehighlighter/amd/src/prism.js 11. Edit the prism.js to make sure the indentation is made using spaces, not tabs, and remove trailing spaces. Note: As long as the grunt watcher says Done, then the upgrade process is complete. classes/privacy/provider.php000064400000002450152266604540012234 0ustar00. namespace filter_codehighlighter\privacy; /** * Privacy Subsystem for filter_codehighlighter implementing null_provider. * * @package filter_codehighlighter * @copyright 2023 Meirza * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class provider implements \core_privacy\local\metadata\null_provider { /** * Get the language string identifier with the component's language * file to explain why this plugin stores no data. * * @return string */ public static function get_reason(): string { return 'privacy:metadata'; } } classes/text_filter.php000064400000003026152266604540011256 0ustar00. namespace filter_codehighlighter; /** * Code highlighter filter. * * Filter converting text code into a well-styled block of code. * * @package filter_codehighlighter * @copyright 2023 Meirza * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class text_filter extends \core_filters\text_filter { #[\Override] public function filter($text, array $options = []): string { global $PAGE; if (!isset($options['originalformat'])) { return $text; } // The pattern. $re = '//i'; // Stops looking after the first match. preg_match($re, $text, $matches); if ($matches) { $PAGE->requires->js_call_amd('filter_codehighlighter/prism-init'); } return $text; } } amd/src/prism.js000064400000356255152266604540007616 0ustar00const prismjs = function(global, module, exports) { // preserve the global if it has already been loaded const oldprism = window.Prism; window.Prism = { manual: true }; /// var _self = (typeof window !== 'undefined') ? window // if in browser : ( (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) ? self // if in worker : {} // if in node js ); /** * Prism: Lightweight, robust, elegant syntax highlighting * * @license MIT * @author Lea Verou * @namespace * @public */ var Prism = (function (_self) { // Private helper vars var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i; var uniqueId = 0; // The grammar object for plaintext var plainTextGrammar = {}; var _ = { /** * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load * additional languages or plugins yourself. * * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. * * You obviously have to change this value before the automatic highlighting started. To do this, you can add an * empty Prism object into the global scope before loading the Prism script like this: * * ```js * window.Prism = window.Prism || {}; * Prism.manual = true; * // add a new