dasImgui documentation Logo
2.0

Contents

  • dasImgui v2.0
    • 1. Boost macro layer
      • 1.1. Boost macro layer — DSL for declarative widget composition
        • 1.1.1. Function annotations
        • 1.1.2. Classes
      • 1.2. Boost runtime — widget state structs, registry, and dispatcher
        • 1.2.1. Type aliases
        • 1.2.2. Structures
        • 1.2.3. Per-frame registry
        • 1.2.4. Path machinery
        • 1.2.5. Coroutines
        • 1.2.6. Window control
        • 1.2.7. Live commands
        • 1.2.8. Synthetic input
        • 1.2.9. Debug logging
        • 1.2.10. Memory debugging
        • 1.2.11. Snapshot transform
        • 1.2.12. JSON serialization
    • 2. Builtin widgets
      • 2.1. Built-in widgets — inputs, selection, color, plots, output
        • 2.1.1. Call macros
        • 2.1.2. Selection
        • 2.1.3. Focus & scrolling
        • 2.1.4. Logging
        • 2.1.5. Status queries
      • 2.2. Built-in containers — windows, child regions, tabs, menus, popups
        • 2.2.1. Call macros
        • 2.2.2. Windows
        • 2.2.3. Tabs
        • 2.2.4. Popups
      • 2.3. ID stack — push/pop, scoped, hashing
        • 2.3.1. ID stack
      • 2.4. Layout helpers — splits, columns, docking, spacing
        • 2.4.1. Call macros
        • 2.4.2. Columns
        • 2.4.3. Trees
        • 2.4.4. List clipping
      • 2.5. Style helpers — colors, vars, push/pop, themes
        • 2.5.1. Call macros
        • 2.5.2. Push/pop
      • 2.6. Icon set
        • 2.6.1. Transport
        • 2.6.2. Edit
        • 2.6.3. Visualize
        • 2.6.4. Mix
        • 2.6.5. Organize
        • 2.6.6. Synth
        • 2.6.7. Scene tools
        • 2.6.8. Scene objects
        • 2.6.9. Arrange
        • 2.6.10. Editor transport
        • 2.6.11. View
        • 2.6.12. File
        • 2.6.13. General
        • 2.6.14. API
    • 3. Live reload and transport
      • 3.1. Live-reload lifecycle and synthetic-IO bypass driver
        • 3.1.1. Structures
        • 3.1.2. Lifecycle
        • 3.1.3. Synth IO drivers
        • 3.1.4. Event timelines
        • 3.1.5. Status / introspection
      • 3.2. Transport — pluggable lambda-based IPC for imgui commands
        • 3.2.1. Type aliases
        • 3.2.2. Constants
        • 3.2.3. Structures
        • 3.2.4. Transport construction
        • 3.2.5. Send / receive
        • 3.2.6. Awaiting
        • 3.2.7. Raw HTTP
    • 4. Testing toolkit
      • 4.1. Playwright — block-form test harness for daslang-live + dasImgui apps
        • 4.1.1. Constants
        • 4.1.2. Structures
        • 4.1.3. App lifecycle
        • 4.1.4. Locators / queries
        • 4.1.5. Actions
        • 4.1.6. Recording / narration
        • 4.1.7. Content-time gating
        • 4.1.8. Snapshots
        • 4.1.9. Polling / await
        • 4.1.10. Pause control
        • 4.1.11. Transport plumbing
      • 4.2. Visual aids — tutorial-mode overlays, mouse trail, narration, key HUD
        • 4.2.1. Constants
        • 4.2.2. Structures
        • 4.2.3. Highlight overlay
        • 4.2.4. Mouse trail
        • 4.2.5. Narration
        • 4.2.6. HUD
        • 4.2.7. Cursor sprite
        • 4.2.8. Override hooks
        • 4.2.9. Memory debugging
        • 4.2.10. Color utilities
        • 4.2.11. Serve / lifecycle
    • 5. External types
      • 5.1. imgui::ImGuiCol
      • 5.2. imgui::ImGui*Flags
      • 5.3. imgui::ImGuiCond
      • 5.4. imgui::ImVec2 / imgui::ImVec4 / imgui::ImColor
      • 5.5. imgui::ImGuiViewport
      • 5.6. imgui::ImGuiSizeCallbackData
      • 5.7. glfw::GLFWwindow
      • 5.8. imgui::ImGuiTextFilter
  • dasImgui tutorials
    • Boost basics
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • The window container
        • Widgets
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Widgets tour
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • Widgets
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Display widgets
      • Walkthrough
        • Requires
        • progress_bar
        • image
        • Snapshot shape
    • Narrative widgets
      • Walkthrough
        • Requires
        • text vs text_unformatted vs text_wrapped
        • Colored vs disabled
        • Bullets
        • label_text
        • separator_text
        • Snapshot shape
    • Custom widgets
      • Walkthrough
        • Requires
        • The state struct
        • The [widget] annotation
        • The drawlist pattern
        • Reusing pending_value_finalize
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Layout
      • Walkthrough
        • Requires
        • Init and shutdown
        • The frame loop
        • Layout helpers
        • Standalone vs live
        • Driving from outside
        • Scope wrappers
        • Next steps
    • Layout primitives
      • Walkthrough
        • Requires
        • When to reach for each
        • Snapshot shape
    • Docking
      • Walkthrough
        • Requires
        • The flag that lights it up
        • Seeding the layout
        • Variant: dockspace inside a host window
        • The frame loop
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With style
      • Walkthrough
        • Requires
        • Single block, mixed types
        • Nesting
        • Pop balance
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With id
      • Walkthrough
        • Requires
        • The single-render rule
        • with_id scopes
        • Nested chains
        • Per-call id= — stable hash across renames
        • Per-call path= — stable registry path across renames
        • Standalone vs live
        • Driving from outside
        • Next steps
    • With disabled / font / button_repeat
      • Walkthrough
        • Requires
        • Why scope wrappers
        • with_disabled
        • with_button_repeat
        • with_font
        • with_clip_rect
        • Combining wrappers
    • State & telemetry
      • Walkthrough
        • Auto-emit
        • Reading state
        • Dotted flags
        • text_show — the app-driven mirror
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Containers
      • Walkthrough
        • Requires
        • menu_bar / menu / menu_item
        • tab_bar / tab_item
        • popup
        • item_tooltip — hover-gated overlay
        • Standalone vs live
        • Driving from outside
        • Context popups
        • Next steps
    • Child windows
      • Walkthrough
        • Requires
        • size — three sizing modes
        • child_flags vs window_flags
        • ChildState — what the snapshot reports
        • Auto-resize variants
        • Horizontal scroll
        • Standalone vs live
        • Driving from outside
    • Group
      • Walkthrough
        • Requires
        • Two columns via same_line
        • Hit-testing a cluster
        • The (label | value | button) row
        • Why no flags?
        • Standalone vs live
        • Driving from outside
    • Tree node
      • Walkthrough
        • Requires
        • Nesting and path composition
        • Open / close from outside
        • Reading state.opened
        • ImGuiTreeNodeFlags
        • tree_node vs tree_node_ex
        • Standalone vs live
    • Collapsing header
      • Walkthrough
        • Requires
        • Two visibility dimensions
        • The closable form
        • The pending-flag channel
        • DefaultOpen flag
        • Standalone vs live
        • Driving from outside
    • Tab bar
      • Walkthrough
        • Requires
        • Active tab + body gating
        • Switching tabs from outside
        • Closable tabs
        • Sharing open state across two surfaces
        • ImGuiTabBarFlags
        • Standalone vs live
    • Modal popups
      • Walkthrough
        • Requires
        • Confirm dialog (non-closable)
        • Closable settings modal
        • popup vs popup_modal
        • Pending-flag channels
        • Standalone vs live
        • Driving from outside
    • Main menu bar
      • Walkthrough
        • Requires
        • main_menu_bar vs menu_bar
        • menu_item vs menu_label
        • Driving from outside
        • Snapshot shape
    • Popup window
      • Walkthrough
        • Requires
        • Two scopes, one str_id
        • Custom predicates
        • State
        • Standalone vs live
    • Flat tooltips
      • Walkthrough
        • Requires
        • set_item_tooltip vs the container form
        • The HelpMarker pattern
        • Standalone vs live
    • Drag and drop
      • Walkthrough
        • Requires
        • Source side
        • Target side
        • Driving from outside
        • Next steps
    • Live reload
      • Walkthrough
        • The reload boundary
        • @live preservation
        • The frame gate
        • [live_command] — user-defined HTTP endpoints
        • Manual reload hooks
        • Init / shutdown idempotence
        • Standalone vs live
        • Driving from outside
        • Next steps
    • Driving from outside
      • Walkthrough
        • The command surface
        • imgui_snapshot — read the world
        • imgui_force_set — value writes
        • imgui_click — fire a click
        • imgui_open / imgui_close — containers
        • The flow on a single command
        • Standalone vs live
        • Driving from outside (recap)
        • Next steps
    • Visual aids tour
      • Walkthrough
        • Layout
        • Highlight
        • Mouse trail
        • Cursor sprite
        • Narrate
        • Auto-highlight on command
        • Key HUD + focus rect (recording’s keyboard tour)
        • Standalone vs live
        • Driving from outside
    • Narrative + layout primitives
      • What the tour shows
      • Driving the tour
      • Idents matter for recordings
    • External-pointer editing rail
      • What the tour shows
      • safe_addr vs unsafe(addr)
      • Driving the tour
    • Recording tutorial videos
      • The subject
      • The driver
        • Anatomy of a driver
        • The visual-aids stack
        • The driver workflow in shell
        • Stop conditions
        • Replay stability
        • Standalone vs live
        • Driving from outside
        • The end of the curriculum
    • Harness + headless mode
      • Why headless
      • Running tests headless
      • What –headless does internally
      • Default-on lint: HARNESS001
      • Limits under –headless
    • data_table
      • Walkthrough
        • Requires
        • Container shape
        • Body primitives
        • Sortable tables
        • Why the name
        • Standalone vs live
    • file_dialog
      • Walkthrough
        • Requires
        • Public API
        • Modes
        • Navigation and sorting
        • Drivability
        • Standalone vs live
    • Window size constraints
      • Walkthrough
        • Requires
        • The three callback patterns
        • Struct layout
        • Standalone vs live
    • With tab stop
      • Walkthrough
        • Requires
        • Behaviour
        • When to reach for it
        • Standalone vs live
    • Color button hover
      • Walkthrough
        • Requires
        • When to reach for it
        • Click vs hover
        • Standalone vs live
    • Selectable hover
      • Walkthrough
        • Requires
        • When to reach for it
        • Toggle vs hover
        • Standalone vs live
    • Drawlist rail
      • Walkthrough
        • Scope wrappers
        • Primitives
        • Shape extras (v2 additions)
        • Path building
        • Channel splitting
        • Clip rect scope
        • Path-key telemetry
        • Standalone vs live
    • Drag widgets
      • Walkthrough
        • Requires
        • Speed and format
        • Bounds
        • Vector forms
        • Range forms
        • Driving from outside
        • Drag vs slider vs input
        • Caller-owned variant
    • Slider widgets
      • Walkthrough
        • Requires
        • Bounds
        • Format
        • Vector forms
        • Vertical orientation
        • Driving from outside
        • Slider vs drag vs input
        • Caller-owned variant
    • Input numeric widgets
      • Walkthrough
        • Requires
        • Step buttons
        • Format
        • Vector forms
        • Double precision
        • Flags
        • Driving from outside
        • Input vs drag vs slider
        • Caller-owned variant
    • Input text widgets
      • Walkthrough
        • Requires
        • Basic and with_hint
        • Multiline
        • Growable
        • Callback
        • text_filter
        • Indexed-form note
        • Driving from outside
    • Toggles
      • Walkthrough
        • Requires
        • checkbox vs radio_button (bool form)
        • radio_button_int — grouped, mutually exclusive
        • Driving from outside
        • Caller-owned variants
    • Dropdown + select
      • Walkthrough
        • Requires
        • combo — items array
        • combo_getter — procedural list
        • selectable — multi-toggle rows
        • selectable_label inside list_box — single-select
        • Driving from outside
        • When to use which
    • Color
      • Walkthrough
        • Requires
        • edit vs picker
        • color_button — click trigger, caller-owned color
        • Flags
        • Driving from outside
        • Caller-owned variants
    • Buttons
      • Walkthrough
        • Requires
        • button — the workhorse
        • small_button — zero padding
        • arrow_button — directional glyph
        • invisible_button — hit area only
        • image_button — textured trigger
        • tab_item_button — button styled as a tab
        • Driving from outside
        • Caller-owned variant
    • Plot
      • Walkthrough
        • Requires
        • Array form vs lambda form
        • Auto-fit vs explicit bounds
        • Size
        • The overlay arg
        • Driving from outside
    • tree_node_ex + image
      • Walkthrough
        • Requires
        • tree_node_ex vs tree_node (container)
        • image vs image_button
        • Driving from outside
    • Right-click context popups
      • Walkthrough
        • Requires
        • popup_context_item — attached to an item
        • popup_context_window — attached to the window
        • Flags
        • State model — stateless_finalize
    • edit_tab_item
      • Walkthrough
        • Requires
        • Why edit_tab_item over tab_item
        • The id arg
        • The pointer arg
        • Driving from outside
    • Icons
      • Walkthrough
        • Requires
        • icon_button — clickable
        • icon() — draw only
        • Enumerating the set
        • Drawing without a button
    • Wrapping tab bar
      • Walkthrough
        • Requires
        • Selecting a tab by name
        • Why an index, not ImGui’s tab state
        • Standalone vs live
    • Dynamic fonts
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
        • Standalone vs live
    • Texture references
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
    • Item flags
      • Walkthrough
        • Requires
        • Behaviour
    • Log capture
      • Walkthrough
        • Requires
        • Behaviour
        • Migration note
  • Internal binding families
    • Render helpers
    • Vertex shading
    • Layout & item sizing
    • Item hit-test & geometry
    • Item assembly (ItemAdd + ButtonBehavior)
    • Behavior-flag buttons
    • Axis layout primitives (splitter & scrollbar)
    • Tree-node behavior
    • Separator & low-level text
    • Combo internals
    • Popups, tooltips & menus
    • ID stack seed & override
    • Focus scope & activation
    • Item flags
    • Logging & capture
