diff --git a/lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod b/lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod
index 635e5caeb621b556f0cd8f13a16dc0a0e18dd79f..d2d6c53071897e16b841272e828ccabb265a56dc 100644
--- a/lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod
+++ b/lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod
@@ -61,6 +61,7 @@ mapping(string : DocTokenType) keywordtype =
   "namespace" : METAKEYWORD,
   "endnamespace" : METAKEYWORD,
   "decl" : METAKEYWORD,
+  "directive" : METAKEYWORD,
   "inherit" : METAKEYWORD,
   "enum" : METAKEYWORD,
   "endenum" : METAKEYWORD,
@@ -966,6 +967,25 @@ protected class DocParserClass {
 	}
 	break;
 
+      case "directive":
+	{
+          if (endkeyword)
+            parseError("@%s must stand alone", endkeyword);
+          int first = !meta->type;
+          if (!meta->type)
+            meta->type = "decl";
+          else if (meta->type != "decl")
+            parseError("@directive can not be combined with @%s", meta->type);
+          if (meta->appears)
+            parseError("@appears before @directive");
+          if (meta->belongs)
+            parseError("@belongs before @directive");
+          meta->type = "decl";
+	  string s = String.trim_all_whites(arg);
+          meta->decls += ({ .PikeObjects.CppDirective(s) });
+	}
+	break;
+
       case "appears":
 	{
           if (endkeyword)
diff --git a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod
index 4014da0816bba9fef65d52fbb3ba01d7b6850f95..650dcf66fbeaa33276b96496c5123e63dd174225 100644
--- a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod
+++ b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod
@@ -601,6 +601,20 @@ class Import {
   }
 }
 
+//! Representation of an inherit.
+class CppDirective {
+  //!
+  inherit PikeObject;
+
+  //!
+  constant objtype = "directive";
+
+  protected void create(string directive)
+  {
+    name = directive;
+  }
+}
+
 //! Base class for representing classes, modules and namespaces.
 //!
 //! @seealso
