Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 })
}
})()