Skip to content

Commit

Permalink
Add tabs to the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-contino committed Sep 6, 2024
1 parent 3561d2b commit 6f66e07
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ build
build-pico-sdk-docs
documentation/html
documentation/asciidoc/pico-sdk
.venv
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ gem "minima", "~> 2.0"
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.17"
gem 'jekyll-asciidoc'
gem 'asciidoctor'
gem 'asciidoctor-tabs', ">= 1.0.0.beta.6"
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
Expand All @@ -37,4 +39,4 @@ gem "nokogiri", "~> 1.16"

# So we can add custom element templates
gem 'slim', '~> 5.2.1'
gem 'thread_safe', '~> 0.3.5'
gem 'thread_safe', '~> 0.3.5'
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ GEM
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
asciidoctor (2.0.20)
asciidoctor-tabs (1.0.0.beta.6)
asciidoctor (>= 2.0.0, < 3.0.0)
colorator (1.1.0)
concurrent-ruby (1.2.3)
em-websocket (0.5.3)
Expand Down Expand Up @@ -94,6 +96,8 @@ PLATFORMS
ruby

DEPENDENCIES
asciidoctor
asciidoctor-tabs (>= 1.0.0.beta.6)
jekyll (~> 4.3.3)
jekyll-asciidoc
jekyll-feed (~> 0.17)
Expand Down
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ githubbranch_edit: develop
# Build settings
theme: minima
plugins:
- asciidoctor-tabs
- jekyll-asciidoc
- jekyll-feed

Expand Down
21 changes: 12 additions & 9 deletions documentation/asciidoc/computers/remote-access/ssh.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,35 @@ You can access the terminal of a Raspberry Pi remotely from another computer on

By default, Raspberry Pi OS disables the SSH server. Enable SSH in one of the following ways:

==== On the desktop

[tabs]
======
On the desktop::
+
. From the *Preferences* menu, launch *Raspberry Pi Configuration*.
. Navigate to the *Interfaces* tab.
. Select *Enabled* next to *SSH*.
. Click *OK*.
==== While flashing a fresh OS image

While flashing a fresh OS image::
+
To configure SSH on a completely new installation of Raspberry Pi OS:

+
. Follow the instructions in the xref:../computers/getting-started.adoc#raspberry-pi-imager[Install with Imager] guide.
. During the **OS Customisation** step, navigate to the **Services** tab.
. Tick the checkbox to **Enable SSH**.
. Select **password authentication** to log in using the same username and password you use while physically using your Raspberry Pi. Select **Allow public-key authentication only** to xref:remote-access.adoc#configure-ssh-without-a-password[configure an SSH key] for passwordless login.
==== From the terminal

From the terminal::
+
. Enter `sudo raspi-config` in a terminal window.
. Select `Interfacing Options`.
. Navigate to and select `SSH`.
. Choose `Yes`.
. Select `Ok`.
. Choose `Finish`.
==== Manually

Manually::
+
. Create an empty file named `ssh` in the boot partition:
+
[source,console]
Expand All @@ -46,6 +48,7 @@ $ sudo touch /boot/firmware/ssh
----
$ sudo reboot
----
======

=== Connect to an SSH server

Expand Down
1 change: 1 addition & 0 deletions jekyll-assets/_includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3"/>
<link rel="stylesheet" href="{{ site.baseurl }}/css/style.css?ver={{ site.time | date: '%s' }}">
<link rel="stylesheet" href="{{ site.baseurl }}/css/tabs.css?ver={{ site.time | date: '%s' }}">
<link rel="stylesheet" href="{{ site.baseurl }}/css/asciidoctor-tabs.css?ver={{ site.time | date: '%s' }}">
<link rel="stylesheet" href="{{ site.baseurl }}/css/syntax-highlighting.css?ver={{ site.time | date: '%s' }}">
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-180927933-8"></script>
<script>
Expand Down
3 changes: 3 additions & 0 deletions jekyll-assets/_includes/scripts.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<!-- Script for the TOC toggle -->
<script src="{{ site.baseurl }}/scripts/nav.js?ver={{ site.time | date: '%s' }}" type="text/javascript"></script>

<!-- Asciidoctor tabs -->
<script src="{{ site.baseurl }}/scripts/asciidoctor-tabs.js?ver={{ site.time | date: '%s' }}" type="text/javascript"></script>

