1"use strict";(self.webpackChunkmeshtastic=self.webpackChunkmeshtastic||[]).push([["12201"],{37327(e,n,t){t.r(n),t.d(n,{metadata:()=>r,default:()=>u,frontMatter:()=>d,contentTitle:()=>l,toc:()=>h,assets:()=>c});var r=JSON.parse('{"id":"development/documentation/style-guides/markdown","title":"Markdown features","description":"MDX components and Docusaurus features available when writing Meshtastic documentation.","source":"@site/docs/development/documentation/style-guides/markdown-features.mdx","sourceDirName":"development/documentation/style-guides","slug":"/development/documentation/style-guides/markdown","permalink":"/docs/development/documentation/style-guides/markdown","draft":false,"unlisted":false,"editUrl":"https://github.com/meshtastic/meshtastic/edit/master/docs/development/documentation/style-guides/markdown-features.mdx","tags":[],"version":"current","lastUpdatedBy":"rcarteraz","sidebarPosition":2,"frontMatter":{"id":"markdown","title":"Markdown features","sidebar_label":"Markdown Features","sidebar_position":2,"description":"MDX components and Docusaurus features available when writing Meshtastic documentation."},"sidebar":"Sidebar","previous":{"title":"Writing Style","permalink":"/docs/development/documentation/style-guides/writing-style"},"next":{"title":"Config Pages","permalink":"/docs/development/documentation/style-guides/config-pages"}}'),s=t(91987),a=t(67008),i=t(87622),o=t(79310);let d={id:"markdown",title:"Markdown features",sidebar_label:"Markdown Features",sidebar_position:2,description:"MDX components and Docusaurus features available when writing Meshtastic documentation."},l,c={},h=[{value:"Code blocks",id:"code-blocks",level:2},{value:"Client tabs",id:"client-tabs",level:2},{value:"Light and dark variants",id:"light-and-dark-variants",level:2},{value:"Diagrams",id:"diagrams",level:2},{value:"Glossary terms",id:"glossary-terms",level:2},{value:"Shared partials",id:"shared-partials",level:2},{value:"Admonitions",id:"admonitions",level:2}];function m(e){let n={a:"a",code:"code",h2:"h2",mermaid:"mermaid",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["Pages are MDX, which is Markdown that can import and use React components. This page covers what is available here. ",(0,s.jsx)(n.a,{href:"/docs/development/documentation/style-guides/writing-style",children:"Writing style"})," covers when to reach for each one."]}),"\n",(0,s.jsx)(n.h2,{id:"code-blocks",children:"Code blocks"}),"\n",(0,s.jsxs)(n.p,{children:["Tag the language directly after the opening fence. Use ",(0,s.jsx)(n.code,{children:"shell"})," for command-line examples rather than ",(0,s.jsx)(n.code,{children:"bash"}),", ",(0,s.jsx)(n.code,{children:"sh"}),", or ",(0,s.jsx)(n.code,{children:"console"}),", so command blocks render the same everywhere."]}),"\n",(0,s.jsxs)(n.p,{children:["Add ",(0,s.jsx)(n.code,{children:'title="..."'})," where the block needs a label, such as a file name."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'```ts title="Demo"\nexport const typedArrayToBuffer = (array: Uint8Array): ArrayBuffer => {\n return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset);\n};\n```\n'})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'title="Demo"',children:"export const typedArrayToBuffer = (array: Uint8Array): ArrayBuffer => {\n return array.buffer.slice(\n array.byteOffset,\n array.byteLength + array.byteOffset,\n );\n};\n"})}),"\n",(0,s.jsx)(n.h2,{id:"client-tabs",children:"Client tabs"}),"\n",(0,s.jsxs)(n.p,{children:["Per-client instructions go in tabs. Keep the platform order the same on every page, with the ",(0,s.jsx)(i.A,{term:"CLI",definition:"A text-based interface used for interacting with software or devices like Meshtastic.",routePath:"/docs/terms/",children:"CLI"})," first where it exists. Give each tab a heading one level deeper than the section containing the tab block."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-mdx",children:"import Tabs from \"@theme/Tabs\";\nimport TabItem from \"@theme/TabItem\";\n\n<Tabs\ngroupId=\"settings\"\ndefaultValue=\"cli\"\nvalues={[\n{label: 'CLI', value: 'cli'},\n{label: 'Android', value: 'android'},\n{label: 'iOS', value: 'iOS'},\n{label: 'Web', value: 'web'},\n]}>\n<TabItem value=\"cli\">\n\n#### CLI\n\nCLI instructions here\n\n</TabItem>\n</Tabs>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Markdown inside a ",(0,s.jsx)(n.code,{children:"TabItem"})," needs a blank line above and below it, or it renders as literal text rather than as a heading."]}),"\n",(0,s.jsxs)(n.p,{children:["A shared ",(0,s.jsx)(n.code,{children:"groupId"})," keeps a reader's choice selected as they move between pages."]}),"\n",(0,s.jsx)(n.h2,{id:"light-and-dark-variants",children:"Light and dark variants"}),"\n",(0,s.jsx)(n.p,{children:"Use these components where a screenshot or a diagram only reads correctly in one color mode. Ship both variants rather than one."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { Dark, Light } from "@site/src/components/ColorMode";\n\n<Dark>\n <p>
1Only shown in dark mode.</p>\n</Dark>\n<Light>\n <p>Only shown in light mode.</p>\n</Light>\n'})}),"\n",(0,s.jsx)(o.F,{children:(0,s.jsx)("div",{className:"not-prose rounded-lg bg-primary shadow-md",children:(0,s.jsx)("p",{className:"p-2 text-lg font-medium",children:"This is only shown in dark mode."})})}),"\n",(0,s.jsx)(o.v,{children:(0,s.jsx)("div",{className:"not-prose rounded-lg border bg-primary shadow-md",children:(0,s.jsx)("p",{className:"p-2 text-lg font-medium",children:"This is only shown in light mode."})})}),"\n",(0,s.jsx)(n.h2,{id:"diagrams",children:"Diagrams"}),"\n",(0,s.jsxs)(n.p,{children:["Mermaid is enabled site-wide, so a fenced ",(0,s.jsx)(n.code,{children:"mermaid"})," block renders as a diagram with no import. Prefer it over a raster image: it stays sharp, diffs cleanly in review, and its text stays selectable and translatable."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"```mermaid\ngraph LR\n A[Node A] --\x3e|relays| B[Node B]\n B --\x3e|relays| C[Node C]\n```\n"})}),"\n",(0,s.jsx)(n.mermaid,{value:"graph LR\n A[Node A] --\x3e|relays| B[Node B]\n B --\x3e|relays| C[Node C]"}),"\n",(0,s.jsx)(n.p,{children:"Diagrams need to stay legible in both color modes, so don't rely on a light page background for contrast."}),"\n",(0,s.jsx)(n.h2,{id:"glossary-terms",children:"Glossary terms"}),"\n",(0,s.jsxs)(n.p,{children:["Terms defined in ",(0,s.jsx)(n.code,{children:"glossary/glossary.json"})," link to the ",(0,s.jsx)(n.a,{href:"/docs/terms/",children:"glossary"})," and show their definition on hover, across the whole site. Add a term by adding an entry."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "term": "ADC",\n "abbreviation": "Analog-to-Digital Converter",\n "definition": "A circuit that turns a varying voltage into a digital value."\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Set ",(0,s.jsx)(n.code,{children:'"autoLink": false'})," on a term that is too common to link on every appearance. Automatic acronym expansion is off, because it rewrites authored prose and produces doubled expansions."]}),"\n",(0,s.jsx)(n.p,{children:"A glossary entry doesn't replace expanding an acronym on first use on a page. Readers arrive from search, and hover text is unavailable on touch devices and to some screen readers."}),"\n",(0,s.jsx)(n.h2,{id:"shared-partials",children:"Shared partials"}),"\n",(0,s.jsxs)(n.p,{children:["Content reused across pages lives in ",(0,s.jsx)(n.code,{children:"docs/blocks"})," with a leading underscore, which keeps it from becoming a page of its own. Import it where it's needed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import QRCode from "@site/docs/blocks/_qr-code.mdx";\n\n<QRCode />;\n'})}),"\n",(0,s.jsx)(n.p,{children:"Use a partial where the same fact belongs on several pages. Editing it once keeps the copies from drifting."}),"\n",(0,s.jsx)(n.h2,{id:"admonitions",children:"Admonitions"}),"\n",(0,s.jsxs)(n.p,{children:["Docusaurus supports ",(0,s.jsx)(n.code,{children:":::note"}),", ",(0,s.jsx)(n.code,{children:":::info"}),", ",(0,s.jsx)(n.code,{children:":::tip"}),", ",(0,s.jsx)(n.code,{children:":::warning"}),", and ",(0,s.jsx)(n.code,{children:":::danger"}),". They are heavily overused across this site, so read the ",(0,s.jsx)(n.a,{href:"/docs/development/documentation/style-guides/writing-style#admonitions",children:"admonition rules"})," before adding one. Body text is the default home for the information."]}),"\n",(0,s.jsxs)(n.p,{children:["Write ",(0,s.jsx)(n.code,{children:"warning"})," and ",(0,s.jsx)(n.code,{children:"info"})," rather than the deprecated ",(0,s.jsx)(n.code,{children:"caution"})," and ",(0,s.jsx)(n.code,{children:"important"})," aliases."]})]})}function u(e={}){let{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(m,{...e})}):m(e)}},79310(e,n,t){t.d(n,{F:()=>s,v:()=>a});var r=t(91987);let s=({children:e})=>(0,r.jsx)("div",{className:"hideLight",children:e}),a=({children:e})=>(0,r.jsx)("div",{className:"hideDark",children:e})},67008(e,n,t){t.d(n,{R:()=>i,x:()=>o});var r=t(71763);let s={},a=r.createContext(s);function i(e){let n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:n},e.children)}},87622(e,n,t){t.d(n,{A:()=>i});var r=t(71763),s=t(37773),a=t(91987);function i({term:e,definition:n,abbreviation:t,routePath:o="/glossary",children:d}){let[l,c]=(0,r.useState)(!1),[h,m]=(0,r.useState)(null),[u,p]=(0,r.useState)("top"),g=(0,r.useRef)(null),f=(0,r.useRef)(null),x=(0,r.useCallback)(()=>{let e;if(!g.current||!f.current)return;let n=g.current.getBoundingClientRect(),t=f.current.getBoundingClientRect(),r=window.innerWidth,s=window.innerHeight,a=document.querySelector(".navbar"),i=a?a.getBoundingClientRect().bottom:0,o=n.top-i>=t.height+8,d=s-n.bottom>=t.height+8,l=o||!d?"top":"bottom";e="top"===l?n.top-t.height-8:n.bottom+8;let c=n.left+n.width/2-t.width/2;c=Math.max(8,Math.min(c,r-t.width-8)),p(l),m({top:Math.max(i+4,e),left:c})},[]);(0,r.useEffect)(()=>{let e;if(!l)return;let n=requestAnimationFrame(()=>{e=requestAnimationFrame(()=>{x()})}),t=()=>x(),r=()=>x();return window.addEventListener("scroll",t,!0),window.addEventListener("resize",r),()=>{cancelAnimationFrame(n),e&&cancelAnimationFrame(e),window.removeEventListener("scroll",t,!0),window.removeEventListener("resize",r)}},[l,x]);let b=(0,s.P_)("docusaurus-plugin-glossary"),y=(0,r.useMemo)(()=>
1{if(n&&"string"==typeof n&&n.length>0)return n;let t=(b&&b.terms||[]).find(n=>"string"==typeof n.term&&n.term.toLowerCase()===String(e).toLowerCase());return t&&t.definition?t.definition:void 0},[n,b,e]),v=(0,r.useMemo)(()=>{let n=t;if(!n){let t=(b&&b.terms||[]).find(n=>"string"==typeof n.term&&n.term.toLowerCase()===String(e).toLowerCase());n=t&&t.abbreviation}if("string"!=typeof n)return;let r=n.trim();if(r&&r.toLowerCase()!==String(e).toLowerCase())return r},[t,b,e]),j=(0,r.useMemo)(()=>o&&"string"==typeof o&&o.length>0?o:b&&b.routePath||"/glossary",[b,o]),w=d||e,k=e.toLowerCase().replace(/\s+/g,"-");return(0,a.jsxs)("span",{ref:g,className:"glossaryTermWrapper_ud7W",children:[(0,a.jsx)("a",{href:`${j}#${k}`,className:"glossaryTerm_x2nJ",onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),onFocus:()=>c(!0),onBlur:()=>c(!1),"aria-describedby":`tooltip-${k}`,children:w}),y&&(0,a.jsxs)("span",{ref:f,id:`tooltip-${k}`,className:`tooltip_WjgA ${l?"tooltipVisible_AjfD":""} ${"top"===u?"tooltipTop_uMN4":"tooltipBottom_U9P5"} tooltipFloating_nLk7`,role:"tooltip",style:l&&h?{top:`${h.top}px`,left:`${h.left}px`}:void 0,children:[(0,a.jsx)("strong",{children:e}),v?` (${v}). `:"",y]})]})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.