highlight.js用のプチコン3号言語定義ファイル

  • tags
    • petitcom
    • javascript
    • highlight.js
  • last modified2015-01-29
  • created2015-01-15

コードなど

ざっくりと作成.以下のように色付けできる.

' コメント
CLS 'コメント2
PRINT "Hello";
PRINT ",world
DATA &hdeadbeaf,&B0011,123,3.14,.59
FOR I=0 TO 3
 LOCATE 0,I:?"FOOBARBAZ"
NEXT
WHILE TRUE:WEND

ラベルなども定義しようかと思ったけれど, 使っていたテーマでとくに色分けされてなかったのでとりやめ.

コード的にはこんな感じ.命令表から全部抜き出したので結構分量あるようにみえるけど,実際は正規表現3つばかし書いただけ.

/*
Language: SMILEBASIC3
Author: myu314
*/

function(hljs) {
    return {
        aliases: ['smilebasic3', 'petitcom3'],
        case_insensitive: true,
        keywords: {
            keyword:
                'CLEAR NEW LIST ERR RUN CONT PROJECT BACKTRACE DIM VAR CHKVAR'+
                ' INC DEC SWAP COPY SORT RSORT PUSH POP UNSHIFT SHIFT CHKLABEL'+
                ' GOTO GOSUB RETURN ON IF THEN ELSE ENDIF FOR TO STEP NEXT'+
                ' WHILE WEND REPEAT UNTIL CONTINUE BREAK END STOP DEF COMMON'+
                ' CALL CHKCALL XON XOFF READ DATA RESTORE OPTION WAIT VSYNC'+
                ' KEY TMREAD DTREAD DIALOG DIALOG CLS COLOR LOCATE PRINT ATTR'+
                ' SCROLL CHKCHR INPUT LINPUT INKEY$ FONTDEF BUTTON BREPEAT'+
                ' STICK STICKEX ACCEL GYROV GYROA GYROSYNC TOUCH MICSTART'+
                ' MICSTOP MICDATA MICSAVE FILES CHKFILE LOAD SAVE RENAME'+
                ' DELETE EXEC USE MPSTART MPEND MPSEND MPRECV MPSTAT MPNAME$'+
                ' MPGET MPSET XSCREEN DISPLAY VISIBLE BACKCOLOR ACLS GPAGE'+
                ' GCOLOR RGB RGBREAD GCLIP GPRIO GCLS GSPOIT GPSET GLINE'+
                ' GCIRCLE GBOX GFILL GPAINT GCOPY GSAVE GLOAD SPPAGE SPCLIP'+
                ' SPDEF SPSET SPCLR SPSHOW SPHIDE SPHOME SPOFS SPROT SPSCALE'+
                ' SPCOLOR SPCHR SPLINK SPUNLINK SPANIM SPCHK SPSTART SPSTOP'+
                ' SPVAR SPCOL SPCOLVEC SPHITSP SPHITRC SPHITINFO BGPAGE'+
                ' BGSCREEN BGCLR BGCLIP BGHOME BGOFS BGROT BGSCALE BGPUT'+
                ' BGFILL BGGET BGANIM BGCHK BGSTART BGSTOP BGVAR BGCOPY'+
                ' BGLOAD BGSAVE BEEP BGMCHK BGMCLEAR BGMPLAY WAVSET WAVSETA'+
                ' BGMSET BGMSETD BGMVAR BGMSTOP BGMVOL EFCON EFCOFF EFCSET'+
                ' EFCWET TALK TALKCHK TALKSTOP FLOOR ROUND CEIL ABS SGN MIN'+
                ' MAX RND RNDF RANDOMIZE SQR EXP LOG POW PI RAD DEG SIN COS'+
                ' TAN ASIN ACOS ATAN SINH COSH TANH ASC CHR$ VAL STR$ HEX$'+
                ' FORMAT$ LEN MID$ LEFT$ RIGHT$ INSTR SUBST$ PRGEDIT PRGGET'+
                ' PRGSET PRGINS PRGDEL PRGSIZE PRGNAME$',
            literal:
                'CSRX CSRY CSRZ FREEMEM VERSION TABSTEP SYSBEEP ERRNUM'+
                ' ERRLINE ERRPRG PRGLINE PRGSLOT RESULT MAINCNT MICPOS'+
                ' MICSIZE MPCOUNT MPHOST MPLOCAL TRUE FALSE'
        },
        contains: [
        {
            className: 'comment',
            begin: "'", end: /$/
        },
        {
            className: 'string',
            begin: '"', end: /($|")/
        },
        {
            className: 'number',
            begin: /(&[hH][a-fA-F0-9]+|&[bB][01]+|(\d+(\.\d+)?|\.\d+))/,
        }]
    };
}

これは圧縮かけてないファイルになるので,highlight.pack.jsでは動作しない.

また以下の様にして定義を登録しないと利用できない. (このへんは,highlight.jsのソースに入ってるtools/build.js を使ってやれば自動的にやってくれるが)

hljs.registerLanguage('smilebasic3', function(hljs) {
    return { /* 言語定義 */ };
})

圧縮済みファイル / smilebasic3.pack.js

覚書

highlight.jsでは文字列を解析するモード,数値を解析するモードといったいくつかのモードを組みあわせてコードの色付けを行う. 上のSMILEBASICの場合だと,まず全体がデフォルトモード(初期状態)を表していて,命令などがキーワードとして登録されている. デフォルトモードはコメント・文字列・数値の各モードをサブモードとして持っており(containsの配列),それぞれのサブモードへ移行する条件がbegin/endに正規表現で指定されている. 指定された正規表現にマッチする文字列が見つかればそのモードへ以降する…を繰り返す. 各モードの中の文字列はspanタグで括られて"hljs-className"というクラス名がつけられるという具合.

今回は設定しなかったけど,サブモードにはrelevanceというパラメータが用意されている.これはその言語に特徴的な文法(モード)の場合高い数字をつけるようにしておくことで,言語の自動判定に役立てるというもの.デフォルトは1.よくあるダブルクオートで括られた文字列は0にした方が良い.

また,highlight.jsにはhljs.PHRASAL_WORDS_MODEというモードが用意されている(他にも数値とかよくある奴は大体定義されおり継承して利用できるようなコマンドも用意されている). このモードは主にコメント解析モードのサブモードとして使われる. コメントでよく使われそうな英単語が複数登録されているモードで,コメントの判定が正しいかどうかに利用されているようだ. これも言語の自動判定に役立つのだろう.