diff --git a/.gitignore b/.gitignore
index 2984493b5..1d7ee958d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ build
build-pico-sdk-docs
documentation/html
documentation/asciidoc/pico-sdk
+.venv
diff --git a/Gemfile b/Gemfile
index a54d14c20..d342d0b9a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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
@@ -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'
\ No newline at end of file
+gem 'thread_safe', '~> 0.3.5'
diff --git a/Gemfile.lock b/Gemfile.lock
index a8d10ab26..5808c168c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -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)
@@ -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)
diff --git a/Makefile b/Makefile
index 7e0bc6854..e3a8c396e 100644
--- a/Makefile
+++ b/Makefile
@@ -83,9 +83,9 @@ clean_doxygen_xml:
$(ASCIIDOC_DOXYGEN_DIR)/picosdk_index.json $(ASCIIDOC_DOXYGEN_DIR)/index_doxygen.adoc: $(ASCIIDOC_DOXYGEN_DIR) $(DOXYGEN_XML_DIR)/index.xml $(DOXYGEN_TO_ASCIIDOC_DIR)/__main__.py $(DOXYGEN_TO_ASCIIDOC_DIR)/cli.py $(DOXYGEN_TO_ASCIIDOC_DIR)/nodes.py $(DOXYGEN_TO_ASCIIDOC_DIR)/helpers.py | $(BUILD_DIR) $(DOXYGEN_TO_ASCIIDOC_DIR)/requirements.txt
$(MAKE) clean_ninja
pip3 install -r $(DOXYGEN_TO_ASCIIDOC_DIR)/requirements.txt
- PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -f $(DOXYGEN_XML_DIR)/index.xml -o $(ASCIIDOC_DOXYGEN_DIR)/all_groups.adoc
- PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -f $(DOXYGEN_XML_DIR)/indexpage.xml -c -o $(ASCIIDOC_DOXYGEN_DIR)/index_doxygen.adoc
- PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -f $(DOXYGEN_XML_DIR)/examples_page.xml -c -o $(ASCIIDOC_DOXYGEN_DIR)/examples_page.adoc
+ PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -o $(ASCIIDOC_DOXYGEN_DIR)/all_groups.adoc $(DOXYGEN_XML_DIR)/index.xml
+ PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -c -o $(ASCIIDOC_DOXYGEN_DIR)/index_doxygen.adoc $(DOXYGEN_XML_DIR)/indexpage.xml
+ PYTHONPATH=$(DOXYGEN_TO_ASCIIDOC_DIR)/.. python3 -m doxygentoasciidoc -c -o $(ASCIIDOC_DOXYGEN_DIR)/examples_page.adoc $(DOXYGEN_XML_DIR)/examples_page.xml
python3 $(SCRIPTS_DIR)/postprocess_doxygen_adoc.py $(ASCIIDOC_DOXYGEN_DIR)
-cp $(DOXYGEN_XML_DIR)/*.png $(ASCIIDOC_DOXYGEN_DIR) 2>/dev/null || true
diff --git a/_config.yml b/_config.yml
index acfa472d3..66a8c67ba 100644
--- a/_config.yml
+++ b/_config.yml
@@ -25,6 +25,7 @@ githubbranch_edit: develop
# Build settings
theme: minima
plugins:
+ - asciidoctor-tabs
- jekyll-asciidoc
- jekyll-feed
diff --git a/documentation/asciidoc/computers/camera/rpicam_apps_writing.adoc b/documentation/asciidoc/computers/camera/rpicam_apps_writing.adoc
index 86287613d..fd5a9217b 100644
--- a/documentation/asciidoc/computers/camera/rpicam_apps_writing.adoc
+++ b/documentation/asciidoc/computers/camera/rpicam_apps_writing.adoc
@@ -3,6 +3,7 @@
`rpicam-apps` does not provide all of the camera-related features that anyone could ever need. Instead, these applications are small and flexible. Users who require different behaviour can implement it themselves.
All of the `rpicam-apps` use an event loop that receives messages when a new set of frames arrives from the camera system. This set of frames is called a `CompletedRequest`. The `CompletedRequest` contains:
+
* all images derived from that single camera frame: often a low-resolution image and a full-size output
* metadata from the camera and post-processing systems
diff --git a/documentation/asciidoc/computers/configuration/kernel-command-line-config.adoc b/documentation/asciidoc/computers/configuration/kernel-command-line-config.adoc
index c97657f3e..27fbc1c26 100644
--- a/documentation/asciidoc/computers/configuration/kernel-command-line-config.adoc
+++ b/documentation/asciidoc/computers/configuration/kernel-command-line-config.adoc
@@ -46,7 +46,7 @@ If no `video` entry is present in `cmdline.txt`, Raspberry Pi OS uses the https:
video=HDMI-A-1:1920x1080M@60
----
-In addition, it is possible to add rotation and reflect parameters as documented in the standard https://github.com/raspberrypi/linux/blob/rpi-6.1.y/Documentation/fb/modedb.rst[Linux framebuffer documentation]. The following example defines a display named `HDMI-A-` at a resolution of 1080p, a refresh rate of 60Hz, 90 degrees of rotation, and a reflection over the X axis:
+In addition, it is possible to add rotation and reflect parameters as documented in the standard https://github.com/raspberrypi/linux/blob/rpi-6.1.y/Documentation/fb/modedb.rst[Linux framebuffer documentation]. The following example defines a display named `HDMI-A-1` at a resolution of 1080p, a refresh rate of 60Hz, 90 degrees of rotation, and a reflection over the X axis:
[source,bash]
----
diff --git a/documentation/asciidoc/computers/configuration/raspi-config.adoc b/documentation/asciidoc/computers/configuration/raspi-config.adoc
index 4d1f02c22..2fd95ad36 100644
--- a/documentation/asciidoc/computers/configuration/raspi-config.adoc
+++ b/documentation/asciidoc/computers/configuration/raspi-config.adoc
@@ -551,7 +551,7 @@ Enable or disable the serial connection hardware.
[source,console]
----
-$ sudo raspi-config nonint do_serial_hw <0/1/2>
+$ sudo raspi-config nonint do_serial_hw <0/1>
----
* `0`: enable serial port
@@ -564,7 +564,7 @@ Enable or disable shell and kernel messages on the serial connection.
[source,console]
----
-$ sudo raspi-config nonint do_serial_cons <0/1/2>
+$ sudo raspi-config nonint do_serial_cons <0/1>
----
* `0`: enable console over serial port
diff --git a/documentation/asciidoc/computers/legacy_config_txt/video.adoc b/documentation/asciidoc/computers/legacy_config_txt/video.adoc
index 68a0fc73a..ba0c7bcf6 100644
--- a/documentation/asciidoc/computers/legacy_config_txt/video.adoc
+++ b/documentation/asciidoc/computers/legacy_config_txt/video.adoc
@@ -1678,7 +1678,7 @@ Increase this value if the text flows off the bottom edge of the screen; decreas
Set `overscan_scale` to `1` to force any non-framebuffer layers to conform to the overscan settings. The default value is `0`.
-*NOTE:* this feature is generally not recommended: it can reduce image quality because all layers on the display will be scaled by the GPU. Disabling overscan on the display itself is the recommended option to avoid images being scaled twice (by the GPU and the display).
+NOTE: this feature is generally not recommended: it can reduce image quality because all layers on the display will be scaled by the GPU. Disabling overscan on the display itself is the recommended option to avoid images being scaled twice (by the GPU and the display).
==== `framebuffer_width`
diff --git a/documentation/asciidoc/computers/linux_kernel/contribute.adoc b/documentation/asciidoc/computers/linux_kernel/contribute.adoc
index 07a633587..74d03d865 100644
--- a/documentation/asciidoc/computers/linux_kernel/contribute.adoc
+++ b/documentation/asciidoc/computers/linux_kernel/contribute.adoc
@@ -18,6 +18,7 @@ Then, submit a pull request containing your changes to the https://github.com/ra
=== Contribute to the Linux kernel
-First, fork the https://github.com/torvalds/linux[Linux kernel repository] and clone it to your development device. You can then make your changes, test them, and commit them into your fork.
+First, clone the https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git[Linux kernel tree] to your development device. You can then make your changes, test them, and commit them into your local tree.
-Then, submit a pull request containing your changes to the https://github.com/torvalds/linux[Linux kernel repository]. Linux kernel contributors will review your contribution and suggest improvements. Once approved, they'll merge in your changes. Eventually, they'll make their way into a long-term release of the Linux kernel. Once we've tested that long-term release for compatibility with the Raspberry Pi kernel, your changes will make their way into a stable release of the Raspberry Pi kernel.
+Once your change is ready you can submit it to the Linux kernel community. Linux kernel development happens on mailing lists, rather than on GitHub. In order for your change to become part of Linux, please email it to the community as a patch. Please follow https://www.kernel.org/doc/html/latest/process/submitting-patches.html[Submitting patches: the essential guide to getting your code into the kernel] and https://www.kernel.org/doc/html/latest/process/coding-style.html[Linux kernel coding style] in the Linux kernel documentation.
+Linux kernel contributors will review your contribution and suggest improvements. Once approved, they'll merge in your changes. Eventually, they'll make their way into a long-term release of the Linux kernel. Once we've tested that long-term release for compatibility with the Raspberry Pi kernel, your changes will make their way into a stable release of the Raspberry Pi kernel.
diff --git a/documentation/asciidoc/computers/remote-access/nfs.adoc b/documentation/asciidoc/computers/remote-access/nfs.adoc
index 2e5a5f6bc..5db9c843c 100644
--- a/documentation/asciidoc/computers/remote-access/nfs.adoc
+++ b/documentation/asciidoc/computers/remote-access/nfs.adoc
@@ -36,7 +36,7 @@ Grant `/export` and `/export/users` read, write, and execute permissions (`777`)
[source,console]
----
-$ chmod -R 777 777 /export
+$ chmod -R 777 /export
----
Next, mount the real `users` directory with:
diff --git a/documentation/asciidoc/computers/remote-access/ssh.adoc b/documentation/asciidoc/computers/remote-access/ssh.adoc
index 0d3e38513..acdec020d 100644
--- a/documentation/asciidoc/computers/remote-access/ssh.adoc
+++ b/documentation/asciidoc/computers/remote-access/ssh.adoc
@@ -7,24 +7,26 @@ 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`.
@@ -32,8 +34,8 @@ To configure SSH on a completely new installation of Raspberry Pi OS:
. Select `Ok`.
. Choose `Finish`.
-==== Manually
-
+Manually::
++
. Create an empty file named `ssh` in the boot partition:
+
[source,console]
@@ -46,6 +48,7 @@ $ sudo touch /boot/firmware/ssh
----
$ sudo reboot
----
+======
=== Connect to an SSH server
diff --git a/documentation/asciidoc/services/connect/use.adoc b/documentation/asciidoc/services/connect/use.adoc
index aee1731b5..207afe6f3 100644
--- a/documentation/asciidoc/services/connect/use.adoc
+++ b/documentation/asciidoc/services/connect/use.adoc
@@ -184,7 +184,7 @@ In the Connect dashboard, the **Remote shell** badge and the **Remote shell** op
image::images/remote-shell-disabled.png[width="80%"]
-To re-enable screen sharing, do one of the following:
+To re-enable remote shell access, do one of the following:
* click the Connect system tray icon and select **Allow remote shell**
* run the following command:
diff --git a/jekyll-assets/_includes/head.html b/jekyll-assets/_includes/head.html
index 369ae8646..4780553b3 100644
--- a/jekyll-assets/_includes/head.html
+++ b/jekyll-assets/_includes/head.html
@@ -18,6 +18,7 @@
+
+
+
+
diff --git a/jekyll-assets/css/asciidoctor-tabs.css b/jekyll-assets/css/asciidoctor-tabs.css
new file mode 100644
index 000000000..1afbd9185
--- /dev/null
+++ b/jekyll-assets/css/asciidoctor-tabs.css
@@ -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;
+}
diff --git a/jekyll-assets/css/tabs.css b/jekyll-assets/css/tabs.css
index 04d927ed0..b1880c02a 100644
--- a/jekyll-assets/css/tabs.css
+++ b/jekyll-assets/css/tabs.css
@@ -79,4 +79,4 @@ p#release + #container {
display: block;
width: 100%;
}
-}
+}
\ No newline at end of file
diff --git a/jekyll-assets/scripts/asciidoctor-tabs.js b/jekyll-assets/scripts/asciidoctor-tabs.js
new file mode 100644
index 000000000..f8966c024
--- /dev/null
+++ b/jekyll-assets/scripts/asciidoctor-tabs.js
@@ -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 })
+ }
+})()
diff --git a/lib/doxygentoasciidoc b/lib/doxygentoasciidoc
index 278bc0874..09e14b6d2 160000
--- a/lib/doxygentoasciidoc
+++ b/lib/doxygentoasciidoc
@@ -1 +1 @@
-Subproject commit 278bc087489951a22c776ee611965d600db4547f
+Subproject commit 09e14b6d2fc7fd016e4556a8e10027033fb7b517