anchor.diff:  (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
  +                                   *my-search-engines*)))))")))
  +
  +     (:section
  +      :id "url-dispatchers"
  +      (: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
  +documentation."))
  +
  +     (:section
  +      :id "downloads"
  +      (: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
  +(:nxref :class-name 'nyxt/blocker-mode:blocker-mode) " documentation."))
  +
  +     (:section
  +      :id "custom-commands"
  +      (: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 ()
  +      (: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
  +      (:p "See the " (:nxref :class-name 'prompt-buffer) " class documentation for how
  +to write custom prompt-buffers."))
  +
  +     (:section
  +      :id "hooks"
  +      (: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
  +      (: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
  +      (: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
  +       " 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
  +      (: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
  +        (: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
  +        (: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
  +       (: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)
  +      (: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))
  
positive.code: ;; Make new profile the default:
  \(define-configuration buffer
    ((profile (make-instance (or (find-profile-class (getf *options* :profile)) 'dev-profile)))))"))
      (:p "Then you can start a separate instance of Nyxt using this profile
  with " (:code "nyxt --profile dev --socket /tmp/nyxt.socket") ".")
  
      (:h3 "Password management")
      (:p "Nyxt provides a uniform interface to some password managers including "
          (:a :href "https://keepassxc.org/" "KeepassXC")
          " and " (:a :href "https://www.passwordstore.org/" "Password Store") ". "
          "The supported installed password manager is automatically detected."
          "See the " (:code "password-interface") " buffer slot for customization.")
      (:p "You may use the " (:code "define-configuration") " macro with
  any of the password interfaces to configure them. Please make sure to
  use the package prefixed class name/slot designators within
  the " (:code "define-configuration") " macro.")
      (:ul
       (:li (command-markup 'nyxt/password-mode:save-new-password) ": Query for name and new password to persist in the database.")
       (:li (command-markup 'nyxt/password-mode:copy-password) ": " (command-docstring-first-sentence 'nyxt/password-mode:copy-password)))
  
      (:h3 "Appearance")
      (:p "Much of the visual style can be configured by the user.  Search the
  class slots for 'style'.  To customize the status buffer, see
  the " (:nxref :slot 'status-buffer :class-name 'window) " window slot.")
  
      (:h3 "Advanced configuration")
      (:p "While " (:code "define-configuration") " is convenient, it is mostly
  restricted to class slot configuration.  If you want to do anything else on
  class instantiation, you'll have to specialize the
  lower-level " (:nxref :function 'customize-instance) " generic function.  Example:"
  (:pre (:code "(defmethod customize-instance ((buffer buffer) &key)
    (echo \"Buffer ~a created.\" buffer))")))
      (:p "All classes with metaclass " (:nxref :class-name 'user-class) " call "
          (:nxref :function 'customize-instance) " on instantiation,
  after " (:nxref :function 'initialize-instance)(:code " :after") ".  The primary method is reserved
  to the user, however the " (:code ":after") " method is reserved to the Nyxt
  core to finalize the instance.")
  
      (:h3 "Scripting")
      (:p "You can evaluate code from the command line with "
          (:code "--eval") " and " (:code "--load") ".  From a shell:")
      (:pre (:code "$ nyxt --no-config --eval '+version+' \
    --load my-lib.lisp --eval '(format t \"Hello ~a!~&\" (my-lib:my-world))'"))
      (:p "You can evaluate multiple --eval and --load in a row, they are
  executed in the order they appear.")
      (:p "You can also evaluate a Lisp file from the Nyxt interface with
  the " (command-markup 'load-file) " command.  For
  convenience, " (command-markup 'load-config-file) " (re)loads your initialization file.")
      (:p "You can even make scripts.  Here is an example foo.lisp:")
      (:pre (:code "#!/bin/sh
  #|
  exec nyxt --script \"$0\"
  |#
  
  ;; Your code follows:
  \(format t \"~a~&\" +version+)"))
      (:p "--eval and --load can be commanded to operate over an
  existing instance instead of a separate instance that exits immediately.")
      (:p "The `remote-execution-p' slot of the `browser' class of the remote
  instance must be non-nil.")
      (:p "To let know a private instance of Nyxt to load a foo.lisp script and run its
  `foo' function:")
      (:pre (:code "nyxt --profile nosave --remote --load foo.lisp --eval '(foo)'"))
  
      (:h3 "Headless mode")
      (:p "Similarly to Nyxt's scripting functionality, headless mode runs without a
  graphical user interface. Possible use-cases for this mode are web scraping,
  automations and web page analysis.")
      (:p "To enable headless mode, simply start Nyxt with the "
          (:code "--headless")
          " CLI flag and provide a script file to serve as the configuration file:")
      (:pre (:code "nyxt --headless --config /path/to/your/headless-config.lisp"))
      (:p "Note that you pass it a " (:i "configuration file")
          "—headless mode is only different from the regular Nyxt functions in that it has
  no GUI, and is all the same otherwise, contrary to all the seeming similarities
  to the " (:code "--script") " flag usage.")
      (:p "The example below showcases frequent idioms that are found in the
  mode's configuration file:")
      (:pre (:code "#!/bin/sh
  #|
  exec nyxt --headless --no-auto-config --profile nosave --config \"$0\"
  |#
  
negative.code: 
  (defun config-content ()
    (spinneret:with-html-string
      (:section
       :id "configuration"
       (:h2 "Configuration")
       (:p "Nyxt is written in the Common Lisp programming language which offers a
  great perk: everything in the browser can be customized by the user, even while
  it's running!")
       (:p "To get started with Common Lisp, we recommend checking out
      our web page: "
           (:a :href "https://nyxt.atlas.engineer/learn-lisp" "Learn Lisp")
           ". It contains numerous pointers to other resources, including
          free books both for beginners and seasoned programmers.")
       (:p "Nyxt provides a mechanism for new users unfamiliar with Lisp to
  customize Nyxt. Start by invoking the commands " (command-markup 'describe-class) "
  or " (command-markup 'describe-slot) ".  You can press the button marked 'Configure' to
  change the value of a setting. The settings will be applied immediately and
  saved for future sessions. Please note that these settings will not alter
  existing object instances.")
       (:p "Settings created by Nyxt are stored in "
           (:code (files:expand *auto-config-file*)) ".")
       (:p "Any settings can be overridden manually by "
           (:code (files:expand *config-file*)) ".")
       (:p "The following section assumes knowledge of basic Common Lisp or a
  similar programming language.")
       (:p "The user needs to manually create the Nyxt configuration file, and the parent folders if necessary."
           (when (and (current-buffer)     ; In case manual is dumped.
                      (not (files:nil-pathname-p (files:expand *config-file*))))
             (:p
              "You can also press the button below to create said file, if it's not
  created yet."
              (let ((config-file-path (files:expand *config-file*)))
                (:p (:a :class "button"
                        :href (ps:ps (nyxt/ps:lisp-eval
                                      (:title "maybe-create-config-file")
                                      (if (uiop:file-exists-p config-file-path)
                                          (echo "Configuration file exists")
                                          (progn (ensure-directories-exist config-file-path)
                                                 (ensure-file-exists config-file-path)
                                                 (echo "Configuration file created at ~s."
                                                       config-file-path)))))
                        "Create configuration file"))))))
  
       (:p "Example:")
       (:pre (:code "(define-configuration buffer
    ((default-modes (append '(no-script-mode) %slot-default%))))"))
       (:p "The above turns on the 'no-script-mode' (disables JavaScript) by default for
  every buffer.")
       (:p "The " (:code "define-configuration") " macro can be used to customize
  the slots of classes like the browser, buffers, windows, etc.  Refer to the
  class and slot documentation for the individual details.")
       (:p "To find out about all modes known to Nyxt,
  run " (command-markup 'describe-command) " and type 'mode'.")
  
       (:section
        :id "slot-configuration"
        (:h3 "Slot configuration")
        (:p "Slots store values that can be either accessed (get) or changed
  (set). Setting new values for slots allows many possibilities of customization.
  For instance, keyboard layouts vary across the world. The slot "
            (:nxref :slot 'nyxt/hint-mode:hints-alphabet :class-name 'nyxt/hint-mode:hint-mode)
            " has the default value of "
            (:code "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
            ". If the user has an American keyboard, they can do:")
        (:ol
         (:li "Execute command " (command-markup 'describe-slot) ";")
         (:li "Type " (:code "hints-alphabet")";")
         (:li "Select " (:code "hints-alphabet") " (" (:code "hint-mode") " class option);")
         (:li "Press the button " (:code "Configure") ", and;")
         (:li "Insert the string \"asfdghjkl\"") ".")
        (:p "This will make link-hinting more comfortable for this user. In
  addition, other similar approaches of customization can be applied to slots
  such as " (:nxref :slot 'nyxt/spell-check-mode:spell-check-language :class-name 'nyxt/spell-check-mode:spell-check-mode)
  ", which can be expanded to do the spelling-check of other languages besides English."))
  
       (:section
        :id "buffers-types"
        (:h3 "Different types of buffers")
        (:p "There are multiple buffer classes, such as "
            (:nxref :class-name 'document-buffer) " (for structured documents) and "
            (:nxref :class-name 'input-buffer) " (for buffers that can receive user input).  A "
            (:nxref :class-name 'web-buffer) " class is used for web pages," (:nxref :class-name 'prompt-buffer)
            " for, well,the prompt buffer.  Some buffer classes may inherit from multiple other classes.
  For instance " (:nxref :class-name 'web-buffer) " and " (:nxref :class-name 'prompt-buffer)
            " both inherit from" (:nxref :class-name 'input-buffer) ".")
        (:p "You can configure one of the parent " (:nxref :class-name 'buffer) " classes slots and the new
  values will automatically cascade down as a new default for all child classes-
  unless this slot is specialized by these child classes.
  For instance if you configure the " (:nxref :slot 'override-map :class-name 'input-buffer)
  " slot in " (:nxref :class-name 'input-buffer) ", both " (:nxref :class-name 'panel-buffer) " and "
  (:nxref :class-name 'web-buffer) " classes will inherit from the new value."))
  
       (:section
        :id "keybinding"
        (:h3 "Keybinding configuration")
        (:p "Nyxt supports multiple " (:i "bindings schemes") " such as CUA (the
      default), Emacs or vi.  Changing scheme is as simple as setting the
      corresponding mode as default, e.g. "
            (:nxref :class-name 'nyxt/emacs-mode:emacs-mode) ".  To make the change persistent across sessions,
  add the following to your configuration:")
        (:ul
         (:li "vi bindings:"
              (:pre (:code "(define-configuration buffer
    ((default-modes (append '(vi-normal-mode) %slot-default%))))")))
         (:li "Emacs bindings:"
              (:pre (:code "(define-configuration buffer
    ((default-modes (append '(emacs-mode) %slot-default%))))"))))
        (:p "You can create new scheme names with " (:code "keymaps:make-scheme-name")
            ".  Also see the " (:code "scheme-name") " class and the "
            (:code "define-keyscheme-map") " macro.")
        (:p "To extend the bindings of a specific mode, you can extend the mode with "
            (:code "define-configuration") " and extend its binding scheme with "
            (:code "define-keyscheme-map") ". For example:")
        (:pre (:code "(define-configuration base-mode
    ((keyscheme-map
      (define-keyscheme-map \"my-base\" (list :import %slot-default%)
        keyscheme:vi-normal
        (list \"g b\" (make-command switch-buffer* ()
                      (switch-buffer :current-is-last-p t)))))))"))
        (:p "The " (:nxref :slot 'override-map :class-name 'input-buffer) " is a keymap that has priority over
  all other keymaps.  By default, it has few bindings like the one
  for " (command-markup 'execute-command) ".  You can use it to set keys globally:")
        (:pre (:code "(define-configuration buffer
    ((override-map (let ((map (make-keymap \"override-map\")))
                     (define-key map
                       \"M-x\" 'execute-command
                       \"C-space\" 'nothing)))))"))
        (:p "The " (:nxref  :command 'nothing) " command is useful to override bindings to do
  nothing. Note that it's possible to bind any command, including those of
  disabled modes that are not listed in " (command-markup 'execute-command) ".")
        (:p "In addition, a more flexible approach is to create your own mode with
  your custom keybindings.  When this mode is added first to the buffer mode list,
  its keybindings have priorities over the other modes.
  Note that this kind of global keymaps also have priority over regular character
  insertion, so you should probably not bind anything without modifiers in such a
  keymap.")
        (:pre (:code "(defvar *my-keymap* (make-keymap \"my-map\"))
  \(define-key *my-keymap*
    \"C-f\" 'nyxt/history-mode:history-forwards
    \"C-b\" 'nyxt/history-mode:history-backwards)
  