<!-- TOCify scripts -->
<script src="{{ site.baseurl }}/scripts/jquery-1.12.4.min.js"></script>
<script src="{{ site.baseurl }}/scripts/jquery-ui-1.13.0.custom.min.js"></script>
Expand Down
116 changes: 116 additions & 0 deletions jekyll-assets/css/asciidoctor-tabs.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

/*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
.tabs {
margin-bottom: 1.25em;
}

.tablist > ul {
display: flex;
flex-wrap: nowrap;
overflow-x: scroll;
overflow-y: hidden;
list-style: none;
margin: 0;
padding: 0;
}

.tablist > ul li {
align-items: center;
background-color: #eee;
cursor: pointer;
display: flex;
font-weight: bold;
line-height: 1.5;
padding: 0.25em 1em;
position: relative;
}

.tablist > ul li p {
margin-bottom: 0px !important;
}

.tablist > ul li:focus-visible {
outline: none;
}

.tablist.ulist,
.tablist.ulist > ul li {
margin: 0;
}

.tablist.ulist > ul li + li {
margin-left: 0.25em;
}

.tabs .tablist li::after {
content: "";
display: block;
height: 1px;
position: absolute;
bottom: -1px;
left: 0;
right: 0;
}

.tabs.is-loading .tablist li:not(:first-child),
.tabs:not(.is-loading) .tablist li:not(.is-selected) {
background-color: initial;
border-left: 1px solid #eee;
border-right: 1px solid #eee;
border-top: 1px solid #eee;
}

.tabs.is-loading .tablist li:first-child::after,
.tabs:not(.is-loading) .tablist li.is-selected::after {
background-color: #eee;
border-top: 2px solid var(--red);
}

/*
.tabs:not(.is-loading) .tablist li,
.tabs:not(.is-loading) .tablist li::after {
transition: background-color 200ms ease-in-out;
}
*/

.tablist > ul p {
line-height: inherit;
margin: 0;
}

.tabpanel {
background-color: #eee;
padding: 1.25em;
}

.tablist > ul li {
border-bottom: 0;
}

.tabs.is-loading .tabpanel + .tabpanel,
.tabs:not(.is-loading) .tabpanel.is-hidden {
display: none;
}

.tabpanel > :first-child {
margin-top: 0;
}

/* #content is a signature of the Asciidoctor standalone HTML output */
#content .tabpanel > :last-child,
#content .tabpanel > :last-child > :last-child,
#content .tabpanel > :last-child > :last-child > li:last-child > :last-child {
margin-bottom: 0;
}

.tablecontainer {
overflow-x: auto;
}

#content .tablecontainer {
margin-bottom: 1.25em;
}