dasImgui documentation
  • dasImgui tutorials
  • Main menu bar
  • Edit on GitHub

Main menu bar

Two related v2 additions live together in this tutorial. The first is main_menu_bar(IDENT) { ... } — the screen-top bar (BeginMainMenuBar / EndMainMenuBar), distinct from menu_bar(IDENT) { ... } which attaches to the current window (BeginMenuBar, requires ImGuiWindowFlags.MenuBar). The second is the menu_item / menu_label split for the leaves under a menu:

  • menu_item(IDENT, (text=, shortcut=, enabled=)) — toggleable. ToggleState.value flips on click.

  • menu_label(IDENT, (text=, shortcut=, selected=, enabled=)) — static. ClickState.click_count accumulates; selected is a fixed check-mark (not driven by the click).

menu_label is the right rail for section headers (selected=false, enabled=false), permanent-check labels (selected=true), and any “do something, don’t toggle” menu entry.

main_menu_bar(MAIN_BAR) {
    menu(FILE_MENU, (text = "File", enabled = true)) {
        menu_item(MI_DARKMODE, (text = "Dark mode", shortcut = "Ctrl+D"))
        menu_item(MI_AUTOSAVE, (text = "Auto-save", shortcut = ""))
        separator(FILE_SEP)
        menu_label(FILE_HEADER, (text = "(recent files)",
                                 shortcut = "", selected = false,
                                 enabled = false))
        menu_label(FILE_RECENT1, (text = "demo.das"))
        menu_label(FILE_STAR, (text = "Star this project",
                               shortcut = "", selected = true))
    }
}

