anchor.diff:      ;; It's good tone to `nyxt:quit' after you're done, but if you use nyxt
       ;; --no-socket, you don't have to. Just be ready for some RAM eating :)
       (nyxt:quit)))"))
  -    (:p "The contents of headless-config.lisp feature configuration forms that
  +      (:p "The contents of headless-config.lisp feature configuration forms that
   make Nyxt perform some actions to the opened pages and/or on certain
   hooks. Things you'd most probably want to put there are: ")
  -    (:ul
  -     (:li "Hook bindings, using the " (:nxref :package 'nhooks)
  -          " library and hooks provided by Nyxt.")
  -     (:li "Operations on the page. Check the " (:nxref :package 'nyxt/dom) "
  +      (:ul
  +       (:li "Hook bindings, using the " (:nxref :package 'nhooks)
  +            " library and hooks provided by Nyxt.")
  +       (:li "Operations on the page. Check the " (:nxref :package 'nyxt/dom) "
             library and the " (:nxref :function 'document-model) "method.")
  -     (:ul
  -      (:li "The " (:nxref :function 'document-model)
  -           " method has a reasonably fresh copy of the page DOM (Document Object Model,
  +       (:ul
  +        (:li "The " (:nxref :function 'document-model)
  +             " method has a reasonably fresh copy of the page DOM (Document Object Model,
   reflecting the dynamic structure of the page). It is a " (:nxref :package 'plump "Plump")
  -" DOM, which means that all " (:nxref :package 'plump "Plump") " (and "
  -(:nxref :package 'clss "CLSS") ") functions can be used on it.")
  -      (:li (:nxref :function 'update-document-model)
  -           " is a function to force DOM re-parsing for the cases when you consider the
  +             " DOM, which means that all " (:nxref :package 'plump "Plump") " (and "
  +             (:nxref :package 'clss "CLSS") ") functions can be used on it.")
  +        (:li (:nxref :function 'update-document-model)
  +             " is a function to force DOM re-parsing for the cases when you consider the
   current " (:nxref :function 'document-model) " too outdated.")
  -      (:li (:nxref :function 'clss:select)
  -           " is a CLSS function to find elements using CSS selectors (a terse
  +        (:li (:nxref :function 'clss:select)
  +             " is a CLSS function to find elements using CSS selectors (a terse
              notation for web page element description).")
  -      ;; FIXME: Make a nxref once we update CLSS submodule.
  -      (:li (:code"clss:ordered-select") " is the same as "
  -           (:nxref :function 'clss:select)
  -           ", except it guarantees that all the elements are returned in a
  +        ;; FIXME: Make a nxref once we update CLSS submodule.
  +        (:li (:code"clss:ordered-select") " is the same as "
  +             (:nxref :function 'clss:select)
  +             ", except it guarantees that all the elements are returned in a
              depth-first traversal order.")
  -      (:li (:nxref :function 'nyxt/dom:click-element)
  -           " to programmatically click a certain element (including the ones returned by "
  -           (:nxref :function 'clss:select) ".)")
  -      (:li (:nxref :function 'nyxt/dom:focus-select-element) " to focus an input
  +        (:li (:nxref :function 'nyxt/dom:click-element)
  +             " to programmatically click a certain element (including the ones returned by "
  +             (:nxref :function 'clss:select) ".)")
  +        (:li (:nxref :function 'nyxt/dom:focus-select-element) " to focus an input
              field, for example.")
  -      (:li (:nxref :function 'nyxt/dom:check-element) " to check a checkbox or a radio button.")
  -      (:li (:nxref :function 'nyxt/dom:select-option-element) " to select an option from the "
  -           (:code "<select>") " element options.")))
  -    (:p "Additionally, headless mode gracefully interacts with other CLI toggles the
  +        (:li (:nxref :function 'nyxt/dom:check-element) " to check a checkbox or a radio button.")
  +        (:li (:nxref :function 'nyxt/dom:select-option-element) " to select an option from the "
  +             (:code "<select>") " element options.")))
  +      (:p "Additionally, headless mode gracefully interacts with other CLI toggles the
   Nyxt has:")
  -    (:ul
  -     (:li (:code "--headless") " itself! Notice that you can debug your script
  +      (:ul
  +       (:li (:code "--headless") " itself! Notice that you can debug your script
   by omitting this CLI flag.  When you're confident enough about it, put it back
   in. A good debugging tip, isn't it?")
  -     (:li (:code "--no-socket")
  -          " flag allows starting as many Nyxt instances as your machine can
  +       (:li (:code "--no-socket")
  +            " flag allows starting as many Nyxt instances as your machine can
   handle. Useful to parallelize computations.")
  -     (:li (:code "--profile nosave")
  -          " to not pollute your history and cache with the script-accessed pages."))
  -
  -    (:h2 "Extensions")
  -    (:p "To install an extension, copy inside the "
  -        (:nxref :variable '*extensions-directory*) " (default to "
  -        (:code "~/.local/share/nyxt/extensions")").")
  -    (:p "Extensions are regular Common Lisp systems.")
  -    (:p "A catalogue of extensions is available in the "
  -        (:code "document/EXTENSIONS.org") " file in the source repository.")
  -
  -    (:h2 "Troubleshooting")
  -    (:h3 "Playing videos")
  -    (:p "Nyxt delegates video support to third-party plugins.")
  -    (:p "When using the WebKitGTK backends, GStreamer and its plugins are
  +       (:li (:code "--profile nosave")
  +            " to not pollute your history and cache with the script-accessed pages.")))
  +
  +     (:section
  +      :id "extension"
  +      (:h2 "Extensions")
  +      (:p "To install an extension, copy inside the "
  +          (:nxref :variable '*extensions-directory*) " (default to "
  +          (:code "~/.local/share/nyxt/extensions")").")
  +      (:p "Extensions are regular Common Lisp systems.")
  +      (:p "A catalogue of extensions is available in the "
  +          (:code "document/EXTENSIONS.org") " file in the source repository."))
  +
  +     (:section
  +      :id "troubleshooting"
  +      (:h2 "Troubleshooting")
  +
  +      (:h3 "Playing videos")
  +      (:p "Nyxt delegates video support to third-party plugins.")
  +      (:p "When using the WebKitGTK backends, GStreamer and its plugins are
   leveraged.  Depending on the video, you will need to install some of the
   following packages:")
  -    (:ul
  -     (:li "gst-libav")
  -     (:li "gst-plugins-bad")
  -     (:li "gst-plugins-base")
  -     (:li "gst-plugins-good")
  -     (:li "gst-plugins-ugly"))
  -    (:p "On Debian-based systems, you might be looking for (adapt the version numbers):")
  -    (:ul
  -     (:li "libgstreamer1.0-0")
  -     (:li "gir1.2-gst-plugins-base-1.0"))
  -    (:p "For systems from the Fedora family:")
  -    (:ul
  -     (:li "gstreamer1-devel")
  -     (:li "gstreamer1-plugins-base-devel"))
  -    (:p "After the desired plugins have been installed, clear the GStreamer cache at "
  -        (:code "~/.cache/gstreamer-1.0") " and restart Nyxt.")
  -    (:h3 "Website crashes")
  -    (:p "If some websites systematically crash, try to install all the required Gstreamer plugins
  +      (:ul
  +       (:li "gst-libav")
  +       (:li "gst-plugins-bad")
  +       (:li "gst-plugins-base")
  +       (:li "gst-plugins-good")
  +       (:li "gst-plugins-ugly"))
  +      (:p "On Debian-based systems, you might be looking for (adapt the version numbers):")
  +      (:ul
  +       (:li "libgstreamer1.0-0")
  +       (:li "gir1.2-gst-plugins-base-1.0"))
  +      (:p "For systems from the Fedora family:")
  +      (:ul
  +       (:li "gstreamer1-devel")
  +       (:li "gstreamer1-plugins-base-devel"))
  +      (:p "After the desired plugins have been installed, clear the GStreamer cache at "
  +          (:code "~/.cache/gstreamer-1.0") " and restart Nyxt.")
  +
  +      (:h3 "Website crashes")
  +      (:p "If some websites systematically crash, try to install all the required Gstreamer plugins
   as mentioned in the 'Playing videos' section.")
  -    (:h3 "Input method support (CJK, etc.)")
  -    (:p "Depending on your setup, you might have to set some environment
  +
  +      (:h3 "Input method support (CJK, etc.)")
  +      (:p "Depending on your setup, you might have to set some environment
   variables or run some commands before starting Nyxt, for instance")
  -    (:pre (:code "GTK_IM_MODULE=xim
  +      (:pre (:code "GTK_IM_MODULE=xim
   XMODIFIERS=@im=ibus
   ibus --daemonize --replace --xim"))
  -    (:p "You can persist this change by saving the commands in
  +      (:p "You can persist this change by saving the commands in
   your " (:code ".xprofile") " or similar.")
  -    (:h3 "Font size on HiDPI displays")
  -    (:p "On HiDPI displays, the font size used for displaying web and Nyxt's
  +
  +      (:h3 "Font size on HiDPI displays")
  +      (:p "On HiDPI displays, the font size used for displaying web and Nyxt's
   prompt-buffer content might be too tiny.")
  -    (:p "To fix this issue when using the WebKitGTK render, export the following
  +      (:p "To fix this issue when using the WebKitGTK render, export the following
   environment variable before starting Nyxt:")
  -    (:pre (:code "export GDK_SCALE=2
  +      (:pre (:code "export GDK_SCALE=2
   export GDK_DPI_SCALE=0.5
   nyxt
   "))
  -    (:h3 "StumpWM mouse scroll")
  -    (:p "If the mouse scroll does not work for you, see the "
  -        (:a
  -         :href "https://github.com/stumpwm/stumpwm/wiki/FAQ#my-mouse-wheel-doesnt-work-with-gtk3-applications-add-the-following-to"
  -         "StumpWM FAQ")
  -        " for a fix.")
  -    (:h3 "Blank WebKit web-views")
  -    (:p "If you are experiencing problems with blank web-views on some sites you
  +      (:h3 "StumpWM mouse scroll")
  +      (:p "If the mouse scroll does not work for you, see the "
  +          (:a
  +           :href "https://github.com/stumpwm/stumpwm/wiki/FAQ#my-mouse-wheel-doesnt-work-with-gtk3-applications-add-the-following-to"
  +           "StumpWM FAQ")
  +          " for a fix.")
  +
  +      (:h3 "Blank WebKit web-views")
  +      (:p "If you are experiencing problems with blank web-views on some sites you
       can try to disable compositing. To disable compositing from your
       initialization file, you can do the following: ")
  -    (:pre (:code "(setf (uiop:getenv \"WEBKIT_DISABLE_COMPOSITING_MODE\") \"1\")"))))
  +      (:pre (:code "(setf (uiop:getenv \"WEBKIT_DISABLE_COMPOSITING_MODE\") \"1\")"))))))
  
positive.code: (define-configuration buffer
    ((search-engines (append %slot-default%
                             (mapcar (lambda (engine) (apply 'make-search-engine engine))
                                     *my-search-engines*)))))"))
  
      (:h3 "URL-dispatchers")
      (:p "You can configure which actions to take depending on the URL to be
  loaded.  For instance, you can configure which Torrent program to start to load
  magnet links.  See the" (:nxref :function 'url-dispatching-handler) " function
  documentation.")
  
      (:h3 "Downloads")
      (:p "See the " (command-markup 'nyxt/download-mode:list-downloads) " command and the "
          (:nxref :slot 'download-path :class-name 'buffer) " buffer slot documentation.")
  
      (:h3 "Proxy and Tor")
      (:p "See the " (:nxref :class-name 'nyxt/proxy-mode:proxy-mode) " documentation.")
  
      (:h3 "Blocker mode")
      (:p "This mode blocks access to websites related to especific hosts. To see
  all hosts being blocked, execute command " (:code "describe-variable") ", choose variable "
  (:code "NYXT/BLOCKER-MODE:*DEFAULT-HOSTLIST*") ", and read data on "
  (:code "nyxt/blocker-mode:url-body") " slot." " To customize host blocking, read the "
  (:nxref :class-name 'nyxt/blocker-mode:blocker-mode) " documentation.")
  
      (:h3 "Custom commands")
      (:p "Creating your own invocable commands is similar to creating a Common
  Lisp function, except the form is " (:code "define-command") " instead of "
  (:code "defun") ". If you want this command to be invocable outside of
          the context of a mode, use " (:code "define-command-global") ".")
      (:p "Example:")
      (:pre (:code "(define-command-global bookmark-url ()
    \"Query the user which URL to bookmark.\"
    (let ((url (prompt
                :prompt \"Bookmark URL\"
                :sources (make-instance 'prompter:raw-source))))
      (bookmark-add url)))"))
      (:p "See the " (:nxref :class-name 'prompt-buffer) " class documentation for how
  to write custom prompt-buffers.")
  
      (:h3 "Hooks")
      (:p "Hooks provide a powerful mechanism to tweak the behaviour of various
  events that occur in the context of windows, buffers, modes, etc.")
      (:p "A hook holds a list of " (:i "handlers") ".  Handlers are named and
  typed functions.  Each hook has a dedicated handler constructor.")
      (:p
       "Hooks can be 'run', that is, their handlers are run according to
  the " (:nxref :slot 'nhooks:combination :class-name 'nhooks:hook) " slot of the hook.  This combination is a function
  of the handlers.  Depending on the combination, a hook can run the handlers
  either in parallel, or in order until one fails, or even " (:i "compose")
       " them (pass the result of one as the input of the next).  The handler types
  specify which input and output values are expected.")
      (:p "To add or delete a hook, you only need to know a couple of functions:"
          (:ul
           (:li (:nxref :class-name 'nhooks:handler) " a class to wrap hook handlers in.")
           (:li (:nxref :function 'nhooks:add-hook) " (also known as "
                (:code "hooks:add-hook")
                ") allows you to add a handler to a hook,for it to be invoked when the hook fires.")
           (:li (:code "nhooks:on") " (also available as " (:code "hooks:on")
                ") as a shorthand for the " (:code "nhooks:add-hook") ".")
           (:li (:nxref :function 'nhooks:remove-hook) " (also available as "
                (:code "hooks:remove-hook") ") that removes the handler from a certain hook.")
           (:li (:code "hnooks:once-on") " (also available as " (:code "hooks:once-on")
                ") as a one-shot version of " (:code "nhooks:on")
                " that removes the handler right after it's completed.")))
      (:p "Many hooks are executed at different points in Nyxt, among others:")
      (:ul
       (:li "Global hooks, such as " (:nxref :variable '*after-init-hook*)
            " or " (:nxref :variable '*after-startup-hook*) ".")
       (:li "Window- or buffer-related hooks.")
       (:ul
        (:li (:nxref :slot 'window-make-hook :class-name 'window) " for when a new window is created.")
        (:li (:nxref :slot 'window-delete-hook :class-name 'window) " for when a window is deleted.")
        (:li (:nxref :slot 'window-set-buffer-hook :class-name 'window)
             " for when the " (:nxref :function 'current-buffer) " changes in the window.")
        (:li (:nxref :slot 'buffer-load-hook :class-name 'network-buffer)
             " for when there's a new page loading in the buffer.")
        (:li (:nxref :slot 'buffer-loaded-hook :class-name 'network-buffer)
             " for when this page is mostly done loading (some scripts/image/styles may not
  be fully loaded yet, so you may need to wait a bit after it fires.)")
        (:li (:nxref :slot 'request-resource-hook :class-name 'network-buffer)
             " for when a new request happens. Allows redirecting and blocking requests, and
  is a good place to do something conditioned on the links being loaded.")
        (:li (:nxref :slot 'prompt-buffer-ready-hook :class-name 'prompt-buffer)
             " fires when the prompt buffer is ready for user input. You may need to call "
             (:nxref :function 'prompter:all-ready-p)
             " on the prompt to ensure all the sources it contains are ready too, and then
  you can safely set new inputs and select the necessary suggestions."))
       (:li "Commands :before and :after methods.")
       (:ul
        (:li "Try, for example, "
             (:code "(defmethod set-url :after (&key (prefill-current-url-p t)) ...)")
             " to do something after the set-url finishes executing."))
       (:li "Modes 'enable' and 'disable' methods and their :before, :after, and :around methods."))
      (:p "For instance, if you want to force 'old.reddit.com' over 'www.reddit.com', you
  can set a hook like the following in your configuration file:")
      (:pre (:code "(defun old-reddit-handler (request-data)
    (let ((url (url request-data)))
      (setf (url request-data)
            (if (search \"reddit.com\" (quri:uri-host url))
  
negative.code: 
  \(define-configuration (buffer web-buffer)
    ((default-modes (append '(my-mode) %slot-default%))))"))
        (:p "Bindings are subject to various translations as per "
            (:nxref :variable 'nkeymaps:*translator*) ". "
            "By default if it fails to find a binding it tries again with inverted
  shifts.  For instance if " (:code "C-x C-F") " fails to match anything " (:code "C-x C-f")
            " is tried."
            "See the default value of " (:nxref :variable 'nkeymaps:*translator*) " to learn how to
           custsomize it or set it to " (:code "nil") " to disable all forms of
           translation."))
  
       (:section
        :id "search-engines"
        (:h3 "Search engines")
        (:p "See the " (:nxref :slot 'search-engines :class-name 'context-buffer) " buffer slot
  documentation.  Bookmarks can also be used as search engines, see the
  corresponding section.")
        (:p "Nyxt comes with some default search engines for "
            (:code (format nil "~{~a~^, ~}"
                           (mapcar (lambda (engine)
                                     (quri:uri-host (quri:uri (getf engine :search-url))))
                                   (rest (getf (mopu:slot-properties 'context-buffer 'search-engines)
                                               :initform)))))
            ". "
            "The following example shows one way to add new search engines.")
        (:pre (:code "(defvar *my-search-engines*
    (list
     '(\"python3\" \"https://docs.python.org/3/search.html?q=~a\" \"https://docs.python.org/3\")\
     '(\"doi\" \"https://dx.doi.org/~a\" \"https://dx.doi.org/\")\)
  