#content .tablecontainer > table.tableblock {
margin-bottom: 0;
}
2 changes: 1 addition & 1 deletion jekyll-assets/css/tabs.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ p#release + #container {
display: block;
width: 100%;
}
}
}
127 changes: 127 additions & 0 deletions jekyll-assets/scripts/asciidoctor-tabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
;(function () { /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
'use strict'

var config = (document.currentScript || {}).dataset || {}
var forEach = Array.prototype.forEach

init(document.querySelectorAll('.tabs'))

function init (tabsBlocks) {
if (!tabsBlocks.length) return
forEach.call(tabsBlocks, function (tabs) {
var syncIds = tabs.classList.contains('is-sync') ? {} : undefined
var tablist = tabs.querySelector('.tablist ul')
tablist.setAttribute('role', 'tablist')
var start
forEach.call(tablist.querySelectorAll('li'), function (tab, idx) {
tab.tabIndex = -1
tab.setAttribute('role', tab.classList.add('tab') || 'tab')
var id, anchor, syncId
if (!(id = tab.id) && (anchor = tab.querySelector('a[id]'))) {
id = tab.id = anchor.parentNode.removeChild(anchor).id
}
var panel = id && tabs.querySelector('.tabpanel[aria-labelledby~="' + id + '"]')
if (!panel) return idx ? undefined : toggleSelected(tab, true) // invalid state
syncIds && (((syncId = tab.textContent.trim()) in syncIds) ? (syncId = undefined) : true) &&
(syncIds[(tab.dataset.syncId = syncId)] = tab)
idx || (syncIds && (start = { tab: tab, panel: panel })) ? toggleHidden(panel, true) : toggleSelected(tab, true)
tab.setAttribute('aria-controls', panel.id)
panel.setAttribute('role', 'tabpanel')
var onClick = syncId === undefined ? activateTab : activateTabSync
tab.addEventListener('click', onClick.bind({ tabs: tabs, tab: tab, panel: panel }))
})
if (!tabs.closest('.tabpanel')) {
forEach.call(tabs.querySelectorAll('.tabpanel table.tableblock'), function (table) {
var container = Object.assign(document.createElement('div'), { className: 'tablecontainer' })
table.parentNode.insertBefore(container, table).appendChild(table)
})
}
if (start) {
var syncGroupId
for (var i = 0, lst = tabs.classList, len = lst.length, className; i !== len; i++) {
if (!(className = lst.item(i)).startsWith('data-sync-group-id=')) continue
tabs.dataset.syncGroupId = syncGroupId = lst.remove(className) || className.slice(19).replace(/\u00a0/g, ' ')
break
}
if (syncGroupId === undefined) tabs.dataset.syncGroupId = syncGroupId = Object.keys(syncIds).sort().join('|')
var preferredSyncId = 'syncStorageKey' in config &&
window[(config.syncStorageScope || 'local') + 'Storage'].getItem(config.syncStorageKey + '-' + syncGroupId)
var tab = preferredSyncId && syncIds[preferredSyncId]
tab && Object.assign(start, { tab: tab, panel: document.getElementById(tab.getAttribute('aria-controls')) })
toggleSelected(start.tab, true) || toggleHidden(start.panel, false)
}
})
onHashChange()
toggleClassOnEach(tabsBlocks, 'is-loading', 'remove')
window.setTimeout(toggleClassOnEach.bind(null, tabsBlocks, 'is-loaded', 'add'), 0)
window.addEventListener('hashchange', onHashChange)
}

function activateTab (e) {
var tab = this.tab
var tabs = this.tabs || (this.tabs = tab.closest('.tabs'))
var panel = this.panel || (this.panel = document.getElementById(tab.getAttribute('aria-controls')))
querySelectorWithSiblings(tabs, '.tablist .tab', 'tab').forEach(function (el) {
toggleSelected(el, el === tab)
})
querySelectorWithSiblings(tabs, '.tabpanel', 'tabpanel').forEach(function (el) {
toggleHidden(el, el !== panel)
})
if (!this.isSync && 'syncStorageKey' in config && 'syncGroupId' in tabs.dataset) {
var storageKey = config.syncStorageKey + '-' + tabs.dataset.syncGroupId
window[(config.syncStorageScope || 'local') + 'Storage'].setItem(storageKey, tab.dataset.syncId)
}
if (!e) return
var loc = window.location
var hashIdx = loc.hash ? loc.href.indexOf('#') : -1
if (~hashIdx) window.history.replaceState(null, '', loc.href.slice(0, hashIdx))
e.preventDefault()
}

function activateTabSync (e) {
activateTab.call(this, e)
var thisTabs = this.tabs
var thisTab = this.tab
var initialY = thisTabs.getBoundingClientRect().y
forEach.call(document.querySelectorAll('.tabs'), function (tabs) {
if (tabs === thisTabs || tabs.dataset.syncGroupId !== thisTabs.dataset.syncGroupId) return
querySelectorWithSiblings(tabs, '.tablist .tab', 'tab').forEach(function (tab) {
if (tab.dataset.syncId === thisTab.dataset.syncId) activateTab.call({ tabs: tabs, tab: tab, isSync: true })
})
})
var shiftedBy = thisTabs.getBoundingClientRect().y - initialY
if (shiftedBy && (shiftedBy = Math.round(shiftedBy))) window.scrollBy({ top: shiftedBy, behavior: 'instant' })
}

function querySelectorWithSiblings (scope, selector, siblingClass) {
var el = scope.querySelector(selector)
if (!el) return []
var result = [el]
while ((el = el.nextElementSibling) && el.classList.contains(siblingClass)) result.push(el)
return result
}

function toggleClassOnEach (elements, className, method) {
forEach.call(elements, function (el) {
el.classList[method](className)
})
}

function toggleHidden (el, state) {
el.classList[(el.hidden = state) ? 'add' : 'remove']('is-hidden')
}

function toggleSelected (el, state) {
el.setAttribute('aria-selected', '' + state)
el.classList[state ? 'add' : 'remove']('is-selected')
el.tabIndex = state ? 0 : -1
}

function onHashChange () {
var id = window.location.hash.slice(1)
if (!id) return
var tab = document.getElementById(~id.indexOf('%') ? decodeURIComponent(id) : id)
if (!(tab && tab.classList.contains('tab'))) return
'syncId' in tab.dataset ? activateTabSync.call({ tab: tab }) : activateTab.call({ tab: tab })
}
})()

0 comments on commit 6f66e07

Please sign in to comment.