Advertisement
Guest User

Untitled

a guest
Jul 29th, 2019
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        forth-highlighter.js
  3. // @namespace   fforum.winglion.ru
  4. // @description highlights forth code
  5. // @include     http://fforum.winglion.ru/*
  6. // @require     https://code.jquery.com/jquery-3.4.1.slim.min.js
  7. // @version     1
  8. // @grant       none
  9. // ==/UserScript==
  10.  
  11. (function($) {
  12.     'use strict';
  13.     function highlight (text) {
  14.         if (!text) return "";
  15.         var all_source = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); // внимание!!! в исходнике заэскейплены спецсимволы HTML
  16.         var rest_all_source = all_source;
  17.         var source;
  18.         var rest_source = '';
  19.         var latest;
  20.         var state = false;
  21.         var dstack = [];
  22.         var output = [];
  23.         var currenttags;  // стиль, который наследует слово
  24.         var current = []; // сюда компилируется слово
  25.         function compile(word) {
  26.             if (word in words) {
  27.                 var t = words[word][words[word].length - 1].tags;
  28.                 if (t && !currenttags) currenttags = t;
  29.                 current.push('this["' + word.replace(/['"\\]/g, '\\$&') + '"][' + String(words[word].length - 1) + ']();');
  30.             }
  31.         }
  32.         function notfound (word) {
  33.             if (word.match(/^(0x)?[0-9a-f]+$/i)) return number;
  34.             return ['', ''];
  35.         }
  36.         var words = {
  37.             parse: [function() {
  38.                 var c = dstack[dstack.length - 1];
  39.                 c = c === ' ' ? '\\s' : c.replace(/[^\w\s]/g, '\\$&');
  40.                 var regex = new RegExp('^[^' + c + ']*', 'g');
  41.                 var match = regex.exec(rest_source);
  42.                 dstack.push(match[0]);
  43.                 output.push(rest_source.slice(0, regex.lastIndex + 1));
  44.                 rest_source = rest_source.slice(regex.lastIndex + 1, rest_source.length);
  45.             }],
  46.             word: [function() {
  47.                 var c = dstack[dstack.length - 1];
  48.                 c = c == ' ' ? '\\s' : s.replace(/[^\w\s]/g, '\\$&');
  49.                 var regex = new RegExp('^[' + c + ']*', 'g');
  50.                 var match = regex.exec(rest_source);
  51.                 rest_source = rest_source.slice(regex.lastIndex, rest_source.length);
  52.                 output.push(match[0]);
  53.                 words.parse[0]();
  54.             }],
  55.             name: [function() {
  56.                 dstack.push(' ');
  57.                 words.word[0]();
  58.             }],
  59.             interpret: [function() {
  60.                 do {
  61.                     words.name[0]();
  62.                     var word = dstack.pop().toLowerCase();
  63.                     var xt = words[word] || false;
  64.                     xt = xt && xt[xt.length - 1];
  65.                     var tags = xt.tags || (!(word in words) && notfound(word));
  66.                     var t = output.pop();
  67.                     output.push(tags[0]);
  68.                     output.push(t);
  69.                     if (xt) {
  70.                         if (xt.immediate || !state) {
  71.                             xt();
  72.                         } else {
  73.                             compile(word);
  74.                         }
  75.                     }
  76.                     output.push(tags[1]);
  77.                 } while (rest_source);
  78.             }],
  79.             refill: [function() {
  80.                 output.push(rest_source);
  81.                 source = rest_source = '';
  82.                 if (!rest_all_source) {
  83.                     return;
  84.                 }
  85.                 var line = /^[^\n]*\n?/g;
  86.                 var match = line.exec(rest_all_source);
  87.                 source = rest_source = match[0];
  88.                 rest_all_source = rest_all_source.slice(line.lastIndex, rest_all_source.length);
  89.             }],
  90.             ':': [function() {
  91.                 words.name[0]();
  92.                 latest = dstack.pop().toLowerCase();
  93.                 current = [];
  94.                 state = true;
  95.             }],
  96.             ';': [function() {
  97.                 if (!words[latest]) words[latest] = [];
  98.                 words[latest].push(new Function(current.join('')).bind(words));
  99.                 state = false;
  100.                 words[latest][words[latest].length - 1].tags = currenttags;
  101.                 currenttags = undefined;
  102.                 current = [];
  103.             }],
  104.             '[': [function() {
  105.                 state = false;
  106.             }],
  107.             ']': [function() {
  108.                 state = true;
  109.             }],
  110.             bl: [function() {
  111.                 dstack.push(' ')
  112.             }],
  113.             immediate: [function() {
  114.                 words[latest][words[latest].length - 1].immediate = true;
  115.             }],
  116.             '(': [function() {
  117.                 dstack.push(')');
  118.                 words.parse[0]();
  119.             }],
  120.             '\\': [function() {
  121.                 words.refill[0]();
  122.             }],
  123.             'if': [function(){}],
  124.             'else': [function(){}],
  125.             then: [function(){}],
  126.             begin: [function(){}],
  127.             'while': [function(){}],
  128.             repeat: [function(){}],
  129.             until: [function(){}],
  130.             again: [function(){}],
  131.             'do': [function(){}],
  132.             loop: [function(){}],
  133.             '?do': [function(){}],
  134.             create: [function() {
  135.                 words.name[0]();
  136.                 latest = dstack.pop();
  137.                 if (!words[latest]) words[latest] = [];
  138.                 words[latest].push(function(){});
  139.             }],
  140.             'does&gt;': [function(){}],
  141.             postpone: [function() {
  142.                 words.name[0]();
  143.                 compile(dstack.pop().toLowerCase());
  144.             }],
  145.             'char': [function() {
  146.                 words.name[0]();
  147.                 dstack.push(dstack.pop()[0]);
  148.             }],
  149.             '[char]': [function() {
  150.                 words.name[0]();
  151.                 current.push('this.push[0]("' + dstack.pop()[0].replace(/[\\"]/g, "\\$&") + '");');
  152.             }],
  153.             push: [function(x) {
  154.                 dstack.push(x);
  155.             }],
  156.             ':noname': [function() {
  157.                 state = true;
  158.             }],
  159.         };
  160.         words[';'][0].immediate = true;
  161.         words['('][0].immediate = true;
  162.         words['\\'][0].immediate = true;
  163.         words['['][0].immediate = true;
  164.         words['does&gt;'][0].immediate = true;
  165.         words['if'][0].immediate = true;
  166.         words['else'][0].immediate = true;
  167.         words['then'][0].immediate = true;
  168.         words.begin[0].immediate = true;
  169.         words['while'][0].immediate = true;
  170.         words.repeat[0].immediate = true;
  171.         words.until[0].immediate = true;
  172.         words.again[0].immediate = true;
  173.         words['do'][0].immediate = true;
  174.         words.loop[0].immediate = true;
  175.         words['?do'][0].immediate = true;
  176.         words.postpone[0].immediate = true;
  177.         words['[char]'][0].immediate = true;
  178.         words['does&gt;'][0].immediate = true;
  179.         // в св-ве tags хранится пара тегов: начало и конец
  180.         var literal = ['<span style="color: green;">', '</span>'];
  181.         var define = ['<span style="color: darkorange;">', '</span>'];
  182.         var comment = ['<span style="color: gray;">', '</span>'];
  183.         var control = ['<span style="color: blue;">', '</span>'];
  184.         var number = ['<span style="color: red;">', '</span>'];
  185.         words.parse[0].tags = literal;
  186.         words.word[0].tags = literal;
  187.         words.name[0].tags = literal;
  188.         words[':'][0].tags = define;
  189.         words[';'][0].tags = define;
  190.         words.create[0].tags = define;
  191.         words['does&gt;'][0].tags = define;
  192.         words[':noname'][0].tags = define;
  193.         words['('][0].tags = comment;
  194.         words['\\'][0].tags = comment;
  195.         words['['][0].tags = ['<i>', ''];
  196.         words[']'][0].tags = ['', '</i>'];
  197.         words['if'][0].tags = control;
  198.         words['else'][0].tags = control;
  199.         words['then'][0].tags = control;
  200.         words.begin[0].tags = control;
  201.         words['while'][0].tags = control;
  202.         words.repeat[0].tags = control;
  203.         words.until[0].tags = control;
  204.         words.again[0].tags = control;
  205.         words['do'][0].tags = control;
  206.         words.loop[0].tags = control;
  207.         words['?do'][0].tags = control;
  208.         words.postpone[0].tags = literal;
  209.         words['[char]'][0].tags = literal;
  210.         function e(s) {
  211.             source = rest_source = s;
  212.             words.interpret[0]();
  213.             output = [];
  214.             dstack = [];
  215.         }
  216.         e(": ' name ; : ['] ' ; immediate : compile ' ; immediate : [compile] ' ; immediate");
  217.         e(': "  [char] " parse ; immediate');
  218.         words['abort"'] = words['."'] = words['c"'] = words['s"'] = words['"'];
  219.         e(': .(  [char] ) parse ; immediate');
  220.         e(': constant create ; : variable create ; : value create ; : vect create ; : ->vect create ; : defer create ; : vocabulary create ; : 2constant create ; : 2variable create ; : ;code postpone does&gt; ;');
  221.         e(': case postpone if ; immediate : of postpone if ; immediate : endof postpone if ; immediate : endcase postpone if ; immediate : exit postpone if ; immediate : ?do postpone if ; immediate : +loop postpone if ; immediate : ahead postpone if ; immediate : catch postpone if ; immediate : throw postpone if ; immediate');
  222.         e(': code  : ;');
  223.         e(': end-code  postpone ; ; immediate');
  224.         function run () {
  225.             do {
  226.                 words.refill[0]();
  227.                 words.interpret[0]();
  228.             } while (rest_all_source);
  229.         }
  230.         try {
  231.             run();
  232.         } catch (e) {
  233.             console.log(e);
  234.         }
  235.         return output.join('').replace(/\n/g, '<br>');
  236.     }
  237.  
  238.     $('.codecontent').each(function(){
  239.         var code = $(this)[0];
  240.         code.setAttribute('style', 'color: black; font-size: 12pt; font-style: bold;');
  241.         var src = code.innerText;
  242.         try {
  243.             code.innerHTML = highlight(src);
  244.         } catch (e) {
  245.             console.log(e);
  246.         }
  247.         try {
  248.             $(code).append('<div><button>оригинал</button></div>');
  249.             var t = $(code).children('div');
  250.             t.children('button').bind('click', function(){this.children('div').css('display', 'block');}.bind(t))
  251.             t.append('<div></div>');
  252.             t.children('div').css('display', 'none')[0].innerText = src;
  253.         } catch (e) {
  254.             console.log(e);
  255.         }
  256.     });
  257. })($);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement