gnus: Writing New Back Ends

 
 11.7.2.4 Writing New Back Ends
 ..............................
 
 Many back ends are quite similar.  ‘nnml’ is just like ‘nnspool’, but it
 allows you to edit the articles on the server.  ‘nnmh’ is just like
 ‘nnml’, but it doesn’t use an active file, and it doesn’t maintain
 overview databases.  ‘nndir’ is just like ‘nnml’, but it has no concept
 of “groups”, and it doesn’t allow editing articles.
 
    It would make sense if it were possible to “inherit” functions from
 back ends when writing new back ends.  And, indeed, you can do that if
 you want to.  (You don’t have to if you don’t want to, of course.)
 
    All the back ends declare their public variables and functions by
 using a package called ‘nnoo’.
 
    To inherit functions from other back ends (and allow other back ends
 to inherit functions from the current back end), you should use the
 following macros:
 
 ‘nnoo-declare’
      This macro declares the first parameter to be a child of the
      subsequent parameters.  For instance:
 
           (nnoo-declare nndir
             nnml nnmh)
 
      ‘nndir’ has declared here that it intends to inherit functions from
      both ‘nnml’ and ‘nnmh’.
 
 ‘defvoo’
      This macro is equivalent to ‘defvar’, but registers the variable as
      a public server variable.  Most state-oriented variables should be
      declared with ‘defvoo’ instead of ‘defvar’.
 
      In addition to the normal ‘defvar’ parameters, it takes a list of
      variables in the parent back ends to map the variable to when
      executing a function in those back ends.
 
           (defvoo nndir-directory nil
             "Where nndir will look for groups."
             nnml-current-directory nnmh-current-directory)
 
      This means that ‘nnml-current-directory’ will be set to
      ‘nndir-directory’ when an ‘nnml’ function is called on behalf of
      ‘nndir’.  (The same with ‘nnmh’.)
 
 ‘nnoo-define-basics’
      This macro defines some common functions that almost all back ends
      should have.
 
           (nnoo-define-basics nndir)
 
 ‘deffoo’
      This macro is just like ‘defun’ and takes the same parameters.  In
      addition to doing the normal ‘defun’ things, it registers the
      function as being public so that other back ends can inherit it.
 
 ‘nnoo-map-functions’
      This macro allows mapping of functions from the current back end to
      functions from the parent back ends.
 
           (nnoo-map-functions nndir
             (nnml-retrieve-headers 0 nndir-current-group 0 0)
             (nnmh-request-article 0 nndir-current-group 0 0))
 
      This means that when ‘nndir-retrieve-headers’ is called, the first,
      third, and fourth parameters will be passed on to
      ‘nnml-retrieve-headers’, while the second parameter is set to the
      value of ‘nndir-current-group’.
 
 ‘nnoo-import’
      This macro allows importing functions from back ends.  It should be
      the last thing in the source file, since it will only define
      functions that haven’t already been defined.
 
           (nnoo-import nndir
             (nnmh
              nnmh-request-list
              nnmh-request-newgroups)
             (nnml))
 
      This means that calls to ‘nndir-request-list’ should just be passed
      on to ‘nnmh-request-list’, while all public functions from ‘nnml’
      that haven’t been defined in ‘nndir’ yet should be defined now.
 
    Below is a slightly shortened version of the ‘nndir’ back end.
 
      ;;; nndir.el — single directory newsgroup access for Gnus
      ;; Copyright (C) 1995,1996 Free Software Foundation, Inc.
 
      ;;; Code:
 
      (require 'nnheader)
      (require 'nnmh)
      (require 'nnml)
      (require 'nnoo)
      (eval-when-compile (require 'cl))
 
      (nnoo-declare nndir
        nnml nnmh)
 
      (defvoo nndir-directory nil
        "Where nndir will look for groups."
        nnml-current-directory nnmh-current-directory)
 
      (defvoo nndir-nov-is-evil nil
        "*Non-nil means that nndir will never retrieve NOV headers."
        nnml-nov-is-evil)
 
      (defvoo nndir-current-group ""
        nil
        nnml-current-group nnmh-current-group)
      (defvoo nndir-top-directory nil nil nnml-directory nnmh-directory)
      (defvoo nndir-get-new-mail nil nil nnml-get-new-mail nnmh-get-new-mail)
 
      (defvoo nndir-status-string "" nil nnmh-status-string)
      (defconst nndir-version "nndir 1.0")
 
      ;;; Interface functions.
 
      (nnoo-define-basics nndir)
 
      (deffoo nndir-open-server (server &optional defs)
        (setq nndir-directory
              (or (cadr (assq 'nndir-directory defs))
                  server))
        (unless (assq 'nndir-directory defs)
          (push `(nndir-directory ,server) defs))
        (push `(nndir-current-group
                ,(file-name-nondirectory
                  (directory-file-name nndir-directory)))
              defs)
        (push `(nndir-top-directory
                ,(file-name-directory (directory-file-name nndir-directory)))
              defs)
        (nnoo-change-server 'nndir server defs))
 
      (nnoo-map-functions nndir
        (nnml-retrieve-headers 0 nndir-current-group 0 0)
        (nnmh-request-article 0 nndir-current-group 0 0)
        (nnmh-request-group nndir-current-group 0 0)
        (nnmh-close-group nndir-current-group 0))
 
      (nnoo-import nndir
        (nnmh
         nnmh-status-message
         nnmh-request-list
         nnmh-request-newgroups))
 
      (provide 'nndir)