Source: examples/tutorial/main_menu_bar.das.

Walkthrough

Your browser doesn't support HTML5 video. Download the recording.
  1options gen2
  2
  3require imgui
  4require imgui_app
  5require opengl/opengl_boost
  6require live/glfw_live
  7require live/live_api
  8require live/live_commands
  9require live/live_vars
 10require live_host
 11require imgui/imgui_live
 12require imgui/imgui_boost_runtime
 13require imgui/imgui_boost_v2
 14require imgui/imgui_widgets_builtin
 15require imgui/imgui_containers_builtin
 16require imgui/imgui_visual_aids
 17
 18// =============================================================================
 19// TUTORIAL: main_menu_bar — top-level menu bar + menu_item vs menu_label split.
 20//
 21// Two related v2 additions live in this tutorial:
 22//
 23// 1. `main_menu_bar(IDENT) { ... }` is the screen-top bar (`BeginMainMenuBar`)
 24//    — distinct from `menu_bar(IDENT) { ... }` which attaches to the current
 25//    window (`BeginMenuBar`, requires `ImGuiWindowFlags.MenuBar`).
 26//
 27// 2. `menu_item` vs `menu_label`:
 28//    - menu_item(IDENT, (text=, shortcut=, enabled=)) → toggleable.
 29//      ToggleState.value mutates on click.
 30//    - menu_label(IDENT, (text=, shortcut=, selected=, enabled=)) → static.
 31//      ClickState.click_count accumulates; `selected` is a fixed check-mark.
 32//
 33// Use menu_label for section headers (`selected=false, enabled=false`),
 34// permanent-check labels (`selected=true`), and any "do something, don't
 35// toggle" menu entry.
 36//
 37// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/main_menu_bar.das
 38// LIVE:       daslang-live modules/dasImgui/examples/tutorial/main_menu_bar.das
 39//
 40// DRIVE (when running live):
 41//   curl -X POST -d '{"name":"imgui_click","args":{"target":"MAIN_BAR/FILE_MENU/MI_DARKMODE"}}' \
 42//        localhost:9090/command
 43// =============================================================================
 44
 45[export]
 46def init() {
 47    live_create_window("dasImgui main_menu_bar tutorial", 800, 480)
 48    live_imgui_init(live_window)
 49    let io & = unsafe(GetIO())
 50    GetStyle().FontScaleMain = 1.4
 51}
 52
 53[export]
 54def update() {
 55    if (!live_begin_frame()) return
 56    begin_frame()
 57
 58    ImGui_ImplGlfw_NewFrame()
 59    apply_synth_io_override()
 60    NewFrame()
 61
 62    // The bar sits at screen top, NOT inside any window().
 63    main_menu_bar(MAIN_BAR) {
 64        menu(FILE_MENU, (text = "File", enabled = true)) {
 65            // Toggleable — clicking flips MI_DARKMODE.value.
 66            menu_item(MI_DARKMODE, (text = "Dark mode", shortcut = "Ctrl+D"))
 67            menu_item(MI_AUTOSAVE, (text = "Auto-save", shortcut = ""))
 68            separator(FILE_SEP)
 69            // Section header — static, disabled, no check.
 70            menu_label(FILE_HEADER, (text = "(recent files)",
 71                                     shortcut = "", selected = false,
 72                                     enabled = false))
 73            menu_label(FILE_RECENT1, (text = "demo.das"))
 74            menu_label(FILE_RECENT2, (text = "tour.das"))
 75            separator(FILE_SEP2)
 76            // Permanent check — selected=true makes it always-checked.
 77            menu_label(FILE_STAR, (text = "Star this project",
 78                                   shortcut = "", selected = true))
 79            menu_item(MI_QUIT, (text = "Quit", shortcut = "Ctrl+Q"))
 80        }
 81        menu(EDIT_MENU, (text = "Edit", enabled = true)) {
 82            // menu_label for an action — emits click_count, no toggle.
 83            menu_label(EDIT_UNDO, (text = "Undo", shortcut = "Ctrl+Z"))
 84            menu_label(EDIT_REDO, (text = "Redo", shortcut = "Ctrl+Y",
 85                                   selected = false, enabled = false))
 86        }
 87    }
 88
 89    SetNextWindowPos(ImVec2(60.0, 80.0), ImGuiCond.Always)
 90    SetNextWindowSize(ImVec2(680.0, 320.0), ImGuiCond.Always)
 91    window(BODY, (text = "State readout", closable = false,
 92                  flags = ImGuiWindowFlags.None)) {
 93        text("Click items in the bar above; the snapshot updates below.")
 94        separator(BODY_SEP)
 95        text("MI_DARKMODE.value = {MI_DARKMODE.value}")
 96        text("MI_AUTOSAVE.value = {MI_AUTOSAVE.value}")
 97        text("EDIT_UNDO.click_count = {EDIT_UNDO.click_count}")
 98        text("MI_QUIT.value = {MI_QUIT.value}")
 99    }
100
101    end_of_frame()
102    Render()
103    var w, h : int
104    live_get_framebuffer_size(w, h)
105    glViewport(0, 0, w, h)
106    glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
107    glClear(GL_COLOR_BUFFER_BIT)
108    live_imgui_render()
109
110    live_end_frame()
111}
112
113[export]
114def shutdown() {
115    live_imgui_shutdown()
116    live_destroy_window()
117}
118
119[export]
120def main() {
121    init()
122    while (!exit_requested()) {
123        update()
124    }
125    shutdown()
126}