diff --git a/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod b/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod
index badaad769495d8277af8877028b7f3c69352d133..4a05268a92b609dc5522bca720af7ade51133df3 100644
--- a/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod
+++ b/lib/modules/Tools.pmod/AutoDoc.pmod/ProcessXML.pmod
@@ -68,6 +68,7 @@ protected private void processWarning(string message, mixed ... args) {
 //   <constant/>
 //   <typedef/>
 //   <inherit/>
+//   <directive/>
 //   <doc/>
 // </docgroup>
 //
@@ -408,7 +409,7 @@ protected int isText(SimpleNode node) { return node->get_node_type() == XML_TEXT
 protected string renderType(SimpleNode node)
 {
   SimpleNode type_node;
-  if ((< "method", "variable", "constant",
+  if ((< "method", "variable", "constant", "directive",
 	 "typedef", "inherit", "import" >)[node->get_any_name()]) {
     type_node = node;
   } else {
@@ -416,6 +417,7 @@ protected string renderType(SimpleNode node)
       node->get_first_element("method") ||
       node->get_first_element("variable") ||
       node->get_first_element("constant") ||
+      node->get_first_element("directive") ||
       node->get_first_element("typedef") ||
       node->get_first_element("inherit") ||
       node->get_first_element("import");
diff --git a/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_html.pike b/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_html.pike
index 9ad00582b4b808b86f0a1121c85dfc6a0e5fb815..b1901bddc773b4b55a3fb22ca4b43506fbd0f55b 100644
--- a/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_html.pike
+++ b/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_html.pike
@@ -1035,6 +1035,7 @@ void resolve_class_paths(Node n, string|void path, Node|void parent)
   case "import":
   case "typedef":
   case "variable":
+  case "directive":
     // These don't have children.
     attrs->class_path = path;
     return;
@@ -1108,7 +1109,7 @@ string render_class_path(Node n,int|void class_only)
 
 string parse_not_doc(Node n) {
   string ret = "";
-  int method, argument, variable, const, typedf;
+  int method, argument, variable, const, typedf, cppdir;
 
   if (!n) return "";
 
@@ -1234,6 +1235,12 @@ string parse_not_doc(Node n) {
     case "import":
       break;
 
+    case "directive":
+      if(cppdir++) ret += "<br />\n";
+      ret += "<tt><font color='#006666'>" + c->get_attributes()->name +
+	"</font></tt>";
+      break;
+
     default:
       error( "Illegal element " + c->get_any_name() + " in !doc.\n" );
       break;
diff --git a/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_split_html.pike b/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_split_html.pike
index 3eeecb6184e3d2d76e996260af59f3ea0dbd885e..c8f3adcd4f28316182f11429fb4d7c65530694a9 100644
--- a/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_split_html.pike
+++ b/lib/modules/Tools.pmod/Standalone.pmod/autodoc_to_split_html.pike
@@ -90,6 +90,7 @@ class Node
   array(Node) class_children  = ({ });
   array(Node) module_children = ({ });
   array(Node) enum_children = ({ });
+  array(Node) directive_children = ({ });
   array(Node) method_children = ({ });
 
   Node parent;
@@ -112,6 +113,7 @@ class Node
     sort(class_children->name, class_children);
     sort(module_children->name, module_children);
     sort(enum_children->name, enum_children);
+    sort(directive_children->name, directive_children);
     sort(method_children->name, method_children);
 
     method_children = check_uniq(method_children);
@@ -206,6 +208,33 @@ class Node
 	return ({ "" });
 	break;
 
+      case "directive":
+	if( m["homogen-name"] ) {
+	  string name = m["homogen-name"];
+	  directive_children +=
+	    ({ Node( "directive", name, c, this_object() ) });
+	  return ({ "" });
+	}
+
+	// Several different directives documented with the same blurb.
+	array directives = ({});
+	Parser.HTML dirparser = Parser.HTML();
+	dirparser->case_insensitive_tag(1);
+	dirparser->xml_tag_syntax(3);
+	dirparser->add_tag("directive",
+			   lambda(Parser.HTML p, mapping m) {
+			     directives += ({
+			       Parser.parse_html_entities(m->name)
+			     });
+			   } );
+	dirparser->finish(c);
+	foreach(Array.uniq(directives) - ({ 0, "" }), string name) {
+	  directive_children +=
+	    ({ Node( "directive", name, c, this_object() ) });
+	}
+	return ({ "" });
+	break;
+
       case "constant":
       case "variable":
       case "inherit":
@@ -262,9 +291,10 @@ class Node
 
   string make_faked_wrapper(string s)
   {
-    if(type=="method")
-      s = sprintf("<docgroup homogen-type='method' homogen-name='%s'>\n"
+    if((type == "method") || (type == "directive"))
+      s = sprintf("<docgroup homogen-type='%s' homogen-name='%s'>\n"
 		  "%s\n</docgroup>\n",
+		  type,
 		  Parser.encode_html_entities(name), s);
     else
       s = sprintf("<%s name='%s'>\n%s\n</%s>\n",
@@ -489,6 +519,7 @@ class Node
       res += make_navbar_really_low(root->namespace_children, "Namespaces");
     else {
       res += make_navbar_really_low(root->enum_children, "Enums");
+      res += make_navbar_really_low(root->directive_children, "Directives");
       res += make_navbar_really_low(root->method_children, "Methods");
     }
 
@@ -497,7 +528,7 @@ class Node
 
   string make_navbar()
   {
-    if(type=="method")
+    if((type == "method") || (type == "directive"))
       return make_navbar_low(parent);
     else
       return make_navbar_low(this_object());
@@ -509,6 +540,7 @@ class Node
       parent->class_children+
       parent->module_children+
       parent->enum_children+
+      parent->directive_children+
       parent->method_children;
   }
 
@@ -518,6 +550,7 @@ class Node
       class_children+
       module_children+
       enum_children+
+      directive_children+
       method_children;
   }
 
@@ -585,6 +618,7 @@ class Node
     class_children->make_html(template, path, exporter);
     module_children->make_html(template, path, exporter);
     enum_children->make_html(template, path, exporter);
+    directive_children->make_html(template, path, exporter);
     method_children->make_html(template, path, exporter);
 
     int num_segments = sizeof(make_filename()/"/")-1;
@@ -666,6 +700,7 @@ class TopNode {
 	class_children += x->class_children;
 	module_children += x->module_children;
 	enum_children += x->enum_children;
+	directive_children += x->directive_children;
 	method_children += x->method_children;
       }
     type = "autodoc";
@@ -684,7 +719,7 @@ class TopNode {
   int(0..0) find_prev_node() { return 0; }
   int(0..0) find_next_node() { return 0; }
   string make_class_path(void|int(0..1) header) {
-    if(header && sizeof(method_children)) {
+    if(header && (sizeof(method_children) + sizeof(directive_children))) {
       if(default_namespace)
 	return "namespace "+default_namespace;
       else
@@ -706,20 +741,46 @@ class TopNode {
     return (string)res;
   }
 
+  string make_directive_page(array(Node) children)
+  {
+    String.Buffer res = String.Buffer(3500);
+    foreach(children, Node node)
+      res->add("&nbsp;<a href='", make_link(node), "'>",
+	       Parser.encode_html_entities(node->name),
+	       "</a><br />\n");
+    return (string)res;
+  }
+
   string make_content() {
     resolve_reference = my_resolve_reference;
-    if(!sizeof(method_children)) return "";
-
-    string contents = "<nav><table class='sidebar' style='width:100%;'><tr>";
-    foreach(method_children/( sizeof(method_children)/4.0 ),
-            array(Node) children)
-      contents += "<td nowrap='nowrap' valign='top'>" +
-	make_method_page(children) + "</td>";
+    if(!sizeof(method_children) && !sizeof(directive_children)) return "";
+
+    string contents = "<nav><table class='sidebar' style='width:100%;'>\n";
+    if (sizeof(directive_children)) {
+      contents += "<tr>\n";
+      foreach(directive_children/( sizeof(directive_children)/4.0 ),
+	      array(Node) children)
+	contents += "<td nowrap='nowrap' valign='top'>" +
+	  make_directive_page(children) + "</td>";
+      contents += "</tr>\n";
+      if (sizeof(method_children)) {
+	contents += "<tr><td colspan='4'><hr /></td></tr>\n";
+      }
+    }
+    if (sizeof(method_children)) {
+      contents += "<tr>\n";
+      foreach(method_children/( sizeof(method_children)/4.0 ),
+	      array(Node) children)
+	contents += "<td nowrap='nowrap' valign='top'>" +
+	  make_method_page(children) + "</td>";
+      contents += "</tr>\n";
+    }
 
-    contents += "</tr><tr><td colspan='4' nowrap='nowrap'>" +
+    contents += "<tr><td colspan='4' nowrap='nowrap'>" +
       parse_children(Parser.XML.Tree.parse_input(data),
 		     "docgroup", parse_docgroup, 1) +
-      "</td></tr></table></nav>";
+      "</td></tr>\n"
+      "</table></nav>";
 
     return contents;
   }
diff --git a/refdoc/keywords.txt b/refdoc/keywords.txt
index abc812269b690029ccb41c296718f392f64967a4..cc2355f1d6a0f4c9fefb97023beb0e8d9cdc0e2f 100644
--- a/refdoc/keywords.txt
+++ b/refdoc/keywords.txt
@@ -112,6 +112,32 @@ Examples:
 
 _______________________________________________________________________________
 
+Keyword:      @directive
+
+Description:  Document a Pike cpp directive.
+
+	      The rest of the line should be the cpp directive to document.
+
+Arguments:    [name]
+              Where:
+                [name] is a cpp directive.
+Children:     Documentation for the directive.
+Groups with:  @directive
+Note:         Typically only used in the cpp:: namespace.
+Examples:
+              //! @directive #include
+              //!
+              //! The @tt{#include@} directive is used
+              //! to include source code from a different file.
+
+              //! @directive #if
+              //! @directive #endif
+	      //!
+              //!  This is how to document multiple related directives
+	      //!  with one documentation string.
+
+_______________________________________________________________________________
+
 Keyword:      @endclass
 Description:  Leave the class scope entered by @class.
 Arguments:    [name]