[{"data":1,"prerenderedAt":979},["ShallowReactive",2],{"docs-docsEn-\u002Fgetting-started":3,"docs-nav-docsEn":868,"docs-surround-docsEn-\u002Fgetting-started":886,"docs-search-docsEn":890},{"id":4,"title":5,"body":6,"description":861,"extension":862,"meta":863,"navigation":421,"path":864,"seo":865,"stem":866,"__hash__":867},"docsEn\u002F1.getting-started.md","Getting started",{"type":7,"value":8,"toc":856},"minimark",[9,14,18,23,42,46,118,122,852],[10,11,13],"h1",{"id":12},"wzoregex-diagram","@wzo\u002Fregex-diagram",[15,16,17],"p",{},"It parses a regex into an AST, lays it out as a railroad diagram, and renders a\nself-contained, themeable SVG — plus syntax\u002Fsemantic validation and a\ntoken-by-token plain-language explanation. Framework-agnostic, usable in any\nJS\u002FTS project.",[19,20,22],"h2",{"id":21},"features","Features",[24,25,26,30,33,36,39],"ul",{},[27,28,29],"li",{},"Modern syntax: named groups, lookbehind, Unicode properties, v-flag set operations",[27,31,32],{},"Self-contained SVG, themeable via CSS variables (incl. dark mode), exportable",[27,34,35],{},"Parsing validates too: syntax errors and semantic issues (never-matching assertions, empty classes)",[27,37,38],{},"Token-by-token, plain-language explanation",[27,40,41],{},"Framework-agnostic pure functions, only two small runtime dependencies",[19,43,45],{"id":44},"install","Install",[47,48,49,75,90,104],"code-group",{},[50,51,57],"pre",{"className":52,"code":53,"filename":54,"language":55,"meta":56,"style":56},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","pnpm add @wzo\u002Fregex-diagram\n","pnpm","bash","",[58,59,60],"code",{"__ignoreMap":56},[61,62,65,68,72],"span",{"class":63,"line":64},"line",1,[61,66,54],{"class":67},"sbgvK",[61,69,71],{"class":70},"s_sjI"," add",[61,73,74],{"class":70}," @wzo\u002Fregex-diagram\n",[50,76,79],{"className":52,"code":77,"filename":78,"language":55,"meta":56,"style":56},"npm install @wzo\u002Fregex-diagram\n","npm",[58,80,81],{"__ignoreMap":56},[61,82,83,85,88],{"class":63,"line":64},[61,84,78],{"class":67},[61,86,87],{"class":70}," install",[61,89,74],{"class":70},[50,91,94],{"className":52,"code":92,"filename":93,"language":55,"meta":56,"style":56},"yarn add @wzo\u002Fregex-diagram\n","yarn",[58,95,96],{"__ignoreMap":56},[61,97,98,100,102],{"class":63,"line":64},[61,99,93],{"class":67},[61,101,71],{"class":70},[61,103,74],{"class":70},[50,105,108],{"className":52,"code":106,"filename":107,"language":55,"meta":56,"style":56},"bun add @wzo\u002Fregex-diagram\n","bun",[58,109,110],{"__ignoreMap":56},[61,111,112,114,116],{"class":63,"line":64},[61,113,107],{"class":67},[61,115,71],{"class":70},[61,117,74],{"class":70},[19,119,121],{"id":120},"quick-start","Quick start",[50,123,128],{"className":124,"code":125,"language":126,"meta":127,"style":56},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark twoslash lsp","import { explainRegex, parseRegex, regexToSvg } from '@wzo\u002Fregex-diagram'\n\n\u002F\u002F One-shot: regex → standalone SVG string (null if invalid or broken)\nconst svg = regexToSvg('(\\\\d{4})-(\\\\d{2})', 'g')\n\n\u002F\u002F Parse + validate: syntax AND semantic issues\nconst { ok, ast, issues } = parseRegex('a$\\\\d')\n\n\u002F\u002F Plain-language, step-by-step explanation\nconst steps = explainRegex('(?\u003Cyear>\\\\d{4})')\n","ts","twoslash",[58,129,130,416,423,430,561,566,572,737,742,748],{"__ignoreMap":56},[61,131,132,136,140,144,248,250,252,325,327,329,401,404,407,411,413],{"class":63,"line":64},[61,133,135],{"class":134},"sVHd0","import",[61,137,139],{"class":138},"sP7_E"," {",[61,141,143],{"class":142},"su5hD"," ",[61,145,146],{"class":142},[147,148,151,154],"v-menu",{"class":149,"popper-class":150,"theme":127},"twoslash-hover","shiki twoslash-floating vp-copy-ignore",[61,152,153],{},"explainRegex",[155,156,158],"template",{"v-slot:popper":157},"{}",[61,159,161,237],{"class":160,"v-pre":56},"twoslash-popup-container vp-copy-ignore",[58,162,164],{"class":163},"twoslash-popup-code",[50,165,169],{"class":166,"style":167,"tabindex":168},"shiki shiki-themes material-theme-lighter github-light github-dark","--shiki-light:#90A4AE;--shiki-default:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#FAFAFA;--shiki-default-bg:#fff;--shiki-dark-bg:#24292e","0",[58,170,171,230],{},[61,172,173,177,181,185,189,193,197,201,204,207,210,212,215,217,221,224,227],{"class":63},[61,174,176],{"style":175},"--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8","(alias) ",[61,178,180],{"style":179},"--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583","function",[61,182,184],{"style":183},"--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0"," explainRegex",[61,186,188],{"style":187},"--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8","(",[61,190,192],{"style":191},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit","source",[61,194,196],{"style":195},"--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583",":",[61,198,200],{"style":199},"--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF"," string",[61,202,203],{"style":187},",",[61,205,206],{"style":191}," flags",[61,208,209],{"style":195},"?:",[61,211,200],{"style":199},[61,213,214],{"style":187},")",[61,216,196],{"style":195},[61,218,220],{"style":219},"--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0"," ExplainItem",[61,222,223],{"style":175},"[] ",[61,225,226],{"style":195},"|",[61,228,229],{"style":199}," null",[61,231,232,235],{"class":63},[61,233,135],{"style":234},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit",[61,236,184],{"style":175},[238,239,241],"div",{"class":240},"twoslash-popup-docs vp-doc",[15,242,243,244,247],{},"Explain a regular expression token by token, in plain language.\nReturns ",[58,245,246],{},"null"," if the pattern (or flags) fail to parse.",[61,249,203],{"class":138},[61,251,143],{"class":142},[61,253,254],{"class":142},[147,255,256,259],{"class":149,"popper-class":150,"theme":127},[61,257,258],{},"parseRegex",[155,260,261],{"v-slot:popper":157},[61,262,263,307],{"class":160,"v-pre":56},[58,264,265],{"class":163},[50,266,267],{"class":166,"style":167,"tabindex":168},[58,268,269,301],{},[61,270,271,273,275,278,280,282,284,286,288,290,292,294,296,298],{"class":63},[61,272,176],{"style":175},[61,274,180],{"style":179},[61,276,277],{"style":183}," parseRegex",[61,279,188],{"style":187},[61,281,192],{"style":191},[61,283,196],{"style":195},[61,285,200],{"style":199},[61,287,203],{"style":187},[61,289,206],{"style":191},[61,291,209],{"style":195},[61,293,200],{"style":199},[61,295,214],{"style":187},[61,297,196],{"style":195},[61,299,300],{"style":219}," ParseResult",[61,302,303,305],{"class":63},[61,304,135],{"style":234},[61,306,277],{"style":175},[238,308,309,312,315],{"class":240},[15,310,311],{},"Parse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and any",[15,313,314],{},"RegexIssue",[15,316,317,318,321,322,324],{},"s; callers that only render\nstructure (explanation, coloring) can ignore ",[58,319,320],{},"issues",", while the diagram and\nexports treat a non-empty ",[58,323,320],{}," as \"don't render — the regex is broken\".",[61,326,203],{"class":138},[61,328,143],{"class":142},[61,330,331],{"class":142},[147,332,333,336],{"class":149,"popper-class":150,"theme":127},[61,334,335],{},"regexToSvg",[155,337,338],{"v-slot:popper":157},[61,339,340,388],{"class":160,"v-pre":56},[58,341,342],{"class":163},[50,343,344],{"class":166,"style":167,"tabindex":168},[58,345,346,382],{},[61,347,348,350,352,355,357,359,361,363,365,367,369,371,373,375,377,380],{"class":63},[61,349,176],{"style":175},[61,351,180],{"style":179},[61,353,354],{"style":183}," regexToSvg",[61,356,188],{"style":187},[61,358,192],{"style":191},[61,360,196],{"style":195},[61,362,200],{"style":199},[61,364,203],{"style":187},[61,366,206],{"style":191},[61,368,209],{"style":195},[61,370,200],{"style":199},[61,372,214],{"style":187},[61,374,196],{"style":195},[61,376,200],{"style":199},[61,378,379],{"style":195}," |",[61,381,229],{"style":199},[61,383,384,386],{"class":63},[61,385,135],{"style":234},[61,387,354],{"style":175},[238,389,390,396,398],{"class":240},[15,391,392,393,395],{},"One-shot: regex source + flags → SVG string.\nReturns ",[58,394,246],{}," if the regex fails to parse OR has semantic issues (a broken\nregex shouldn't yield a diagram) — use",[15,397,258],{},[15,399,400],{},"for the details.",[61,402,403],{"class":138}," }",[61,405,406],{"class":134}," from",[61,408,410],{"class":409},"sjJ54"," '",[61,412,13],{"class":70},[61,414,415],{"class":409},"'\n",[61,417,419],{"class":63,"line":418},2,[61,420,422],{"emptyLinePlaceholder":421},true,"\n",[61,424,426],{"class":63,"line":425},3,[61,427,429],{"class":428},"sutJx","\u002F\u002F One-shot: regex → standalone SVG string (null if invalid or broken)\n",[61,431,433,437,440,467,471,474,529,531,534,536,539,542,544,547,549,551,553,556,558],{"class":63,"line":432},4,[61,434,436],{"class":435},"sbsja","const",[61,438,143],{"class":439},"s_hVV",[61,441,442],{"class":439},[147,443,444,447],{"class":149,"popper-class":150,"theme":127},[61,445,446],{},"svg",[155,448,449],{"v-slot:popper":157},[61,450,451],{"class":160,"v-pre":56},[58,452,453,455,459,461,463,465],{"class":163},[61,454,436],{"style":179},[61,456,458],{"style":457},"--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF"," svg",[61,460,196],{"style":195},[61,462,200],{"style":199},[61,464,379],{"style":195},[61,466,229],{"style":199},[61,468,470],{"class":469},"smGrS"," =",[61,472,143],{"class":473},"sGLFI",[61,475,476],{"class":473},[147,477,478,480],{"class":149,"popper-class":150,"theme":127},[61,479,335],{},[155,481,482],{"v-slot:popper":157},[61,483,484,519],{"class":160,"v-pre":56},[58,485,486],{"class":163},[50,487,488],{"class":166,"style":167,"tabindex":168},[58,489,490,513],{},[61,491,492,494,496,499,501,503,505,508,510],{"class":63},[61,493,176],{"style":175},[61,495,335],{"style":183},[61,497,498],{"style":175},"(source: string",[61,500,203],{"style":187},[61,502,206],{"style":175},[61,504,209],{"style":195},[61,506,507],{"style":175}," string): string ",[61,509,226],{"style":195},[61,511,229],{"style":512},"--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF",[61,514,515,517],{"class":63},[61,516,135],{"style":234},[61,518,354],{"style":175},[238,520,521,525,527],{"class":240},[15,522,392,523,395],{},[58,524,246],{},[15,526,258],{},[15,528,400],{},[61,530,188],{"class":142},[61,532,533],{"class":409},"'",[61,535,188],{"class":70},[61,537,538],{"class":439},"\\\\",[61,540,541],{"class":70},"d{4})-(",[61,543,538],{"class":439},[61,545,546],{"class":70},"d{2})",[61,548,533],{"class":409},[61,550,203],{"class":138},[61,552,410],{"class":409},[61,554,555],{"class":70},"g",[61,557,533],{"class":409},[61,559,560],{"class":142},")\n",[61,562,564],{"class":63,"line":563},5,[61,565,422],{"emptyLinePlaceholder":421},[61,567,569],{"class":63,"line":568},6,[61,570,571],{"class":428},"\u002F\u002F Parse + validate: syntax AND semantic issues\n",[61,573,575,577,579,581,604,606,608,635,637,639,664,666,668,670,721,723,725,728,730,733,735],{"class":63,"line":574},7,[61,576,436],{"class":435},[61,578,139],{"class":138},[61,580,143],{"class":439},[61,582,583],{"class":439},[147,584,585,588],{"class":149,"popper-class":150,"theme":127},[61,586,587],{},"ok",[155,589,590],{"v-slot:popper":157},[61,591,592],{"class":160,"v-pre":56},[58,593,594,596,599,601],{"class":163},[61,595,436],{"style":179},[61,597,598],{"style":457}," ok",[61,600,196],{"style":195},[61,602,603],{"style":199}," boolean",[61,605,203],{"class":138},[61,607,143],{"class":439},[61,609,610],{"class":439},[147,611,612,615],{"class":149,"popper-class":150,"theme":127},[61,613,614],{},"ast",[155,616,617],{"v-slot:popper":157},[61,618,619],{"class":160,"v-pre":56},[58,620,621,623,626,628,631,633],{"class":163},[61,622,436],{"style":179},[61,624,625],{"style":457}," ast",[61,627,196],{"style":195},[61,629,630],{"style":219}," Pattern",[61,632,379],{"style":195},[61,634,229],{"style":199},[61,636,203],{"class":138},[61,638,143],{"class":439},[61,640,641],{"class":439},[147,642,643,645],{"class":149,"popper-class":150,"theme":127},[61,644,320],{},[155,646,647],{"v-slot:popper":157},[61,648,649],{"class":160,"v-pre":56},[58,650,651,653,656,658,661],{"class":163},[61,652,436],{"style":179},[61,654,655],{"style":457}," issues",[61,657,196],{"style":195},[61,659,660],{"style":219}," RegexIssue",[61,662,663],{"style":175},"[]",[61,665,403],{"class":138},[61,667,470],{"class":469},[61,669,143],{"class":473},[61,671,672],{"class":473},[147,673,674,676],{"class":149,"popper-class":150,"theme":127},[61,675,258],{},[155,677,678],{"v-slot:popper":157},[61,679,680,709],{"class":160,"v-pre":56},[58,681,682],{"class":163},[50,683,684],{"class":166,"style":167,"tabindex":168},[58,685,686,703],{},[61,687,688,690,692,694,696,698,700],{"class":63},[61,689,176],{"style":175},[61,691,258],{"style":183},[61,693,498],{"style":175},[61,695,203],{"style":187},[61,697,206],{"style":175},[61,699,209],{"style":195},[61,701,702],{"style":175}," string): ParseResult",[61,704,705,707],{"class":63},[61,706,135],{"style":234},[61,708,277],{"style":175},[238,710,711,713,715],{"class":240},[15,712,311],{},[15,714,314],{},[15,716,317,717,321,719,324],{},[58,718,320],{},[58,720,320],{},[61,722,188],{"class":142},[61,724,533],{"class":409},[61,726,727],{"class":70},"a$",[61,729,538],{"class":439},[61,731,732],{"class":70},"d",[61,734,533],{"class":409},[61,736,560],{"class":142},[61,738,740],{"class":63,"line":739},8,[61,741,422],{"emptyLinePlaceholder":421},[61,743,745],{"class":63,"line":744},9,[61,746,747],{"class":428},"\u002F\u002F Plain-language, step-by-step explanation\n",[61,749,751,753,755,783,785,787,836,838,840,843,845,848,850],{"class":63,"line":750},10,[61,752,436],{"class":435},[61,754,143],{"class":439},[61,756,757],{"class":439},[147,758,759,762],{"class":149,"popper-class":150,"theme":127},[61,760,761],{},"steps",[155,763,764],{"v-slot:popper":157},[61,765,766],{"class":160,"v-pre":56},[58,767,768,770,773,775,777,779,781],{"class":163},[61,769,436],{"style":179},[61,771,772],{"style":457}," steps",[61,774,196],{"style":195},[61,776,220],{"style":219},[61,778,223],{"style":175},[61,780,226],{"style":195},[61,782,229],{"style":199},[61,784,470],{"class":469},[61,786,143],{"class":473},[61,788,789],{"class":473},[147,790,791,793],{"class":149,"popper-class":150,"theme":127},[61,792,153],{},[155,794,795],{"v-slot:popper":157},[61,796,797,830],{"class":160,"v-pre":56},[58,798,799],{"class":163},[50,800,801],{"class":166,"style":167,"tabindex":168},[58,802,803,824],{},[61,804,805,807,809,811,813,815,817,820,822],{"class":63},[61,806,176],{"style":175},[61,808,153],{"style":183},[61,810,498],{"style":175},[61,812,203],{"style":187},[61,814,206],{"style":175},[61,816,209],{"style":195},[61,818,819],{"style":175}," string): ExplainItem[] ",[61,821,226],{"style":195},[61,823,229],{"style":512},[61,825,826,828],{"class":63},[61,827,135],{"style":234},[61,829,184],{"style":175},[238,831,832],{"class":240},[15,833,243,834,247],{},[58,835,246],{},[61,837,188],{"class":142},[61,839,533],{"class":409},[61,841,842],{"class":70},"(?\u003Cyear>",[61,844,538],{"class":439},[61,846,847],{"class":70},"d{4})",[61,849,533],{"class":409},[61,851,560],{"class":142},[853,854,855],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":56,"searchDepth":418,"depth":418,"links":857},[858,859,860],{"id":21,"depth":418,"text":22},{"id":44,"depth":418,"text":45},{"id":120,"depth":418,"text":121},"Framework-agnostic regular-expression railroad-diagram visualizer.","md",{},"\u002Fgetting-started",{"title":5,"description":861},"1.getting-started","hXp0NDtSmpZTx0Eea0YeNz0YVpWphOu4eJAnw0aub1g",[869,870,874,878,882],{"title":5,"path":864,"stem":866},{"title":871,"path":872,"stem":873},"Examples","\u002Fexamples","2.examples",{"title":875,"path":876,"stem":877},"API reference","\u002Fapi","3.api",{"title":879,"path":880,"stem":881},"Localizing the explanation","\u002Flocalization","4.localization",{"title":883,"path":884,"stem":885},"Theming and colors","\u002Ftheming","5.theming",[887,888],null,{"title":871,"path":872,"stem":873,"description":889,"children":-1},"Practical recipes for rendering, validating and explaining regexes.",[891,893,896,900,904,908,910,913,918,923,928,933,936,940,945,948,952,957,962,965,969,974],{"id":864,"title":5,"titles":892,"content":861,"level":64},[],{"id":894,"title":13,"titles":895,"content":17,"level":64},"\u002Fgetting-started#wzoregex-diagram",[],{"id":897,"title":22,"titles":898,"content":899,"level":418},"\u002Fgetting-started#features",[13],"Modern syntax: named groups, lookbehind, Unicode properties, v-flag set operationsSelf-contained SVG, themeable via CSS variables (incl. dark mode), exportableParsing validates too: syntax errors and semantic issues (never-matching assertions, empty classes)Token-by-token, plain-language explanationFramework-agnostic pure functions, only two small runtime dependencies",{"id":901,"title":45,"titles":902,"content":903,"level":418},"\u002Fgetting-started#install",[13],"pnpm add @wzo\u002Fregex-diagram\nnpm install @wzo\u002Fregex-diagram\nyarn add @wzo\u002Fregex-diagram\nbun add @wzo\u002Fregex-diagram",{"id":905,"title":121,"titles":906,"content":907,"level":418},"\u002Fgetting-started#quick-start",[13],"import { explainRegex(alias) function explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse., parseRegex(alias) function parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\"., regexToSvg(alias) function regexToSvg(source: string, flags?: string): string | nullimport regexToSvgOne-shot: regex source + flags → SVG string.\nReturns null if the regex fails to parse OR has semantic issues (a broken\nregex shouldn't yield a diagram) — useparseRegexfor the details. } from '@wzo\u002Fregex-diagram'\n\n\u002F\u002F One-shot: regex → standalone SVG string (null if invalid or broken)\nconst svgconst svg: string | null = regexToSvg(alias) regexToSvg(source: string, flags?: string): string | nullimport regexToSvgOne-shot: regex source + flags → SVG string.\nReturns null if the regex fails to parse OR has semantic issues (a broken\nregex shouldn't yield a diagram) — useparseRegexfor the details.('(\\\\d{4})-(\\\\d{2})', 'g')\n\n\u002F\u002F Parse + validate: syntax AND semantic issues\nconst { okconst ok: boolean, astconst ast: Pattern | null, issuesconst issues: RegexIssue[] } = parseRegex(alias) parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\".('a$\\\\d')\n\n\u002F\u002F Plain-language, step-by-step explanation\nconst stepsconst steps: ExplainItem[] | null = explainRegex(alias) explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse.('(?\u003Cyear>\\\\d{4})') html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"id":872,"title":871,"titles":909,"content":889,"level":64},[],{"id":911,"title":871,"titles":912,"content":56,"level":64},"\u002Fexamples#examples",[],{"id":914,"title":915,"titles":916,"content":917,"level":418},"\u002Fexamples#render-to-svg","Render to SVG",[871],"Get a self-contained SVG string in one call — drop it into the page or save it\nto a file. import { regexToSvg(alias) function regexToSvg(source: string, flags?: string): string | nullimport regexToSvgOne-shot: regex source + flags → SVG string.\nReturns null if the regex fails to parse OR has semantic issues (a broken\nregex shouldn't yield a diagram) — useparseRegexfor the details. } from '@wzo\u002Fregex-diagram'\n\n\u002F\u002F Returns a self-contained SVG string, or null if the regex is invalid\u002Fbroken.\nconst svgconst svg: string | null = regexToSvg(alias) regexToSvg(source: string, flags?: string): string | nullimport regexToSvgOne-shot: regex source + flags → SVG string.\nReturns null if the regex fails to parse OR has semantic issues (a broken\nregex shouldn't yield a diagram) — useparseRegexfor the details.('(?\u003Cyear>\\\\d{4})-(?\u003Cmonth>\\\\d{2})', 'g')\ndocumentvar document: Documentwindow.document returns a reference to the document contained in the window.MDN Reference.querySelector(method) ParentNode.querySelector\u003CElement>(selectors: string): Element | null (+4 overloads)Returns the first element that is a descendant of node that matches selectors.MDN Reference('#out')!.innerHTML(property) Element.innerHTML: stringThe innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element.MDN Reference = svgconst svg: string | null ?? 'invalid regex'",{"id":919,"title":920,"titles":921,"content":922,"level":418},"\u002Fexamples#validate-a-regex","Validate a regex",[871],"parseRegex returns syntax errors and semantic issues alike (e.g. an assertion\nthat never matches). import { parseRegex(alias) function parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\". } from '@wzo\u002Fregex-diagram'\n\nconst resultconst result: ParseResult = parseRegex(alias) parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\".('a$\\\\d') \u002F\u002F valid syntax, but never matches\nif (!resultconst result: ParseResult.ok(property) ok: boolean || resultconst result: ParseSuccess.issues(property) ParseSuccess.issues: RegexIssue[].length(property) Array\u003CRegexIssue>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.) {\n  for (const issueconst issue: RegexIssue of resultconst result: ParseResult.issues(property) issues: RegexIssue[]) {\n    consolevar console: Console.warn(method) console.Console.warn(...data: any[]): void(issueconst issue: RegexIssue.message(property) RegexIssue.message: stringHuman-readable fallback (the parser's text for syntax errors)., 'at', issueconst issue: RegexIssue.start(property) RegexIssue.start?: number | undefinedPattern offsets of the offending token; absent for flag errors.)\n  }\n}",{"id":924,"title":925,"titles":926,"content":927,"level":418},"\u002Fexamples#explain-a-regex","Explain a regex",[871],"Get a token-by-token explanation and print it indented by depth. import { explainRegex(alias) function explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse. } from '@wzo\u002Fregex-diagram'\n\nfor (const stepconst step: ExplainItem of explainRegex(alias) explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse.('(?\u003Cy>\\\\d{4})') ?? []) {\n  consolevar console: Console.log(method) console.Console.log(...data: any[]): void('  '.repeat(method) String.repeat(count: number): stringReturns a String value that is made from count copies appended together. If count is 0,\nthe empty string is returned.@paramcount  number of copies to append(stepconst step: ExplainItem.depth(property) ExplainItem.depth: number) + stepconst step: ExplainItem.token(property) ExplainItem.token: string + ' — ' + stepconst step: ExplainItem.text(property) ExplainItem.text: stringEnglish rendering of desc, for zero-config use.)\n}",{"id":929,"title":930,"titles":931,"content":932,"level":418},"\u002Fexamples#lower-level-control","Lower-level control",[871],"Two steps: lay out the AST into a model, then render it to SVG yourself. import { buildDiagram(alias) function buildDiagram(pattern: Pattern): Diagramimport buildDiagramBuild a fully laid-out diagram from a regexpp Pattern AST.\nMaps AST → railroad tree (build.ts), measures it, and wraps it with the\nouter padding, lead-in\u002Fout rails and start\u002Fend caps., parseRegex(alias) function parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\"., renderToSvg(alias) function renderToSvg(diagram: Diagram, flags?: string): stringimport renderToSvgRender a laid-out diagram to a standalone SVG string.Colors use CSS custom properties with sensible fallbacks, so the output works\non its own yet can be themed (e.g. dark mode) by the host via --rr-* vars. } from '@wzo\u002Fregex-diagram'\n\nconst parsedconst parsed: ParseResult = parseRegex(alias) parseRegex(source: string, flags?: string): ParseResultimport parseRegexParse a regular expression source + flags into a regexpp AST, then lint it for\nsemantic problems. Flags are validated first, then the pattern. On success the\nresult carries the AST and anyRegexIssues; callers that only render\nstructure (explanation, coloring) can ignore issues, while the diagram and\nexports treat a non-empty issues as \"don't render — the regex is broken\".('a|b|c')\nif (parsedconst parsed: ParseResult.ok(property) ok: boolean) {\n  const diagramconst diagram: Diagram = buildDiagram(alias) buildDiagram(pattern: Pattern): Diagramimport buildDiagramBuild a fully laid-out diagram from a regexpp Pattern AST.\nMaps AST → railroad tree (build.ts), measures it, and wraps it with the\nouter padding, lead-in\u002Fout rails and start\u002Fend caps.(parsedconst parsed: ParseSuccess.ast(property) ParseSuccess.ast: Pattern) \u002F\u002F positioned model\n  const svgconst svg: string = renderToSvg(alias) renderToSvg(diagram: Diagram, flags?: string): stringimport renderToSvgRender a laid-out diagram to a standalone SVG string.Colors use CSS custom properties with sensible fallbacks, so the output works\non its own yet can be themed (e.g. dark mode) by the host via --rr-* vars.(diagramconst diagram: Diagram, 'i') \u002F\u002F model → SVG string\n} html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"id":876,"title":875,"titles":934,"content":935,"level":64},[],"Every exported function and type.",{"id":937,"title":875,"titles":938,"content":939,"level":64},"\u002Fapi#api-reference",[],"One call from a regex source and optional flags to a standalone, themeable SVG string. Returns null when the regex fails to parse or has a semantic issue (e.g. a never-matching assertion or an empty character class).Parses the source to a regexpp AST and validates it. The result carries ok, the ast (null on failure) and an issues array covering both syntax errors and semantic problems.Runs only the semantic checks and returns the issues array — never-matching assertions, empty character classes and the like. Empty for a clean regex.Returns a flat list of steps, each with its depth, syntax category, token slice and a plain-language description. Null when the regex is invalid.Renders one ExplainDesc to a string using a message table. Pass a partial table to localize — any key you omit falls back to the built-in English (see the Localization page).Lays out a parsed AST into a positioned railroad-diagram model with coordinates, ready to render.Renders a diagram model to a self-contained SVG string; pass the flags to show them after the pattern.Returns the syntax category of each source character (or null), for highlighting the raw pattern text.Returns, per source character, the start and end offsets of the smallest diagram node covering it — used to sync caret and hover with the diagram.Assembles a valid regex literal from a source and flags, escaping slashes and handling the empty pattern.",{"id":941,"title":942,"titles":943,"content":944,"level":418},"\u002Fapi#types","Types",[875],"\u002F\u002F Returned in parseRegex().issues and by lintRegex()\ninterface RegexIssue {\n  rule?: 'assertionNeverMatches' | 'emptyCharClass' \u002F\u002F stable id; absent for syntax errors\n  message: string \u002F\u002F human-readable (the parser's text for syntax errors)\n  start?: number \u002F\u002F pattern offsets of the offending token, when known\n  end?: number\n}\n\n\u002F\u002F One line of explainRegex()\ninterface ExplainItem {\n  depth: number \u002F\u002F nesting level, for indentation\n  cat: SyntaxCategory \u002F\u002F the token's syntax category (drives the shared color)\n  token: string \u002F\u002F the source slice this line describes\n  desc: ExplainDesc \u002F\u002F language-neutral description — render this to localize\n  text: string \u002F\u002F English rendering of desc, for zero-config use\n  start?: number\n  end?: number\n}\n\n\u002F\u002F Color-category keys — also the --rr-syntax-* variable suffixes\ntype SyntaxCategory =\n  | 'literal' | 'charset' | 'class' | 'anchor' | 'quantifier'\n  | 'group' | 'lookaround' | 'backref' | 'alternation' html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":880,"title":879,"titles":946,"content":947,"level":64},[],"Render explanations in any language with a message table.",{"id":949,"title":879,"titles":950,"content":951,"level":64},"\u002Flocalization#localizing-the-explanation",[],"explainRegex gives each line a ready-made English text plus a\nlanguage-neutral desc. For other languages, call formatExplain(desc, messages)\nwith a translated table — it can be partial, and any key you omit falls back to\nEnglish. No i18n library required; the English text is itself rendered this\nway, so the two never drift. import { explainRegex(alias) function explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse., formatExplain(alias) function formatExplain(desc: ExplainDesc, messages?: Partial\u003CExplainMessages>): stringimport formatExplainRender a description to a string using a message table. Pass a partial\nmessages to localize — omitted keys fall back to English. This is the one\nfunction a library consumer needs for i18n: give it your translated table. } from '@wzo\u002Fregex-diagram'\n\n\u002F\u002F Zero config — item.text is ready-made English:\nfor (const itconst it: ExplainItem of explainRegex(alias) explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse.('a+', 'i') ?? [])\n  consolevar console: Console.log(method) console.Console.log(...data: any[]): void(itconst it: ExplainItem.text(property) ExplainItem.text: stringEnglish rendering of desc, for zero-config use.)\n\n\u002F\u002F Localize — hand formatExplain your translated table.\n\u002F\u002F Templates use {placeholder} slots; any key you omit stays English.\nconst zhconst zh: {    csDigit: string;    qExact: string;    qRange: string;    groupNamed: string;} = {\n  csDigit(property) csDigit: string: '数字（0-9）',\n  qExact(property) qExact: string: '恰好重复 {n} 次',\n  qRange(property) qRange: string: '重复 {min} 到 {max} 次',\n  groupNamed(property) groupNamed: string: '捕获组 #{index}（命名为 \"{name}\"）',\n  \u002F\u002F …only the keys you want to translate\n}\nfor (const itconst it: ExplainItem of explainRegex(alias) explainRegex(source: string, flags?: string): ExplainItem[] | nullimport explainRegexExplain a regular expression token by token, in plain language.\nReturns null if the pattern (or flags) fail to parse.('(?\u003Cy>\\\\d{2,4})') ?? [])\n  consolevar console: Console.log(method) console.Console.log(...data: any[]): void(formatExplain(alias) formatExplain(desc: ExplainDesc, messages?: Partial\u003CExplainMessages>): stringimport formatExplainRender a description to a string using a message table. Pass a partial\nmessages to localize — omitted keys fall back to English. This is the one\nfunction a library consumer needs for i18n: give it your translated table.(itconst it: ExplainItem.desc(property) ExplainItem.desc: ExplainDescLanguage-neutral description — render withformatExplainfor i18n., zhconst zh: {    csDigit: string;    qExact: string;    qRange: string;    groupNamed: string;}))",{"id":953,"title":954,"titles":955,"content":956,"level":418},"\u002Flocalization#the-message-table","The message table",[879],"Every key formatExplain understands, with its default English template — this\nis the EXPLAIN_EN table you spread from. {...} slots are filled at render\ntime; override any subset and the rest stay English. export const EXPLAIN_EN = {\n  char: 'the character \"{value}\"',\n  space: 'a space',\n  text: 'the text \"{value}\"',\n  csAny: 'any character (except line breaks)',\n  csDigit: 'a digit (0-9)',\n  csDigitNeg: 'any non-digit',\n  csWord: 'a word character (letter, digit, or underscore)',\n  csWordNeg: 'a non-word character',\n  csSpace: 'a whitespace character',\n  csSpaceNeg: 'a non-whitespace character',\n  csProperty: 'a character with Unicode property {raw}',\n  classEmpty: 'nothing',\n  classEmptyNeg: 'any character',\n  classOneOf: 'one of: {parts}',\n  classExcept: 'any character except: {parts}',\n  listSep: ', ',\n  classExpr: 'a set-operation character class (see the diagram)',\n  anchorStart: 'the start of the string (or line with the m flag)',\n  anchorEnd: 'the end of the string (or line with the m flag)',\n  wordBoundary: 'a word boundary',\n  notWordBoundary: 'a position that is not a word boundary',\n  followedBy: 'followed by',\n  notFollowedBy: 'not followed by',\n  precededBy: 'preceded by',\n  notPrecededBy: 'not preceded by',\n  qStar: 'repeated zero or more times',\n  qPlus: 'repeated one or more times',\n  qMin: 'repeated {min} or more times',\n  qOptional: 'optional (zero or one time)',\n  qExact: 'repeated exactly {n} times',\n  qRange: 'repeated {min} to {max} times',\n  lazy: '{base} (lazy)',\n  groupNamed: 'capturing group #{index} (named \"{name}\")',\n  group: 'capturing group #{index}',\n  groupNonCapturing: 'a non-capturing group',\n  backref: 'a back-reference',\n  backrefTo: 'a back-reference to group #{index}',\n  option: 'option {n}',\n  withColon: '{text}:',\n}",{"id":958,"title":959,"titles":960,"content":961,"level":418},"\u002Flocalization#explaindesc","ExplainDesc",[879],"The description handed to formatExplain. Switch on kind if you want full\ncontrol instead of a table. \u002F\u002F (shape simplified; see the .d.ts for the exact discriminated unions)\ntype ExplainDesc =\n  | { kind: 'char', value: string }\n  | { kind: 'text', value: string }\n  | { kind: 'charset', set: 'any' | 'digit' | 'word' | 'space' | 'property', negate?: boolean, raw?: string }\n  | { kind: 'class', negate: boolean, members: ClassMember[] }\n  | { kind: 'anchor', at: 'start' | 'end' | 'word', negate?: boolean }\n  | { kind: 'lookaround', dir: 'ahead' | 'behind', negate: boolean }\n  | { kind: 'quantifier', min: number, max: number, greedy: boolean }\n  | { kind: 'group', capturing: boolean, index?: number, name?: string }\n  | { kind: 'backref', index?: number }\n  | { kind: 'option', n: number }\n  \u002F\u002F …and 'space' \u002F 'classExpr' html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"id":884,"title":883,"titles":963,"content":964,"level":64},[],"Recolor the diagram with --rr-* CSS variables.",{"id":966,"title":883,"titles":967,"content":968,"level":64},"\u002Ftheming#theming-and-colors",[],"Every rendered SVG is styled with --rr-* CSS custom properties and ships with\nlight-mode fallbacks baked in, so it looks right out of the box. To recolor it\nor add a dark theme, set the variables on any element that wraps the SVG — you\nonly override what you want to change, and nothing has to be re-rendered.",{"id":970,"title":971,"titles":972,"content":973,"level":418},"\u002Ftheming#syntax-palette","Syntax palette",[883],"One color per syntax category, shared by the source band, the syntax reference\nand the diagram's accents so a token reads the same color everywhere. These are\nthe --rr-syntax-* variables and their light-mode defaults. \u002F* The SVG ships with these light-mode defaults baked in; override only\n   the variables you want to change, on any element wrapping the SVG. *\u002F\n.regex-diagram {\n  --rr-syntax-literal: #3b82f6;     \u002F* a b 1            *\u002F\n  --rr-syntax-charset: #16a34a;     \u002F* \\d \\w .          *\u002F\n  --rr-syntax-class: #d97706;       \u002F* [a-z] [^0-9]     *\u002F\n  --rr-syntax-anchor: #8b5cf6;      \u002F* ^ $ \\b           *\u002F\n  --rr-syntax-quantifier: #c026d3;  \u002F* * + ? {n,m}      *\u002F\n  --rr-syntax-group: #e11d48;       \u002F* ( ) (?\u003Cname>     *\u002F\n  --rr-syntax-lookaround: #ea580c;  \u002F* (?= (?! (?\u003C=     *\u002F\n  --rr-syntax-backref: #0d9488;     \u002F* \\1 \\k\u003Cname>      *\u002F\n  --rr-syntax-alternation: #64748b; \u002F* a|b|c            *\u002F\n}",{"id":975,"title":976,"titles":977,"content":978,"level":418},"\u002Ftheming#structure-and-dark-mode","Structure and dark mode",[883],"Beyond the palette, these variables drive the rail, text and labels — most of\nwhat a dark theme needs — plus the source-band hover highlight. .dark .regex-diagram {\n  --rr-rail: #64748b;   \u002F* connecting rail            *\u002F\n  --rr-text: #e2e8f0;   \u002F* source band + box text     *\u002F\n  --rr-muted: #94a3b8;  \u002F* group \u002F class labels       *\u002F\n  --rr-group: #64748b;  \u002F* neutral group outline      *\u002F\n}\n\n\u002F* Source-band hover highlight: tint strength and glow spread. *\u002F\n.regex-diagram {\n  --rr-syntax-hl-opacity: 0.18;\n  --rr-syntax-glow: 8px;\n} html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sMMDD, html code.shiki .sMMDD{--shiki-light:#90A4AE;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sw1J6, html code.shiki .sw1J6{--shiki-light:#F76D47;--shiki-default:#D73A49;--shiki-dark:#F97583}",1782730712468]