Requires

Baseline boost layer (imgui/imgui_boost_v2 re-exports imgui/imgui_containers_builtin). No extra modules.

main_menu_bar vs menu_bar

The two bar variants pick opposite anchor strategies:

  • main_menu_bar(IDENT) { ... } attaches to the viewport — sits at the top of the screen, persists across windows, ImGui draws the chrome. Use it when there’s exactly one bar in the app.

  • menu_bar(IDENT) { ... } attaches to the current window — appears inside that window’s titlebar area. The host window must have ImGuiWindowFlags.MenuBar set, or the menu_bar render is a no-op. Use it for per-document menus inside a tabbed editor, the imgui_demo’s own menu bar, or any window-local command surface.

Both expose the same menu() / menu_item / menu_label children; only the anchor differs.

menu_item vs menu_label

menu_item and menu_label look identical visually (text + optional shortcut + optional check-mark) but back different state structs:

  • menu_item carries ToggleState — the value bool flips on every click. Use it for boolean app-state toggles (“Dark mode”, “Auto-save”, “Show hidden files”).

  • menu_label carries ClickState — the click_count int accumulates without touching selected. Use it for actions (“Undo”, “Quit”, “About”) and for static labels with a fixed check (selected=true) or no check at all.

Combine selected= and enabled= on menu_label to get section headers (selected=false, enabled=false greys the entry and shows no check) or permanent-check items (selected=true, enabled=true shows the check and stays clickable).

