wordpress에서 modelica code 표시하기(prism.js + Highlighting Code Block plug-in)

워드 프레스에서 Highlighting Code Block을 이용하여 modelica code를 보여주는데, 선택할 수 있는 Default Language set에 “modelica” 항목이 없다.
그래서 직접 만들어서 서버에 업로드 해서 사용하는데, prism.js를 잘 모르는 상태에서 만들어 쓰려니 힘들다.

사용한 방식은 prism.js 파일에 “modelica” 항목을 추가하는 방법.
다른 사람이 먼저 작업해 놓은 파일이 분명 있을 듯 한데(visual studio code, obsidian 등에서 이미 modelica를 지원함) 못 찾겠다.


prism js 관련 언어
웹사이트 링크

Modelica Prism.js 작성

아직 Prism을 정확히 이해하지 못해서, CPP를 기반으로 우선 키워드 부분만 반영함.

reference
keyword : 13page

[전체 소스 : Github](https://github.com/eraracom/ModelicaLanguage/tree/main/Prism.js)

Prism.languages.modelica=
Prism.languages.extend("cpp",
{
    keyword:
    /\b(?:algorithm|and|annotation|block|break|class|connect|connector|constant|constrainedby|der|discrete|each|elseif|elsewhen|encapsulated|end|enumeration|equation|expandable|extends|external|false|final|flow|for|function|if|import|impure|in|initial|inner|input|loop|model|not|operator|or|outer|output|package|parameter|partial|protected|public|pure|record|redeclare|replaceable|return|stream|then|true|type|when|while|within)\b/,

}),

;

기존 언어 분석

C 언어 분석

시작

Prism.languages.c=
Prism.languages.extend("clike",
{ 

extend 의 의미는 기존의 규칙을 따른다는 의미이다.
즉 C언어는 clike라는 언어의 규칙을 포함한다.

키워드

keyword:
/\b(?:
_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while
)\b

연산자

/,
operator:
/>>=?
|<<=?
|->
|([-+&|:])\1
|[?:~]
|[-+*\/%&|^!=<>]=?

숫자

/,
number:
/(?:
\b0x[\da-f]+
|(?:\b\d+\.?\d*
|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i}
),

instartBefore

(static) insertBefore(inside, before, insert, rootopt) → {Grammar}
다른 토큰 앞에 정의한 토큰을 삽입합니다.

Prism.languages.insertBefore
("c",

"string",

{
    macro:
    {
        pattern:/(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,
        lookbehind:!0,
        alias:"property",
        inside:
        {
            string:
            {
                pattern:
                /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,

                lookbehind:
                !0
            },

            directive:
            {
                pattern:/(#\s*)
                \b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|
                include|line|pragma|undef|using
                )\b/,

                lookbehind:
                !0,

                alias:
                "keyword"
            }
        }
    },

    constant:

    /\b(?:
    __FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|
    SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr
    )\b

/}
)
,delete 

Prism.languages.c["class-name"]
,delete 

Prism.languages.c["boolean"];

C++ 분석

Prism.languages.cpp=
Prism.languages.extend("c",
{
    keyword:
    /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,

    "boolean":
    /\b(?:true|false)\b/,

    operator:   
    />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*\/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/


}),

Prism.languages.insertBefore(
"cpp",
"keyword",

{
    "class-name":
    {
        pattern:
        /(class\s+)\w+/i,

        lookbehind:
        !0
    }
}),

Prism.languages.insertBefore(
"cpp",
"string",

{
    "raw-string":
    {
        pattern:
        /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
        alias:"string",
        greedy:!0
    }
});

CSS 분석

Prism.languages.css=
{
comment:
/\/\*[\s\S]*?\*\/

/,
atrule:
{
    pattern:
    /@[\w-]+?.*?(?:;|(?=\s*\{))/i,

    inside:
    {
        rule:
        /@[\w-]+/}},

        url:
        /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,

        selector:
        /[^{}\s][^{};]*?(?=\s*\{)/,

        string:
        {
            pattern:
            /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,

            greedy:
            !0
        },

        property:
        /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,

        important:
        /!important\b/i,"function":/[-a-z0-9]+(?=\()/i,

        punctuation:/[(){};:,]
    /},

    Prism.languages.css.atrule.inside.rest=Prism.languages.css,
    Prism.languages.markup&&(
    Prism.languages.insertBefore
    ("markup",
    "tag",

    {
        style:
        {
            pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,
            lookbehind:!0,inside:Prism.languages.css,
            alias:"language-css",
            greedy:!0
        }
    }),

    Prism.languages.insertBefore
    ("inside",
    "attr-value",

    {
        "style-attr":
        {
            pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,
            inside:{"attr-name":
            {
                pattern:/^\s*style/i,
                inside:Prism.languages.markup.tag.inside
            },
        punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":
        {
            pattern:/.+/i,inside:Prism.languages.css
        }
    },
    alias:"language-css"}},Prism.languages.markup.tag));

Clike 분석

Prism.languages.clike=
{
    comment:[
    {
        pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
        lookbehind:!0
    },
    {
        pattern:/(^|[^\\:])\/\/.*/,
        lookbehind:!0,
        greedy:!0
    }],

    string:
    {
        pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
        greedy:!0
    },

    "class-name":
    {
        pattern:
        /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,

        lookbehind:
        !0,

        inside:
        {
            punctuation:
            /[.\\]/
        }
    },

    keyword:
                /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(?:true|false)\b/,"function":/\w+(?=\()/,

    number:
    /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,

    operator:
    /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,

    punctuation:
    /[{}[\];(),.:]/
};