? templates/api-project-page.tpl.php
? tests/cvs
Index: api.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/api/api.module,v
retrieving revision 1.88.2.39
diff -u -p -r1.88.2.39 api.module
--- api.module	4 Oct 2009 23:10:34 -0000	1.88.2.39
+++ api.module	4 Oct 2009 23:57:19 -0000
@@ -142,6 +142,14 @@ function api_menu() {
     'page arguments' => array($default_branch, 'group'),
     'type' => MENU_CALLBACK,
   );
+  $items['api/projects'] = array(
+    'title' => 'Projects',
+    'page callback' => 'api_page_listing',
+    'access callback' => $access_callback,
+    'access arguments' => $access_arguments,
+    'page arguments' => array($default_branch, 'project'),
+    'type' => MENU_CALLBACK,
+  );
 
   $items['api/search'] = array(
     'title' => 'API Search',
@@ -273,6 +281,15 @@ function api_menu() {
     'access arguments' => $access_arguments,
     'type' => MENU_CALLBACK,
   );
+  $items['api/project/%api_object'] = array(
+    'title' => 'Project',
+    'load arguments' => array('project', $default_branch),
+    'page callback' => 'api_page_project',
+    'page arguments' => array(2),
+    'access callback' => $access_callback,
+    'access arguments' => $access_arguments,
+    'type' => MENU_CALLBACK,
+  );
 
   $items['api/opensearch/%'] = array(
     'page callback' => 'api_opensearch',
@@ -412,6 +429,15 @@ function api_menu() {
       'access arguments' => $access_arguments,
       'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
     );
+    $items['api/project/%api_object/'. $branch->branch_name] = array(
+      'title' => $branch->title,
+      'load arguments' => array('project', $branch->branch_name),
+      'page callback' => 'api_page_project',
+      'page arguments' => array(2),
+      'access callback' => $access_callback,
+      'access arguments' => $access_arguments,
+      'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+    );
     $items['api/search/'. $branch->branch_name .'/%menu_tail'] = array(
       'title' => $branch->title,
       'page callback' => 'api_search_listing',
@@ -561,6 +587,14 @@ function api_theme() {
       ),
       'template' => 'templates/api-group-page'
     ),
+    'api_project_page' => array(
+      'arguments' => array(
+        'summary' => NULL,
+        'documentation' => NULL,
+        'functions' => NULL,
+      ),
+      'template' => 'templates/api-project-page'
+    ),
     'api_branch_default_page' => array(
       'arguments' => array(
         'branch' => NULL,
@@ -637,6 +671,7 @@ function api_block($op, $delta = NULL, $
 
             $links = array();
             $links[] = l($branches[$branch]->title, 'api'. $suffix);
+            $links[] = l(t('Projects'), 'api/projects'. $suffix);
             $links[] = l(t('Constants'), 'api/constants'. $suffix);
             $links[] = l(t('Files'), 'api/files'. $suffix);
             $links[] = l(t('Functions'), 'api/functions'. $suffix);
@@ -1309,6 +1344,43 @@ function api_page_group($group) {
   return $output;
 }
 
+/**
+ * Menu callback; displays documentation for a project (a module or theme
+ * defined by an info file).
+ */
+function api_page_project($global) {
+  drupal_set_title($global->title);
+  $documentation = api_link_documentation($global->documentation, $global->branch_name);
+
+  // When parsing info files, we could probably assume that everything 
+  // in the same folder is part of the 'project'
+  // Not always, but it's hard to reference the related files and functions 
+  // based on what we (don't) know.
+  //
+  // Scan the directory and point at nearby stuff?
+  
+  // This does pretty much what api_page_file() does,
+  // currently just for the matching *.module
+  // TODO a whole directory?
+  $module_file_name = dirname($global->file_name) .'/'. $global->object_name .'.module';
+  $result = db_query("SELECT title, object_name, summary, object_type, branch_name FROM {api_documentation} WHERE file_name = '%s' AND branch_name = '%s' AND object_type IN ('constant', 'global', 'function') ORDER BY title", $module_file_name, $global->branch_name);
+  while ($object = db_fetch_object($result)) {
+    $rows[] = array(
+      l($object->title, 'api/'. $object->object_type .'/'. $object->object_name .'/'. $object->branch_name),
+      api_link_documentation($object->summary, $global->branch_name),
+    );
+  }
+  $header = array(
+    t('Name'),
+    t('Description'),
+  );
+  if (count($rows) > 0) {
+    $contents = theme('table', $header, $rows);
+  }
+
+  return theme('api_project_page', $global->summary, $documentation, $contents);
+}
+
 function api_related_topics($did, $branch_name) {
   $header = array(
     t('Name'),
Index: parser.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/api/parser.inc,v
retrieving revision 1.41.2.24
diff -u -p -r1.41.2.24 parser.inc
--- parser.inc	14 Sep 2009 00:22:52 -0000	1.41.2.24
+++ parser.inc	4 Oct 2009 23:57:19 -0000
@@ -35,6 +35,7 @@ function api_parse_file($callback, $file
     'branch_name' => $branch_name,
     'object_type' => 'file',
     'file_name' => $file_name,
+    'file_path' => $file_path,
     'title' => strpos($file_name, '/') ? substr($file_name, strrpos($file_name, '/') + 1) : $file_name,
     'documentation' => '',
     'version' => '',
@@ -238,6 +239,42 @@ function api_parse_php_file($docblock) {
 }
 
 /**
+ * Read in the file at the given path and parse it as an ini file.
+ * 
+ * Save the info as a 'project' definition - projects can be modules, themes or
+ * profiles. Usually modules.
+ * 
+ * TODO Equate drupal 'package' with doxygen 'groups'?  -  tricky to include the
+ * inc files
+ * 
+ * @see drupal_parse_info_file()
+ * @see module_rebuild_cache()
+ */
+function api_parse_info_file($docblock) {
+  // Docblock needs to hand us the filepath of our thing
+  $info = drupal_parse_info_file($docblock['file_path']);
+
+  // Merge in defaults.
+  $defaults = array(
+    'dependencies' => array(),
+    'dependents' => array(),
+    'description' => '',
+    'version' => NULL,
+  );
+  $info = $info + $defaults;
+
+  // Set up documentation block for module
+  $docblock['object_name'] = pathinfo($docblock['file_name'], PATHINFO_FILENAME);
+  $docblock['object_type'] = 'project';
+  $docblock['title'] = $info['name'] . (isset($info['package']) ? ' ('. $info['package'] .')' : '');
+  $docblock['summary'] = $info['description'];
+  $docblock['documentation'] = api_format_info($info, $docblock['branch_name']);
+  $docblock['version'] = $info['version'];
+  
+  api_save_documentation(array($docblock));
+}
+
+/**
  * Find functions called in a formatted block of code.
  */
 function api_parse_function_calls($code) {
@@ -474,6 +511,31 @@ function api_format_embedded_php($matche
 }
 
 /**
+ * Formatted version of module info and dependancies
+ * 
+ * TODO should this actually be a theme_() function or handled in the page
+ * display callback api_page_project() ? Here I'm formatting it before putting
+ * it into the DB. Seems like the other ones are doing something similar.
+ */
+function api_format_info($info, $branch) {
+  $output = '';
+  if (!empty($info['dependencies'])) {
+    $output .= "<dt>Dependencies</dt><dd>". join($info['dependencies'], ', ') ."</dd>";
+  }
+  if (!empty($info->dependents)) {
+    $output .= "<dt>Dependents</dt><dd>". join($info['dependents'], ', ') ."</dd>";
+  }
+  if (!empty($info['version'])) {
+    $output .= "<dt>Version</dt><dd>{$info['version']}</dd>";
+  }
+  if (!empty($info['php'])) {
+    $output .= "<dt>PHP version</dt><dd>{$info['php']}</dd>";
+  }
+  $output = "<dd>$output</dd>";
+  return $output;
+}
+
+/**
  * Parse a block of text for lists that use hyphens or asterisks as bullets, and
  * format them as proper HTML lists.
  */
@@ -676,7 +738,6 @@ function api_schedule_shutdown() {
 function api_shutdown() {
   // Figure out all the dids of the object/branch/types.
   db_query('UPDATE {api_reference_storage} r INNER JOIN {api_documentation} d ON r.object_name = d.object_name AND r.branch_name = d.branch_name AND r.object_type = d.object_type SET r.to_did = d.did');
-
   $directory = file_directory_path();
   if (is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC)) {
     $path = file_create_path('api');
@@ -723,6 +784,8 @@ function api_update_branch($branch) {
 
     'htm' => 'api_parse_html_file',
     'html' => 'api_parse_html_file',
+
+    'info' => 'api_parse_info_file',
   );
 
   // List all documented files for the branch.
@@ -742,6 +805,7 @@ function api_update_branch($branch) {
       else { // New file.
         $parse = TRUE;
       }
+
       if ($parse) {
         job_queue_add('api_parse_file', t('API parse %branch %file'), array($parse_functions[$matches[1]], $path, '%branch' => $branch->branch_name, '%file' => $file_name), drupal_get_path('module', 'api') .'/parser.inc', TRUE);
       }
@@ -804,7 +868,11 @@ function api_scan_directories($directori
         }
       }
       if (!$excluded) {
-        $file_name = substr($path, strlen($common_ancestor) + 1);
+        # dman
+        # this is truncating something off the path. not sure what the +1 was trying to achieve
+        # $file_name = substr($path, strlen($common_ancestor) + 1);
+        $file_name = substr($path, strlen($common_ancestor));
+
         $source_files[$path] = $file_name;
       }
     }
Index: templates/api-branch-default-page.tpl.php
===================================================================
RCS file: /cvs/drupal/contributions/modules/api/templates/Attic/api-branch-default-page.tpl.php,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 api-branch-default-page.tpl.php
--- templates/api-branch-default-page.tpl.php	5 Aug 2009 07:31:19 -0000	1.1.2.1
+++ templates/api-branch-default-page.tpl.php	4 Oct 2009 23:57:19 -0000
@@ -1,6 +1,7 @@
 <?php if (!empty($branch)) { ?>
   <h3><?php print l('Topics', 'api/groups/' . $branch); ?></h3>
   <?php print api_page_listing($branch, 'group'); ?>
+  <h3><?php print l('Projects', 'api/projects/' . $branch); ?></h3>
   <h3><?php print l('Files', 'api/files/' . $branch); ?></h3>
   <h3><?php print l('Globals', 'api/globals/' . $branch); ?></h3>
   <h3><?php print l('Constants', 'api/constants/' . $branch); ?></h3>