Driving from outside

The full menu hierarchy is routable once a menu is open:

curl -X POST -d '{"name":"imgui_click","args":{"target":"MAIN_BAR/FILE_MENU/MI_DARKMODE"}}' \
     localhost:9090/command

The bar’s own header (MAIN_BAR) has a degenerate bbox (the chrome has no clickable “header”). The first-level menu() children (MAIN_BAR/FILE_MENU, MAIN_BAR/EDIT_MENU) DO register routable headers. Submenu items only register a bbox while their parent menu is open, so external drivers wanting to click a menu_item have to open the parent first (synth click on the header, wait one frame, then click the child). The walkthrough above does exactly this with real clicks, dropping straight DOWN the open menu’s column onto each item: a diagonal travel to an item that sits off-axis from its header would clip a sibling header, and ImGui hover-switches the open menu mid-travel (the click then lands in the wrong menu). Menu items span the full menu width, so a vertical drop at the header’s center-x always lands on the item.

Snapshot shape

MI_DARKMODE.value is the live toggle bool; EDIT_UNDO.click_count is the accumulating action counter. Both surface in the snapshot under their qualified path:

curl -X POST -d '{"name":"imgui_snapshot"}' localhost:9090/command \
    | jq '.globals."MAIN_BAR/FILE_MENU/MI_DARKMODE".payload'

The tutorial’s body window prints both per-frame so the state changes are visible alongside the menu interactions.

See also

Full source: examples/tutorial/main_menu_bar.das

Integration tests: tests/integration/test_menu_main.das and tests/integration/test_menu_label_static.das.

Boost macros — the macro layer.

Previous Next

© Copyright 2026-2026, Gaijin Entertainment.

Built with Sphinx using a theme provided by Read the Docs.