mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-09-24 04:35:10 -04:00
2 lines
39 KiB
HTML
2 lines
39 KiB
HTML
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <link rel="stylesheet" href="/Meshtastic-Android/main/assets/css/just-the-docs-default.css"> <link rel="stylesheet" href="/Meshtastic-Android/main/assets/css/just-the-docs-head-nav.css" id="jtd-head-nav-stylesheet"> <style id="jtd-nav-activation"> .site-nav > ul.nav-list:first-child > li > a, .site-nav > ul.nav-list:first-child > li > ul > li:not(:nth-child(11)) > a, .site-nav > ul.nav-list:first-child > li > ul > li > ul > li a { background-image: none; } .site-nav > ul.nav-list:not(:first-child) a, .site-nav li.external a { background-image: none; } .site-nav > ul.nav-list:first-child > li:nth-child(4) > ul > li:nth-child(11) > a { font-weight: 600; text-decoration: none; }.site-nav > ul.nav-list:first-child > li:nth-child(4) > button svg, .site-nav > ul.nav-list:first-child > li:nth-child(4) > ul > li:nth-child(11) > button svg { transform: rotate(-90deg); }.site-nav > ul.nav-list:first-child > li.nav-list-item:nth-child(4) > ul.nav-list, .site-nav > ul.nav-list:first-child > li.nav-list-item:nth-child(4) > ul.nav-list > li.nav-list-item:nth-child(11) > ul.nav-list { display: block; } </style> <script src="/Meshtastic-Android/main/assets/js/vendor/lunr.min.js"></script> <script src="/Meshtastic-Android/main/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Begin Jekyll SEO tag v2.9.0 --> <title>Documentation Style | Meshtastic Android</title> <meta name="generator" content="Jekyll v4.4.1" /> <meta property="og:title" content="Documentation Style" /> <meta property="og:locale" content="en_US" /> <meta name="description" content="How this repository’s docs work, and the one prose rule the Meshtastic design standards leave to us." /> <meta name="twitter:description" property="og:description" content="How this repository’s docs work, and the one prose rule the Meshtastic design standards leave to us." /> <link rel="canonical" href="/Meshtastic-Android/main/en/developer/documentation-style.html" /> <meta property="og:url" content="/Meshtastic-Android/main/en/developer/documentation-style.html" /> <meta property="og:site_name" content="Meshtastic Android" /> <meta property="og:type" content="website" /> <meta name="twitter:card" content="summary" /> <meta name="twitter:title" content="Documentation Style" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","description":"How this repository’s docs work, and the one prose rule the Meshtastic design standards leave to us.","headline":"Documentation Style","url":"/Meshtastic-Android/main/en/developer/documentation-style.html"}</script> <!-- End Jekyll SEO tag --> <!-- Inter font from Google Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> <style> /* M3-inspired typography */ :root { --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; --font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', ui-monospace, monospace; } body, .site-title, .search-input { font-family: var(--font-sans) !important; } code, pre, .highlight { font-family: var(--font-mono) !important; font-size: 0.875em; } /* M3 surface elevation & rounding */ .main-content table { border-radius: 12px; overflow: hidden; } .main-content blockquote { border-radius: 12px; padding: 1rem 1.25rem; border-left-width: 4px; } .main-content pre { border-radius: 12px; } .main-content code { border-radius: 6px; padding: 0.15em 0.4em; } /* Smooth transitions for theme switching */ body, .side-bar, .main, .main-content, .site-header, .search-input, .search-results, a { transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; } /* Theme toggle button styling */ .theme-toggle { background: none; border: 1px solid var(--border-color, #D5D6E0); border-radius: 20px; padding: 6px 12px; cursor: pointer; font-family: var(--font-sans); font-size: 0.75rem; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; color: inherit; margin: 0 auto; transition: background-color 0.2s ease, border-color 0.2s ease; } .theme-toggle:hover { background-color: rgba(128, 128, 128, 0.1); } .theme-toggle-wrap { text-align: center; padding: 12px 0 4px; } /* Heading weight refinement */ h1, h2, h3, h4, h5, h6 { font-weight: 600; letter-spacing: -0.01em; } h1 { font-weight: 700; letter-spacing: -0.02em; } /* Smooth anchor scroll */ html { scroll-behavior: smooth; } /* Language switcher */ .language-switcher { display: inline-block; position: relative; margin-left: 8px; } .language-switcher-btn { cursor: pointer; font-size: 0.8rem; font-weight: 500; font-family: var(--font-sans); list-style: none; padding: 4px 10px; border: 1px solid var(--border-color, #D5D6E0); border-radius: 16px; display: inline-flex; align-items: center; gap: 4px; transition: background-color 0.2s ease; } .language-switcher-btn:hover { background-color: rgba(128, 128, 128, 0.1); } .language-switcher[open] .language-switcher-list { display: block; } .language-switcher-list { position: absolute; top: 100%; right: 0; left: auto; z-index: 100; list-style: none; padding: 8px 0; margin: 4px 0 0; min-width: 140px; background: var(--body-background-color, #fff); border: 1px solid var(--border-color, #D5D6E0); border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .language-switcher-list li { padding: 0; } .language-switcher-list a { display: block; padding: 6px 16px; text-decoration: none; font-size: 0.85rem; color: inherit; } .language-switcher-list a:hover { background-color: rgba(103, 234, 148, 0.15); } /* Version switcher (shares the language-switcher dropdown styling) */ .version-switcher { margin-left: 8px; } .version-switcher[hidden] { display: none; } /* Link out to the upstream meshtastic.org docs */ .upstream-docs-link { display: inline-flex; align-items: center; margin-left: 8px; padding: 4px 10px; border: 1px solid var(--border-color, #D5D6E0); border-radius: 16px; font-size: 0.8rem; font-weight: 500; font-family: var(--font-sans); text-decoration: none; color: inherit; transition: background-color 0.2s ease; } .upstream-docs-link:hover { background-color: rgba(128, 128, 128, 0.1); } </style> <script> // Respect OS preference on first visit, then remember user choice (function() { var stored = localStorage.getItem('jtd-theme'); if (stored) return; // will be applied by jtd.setTheme below if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { localStorage.setItem('jtd-theme', 'meshtastic-dark'); } })(); </script> </head> <body> <a class="skip-to-main" href="#main-content">Skip to main content</a> <svg xmlns="http://www.w3.org/2000/svg" class="d-none"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <!-- Feather. MIT License: https://github.com/feathericons/feather/blob/master/LICENSE --> <symbol id="svg-external-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"> <title id="svg-external-link-title">(external link)</title> <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <!-- Bootstrap Icons. MIT License: https://github.com/twbs/icons/blob/main/LICENSE.md --> <symbol id="svg-copy" viewBox="0 0 16 16"> <title>Copy</title> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16"> <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/> <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/> </svg> </symbol> <symbol id="svg-copied" viewBox="0 0 16 16"> <title>Copied</title> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard-check-fill" viewBox="0 0 16 16"> <path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/> <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/> </svg> </symbol> </svg> <header class="side-bar"> <div class="site-header"> <a href="/Meshtastic-Android/main/" class="site-title lh-tight"> Meshtastic Android </a> <button id="menu-button" class="site-button btn-reset" aria-label="Menu" aria-expanded="false"> <svg viewBox="0 0 24 24" class="icon" aria-hidden="true"><use xlink:href="#svg-menu"></use></svg> </button> </div> <nav aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/" class="nav-list-link">Home</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/" class="nav-list-link">Home</a></li><li class="nav-list-item"><button class="nav-list-expander btn-reset" aria-label="User Guide submenu" aria-expanded="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/Meshtastic-Android/main/en/user.html" class="nav-list-link">User Guide</a><ul class="nav-list"><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/onboarding.html" class="nav-list-link">Getting Started</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/onboarding.html" class="nav-list-link">Getting Started</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/connections.html" class="nav-list-link">Connections</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/connections.html" class="nav-list-link">Connexions</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/messages-and-channels.html" class="nav-list-link">Messages & Channels</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/messages-and-channels.html" class="nav-list-link">Messages & Channels</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/nodes.html" class="nav-list-link">Nodes</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/nodes.html" class="nav-list-link">Nœuds</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/node-metrics.html" class="nav-list-link">Node Metrics</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/node-metrics.html" class="nav-list-link">Node Metrics</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/map-and-waypoints.html" class="nav-list-link">Map & Waypoints</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/map-and-waypoints.html" class="nav-list-link">Map & Waypoints</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/settings-radio-user.html" class="nav-list-link">Settings — Radio & User</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/settings-radio-user.html" class="nav-list-link">Settings — Radio & User</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/settings-module-admin.html" class="nav-list-link">Settings — Modules & Admin</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/settings-module-admin.html" class="nav-list-link">Settings — Modules & Admin</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/telemetry-and-sensors.html" class="nav-list-link">Telemetry & Sensors</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/telemetry-and-sensors.html" class="nav-list-link">Telemetry & Sensors</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/tak.html" class="nav-list-link">TAK Integration</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/tak.html" class="nav-list-link">TAK Integration</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/mqtt.html" class="nav-list-link">MQTT</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/mqtt.html" class="nav-list-link">MQTT</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/discovery.html" class="nav-list-link">Local Mesh Discovery</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/discovery.html" class="nav-list-link">Découverte de maille locale</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/firmware.html" class="nav-list-link">Firmware Updates</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/firmware.html" class="nav-list-link">Firmware Updates</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/desktop.html" class="nav-list-link">Desktop App</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/desktop.html" class="nav-list-link">Desktop App</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/signal-meter.html" class="nav-list-link">How the Meshtastic Signal Meter Works</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/signal-meter.html" class="nav-list-link">How the Meshtastic Signal Meter Works</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/units-and-locale.html" class="nav-list-link">Units, Measurement & Locale</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/units-and-locale.html" class="nav-list-link">Units, Measurement & Locale</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/translate.html" class="nav-list-link">Translate the App</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/fr-rCA/user/translate.html" class="nav-list-link">Translate the App</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/app-functions.html" class="nav-list-link">App Functions</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/widget.html" class="nav-list-link">Home Screen Widget</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/help-and-docs.html" class="nav-list-link">Help & In-App Docs</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/user/debug-logs.html" class="nav-list-link">Debug Logs</a></li></ul></li><li class="nav-list-item"><button class="nav-list-expander btn-reset" aria-label="Developer Guide submenu" aria-expanded="false"> <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg> </button><a href="/Meshtastic-Android/main/en/developer.html" class="nav-list-link">Developer Guide</a><ul class="nav-list"><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/architecture.html" class="nav-list-link">Architecture</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/codebase.html" class="nav-list-link">Codebase</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/adding-a-feature-module.html" class="nav-list-link">Adding a Feature Module</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/navigation-and-deep-links.html" class="nav-list-link">Navigation & Deep Links</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/transport.html" class="nav-list-link">Transport</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/persistence.html" class="nav-list-link">Persistence</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/testing.html" class="nav-list-link">Testing</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/contributing.html" class="nav-list-link">Contributing</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/measurement.html" class="nav-list-link">Measurement & Formatting</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/test-builds.html" class="nav-list-link">Test Builds & Obtainium</a></li><li class="nav-list-item"><a href="/Meshtastic-Android/main/en/developer/documentation-style.html" class="nav-list-link">Documentation Style</a></li></ul></li></ul> </nav> <div class="d-md-block d-sm-none"> <div class="site-footer"> This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </div> </div> </header> <div class="main" id="top"> <div id="main-header" class="main-header"> <div class="search" role="search"> <div class="search-input-wrap"> <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search Meshtastic Android" autocomplete="off"> <label for="search-input" class="search-label"> <span class="sr-only">Search Meshtastic Android</span> <svg viewBox="0 0 24 24" class="search-icon" aria-hidden="true"><use xlink:href="#svg-search"></use></svg> </label> </div> <div id="search-results" class="search-results"></div> </div> <div class="theme-toggle-wrap"> <button class="theme-toggle" id="theme-toggle" aria-label="Toggle dark mode" title="Toggle light/dark theme" onclick="toggleMeshtasticTheme()"> <span id="theme-icon">🌙</span> <span id="theme-label">Dark</span> </button> <details class="language-switcher version-switcher" id="version-switcher" aria-label="Documentation version" hidden> <summary class="language-switcher-btn" title="Switch documentation version"> 🏷️ <span id="version-current"></span> </summary> <ul class="language-switcher-list" id="version-switcher-list"></ul> </details> <script> (function() { var baseurl = '/Meshtastic-Android/main'; var root = baseurl; var channel = 'latest'; // /main/, /vX.Y.Z/ or a prerelease snapshot like /v2.8.0-open.1/. var match = baseurl.match(/^(.*)\/(main|v\d+\.\d+\.\d+(?:-(?:open|closed)\.\d+)?)$/); if (match) { root = match[1]; channel = match[2]; } fetch(root + '/versions.json') .then(function(res) { return res.ok ? res.json() : Promise.reject(); }) .then(function(data) { var switcher = document.getElementById('version-switcher'); var list = document.getElementById('version-switcher-list'); var current = document.getElementById('version-current'); if (!switcher || !list || !current) return; // Keep the reader on the same page when switching channels; a page // that doesn't exist in the target version lands on the 404 page. var relativePath = location.pathname.slice(baseurl.length) + location.hash; var entries = []; if (data.latest) { entries.push({ id: 'latest', label: 'latest (v' + data.latest + ')', base: root }); } // Prereleases are documented ahead of general availability, so the track // is always spelled out — a reader must not mistake a closed-testing // snapshot for a shipped release. (data.prereleases || []).forEach(function(p) { entries.push({ id: p.dir, label: p.dir.replace(/^v/, 'v') + ' — ' + p.track + ' testing', base: root + '/' + p.dir }); }); if (data.hasMain) { entries.push({ id: 'main', label: 'main (unreleased snapshot)', base: root + '/main' }); } (data.versions || []).forEach(function(v) { entries.push({ id: 'v' + v, label: 'v' + v, base: root + '/v' + v }); }); var currentEntry = entries.filter(function(e) { return e.id === channel; })[0]; current.textContent = currentEntry ? currentEntry.label : channel; var others = entries.filter(function(e) { return e.id !== channel; }); if (others.length === 0) return; others.forEach(function(e) { var li = document.createElement('li'); var a = document.createElement('a'); a.href = e.base + relativePath; a.textContent = e.label; li.appendChild(a); list.appendChild(li); }); switcher.hidden = false; }) .catch(function() { /* no manifest (local build) — leave switcher hidden */ }); })(); </script> <a class="upstream-docs-link" href="https://meshtastic.org/docs/" title="Official Meshtastic documentation (meshtastic.org)">Meshtastic Docs ↗</a> </div> <script> function toggleMeshtasticTheme() { var current = localStorage.getItem('jtd-theme') || 'meshtastic'; var next = (current === 'meshtastic-dark') ? 'meshtastic' : 'meshtastic-dark'; if (typeof jtd !== 'undefined' && typeof jtd.setTheme === 'function') { jtd.setTheme(next); } localStorage.setItem('jtd-theme', next); var icon = document.getElementById('theme-icon'); var label = document.getElementById('theme-label'); if (icon && label) { icon.textContent = (next === 'meshtastic-dark') ? '☀️' : '🌙'; label.textContent = (next === 'meshtastic-dark') ? 'Light' : 'Dark'; } } // Apply stored/OS theme on page load (function() { var theme = localStorage.getItem('jtd-theme') || 'meshtastic'; // Sync toggle label immediately var icon = document.getElementById('theme-icon'); var label = document.getElementById('theme-label'); if (icon && label) { icon.textContent = (theme === 'meshtastic-dark') ? '☀️' : '🌙'; label.textContent = (theme === 'meshtastic-dark') ? 'Light' : 'Dark'; } // Apply theme once jtd is ready function tryApply() { if (typeof jtd !== 'undefined' && typeof jtd.setTheme === 'function') { jtd.setTheme(theme); } else { setTimeout(tryApply, 50); } } tryApply(); })(); </script> </div> <div class="main-content-wrap"> <nav aria-label="Breadcrumb" class="breadcrumb-nav"> <ol class="breadcrumb-nav-list"> <li class="breadcrumb-nav-list-item"><a href="/Meshtastic-Android/main/en/developer.html">Developer Guide</a></li> <li class="breadcrumb-nav-list-item"><span>Documentation Style</span></li> </ol> </nav> <div id="main-content" class="main-content"> <main> <h1 id="documentation-style"> <a href="#documentation-style" class="anchor-heading" aria-labelledby="documentation-style"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Documentation Style </h1> <p>Section 11 of the <a href="https://github.com/meshtastic/design/tree/master/standards">Meshtastic Client Design Standards</a> is the style guide for everything under <code class="language-plaintext highlighter-rouge">docs/en/</code>. Read it first. It decides voice, plain language, terminology, page structure, instructions, cross-platform coverage, code and CLI examples, media, accessibility, admonition use, units, translation, versioning, and in-product text, and it closes with a checklist of the rules a reviewer can check without judgment.</p> <p>This page carries what Section 11 doesn’t: how documentation works in this repository, two forms that differ here, and the one prose rule the standards leave open. Where the two ever disagree on something not listed here, Section 11 wins and this page is wrong.</p> <p>Pages under <code class="language-plaintext highlighter-rouge">docs/en/</code> ship to three places — the in-app docs browser, the GitHub Pages site, and meshtastic.org — so one page has to read well in all of them, and its English source is the translation base for 40+ locales on Crowdin. Section 11.1 describes the sync: user pages land in <code class="language-plaintext highlighter-rouge">docs/software/android/</code> on the documentation site weekly, taken from the latest release, and pull requests against those paths there are reverted.</p> <p>Rules keep the IDs they had so review feedback and audit findings can still cite them. Rules that Section 11 now covers are retired, and their IDs aren’t reused.</p> <h2 id="in-transition"> <a href="#in-transition" class="anchor-heading" aria-labelledby="in-transition"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> In transition </h2> <p>Two rules changed when Section 11 landed. Neither is a sweep.</p> <ul> <li><strong>Headings are sentence case</strong> (11.5, and a quick check in 11.16). Existing Title Case headings stay until the page is edited for another reason. Re-casing a heading invalidates its translation memory across 40+ locales, so it happens as pages are touched and never as a pass of its own. Frontmatter <code class="language-plaintext highlighter-rouge">title</code> values are the nav labels the in-app browser and the site share, so they change with the rest of the nav rather than one page at a time.</li> <li><strong>The hardware is a node</strong> (11.4). This repo used <em>radio</em> to disambiguate the hardware from the phone, and roughly 300 uses of it remain. Prefer <em>node</em> in new writing and drop <em>radio</em> when you edit a page. <em>Phone</em> still means the Android handset the app runs on, which Section 11 has no word for.</li> </ul> <h2 id="repository-mechanics"> <a href="#repository-mechanics" class="anchor-heading" aria-labelledby="repository-mechanics"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Repository mechanics </h2> <ul> <li><strong>STRUCT-1</strong> — Complete frontmatter on every page, user <em>and</em> developer: <code class="language-plaintext highlighter-rouge">title</code>, <code class="language-plaintext highlighter-rouge">parent</code>, <code class="language-plaintext highlighter-rouge">nav_order</code>, <code class="language-plaintext highlighter-rouge">last_updated</code> (bump it whenever content changes — CI checks freshness), <code class="language-plaintext highlighter-rouge">description</code> (one sentence, ~160 characters, used by search and link previews), and <code class="language-plaintext highlighter-rouge">aliases</code> (search terms the in-app browser resolves).</li> <li><strong>HEAD-2</strong> — One <code class="language-plaintext highlighter-rouge">#</code> H1 per page, and it matches the frontmatter <code class="language-plaintext highlighter-rouge">title</code> exactly. The in-app index is built from the frontmatter, so a mismatch shows the reader two different titles for one page.</li> <li><strong>STRUCT-3</strong> — User pages end with a <code class="language-plaintext highlighter-rouge">## Related Topics</code> section: bulleted links, each with an em-dash clause saying why you’d go there. The heading is a fixed section name shared by 22 pages, so like a frontmatter <code class="language-plaintext highlighter-rouge">title</code> it stays Title Case until they all change together.</li> <li><strong>STRUCT-4</strong> — No horizontal rules (<code class="language-plaintext highlighter-rouge">---</code>) in page bodies, and especially not at the end of the file — the site layout adds its own footer rule, so a trailing <code class="language-plaintext highlighter-rouge">---</code> renders as a doubled line.</li> <li><strong>STRUCT-5</strong> — New pages must be registered in <code class="language-plaintext highlighter-rouge">DocBundleLoader.kt</code> (the in-app index) — CI fails in both directions if the page and the index disagree.</li> <li><strong>STRUCT-6</strong> — Notable page changes get a <em>What’s New</em> entry at the top of <code class="language-plaintext highlighter-rouge">user.md</code> or <code class="language-plaintext highlighter-rouge">developer.md</code>, in the format the HTML comment there specifies.</li> <li><strong>IMG-1</strong> — Reference screenshots by relative path from <code class="language-plaintext highlighter-rouge">docs/assets/screenshots/</code>: <code class="language-plaintext highlighter-rouge">../../assets/screenshots/<page>_<subject>.png</code>. Both the Docusaurus sync and the in-app renderer anchor on the <code class="language-plaintext highlighter-rouge">assets/</code> segment, so this one form works in all three consumers.</li> <li><strong>LINK-2</strong> — Sibling pages link by bare slug (<code class="language-plaintext highlighter-rouge">connections</code>), cross-section by relative path (<code class="language-plaintext highlighter-rouge">../developer/testing</code>). <code class="language-plaintext highlighter-rouge">scripts/validate-doc-links.js</code> enforces resolvability.</li> <li><strong>LINK-3</strong> — Node-side concepts (LoRa presets, firmware regions, MQTT topics) link out to the <a href="https://meshtastic.org/docs/">meshtastic.org docs</a> rather than being re-explained here. One source drifts less than two.</li> <li><strong>CODE-1</strong> — Code font for module paths (<code class="language-plaintext highlighter-rouge">core:ble</code>), Gradle tasks, class and function names, and setting keys, alongside the cases 11.8 covers.</li> <li><strong>DEV-1</strong> — Developer pages assume Kotlin, Gradle, and Android fluency and skip the reassurance, but every rule on this page and in Section 11 still applies. Terse is good; cryptic is not.</li> <li><strong>DEV-3</strong> — Structural or procedural changes get a <em>What’s New for Developers</em> entry in <code class="language-plaintext highlighter-rouge">developer.md</code>.</li> </ul> <h2 id="local-forms"> <a href="#local-forms" class="anchor-heading" aria-labelledby="local-forms"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Local forms </h2> <p>Two forms differ from Section 11. The first is a renderer requirement. The second is the entrenched house form, kept because changing it would touch every page for no reader benefit.</p> <ul> <li> <p><strong>ADMON-1</strong> — Admonitions are a blockquote starting with an emoji and a bold label, from this closed set. The in-app renderer has no admonition component, so <code class="language-plaintext highlighter-rouge">:::note</code> would reach the reader as literal text. Section 11.11 exempts synced client documentation for exactly this reason and leaves the form to this guide; its rules on <em>when</em> to use one still apply in full, including at most one per H2 section.</p> <div class="table-wrapper"><table> <thead> <tr> <th>Admonition</th> <th>Use for</th> </tr> </thead> <tbody> <tr> <td><code class="language-plaintext highlighter-rouge">> 💡 **Tip:**</code></td> <td>An optional shortcut or non-obvious alternative. The reader loses nothing by skipping it.</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">> ℹ️ **Note:**</code></td> <td>Supplementary information worth knowing but not required for the task.</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">> ⚠️ **Important:**</code></td> <td>Information essential to completing the task correctly, without danger of loss.</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">> ⚠️ **Warning:**</code></td> <td>Risk of data loss, lockout, or hardware damage. Must come <em>before</em> the action it applies to.</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">> 🔒 **Privacy:**</code></td> <td>What data leaves the phone, who on the mesh can see it, and how to limit it.</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">> 🔒 **Security:**</code></td> <td>Cryptographic caveats — key handling, unencrypted channels, admin access.</td> </tr> </tbody> </table></div> <p>Privacy and Security are house labels with no equivalent upstream. They exist because the app’s constitution makes privacy a core principle, and they shouldn’t be flattened into Note.</p> </li> <li> <p><strong>PROC-2</strong> — Menu paths use a spaced arrow between bold labels: <strong>Settings → Permissions</strong>. Never <code class="language-plaintext highlighter-rouge">></code> or <code class="language-plaintext highlighter-rouge">›</code>. Section 11.6 writes the separator as <code class="language-plaintext highlighter-rouge">></code> in its example; the arrow is this corpus’s established form, unambiguous in Markdown, and it reads naturally in the in-app renderer.</p> </li> </ul> <h2 id="prose-rules-section-11-leaves-open"> <a href="#prose-rules-section-11-leaves-open" class="anchor-heading" aria-labelledby="prose-rules-section-11-leaves-open"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Prose rules Section 11 leaves open </h2> <p>One rule. <a href="https://github.com/meshtastic/design/pull/154">design#154</a> moved the rest into Section 11, where they read the same, so nothing about how you write changes — the rules have one home rather than two that can drift apart.</p> <ul> <li><strong>LANG-7</strong> — Em dashes are spaced — like this — matching the entire existing corpus. Section 11 doesn’t mention them.</li> </ul> <p>These are retired, with the section that owns each. Their IDs aren’t reused.</p> <div class="table-wrapper"><table> <thead> <tr> <th>Retired rule</th> <th>Section</th> </tr> </thead> <tbody> <tr> <td>VOICE-2 — contractions, and <em>do not</em> in warnings</td> <td>11.2</td> </tr> <tr> <td>LANG-3 — requirement words</td> <td>11.3</td> </tr> <tr> <td>LANG-4 — <em>e.g.</em> and <em>i.e.</em></td> <td>11.3</td> </tr> <tr> <td>LANG-6 — inclusive, literal language</td> <td>11.3</td> </tr> <tr> <td>LANG-7 — the Oxford comma half; the em dash stays</td> <td>11.3</td> </tr> <tr> <td>LANG-1 — American spelling</td> <td>11.4</td> </tr> <tr> <td>LANG-9 — <em>above</em> and <em>below</em></td> <td>11.5</td> </tr> <tr> <td>LANG-8 — number style</td> <td>11.12</td> </tr> </tbody> </table></div> <h2 id="word-list"> <a href="#word-list" class="anchor-heading" aria-labelledby="word-list"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Word list </h2> <p>Terms this repository needs that the Section 11 tables don’t cover. Section 11.4 decides the rest.</p> <div class="table-wrapper"><table> <thead> <tr> <th>Term</th> <th>Rule</th> </tr> </thead> <tbody> <tr> <td>email</td> <td>No hyphen.</td> </tr> <tr> <td>internet</td> <td>Lowercase.</td> </tr> <tr> <td>phone</td> <td>The Android handset the app runs on. Use <em>phone</em> even when a tablet also works, unless the distinction matters.</td> </tr> <tr> <td>set up / setup</td> <td>Verb two words, noun/adjective one word.</td> </tr> <tr> <td>sign in</td> <td>Verb; <em>sign-in</em> as adjective. Not <em>log in</em> or <em>login</em>.</td> </tr> <tr> <td>tap</td> <td>The interaction verb for the app’s touch UI. These pages are mobile-specific, so <em>tap</em> stands where 11.7 would prefer <em>select</em>. Never <em>tap on</em>.</td> </tr> <tr> <td>touch & hold</td> <td>Exactly this form (Google’s Android convention). Not <em>long press</em>, not <em>tap and hold</em>.</td> </tr> </tbody> </table></div> <h2 id="new-page-checklist"> <a href="#new-page-checklist" class="anchor-heading" aria-labelledby="new-page-checklist"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> New page checklist </h2> <ol> <li>Create <code class="language-plaintext highlighter-rouge">docs/en/user/<slug>.md</code> or <code class="language-plaintext highlighter-rouge">docs/en/developer/<slug>.md</code> with complete frontmatter (STRUCT-1).</li> <li>Register the page in <code class="language-plaintext highlighter-rouge">feature/docs/.../data/DocBundleLoader.kt</code> with keywords and aliases.</li> <li>Put screenshots in <code class="language-plaintext highlighter-rouge">docs/assets/screenshots/</code>, referenced per IMG-1.</li> <li>Add a <em>What’s New</em> entry (STRUCT-6).</li> <li>Validate locally: <code class="language-plaintext highlighter-rouge">node scripts/validate-doc-links.js docs/en</code>, <code class="language-plaintext highlighter-rouge">node scripts/check-doc-coverage.js .</code>, <code class="language-plaintext highlighter-rouge">node scripts/check-doc-aliases.js .</code> (every alias in step 1’s frontmatter must also be in step 2’s loader entry — only the loader’s list reaches in-app search), and the docs bundle Gradle checks in <a href="contributing">Contributing</a>.</li> <li>Run the Section 11.16 quick checks over the page before you open the pull request.</li> </ol> <h2 id="related-topics"> <a href="#related-topics" class="anchor-heading" aria-labelledby="related-topics"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Related Topics </h2> <ul> <li><a href="contributing">Contributing</a> — branch naming, PR workflow, and the verification gates docs changes run through</li> <li><a href="test-builds">Test Builds & Obtainium</a> — where prerelease docs snapshots are published</li> </ul> </main> <hr> <footer> <footer class="site-footer"> Copyright © 2026 Meshtastic LLC. Distributed under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPL v3 License.</a> </footer> <div class="d-sm-block d-md-none"> <div class="mt-4 fs-2"> This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </div> </div> </footer> </div> </div> <div class="search-overlay"></div> </div> </body> </html>
|