Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f8336e7
feat(internal-infra): syntax highlighting for TON languages in MDX co…
novusnota Nov 14, 2025
0211aa4
Merge branch 'main' into closes-1120/huehuehuehuehue-2
verytactical Nov 20, 2025
08aca2e
pkg
novusnota Dec 10, 2025
312940b
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Dec 10, 2025
e43fb7d
Merge branch 'closes-1120/huehuehuehuehue-2' of github.com:ton-org/do…
novusnota Dec 10, 2025
694edc9
remove the Prism.js hack
novusnota Dec 10, 2025
7ce51ac
update definitions
novusnota Dec 10, 2025
2e3b6c0
this will only take effect after the merge
novusnota Dec 10, 2025
0ed0b7f
upd
novusnota Dec 12, 2025
fd68357
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Dec 16, 2025
9aaa452
upd
novusnota Dec 18, 2025
3d642ed
Merge branch 'closes-1120/huehuehuehuehue-2' of github.com:ton-org/do…
novusnota Dec 18, 2025
0099504
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Dec 23, 2025
203a115
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Jan 6, 2026
6ef2c42
Revert changes in the `bouncer.yml` — let's apply them elsewhere
novusnota Jan 6, 2026
d6246a0
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Feb 15, 2026
a7cc11f
Merge branch 'main' into closes-1120/huehuehuehuehue-2
novusnota Mar 22, 2026
bd6cb0c
Synchronize FunC, TASM, TL-B, and Tolk with the upstream
novusnota Mar 22, 2026
96215e9
Remove Tact highlighting
novusnota Mar 22, 2026
4d014b0
typo
novusnota Mar 22, 2026
a86df33
syntaxes/ -> grammars/
novusnota Mar 22, 2026
5a2813c
tlb page upd
novusnota Mar 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,22 @@
"background": "/resources/logo/og-image-bg.svg"
},
"styling": {
"eyebrows": "breadcrumbs"
"eyebrows": "breadcrumbs",
"codeblocks": {
"theme": {
"light": "github-light-default",
"dark": "dark-plus"
},
"languages": {
"custom": [
"/resources/grammars/tolk.tmLanguage.json",
"/resources/grammars/tlb.tmLanguage.json",
"/resources/grammars/fift.tmLanguage.json",
"/resources/grammars/tasm.tmLanguage.json",
"/resources/grammars/func.tmLanguage.json"
]
}
}
},
"contextual": {
"options": [
Expand Down
54 changes: 0 additions & 54 deletions extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,57 +75,3 @@ table {
div[data-component-part="callout-content"]>.code-block:last-child {
margin-bottom: 0;
}

/*
A temporary solution syntax highlighting of Tolk snippets: invoke Prism.js on a client-side.
See `snippets/tolk-highlight.jsx`.
@link https://github.com/ton-org/docs/issues/1473
*/

:root {
--tolk-token-comment: #808080;
--tolk-token-type-hint: #D500EC;
--tolk-token-keyword: #0000FF;
--tolk-token-struct: #007EA2;
--tolk-token-variable: #444444;
--tolk-token-attr-name: #808000;
--tolk-token-function: #A82D2D;
--tolk-token-number: #0B9000;
--tolk-token-string: #008000;
--tolk-token-string-bg: #FAF9EF;
--tolk-token-operator: #A0A000;
--tolk-token-punctuation: #808000;
--tolk-token-three-dots: #999999;
}

code.language-tolk { color: var(--tolk-token-variable); }
.token.comment { color: var(--tolk-token-comment); font-style: italic; }
.token.type-hint { color: var(--tolk-token-type-hint); }
.token.boolean { color: var(--tolk-token-keyword); }
.token.keyword { color: var(--tolk-token-keyword); }
.token.self { color: var(--tolk-token-variable); font-weight: bold; }
.token.attr-name { color: var(--tolk-token-attr-name); }
.token.function { color: var(--tolk-token-function); }
.token.number { color: var(--tolk-token-number); }
.token.string { color: var(--tolk-token-string); background-color: var(--tolk-token-string-bg); }
.token.operator { color: var(--tolk-token-operator); }
.token.punctuation { color: var(--tolk-token-punctuation); }
.token.three-dots { color: var(--tolk-token-three-dots); }
.token.struct { color: var(--tolk-token-struct); }
.token.variable { color: var(--tolk-token-variable); }

html.dark {
--tolk-token-comment: #808080;
--tolk-token-type-hint: #DF90F8;
--tolk-token-keyword: #D75F02;
--tolk-token-struct: #56C1FF;
--tolk-token-variable: #C5D2E0;
--tolk-token-attr-name: #808000;
--tolk-token-function: #F9B900;
--tolk-token-number: #33A033;
--tolk-token-string: #33A033;
--tolk-token-string-bg: #1B1C1E;
--tolk-token-operator: #A0A000;
--tolk-token-punctuation: #85B2A0;
--tolk-token-three-dots: #777777;
}
117 changes: 0 additions & 117 deletions extra.js
Original file line number Diff line number Diff line change
@@ -1,118 +1 @@
/* See: https://mintlify.com/docs/settings/custom-scripts#custom-javascript */
/*
A temporary solution syntax highlighting of Tolk snippets: invoke Prism.js on a client-side.
Sources of Prism.js are embedded right here, it's not downloaded separately.
@link https://github.com/ton-org/docs/issues/1473

All code blocks for the Tolk language are highlighted:
```tolk
// automatically highlighted: see isTolkBlockCode()
```

Visual appearance is defined in `extra.css`.
*/

(function() {
const TOLK_GRAMMAR = {
'comment': [
{ pattern: /\/\/.*/, greedy: true },
// http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
{ pattern: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//, greedy: true },
],
'attr-name': /@[a-zA-Z0-9_]+/,
'keyword': /\b(do|if|as|is|try|else|while|break|throw|catch|return|assert|repeat|continue|asm|builtin|import|export|true|false|null|redef|mutate|tolk|global|const|var|val|fun|get\sfun|struct|match|type|lazy|enum|private|readonly)\b/,
'function': /[a-zA-Z$_][a-zA-Z0-9$_]*(?=(<[^>]+>)*\()/,
'type-hint': /\b(int|cell|void|never|bool|slice|tuple|builder|continuation|coins|int\d+|uint\d+|bytes\d+|bits\d+|address|any_address|map|dict)\b/,
'boolean': /\b(false|true|null)\b/,
'self': /\b(self)\b/,
'number': /\b(-?\d+|0x[\da-fA-F]+|0b[01]+)\b/,
'string': [
{ pattern: /"""[\s\S]*?"""/, greedy: true },
{ pattern: /"[^\n"]*"\w?/, greedy: true },
],
'operator': new RegExp("\\+|-|\\*|/|%|\\?|:|=|<|>|!|&|\\||\\^|==|!=|<=|>=|<<|>>|&&|\\|\\||~/|\\^/|\\+=|-=|\\*=|/=|%=|&=|\\|=|\\^=|->|<=>|~>>|\\^>>|<<=|>>=|=>"),
'three-dots': /\.\.\./,
'punctuation': /[.,;(){}\[\]]/,
'struct': /\b[A-Z][a-z][a-zA-Z0-9$_]*\b/,
'variable': [
{ pattern: /`[^`]+`/ },
{ pattern: /\b[a-zA-Z$_][a-zA-Z0-9$_]*\b/ },
],
};

// code blocks inserted with ```tolk are rendered as <code language="text"> actually,
// because Mintlify knows nothing about custom languages;
// here we try to detect whether it's not func/fift/tlb
function isTolkBlockCode(/**HTMLElement*/ codeElement) {
if (codeElement.getAttribute('language') !== 'text') {
return false;
}

// highlight all snippets inside the "Tolk" left menu sections
// (even small ones, like `var x = 123`; they cannot be distinguished from FunC,
// but on "Tolk" pages, no other languages are present)
const isTolkPage = window.location.href.includes('/languages/tolk');
if (isTolkPage) {
return true;
}

// highlight if markdown has a title: ```tolk title="filename.tolk"
const hasTitleFilenameTolk = codeElement
.closest('div.code-block')
?.querySelector('div[data-component-part="code-block-header-filename"]')
?.innerText
?.toLowerCase()
?.endsWith('tolk');
if (hasTitleFilenameTolk) {
return true;
}

// try to detect the language based on innerText;
// treat the occurrence of fun/struct/enum/etc. as Tolk;
// it works without false positives for quite big, "real-world", meaningful snippets;
// it does not work for small snippets like `var x = 123` or `if (x != 0) {}`
const innerText = codeElement.innerText;
return /\b(fun\s\w+|struct\s\w+|struct\s*\([0-9a-fx]{4,}|enum\s\w+|lazy\s\w+)\b/.test(innerText);
}

// check if Prism was called for <code>
function isCodeHighlighted(/**HTMLElement*/ codeElement) {
return codeElement.classList.contains('language-tolk');
}

// call Prism for <code>
function highlightCode(/**HTMLElement*/ codeElement, Prism) {
codeElement.classList.add('language-tolk');
codeElement.parentElement.style.backgroundColor = ''; // parent is <pre>
codeElement.parentElement.classList.remove('shiki'); // avoid css mixing
try {
Prism.highlightElement(codeElement);
} catch (ex) {
console.error('suppressed Prism error for code', codeElement, ex);
}
}

function highlightAllCodeElementsOnPage(Prism) {
let allCodes = document.querySelectorAll('code');
for (let i = 0; i < allCodes.length; ++i) {
if (isTolkBlockCode(allCodes[i]) && !isCodeHighlighted(allCodes[i])) {
highlightCode(allCodes[i], Prism)
}
}

// call it iteratively in case of dynamic content changes
setTimeout(function() {
highlightAllCodeElementsOnPage(Prism)
}, 500);
}

if (typeof window !== "undefined") {
/* PrismJS 1.30.0 */
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(n,t){var r,i;switch(t=t||{},a.util.type(n)){case"Object":if(i=a.util.objId(n),t[i])return t[i];for(var l in r={},t[i]=r,n)n.hasOwnProperty(l)&&(r[l]=e(n[l],t));return r;case"Array":return i=a.util.objId(n),t[i]?t[i]:(r=[],t[i]=r,n.forEach((function(n,a){r[a]=e(n,t)})),r);default:return n}},getLanguage:function(e){for(;e;){var t=n.exec(e.className);if(t)return t[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,t){e.className=e.className.replace(RegExp(n,"gi"),""),e.classList.add("language-"+t)},currentScript:function(){if("undefined"==typeof document)return null;if(document.currentScript&&"SCRIPT"===document.currentScript.tagName)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var n=document.getElementsByTagName("script");for(var t in n)if(n[t].src==e)return n[t]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,n){var t=a.util.clone(a.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(e,n,t,r){var i=(r=r||a.languages)[e],l={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var s in t)t.hasOwnProperty(s)&&(l[s]=t[s]);t.hasOwnProperty(o)||(l[o]=i[o])}var u=r[e];return r[e]=l,a.languages.DFS(a.languages,(function(n,t){t===u&&n!=e&&(this[n]=l)})),l},DFS:function e(n,t,r,i){i=i||{};var l=a.util.objId;for(var o in n)if(n.hasOwnProperty(o)){t.call(n,o,n[o],r||o);var s=n[o],u=a.util.type(s);"Object"!==u||i[l(s)]?"Array"!==u||i[l(s)]||(i[l(s)]=!0,e(s,t,o,i)):(i[l(s)]=!0,e(s,t,null,i))}}},plugins:{},highlightAll:function(e,n){a.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,l=0;i=r.elements[l++];)a.highlightElement(i,!0===n,r.callback)},highlightElement:function(n,t,r){var i=a.util.getLanguage(n),l=a.languages[i];a.util.setLanguage(n,i);var o=n.parentElement;o&&"pre"===o.nodeName.toLowerCase()&&a.util.setLanguage(o,i);var s={element:n,language:i,grammar:l,code:n.textContent};function u(e){s.highlightedCode=e,a.hooks.run("before-insert",s),s.element.innerHTML=s.highlightedCode,a.hooks.run("after-highlight",s),a.hooks.run("complete",s),r&&r.call(s.element)}if(a.hooks.run("before-sanity-check",s),(o=s.element.parentElement)&&"pre"===o.nodeName.toLowerCase()&&!o.hasAttribute("tabindex")&&o.setAttribute("tabindex","0"),!s.code)return a.hooks.run("complete",s),void(r&&r.call(s.element));if(a.hooks.run("before-highlight",s),s.grammar)if(t&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:s.language,code:s.code,immediateClose:!0}))}else u(a.highlight(s.code,s.grammar,s.language));else u(a.util.encode(s.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new s;return u(a,a.head,e),o(e,a,n,a.head,0),function(e){for(var n=[],t=e.head.next;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=a.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=a.hooks.all[e];if(t&&t.length)for(var r,i=0;r=t[i++];)r(n)}},Token:i};function i(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function l(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function o(e,n,t,r,s,g){for(var f in t)if(t.hasOwnProperty(f)&&t[f]){var h=t[f];h=Array.isArray(h)?h:[h];for(var d=0;d<h.length;++d){if(g&&g.cause==f+","+d)return;var v=h[d],p=v.inside,m=!!v.lookbehind,y=!!v.greedy,k=v.alias;if(y&&!v.pattern.global){var x=v.pattern.toString().match(/[imsuy]*$/)[0];v.pattern=RegExp(v.pattern.source,x+"g")}for(var b=v.pattern||v,w=r.next,A=s;w!==n.tail&&!(g&&A>=g.reach);A+=w.value.length,w=w.next){var P=w.value;if(n.length>e.length)return;if(!(P instanceof i)){var E,S=1;if(y){if(!(E=l(b,A,e,m))||E.index>=e.length)break;var L=E.index,O=E.index+E[0].length,C=A;for(C+=w.value.length;L>=C;)C+=(w=w.next).value.length;if(A=C-=w.value.length,w.value instanceof i)continue;for(var j=w;j!==n.tail&&(C<O||"string"==typeof j.value);j=j.next)S++,C+=j.value.length;S--,P=e.slice(A,C),E.index-=A}else if(!(E=l(b,0,P,m)))continue;L=E.index;var N=E[0],_=P.slice(0,L),M=P.slice(L+N.length),W=A+P.length;g&&W>g.reach&&(g.reach=W);var I=w.prev;if(_&&(I=u(n,I,_),A+=_.length),c(n,I,S),w=u(n,I,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),S>1){var T={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,T),g&&T.reach>g.reach&&(g.reach=T.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;n.next=r,r.prev=n,e.length-=a}if(e.Prism=a,i.stringify=function e(n,t){if("string"==typeof n)return n;if(Array.isArray(n)){var r="";return n.forEach((function(n){r+=e(n,t)})),r}var i={type:n.type,content:e(n.content,t),tag:"span",classes:["token",n.type],attributes:{},language:t},l=n.alias;l&&(Array.isArray(l)?Array.prototype.push.apply(i.classes,l):i.classes.push(l)),a.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=" "+s+'="'+(i.attributes[s]||"").replace(/"/g,"&quot;")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+o+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
Prism.languages.tolk = TOLK_GRAMMAR;

setTimeout(function() {
highlightAllCodeElementsOnPage(Prism);
}, 0);
}
})();
11 changes: 6 additions & 5 deletions languages/tl-b/syntax-and-semantics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,18 @@ _ {X:Type} my_val:(## 32) next_val:X = A X;
- **Combinator name**: the right side of the TL-B scheme that represents the name of the defined combinator. Could be parameterized.

```tlb
... = MsgAddrSmpl;
// parameterized combinators
... = Maybe X;
... = Hashmap n X.
_ = MsgAddrSmpl;

// Parameterized combinators
_ = Maybe X;
_ = Hashmap n X.
```

### Comments

The comments follow the same conventions as in C++.

```
```tlb
/*
This is
a comment
Expand Down
145 changes: 145 additions & 0 deletions resources/grammars/fift.tmLanguage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
"name": "fift",
"scopeName": "source.fift",
"fileTypes": ["fif"],
"patterns": [
{
"include": "#comments"
},
{
"include": "#strings"
},
{
"include": "#numbers"
},
{
"include": "#stack_words"
},
{
"include": "#program_words"
},
{
"include": "#control_words"
},
{
"include": "#literals"
},
{
"include": "#commands"
}
],
"repository": {
"comments": {
"patterns": [
{
"match": "//.*$",
"name": "comment.line.double-slash.fift"
}
]
},
"strings": {
"patterns": [
{
"begin": "\"",
"end": "\"",
"name": "string.quoted.double.fift",
"patterns": [
{
"match": "\\\\.",
"name": "constant.character.escape.fift"
}
]
},
{
"match": "abort\"[^\"]*\"",
"name": "string.quoted.double.abort.fift"
},
{
"match": "\\.\"[^\"]*\"",
"name": "string.quoted.double.print.fift"
}
]
},
"numbers": {
"patterns": [
{
"match": "\\b-?[0-9]+(/-?[0-9]+)?\\b",
"name": "constant.numeric.decimal.fift"
},
{
"match": "\\b0x[0-9a-fA-F]+\\b",
"name": "constant.numeric.hex.fift"
},
{
"match": "\\b0b[01]+\\b",
"name": "constant.numeric.binary.fift"
}
]
},
"stack_words": {
"patterns": [
{
"match": "\\b(dup|drop|swap|rot|-rot|over|tuck|nip|2dup|2drop|2swap|pick|roll|-roll|exch|exch2|\\?dup)\\b",
"name": "keyword.operator.stack.fift"
}
]
},
"program_words": {
"patterns": [
{
"match": "\\b(PROGRAM|END>c|PROC|PROCINLINE|DECLPROC|DECLMETHOD)\\b",
"name": "keyword.control.program.fift"
},
{
"match": "\\b(CALLDICT|INLINECALLDICT)\\b",
"name": "keyword.control.call.fift"
}
]
},
"control_words": {
"patterns": [
{
"match": "\\b(if|ifnot|cond|until|while|times)\\b",
"name": "keyword.control.flow.fift"
},
{
"match": "\\b(include)\\b",
"name": "keyword.control.import.fift"
}
]
},
"literals": {
"patterns": [
{
"match": "\\b(true|false)\\b",
"name": "constant.language.boolean.fift"
},
{
"match": "b\\{[01]+\\}",
"name": "constant.other.binary-slice.fift"
},
{
"match": "x\\{[0-9a-fA-F_]+\\}",
"name": "constant.other.hex-slice.fift"
},
{
"match": "B\\{[0-9a-fA-F_]+\\}",
"name": "constant.other.hex-bytes.fift"
},
{
"match": "char .",
"name": "constant.character.fift"
}
]
},
"commands": {
"patterns": [
{
"match": "\\b[A-Z][A-Z0-9_]*\\b",
"name": "keyword.other.command.fift"
}
]
}
}
}
Loading
Loading