[← Home](../README.md) · [Libraries](README.md) # AmigaGuide — Hypertext Help System and Database Format ## Overview AmigaGuide is AmigaOS's native hypertext document format, introduced in 1991 and elevated to a system component with OS 3.0. An AmigaGuide database is a plain ASCII file annotated with `@` commands that define nodes, links, text attributes, and executable actions. The `amigaguide.library` provides both a standalone viewer and a programmatic API, allowing applications to open help databases synchronously or asynchronously, send navigation commands via an ARexx port, and even generate content dynamically at runtime through **dynamic nodes**. Because AmigaGuide is also implemented as a DataType class (`amigaguideclass`), any application using the DataTypes framework — including MultiView — can display `.guide` files without additional code. For developers, this means a single help file format serves both standalone documentation and in-application context-sensitive help, with cross-database linking, embedded images (via DataTypes), and ARexx-driven interactivity built in. > **Key constraint**: AmigaGuide is text-centric. While it can launch images, animations, and audio through DataType links, the document itself is linear text — there is no concept of a 2D page layout, embedded widgets, or cascading stylesheets. --- ## Architecture ### System Components ```mermaid graph TB subgraph "Application" APP["Application\nHelp menu / F1 key"] SYNC["OpenAmigaGuide()\nSynchronous viewer"] ASYNC["OpenAmigaGuideAsync()\nAsync + ARexx control"] end subgraph "amigaguide.library" LIB["amigaguide.library\nParser + Window manager"] DNODE["Dynamic Node Host\n(optional callback)"] end subgraph "DataTypes" DT["amigaguideclass\nRenders .guide in MultiView"] PIC["pictureclass\nEmbedded images"] ANI["animationclass\nEmbedded animations"] end subgraph "External" AREXX["ARexx port\nRemote control / callbacks"] SHELL["Shell\nSYSTEM links"] end APP --> SYNC --> LIB APP --> ASYNC --> LIB LIB --> DT LIB --> DNODE DT --> PIC DT --> ANI LIB --> AREXX LIB --> SHELL style LIB fill:#e8f4fd,stroke:#2196f3,color:#333 style DT fill:#e8f5e9,stroke:#4caf50,color:#333 ``` ### File → Nodes → Links An AmigaGuide database is a flat file divided into **nodes**. Each node is a self-contained document fragment. Navigation between nodes happens through **links**, which are rendered as clickable buttons in the viewer. ``` @DATABASE MyApp.guide @INDEX Main @NODE Main "MyApp Help" Welcome to MyApp. @{"Getting Started" LINK GettingStarted} @{"Reference" LINK Reference} @EndNode @NODE GettingStarted "Getting Started" 1. Install the software. 2. Run from Workbench. @{"Back to Main" LINK Main} @EndNode ``` --- ## File Format Reference ### Database-Level Commands (Global) These commands apply to the entire database. Most must appear at the start of the file, before the first `@NODE`. | Command | Description | Required | |---|---|---| | `@DATABASE ` | Identifies this file as an AmigaGuide database. Must be the **first line**. | Yes | | `@INDEX ` | Specifies the node used for the **Index** button. Defaults to MAIN if omitted. | No | | `@HELP ` | Specifies the node used for the **Help** button. | No | | `@WIDTH ` | Declares the maximum width of any node (viewer hint). | No | | `@HEIGHT ` | Declares the maximum height of any node. | No | | `@FONT ` | Default font for the database. | No | | `@WORDWRAP` | Enables automatic word wrapping (V39). | No | | `@SMARTWRAP` | Smarter wrapping: paragraphs separated by blank lines (V40). | No | | `@TAB ` | Tab stop width (default 8) (V40). | No | | `@AUTHOR ` | Author metadata. | No | | `@(C) ` | Copyright notice. | No | | `$VER: ` | Standard AmigaDOS version string. | No | | `@ONOPEN ` | ARexx command to execute when the database opens (V40). | No | | `@ONCLOSE ` | ARexx command to execute when the database closes (V40). | No | ### Node-Level Commands | Command | Description | |---|---| | `@NODE ""` | Starts a new node. `<name>` must be unique, no spaces. `<title>` appears in the window title bar. | | `@ENDNODE` | Ends the current node. | | `@TITLE "<title>"` | Overrides the window title for this node (alternative to `@NODE`'s title argument). | | `@TOC <node>` | Sets the **Contents** button target for this node. Defaults to MAIN. | | `@PREV <node>` | Sets the **Browse <** target. Defaults to previous node in file. | | `@NEXT <node>` | Sets the **Browse >** target. Defaults to next node in file. | | `@REMARK <text>` | Comment — not displayed. | ### Link Syntax Links are the core hypertext mechanism. They can appear anywhere on a line and are rendered as buttons. ``` @{"<label>" <action> <arguments>} ``` #### Action Commands | Action | Syntax | Description | |---|---|---| | `LINK` | `@{"Label" LINK TargetNode}` | Jump to another node in this database. | | `LINK` (cross-db) | `@{"Label" LINK Other.guide/NodeName}` | Jump to a node in another database. | | `RX` | `@{"Label" RX 'ADDRESS MYPORT MyCommand'}` | Execute an ARexx command. | | `RXS` | `@{"Label" RXS MyScript.rexx}` | Run an ARexx script file. | | `SYSTEM` | `@{"Label" SYSTEM 'dir >ram:output'}` | Execute a Shell command. | | `BEEP` | `@{"Label" BEEP}` | Play the system beep. | | `QUIT` | `@{"Label" QUIT}` | Close the AmigaGuide viewer. | > **Cross-database paths**: The path can be any AmigaDOS path, including assigns. If no path is given, AmigaGuide searches `ENV:AmigaGuide/Path`. As of OS 3.0, you can also link to any DataTypes-supported file: `@{"Picture" LINK image.iff/Main}`. ### Text Attributes Attributes wrap text in `@{name ...}` and must be terminated with `@{uname}` (undo attribute). | Attribute | Description | Example | |---|---|---| | `@{b}` / `@{ub}` | Bold on / off | `@{b}bold text@{ub}` | | `@{i}` / `@{ui}` | Italic on / off | `@{i}italic@{ui}` | | `@{u}` / `@{uu}` | Underline on / off | `@{u}underlined@{uu}` | | `@{fg <n>}` / `@{ufg}` | Foreground pen color | `@{fg 2}red text@{ufg}` | | `@{bg <n>}` / `@{ubg}` | Background pen color | `@{bg 1}highlighted@{ubg}` | | `@{jleft}` | Left justify (default) | | | `@{jright}` | Right justify | | | `@{jcenter}` | Center justify | | | `@{amigaguide}` | Embed an AmigaGuide glyph | | | `@{clear}` | Clear to end of line | | ### Macros (V40) Macros let you define reusable attribute sequences: ``` @MACRO warning "@{b}WARNING:@{ub} $1" Later in text: This is a @{"critical issue" warning "Do not power off during format."} ``` --- ## Data Structures ### NewAmigaGuide ```c /* libraries/amigaguide.h — NDK 3.9 */ struct NewAmigaGuide { BPTR nag_Lock; /* Lock on database directory */ STRPTR nag_Name; /* Database file name */ struct Screen * nag_Screen; /* Screen to open on, or NULL */ STRPTR nag_PubScreen; /* Name of public screen */ STRPTR nag_HostPort; /* App's ARexx port (unused) */ STRPTR nag_ClientPort; /* Base name for DB's ARexx port */ ULONG nag_Flags; /* NAGF_* flags */ STRPTR * nag_Context; /* NULL-terminated context array */ STRPTR nag_Node; /* Starting node name */ LONG nag_Line; /* Starting line number */ struct TagItem * nag_Extens; /* Additional tags (V37+) */ APTR nag_Client; /* Private — must be NULL */ }; ``` ### Flags | Flag | Value | Meaning | |---|---|---| | `NAGF_LOCK` | `0x0001` | `nag_Lock` is valid | | `NAGF_CLOSE` | `0x0002` | Close the database file when done | | `NAGF_NOTIFY` | `0x0004` | Enable ARexx notification | | `NAGF_HOSTPORT` | `0x0008` | `nag_HostPort` is valid | | `NAGF_CONTEXT` | `0x0010` | `nag_Context` is valid | | `NAGF_UNIQUE` | `0x0020` | Create unique ARexx port name | --- ## API Reference ### Synchronous Viewer ```c #include <libraries/amigaguide.h> #include <proto/amigaguide.h> /* Open a modal AmigaGuide viewer. Blocks until user closes all windows. */ AMIGAGUIDECONTEXT OpenAmigaGuideA(struct NewAmigaGuide *nag, struct TagItem *attrs); AMIGAGUIDECONTEXT OpenAmigaGuide(struct NewAmigaGuide *nag, Tag tag1, ...); /* Close the viewer and free resources */ void CloseAmigaGuide(AMIGAGUIDECONTEXT handle); ``` **Common tags for `OpenAmigaGuide()`:** | Tag | Description | |---|---| | `AGA_HelpGroup` | Unique ID for help window grouping (V39) | ### Asynchronous Viewer ```c /* Open a non-modal viewer. Returns immediately. */ AMIGAGUIDECONTEXT OpenAmigaGuideAsyncA(struct NewAmigaGuide *nag, struct TagItem *attrs); /* Send a command to an async AmigaGuide instance */ LONG SendAmigaGuideCmdA(AMIGAGUIDECONTEXT handle, STRPTR cmd, struct TagItem *attrs); /* Send a context-sensitive help request */ LONG SendAmigaGuideContextA(AMIGAGUIDECONTEXT handle, struct TagItem *attrs); ``` ### Navigation Commands (SendAmigaGuideCmd) Commands are sent as strings to the async viewer: | Command | Effect | |---|---| | `"BUTTON Contents"` | Click the Contents button | | `"BUTTON Index"` | Click the Index button | | `"BUTTON Retrace"` | Click Retrace | | `"BUTTON Browse <"` | Browse previous | | `"BUTTON Browse >"` | Browse next | | `"BUTTON Help"` | Click Help | | `"NODE <name>"` | Jump to a specific node | | `"QUIT"` | Close the viewer | --- ## Practical Examples ### Example 1: Minimal Help Database ``` @database MyApp.guide @NODE Main "MyApp Help" @{b}MyApp v1.0 Help@{ub} Welcome to MyApp. Choose a topic: @{"Quick Start" LINK QuickStart} @{"Menu Reference" LINK MenuRef} @{"Troubleshooting" LINK Troubleshoot} @EndNode @NODE QuickStart "Quick Start" 1. Double-click the MyApp icon. 2. Select @{"New Project" LINK NewProject} from the Project menu. 3. Save often with @{"Save" SYSTEM "echo Save reminder >CON:0/0/400/50/MyApp"}. @{"Back to Main" LINK Main} @EndNode @NODE MenuRef "Menu Reference" | Menu | Item | Action | | Project | New | Creates a new document | | Project | Open | Opens an existing document | | Project | Save | Saves the current document | @{"Back to Main" LINK Main} @EndNode @NODE Troubleshoot "Troubleshooting" @{b}Common Problems@{ub} @{b}Problem:@{ub} App crashes on startup. @{b}Solution:@{ub} Ensure @{"MYAPP: assign" SYSTEM "assign >NIL:"} exists. @{"Back to Main" LINK Main} @EndNode ``` ### Example 2: Open Help from an Application ```c #include <exec/types.h> #include <libraries/amigaguide.h> #include <proto/amigaguide.h> #include <proto/dos.h> void ShowHelp(CONST_STRPTR dbPath, CONST_STRPTR nodeName) { struct NewAmigaGuide nag = {0}; nag.nag_Name = (STRPTR)dbPath; nag.nag_Node = (STRPTR)nodeName; nag.nag_Flags = NAGF_CLOSE; AMIGAGUIDECONTEXT ctx = OpenAmigaGuide(&nag, TAG_DONE); if (ctx) { /* Synchronous: blocks here until user closes viewer */ CloseAmigaGuide(ctx); } else { LONG err = IoErr(); Printf("Failed to open help: %ld\n", err); } } ``` ### Example 3: Async Help with ARexx Control ```c #include <libraries/amigaguide.h> #include <proto/amigaguide.h> struct NewAmigaGuide nag = {0}; nag.nag_Name = "MyApp.guide"; nag.nag_Node = "Main"; nag.nag_Flags = NAGF_CLOSE | NAGF_NOTIFY; AMIGAGUIDECONTEXT ctx = OpenAmigaGuideAsyncA(&nag, NULL); if (ctx) { /* Application continues running... */ /* Later: programmatically navigate to a node */ SendAmigaGuideCmdA(ctx, "NODE Troubleshoot", NULL); /* Later: close help from code */ SendAmigaGuideCmdA(ctx, "QUIT", NULL); CloseAmigaGuide(ctx); } ``` ### Example 4: Context-Sensitive Help (F1 Key) ```c /* In your IDCMP event loop: */ case IDCMP_RAWKEY: if (code == 0x5B) /* Help key scancode */ { /* Determine which gadget is under the mouse */ UWORD gadID = GetGadgetIDUnderMouse(win); CONST_STRPTR node = "Main"; switch (gadID) { case GAD_OPEN: node = "FileOpen"; break; case GAD_SAVE: node = "FileSave"; break; case GAD_PREFS: node = "Preferences"; break; } ShowHelp("PROGDIR:MyApp.guide", node); } break; ``` --- ## Decision Guide | Criterion | AmigaGuide | Raw Text + More | IFF-FTXT | |---|---|---|---| | **When to use** | Application help; cross-linked docs; need buttons and ARexx | Simple one-page docs; minimal dependencies | Structured text with formatting but no interactivity | | **Interactivity** | Links, ARexx, Shell commands | None | None | | **Images/audio** | Via DataType links (V39+) | None | None | | **Cross-database links** | Yes — `@{"Label" LINK other.guide/node}` | No | No | | **Viewer required** | amigaguide.library or MultiView | Any text viewer | Any IFF text viewer | | **OS version** | OS 2.0+ (full features: 3.0+) | Works everywhere | OS 1.3+ | | **Embedding in app UI** | Can open standalone only; not embeddable as gadget | Display in custom read-only string gadget | Display in custom gadget | --- ## Historical Context & Modern Analogies ### The Elegance of Executable Documentation AmigaGuide was not merely a hypertext format — it was a **programmable application extension mechanism** disguised as a help file. A developer could ship a `.guide` file that, when the user clicked a link, sent an ARexx command back to the running application, executed a shell script to repair a configuration, or opened an IFF image through the DataTypes system. The help file was not static documentation; it was an interactive partner to the application. This design philosophy — **documentation as code** — would not resurface in mainstream computing until the rise of literate programming tools, Jupyter notebooks, and interactive web documentation in the 2010s. In 1991, it was genuinely unique. Consider what a single AmigaGuide database could do without the host application knowing anything about its internal structure: 1. **Navigate internally** — `@NODE` and `@LINK` provide structured hypertext 2. **Control the host application** — `RX` links send ARexx commands to the app's port 3. **Modify the system** — `SYSTEM` links execute shell commands 4. **Display rich media** — cross-links to any DataType-supported image, sound, or animation 5. **Form a documentation graph** — cross-database `@{"Other" LINK lib.guide/Main}` creates a web of help files The host application only needed to call `OpenAmigaGuideAsyncA()` with a file path. Everything else — rendering, navigation, interactivity, media embedding — was handled by `amigaguide.library` and the DataTypes framework. ### The 1991 Competitive Landscape | Platform (1991) | System | Hypertext | Scripting | External Linking | App Control | System Integration | |---|---|---|---|---|---|---| | **AmigaOS** | **AmigaGuide** | Nodes | ARexx (RX/RXS) | Cross-db `.guide` | Yes — ARexx ports | DataTypes, Shell | | **Mac OS** | **HyperCard** (1987) | Visual stacks | HyperTalk | Stack-to-stack | Limited — AppleEvents | Clipboard, File | | **Windows 3.0** | **WinHelp** (`.hlp`) | Popups, macros | Limited macro lang | No | No | ShellExecute | | **NeXTSTEP** | **Help** + **Digital Librarian** | Rich text | No | No | No | Search index | | **UNIX** | **Texinfo** / **man -k`** | Cross-references | No | Info nodes only | No | man path | | **VMS** | **Bookreader** | Structured docs | No | No | No | DEC-specific | The critical differentiator is the **ARexx bidirectional control**. HyperCard stacks could script the Macintosh (via AppleEvents, later), but the help file could not easily send a command to a *specific running application* and expect a response. WinHelp macros were confined to the help viewer itself. AmigaGuide's `RX` links could address any ARexx port on the system — including the application that opened the help file — creating a true conversational relationship between documentation and software. ### How It Worked in Practice: The MUI Developer Reference The **MUI (Magic User Interface)** developer reference — `MUIdev.guide` — is perhaps the finest example of AmigaGuide's power. It was not a manual; it was an ecosystem: | Feature | Traditional Manual | MUIdev.guide | |---|---|---| | Class reference | Static tables | `@NODE` per class with `@TOC` navigation | | Example code | Embedded in text | `SYSTEM` links to run example scripts | | Cross-references | Page numbers | `@LINK` to other `.guide` databases | | Method parameters | Text description | ARexx-driven parameter exploration (in advanced setups) | | Updates | Re-print or new edition | Drop-in replacement `.guide` file | A developer reading about `Listview.mui` could click a link to jump to the `List` class reference in the same file, click another to open the `Popobject.mui` reference in a separate database, and click a third to execute an ARexx script that created a live example window — all without leaving the help viewer. ### Modern Analogies No single modern system replicates AmigaGuide's exact combination of properties, but several come close in different dimensions: | AmigaGuide Concept | Modern Equivalent | Why It Maps (and Where It Diverges) | |---|---|---| | `@NODE` / modular docs | **DITA topics / DocBook `<section>`** | Modular, reusable document fragments. DITA goes further with conditional profiling (`@audience`, `@platform`); AmigaGuide has no conditional text. | | `@{"Label" LINK Node}` | **HTML `<a href>` + anchor** | Direct hypertext navigation. HTML is richer (CSS styling, embedded media); AmigaGuide links are constrained to button-like widgets. | | `RX` / `RXS` — app control from docs | **Jupyter Notebook cells** | Documentation that executes code and returns results. Jupyter is far more powerful (Python, visualization, stateful kernels), but requires a heavy runtime. AmigaGuide's ARexx was lightweight and system-wide. | | `SYSTEM` — shell from docs | **Markdown code fences with `bash` execution** (e.g., R Markdown, Quarto) | Document-embedded command execution. Modern tools sandbox or prompt; AmigaGuide executed with the user's full privileges. | | Cross-database `@LINK other.guide` | **HTML `<a href>` across files** | The web itself is the analogy — a distributed documentation graph. AmigaGuide's `ENV:AmigaGuide/Path` is a primitive `PATH` for docs. | | `amigaguide.library` viewer | **Qt Assistant / Apple Help Viewer / DevDocs** | Dedicated offline help viewers. Modern viewers support full-text search, indexing, and CSS; AmigaGuide had none of these but loaded instantly on 68000-class hardware. | | `.guide` as DataType | **HTML rendered in any WebKit view** | Universal rendering via shared framework. The key difference: a DataType object is an OS-native BOOPSI object; a WebKit view is an application-embedded widget. | | `@ONOPEN` / `@ONCLOSE` | **HTML `<body onload>` / JavaScript `DOMContentLoaded`** | Event-driven document lifecycle. AmigaGuide's events are limited to ARexx commands; modern web docs have full Turing-complete scripting. | ### What Made AmigaGuide Unique (and Unreplicated) Despite the partial modern analogies above, no contemporary system in 1991 — and few today — offered this specific combination: 1. **Zero-compilation hypertext with system-wide reach**: HyperCard required the HyperCard runtime (a separate application). WinHelp required a compiler (`hc.exe`) to build `.hlp` from `.rtf` source. AmigaGuide files are plain ASCII — editable in any text editor, viewable in any AmigaGuide-aware application, with no build step. 2. **Documentation as remote control**: The `RX` link is not merely "run a script" — it is "send a message to a named port." This means the help file can query application state (`ADDRESS MyApp GETVERSION`), trigger actions (`ADDRESS MyApp DOACTION`), or chain multiple applications together. It is RPC embedded in documentation. 3. **Late-bound media embedding**: Because AmigaGuide links to DataTypes, a `.guide` file written in 1991 could embed a PNG image in 1996, an MP3 in 2000, or a video in 2026 — without the help file or the viewer knowing what PNG, MP3, or video formats are. The DataTypes system (see [datatypes.md](datatypes.md)) handles the indirection. 4. **No host application dependency**: A `.guide` file is self-sufficient. It carries its own navigation structure (`@INDEX`, `@TOC`), styling (`@MACRO`, attributes), and actions. The host application does not need to parse, render, or understand the file format — it merely hands the path to `amigaguide.library`. ### Where the Analogies Break Down - **No compilation step**: Unlike WinHelp (`.hlp`) or modern CHM, `.guide` files are raw text — no indexing, compression, or encryption. This is simpler but slower for large documents. - **No full-text search**: The viewer does not index content. Navigation is entirely through pre-defined links or external tools. - **No conditional text**: There is no `#if`, audience profiling, or platform-specific filtering. Every user sees every node. - **Linear rendering**: Nodes are displayed as scrolling text — no pagination, no columns, no responsive layout, no CSS. - **No security model**: `SYSTEM` and `RX` links execute with the user's full privileges. There is no sandbox, no confirmation dialog, and no capability system. A malicious `.guide` file can delete files or send harmful ARexx commands. - **ARexx dependency**: The full power of AmigaGuide requires a functional `rexxsyslib.library` and ARexx port infrastructure. On systems without ARexx, `RX` links fail silently and async mode loses much of its utility. --- ## When to Use / When NOT to Use ### When to Use AmigaGuide | Scenario | Why AmigaGuide Works | |---|---| | **Application help files** | Native OS support; opens from Help key; context-sensitive via `nag_Node` | | **Cross-referenced documentation** | `LINK other.guide/node` creates a documentation ecosystem | | **Interactive tutorials** | `SYSTEM` and `RX` links let users execute commands from within help | | **Small-to-medium docs (< 200 KB)** | Raw text is efficient; no compilation overhead | | **Integration with ARexx-enabled apps** | Help can send commands back to the application | ### When NOT to Use AmigaGuide | Scenario | Problem | Better Alternative | |---|---|---| | **Large manuals (> 500 KB)** | No search; linear loading; slow navigation | Split into multiple `.guide` files or use external viewer | | **Print-quality documentation** | No page layout, margins, or typography control | Texinfo → PostScript, or DTP tools | | **Secure/restricted content** | No access control; plain text is trivially editable | Compiled help (WinHelp-style) or PDF | | **Embedded in-app help pane** | Cannot embed AmigaGuide viewer as a sub-window gadget | Custom read-only BOOPSI gadget with formatted text | | **Modern cross-platform docs** | `.guide` is Amiga-only | HTML, Markdown, or plain text | --- ## Best Practices & Antipatterns ### Best Practices 1. **Always name the first node `MAIN`** — viewers default to it if no starting node is specified. 2. **Set `@INDEX` and `@TOC`** — gives users predictable navigation buttons. 3. **Use `@SMARTWRAP` (V40) instead of `@WORDWRAP`** — produces cleaner output on all viewer versions. 4. **Provide a `@{"Back" LINK ...}` link on every non-MAIN node** — users expect a way back. 5. **Use `PROGDIR:` or assigned paths for cross-database links** — avoids breakage when the user moves the application. 6. **Set `$VER:`** — allows the `Version` command to report the help file version. 7. **Keep nodes focused** — one topic per node; deep nesting via links is better than long scrolling. 8. **Test in both MultiView and standalone AmigaGuide** — rendering differs slightly between viewers. 9. **Use `@MACRO` for consistent styling** (V40) — reduces markup repetition. 10. **Set `@ONCLOSE` to clean up** if your `@{RX}` links create temporary files or ports. ### Antipatterns #### 1. The Missing EndNode ``` /* ANTIPATTERN — @ENDNODE omitted */ @NODE Main "Help" Welcome to the app. @NODE Setup "Setup" Install instructions. @EndNode /* RESULT: "Setup" node includes all text from MAIN onwards because MAIN was never properly closed. */ /* CORRECT — always close every node */ @NODE Main "Help" Welcome to the app. @EndNode @NODE Setup "Setup" Install instructions. @EndNode ``` #### 2. The Broken Cross-Database Link ``` /* ANTIPATTERN — relative path assumes current directory */ @{"See Also" LINK OtherApp.guide/Main} /* If the user opens help from a different directory, this fails. */ /* CORRECT — use an assign or absolute path */ @{"See Also" LINK MYAPP:Docs/OtherApp.guide/Main} ``` #### 3. The Unclean RX Link ``` /* ANTIPATTERN — RX command with unquoted special characters */ @{"Run" RX 'ADDRESS MYPORT Run script with spaces'} /* Parsing ambiguity — may truncate at first space in argument. */ /* CORRECT — quote the argument or use RXS for complex scripts */ @{"Run" RX 'ADDRESS MYPORT "Run script with spaces"'} ``` #### 4. The Invisible Link ``` /* ANTIPATTERN — link text that looks like body text */ For more information see the advanced topics section. /* No clickable link — users won't know it's interactive. */ /* CORRECT — use explicit button-like labels */ For more information, @{"click here for advanced topics" LINK Advanced}. ``` --- ## Pitfalls & Common Mistakes ### 1. Node Name Collisions ``` /* PITFALL — node names are case-insensitive but must be unique */ @NODE Setup "Setup" @NODE setup "Setup Details" /* COLLISION: "setup" == "Setup" */ ``` ### 2. AmigaGuide Path Not Set ``` /* PITFALL — cross-database links fail if ENV:AmigaGuide/Path is missing */ @{"External" LINK SomeLib.guide/Main} /* If SomeLib.guide is not in the current directory or the path, the link silently fails. Set the path at install time: SetEnv AmigaGuide/Path "MYAPP:Docs" */ ``` ### 3. Forgetting Synchronous Blocks ```c /* PITFALL — calling OpenAmigaGuide() from the main task freezes UI */ void OnHelpClick(void) { /* This blocks until the user closes the help window! */ OpenAmigaGuide(&nag, TAG_DONE); /* App is frozen — no IDCMP processing, no timer events */ } /* CORRECT — use async mode for multi-window apps */ void OnHelpClick(void) { ctx = OpenAmigaGuideAsyncA(&nag, NULL); /* App continues; handle help closure via ARexx or ignore */ } ``` ### 4. Dynamic Node Confusion Dynamic nodes are generated on-the-fly by an application hosting `amigaguide.library`. If you are not implementing a dynamic node host, do not use `@DNODE` — it is obsolete and ignored by modern viewers. ### 5. Attribute Nesting Errors ``` /* PITFALL — incorrect nesting of attributes */ @{b}bold @{i}bold-italic@{ub} still italic@{ui} /* @{ub} undoes bold, but italic is still active. Viewer rendering is undefined. */ /* CORRECT — close in reverse order of opening (LIFO) */ @{b}bold @{i}bold-italic@{ui} bold again@{ub} normal ``` --- ## Use Cases ### Real-World Software Using AmigaGuide | Software | AmigaGuide Usage | |---|---| | **MultiView** (OS 3.0+) | Displays any `.guide` file via `amigaguideclass` — the default viewer | | **SAS/C** | Compiler error explanations linked via AmigaGuide | | **Directory Opus** | Configuration help and button reference | | **MUI** | `MUIdev.guide` — the entire MUI developer reference is an AmigaGuide database | | **AmigaOS installer scripts** | Post-install help often launched as AmigaGuide | | **Aminet** | Package documentation frequently shipped as `.guide` files | ### Common Integration Patterns **Pattern A: Context-Sensitive Help** ``` Application maintains a mapping: Window A + Gadget X → "NodeRef/GadgetX" Window B + Menu Y → "NodeRef/MenuY" On Help key: nag.nag_Node = mappedNode; OpenAmigaGuideAsyncA(&nag, NULL); ``` **Pattern B: ARexx-Driven Navigation** ``` Application exposes ARexx port "MYAPP.1" AmigaGuide links use: @{"Do Action" RX 'ADDRESS MYAPP.1 DOACTION'} Result: User clicks help → ARexx command sent → app performs action ``` **Pattern C: Documentation Suite** ``` MyApp.guide (main help) MyApp_API.guide (function reference) MyApp_Tools.guide (utility reference) Cross-links: MyApp.guide: @{"API Reference" LINK MyApp_API.guide/Main} MyApp_API.guide: @{"Back to User Guide" LINK MyApp.guide/Main} ``` ### AmigaOS Developer Documentation as AmigaGuide Commodore itself structured the entire AmigaOS developer documentation corpus as AmigaGuide databases. The **Amiga Developer CD 2.1 (ADCD 2.1)** — the definitive official SDK — shipped the following manuals as `.guide` files: | ADCD 2.1 Path | Content | Approximate Scope | |---|---|---| | `Libraries_Manual_guide/` | *ROM Kernel Reference Manual: Libraries* | Every system library: Exec, DOS, Intuition, Graphics, etc. | | `Devices_Manual_guide/` | *ROM Kernel Reference Manual: Devices* | TrackDisk, Audio, Serial, Parallel, Timer, etc. | | `Hardware_Manual_guide/` | *ROM Kernel Reference Manual: Hardware* | Custom chips, DMA, CIA, chipset registers | | `Includes_and_Autodocs_3._guide/` | NDK 3.1 headers + autodocs | All struct definitions and function-by-function API docs | This was not merely a packaging choice — it was an architectural statement. The same AmigaGuide viewer that displayed a game's help file could display the complete technical reference for `graphics.library` or the Blitter's minterm logic. A developer could: 1. **Browse autodocs interactively** — click `@LINK` cross-references to jump from `AllocMem` to `MemHeader` to `FreeMem` 2. **Keep docs open while coding** — the async viewer sat alongside the editor, navigable without leaving the Workbench 3. **Search with external tools** — because `.guide` files are plain ASCII, `grep` and `Search` could find text inside them; no proprietary indexing format required 4. **Ship custom subsets** — a developer could copy just the relevant autodoc nodes into a project's `Docs/` drawer The autodoc format — a structured comment convention in NDK header files — was also converted to AmigaGuide by community tools. **New Style Autodocs** (Aminet `dev/misc/NSA_amigaguide.lha`, 2002) repackaged library autodocs as hyperlinked `.guide` files with `@NODE` per function and `@TOC` navigation, making the raw API reference far more browsable than scrolling through flat text files. ### Authoring Tools and Converters Because AmigaGuide is plain ASCII, any text editor suffices for authoring. However, several specialized tools streamlined creation and conversion: | Tool | Aminet Path | Purpose | |---|---|---| | **AGWriter** | `text/hyper/AGWriter103.lha` | GUI editor for creating, editing, and validating AmigaGuide files. Supports WYSIWYG-style node management, link insertion (`LINK`, `RX`, `RXS`, `SYSTEM`), and round-trip conversion to plain text. | | **GuideML** | `text/hyper/guideml.lha` | AmigaGuide-to-HTML converter (C + GUI). Converts `@NODE` to HTML pages, `@LINK` to `<a href>`, and attributes to inline styles. Includes source code. | | **ag2html** | `text/hyper/ag2html.lha` | Perl script that converts a `.guide` file into a directory of interlinked HTML files suitable for web serving. | | **HTML2Guide** | `util/conv/HTML2Guide-1.2.lha` | Reverse converter: batch-converts `.html`/`.htm` files (including subdirectories) into a single AmigaGuide database with preserved relative links. | | **New Style Autodocs** | `dev/misc/NSA_amigaguide.lha` | Reformats NDK autodoc text files into hyperlinked AmigaGuide databases with per-function `@NODE` entries. | > [!NOTE] > The ADCD 2.1 online mirror (`http://amigadev.elowar.com/read/ADCD_2.1/`) renders the original AmigaGuide `.guide` files as HTML using modern server-side conversion. The URL structure directly maps to the original ADCD directory layout, preserving the node hierarchy that Commodore established in 1994. --- ## FAQ **Q: Can I embed an image directly in an AmigaGuide node?** > Not inline. You link to it via `@{"Image" LINK picture.iff/Main}` (V39+). The DataTypes viewer opens the image in a separate window or replaces the current view depending on the viewer. **Q: Why does my link to another database fail?** > Either the path is wrong, or `ENV:AmigaGuide/Path` does not include the target directory. Always use assigns (e.g., `MYAPP:Docs/Other.guide/Main`) for reliability. **Q: What is the difference between `RX` and `RXS`?** > `RX` executes an inline ARexx command string. `RXS` executes an ARexx script file from disk. Use `RXS` for complex multi-line scripts. **Q: Can I use AmigaGuide on OS 1.3?** > No. AmigaGuide requires OS 2.0+ for the viewer, and OS 3.0+ for DataType integration (cross-linking to images/audio). On 1.3, use plain text or IFF-FTXT. **Q: How do I make my `.guide` file open from Workbench?** > Set the icon's default tool to `SYS:Utilities/MultiView` (OS 3.0+) or `SYS:Utilities/AmigaGuide`. Ensure `amigaguide.library` is in `LIBS:`. **Q: Is there a size limit for AmigaGuide files?** > No hard limit, but files over ~500 KB become unwieldy due to the lack of full-text search. Split large documentation into multiple linked databases. **Q: Can I convert AmigaGuide to HTML?** > Not natively. Third-party tools exist (e.g., `guide2html` on Aminet) that parse the `@` commands and emit HTML. The mapping is straightforward since the concepts are similar. --- ## References - NDK 3.9: `libraries/amigaguide.h`, `datatypes/amigaguideclass.h` - ADCD 2.1: `amigaguide.library` autodocs (`OpenAmigaGuide`, `OpenAmigaGuideAsync`, `SendAmigaGuideCmd`) - *Amiga ROM Kernel Reference Manual: Libraries* — Appendix C: AmigaGuide - See also: [datatypes.md](datatypes.md) — DataTypes framework that powers `amigaguideclass` and media embedding - See also: [rexxsyslib.md](rexxsyslib.md) — ARexx scripting and port communication - See also: [input_events.md](../09_intuition/input_events.md) — Handling Help key and IDCMP for context-sensitive help - See also: [boopsi.md](../09_intuition/boopsi.md) — BOOPSI foundation underlying the AmigaGuide DataType