Index: nodewords_basic/nodewords_basic.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords_basic/nodewords_basic.module,v
retrieving revision 1.1.2.52
diff -u -p -r1.1.2.52 nodewords_basic.module
--- nodewords_basic/nodewords_basic.module	25 Dec 2009 03:09:07 -0000	1.1.2.52
+++ nodewords_basic/nodewords_basic.module	28 Dec 2009 20:59:32 -0000
@@ -25,7 +25,7 @@ function nodewords_basic_node_type($op, 
  */
 function nodewords_basic_nodewords_api() {
   return array(
-    'version' => 1.1,
+    'version' => '1.9',
   );
 }
 
@@ -322,28 +322,26 @@ function nodewords_basic_description_pre
   switch ($options['type']) {
     case NODEWORDS_TYPE_NODE:
       $bool = (
-        empty($content['value']) &&
         count($options['ids']) == 1 &&
-        ($node = node_load($options['ids'][0])) &&
-        variable_get('nodewords_basic_use_teaser_' . $node->type, variable_get('nodewords_basic_use_teaser', FALSE)) &&
-        !empty($node->teaser)
+        ($node = node_load($options['ids'][0]))
       );
 
       if ($bool) {
-        $content['value'] = nodewords_metatag_from_teaser($node->teaser,
-          $node->format
-        );
+        $content['value'] = nodewords_metatag_from_node_content($node, $content);
       }
       break;
 
     case NODEWORDS_TYPE_TERM:
-      if (empty($content['value']) && count($options['ids']) == 1) {
-        $term = nodewords_get_term($options['ids'][0]);
-        if ($term) {
-          $content['value'] = $term->description;
-        }
+      $bool = (
+        empty($content['value']) &&
+        count($options['ids']) == 1 &&
+        ($term = nodewords_get_term($options['ids'][0]))
+      );
+
+      if ($bool) {
+        $content['value'] = $term->description;
       }
-        break;
+      break;
 
     case NODEWORDS_TYPE_VOCABULARY:
       // TODO: probably we have to do a db_rewrite_sql() query here so access is restricted
@@ -362,28 +360,6 @@ function nodewords_basic_description_pre
   $tags['description'] = empty($content['value']) ? (!empty($options['default']['description']['value']) ? $options['default']['description']['value'] : '') : $content['value'];
 }
 
-function nodewords_basic_description_settings_form(&$form, $form_id, $options) {
-  switch ($form_id) {
-    case 'nodewords_settings_form':
-      $form['metatags_creation']['node_teaser']['nodewords_basic_use_teaser'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Use the node teaser if the description meta tag is not set'),
-        '#description' => t('Using the node teaser to populate the meta tag DESCRIPTION can cause problems with some content types; rather than enabling this option globally, it would be better to enable it separately for each content type (when it has been verified that enabling it for a specific content type does not create problems). This option is overwritten from the similar option for the content type.'),
-        '#default_value' => variable_get('nodewords_basic_use_teaser', FALSE),
-      );
-      break;
-
-    case 'node_type_form':
-      $form['nodewords']['nodewords_basic_use_teaser'] = array(
-        '#type' => 'checkbox',
-        '#title' => t('Use the node teaser if the description meta tag is not set'),
-        '#description' => t('Using the node teaser to populate the meta tag DESCRIPTION can cause problems with some content types; before to enable the option permanently, verify it does not create problems when used with the content type.'),
-        '#default_value' => variable_get('nodewords_basic_use_teaser_' . $form['#node_type']->type, variable_get('nodewords_basic_use_teaser', FALSE)),
-      );
-      break;
-  }
-}
-
 /**
  * Set the form fields used to implement the options for the meta tag.
  */
Index: nodewords_extra/nodewords_extra.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords_extra/nodewords_extra.module,v
retrieving revision 1.1.2.42
diff -u -p -r1.1.2.42 nodewords_extra.module
--- nodewords_extra/nodewords_extra.module	25 Dec 2009 03:09:13 -0000	1.1.2.42
+++ nodewords_extra/nodewords_extra.module	28 Dec 2009 20:59:32 -0000
@@ -43,7 +43,7 @@ function nodewords_extra_menu() {
  */
 function nodewords_extra_nodewords_api() {
   return array(
-    'version' => 1.1,
+    'version' => '1.9',
   );
 }
 
@@ -302,7 +302,7 @@ function nodewords_extra_dc_description_
   if (!isset($form['description'])) {
     $bool = (
       isset($options['node_type']) &&
-      variable_get('nodewords_basic_use_teaser_' . $options['node_type'], variable_get('nodewords_basic_use_teaser', FALSE))
+      variable_get('nodewords_use_teaser_' . $options['node_type'], variable_get('nodewords_use_teaser', FALSE))
     );
 
     if (!$bool) {
Index: nodewords_verification_tags/nodewords_verification_tags.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords_verification_tags/nodewords_verification_tags.module,v
retrieving revision 1.1.2.7
diff -u -p -r1.1.2.7 nodewords_verification_tags.module
--- nodewords_verification_tags/nodewords_verification_tags.module	25 Dec 2009 03:09:09 -0000	1.1.2.7
+++ nodewords_verification_tags/nodewords_verification_tags.module	28 Dec 2009 20:59:32 -0000
@@ -16,7 +16,7 @@
  */
 function nodewords_verification_tags_nodewords_api() {
   return array(
-    'version' => 1.1,
+    'version' => '1.9',
   );
 }
 
Index: nodewords.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords.admin.inc,v
retrieving revision 1.1.2.127
diff -u -p -r1.1.2.127 nodewords.admin.inc
--- nodewords.admin.inc	25 Dec 2009 03:09:03 -0000	1.1.2.127
+++ nodewords.admin.inc	28 Dec 2009 20:59:32 -0000
@@ -154,7 +154,7 @@ function nodewords_pages_edit($form_stat
   );
 
   if (empty($nodewords_form)) {
-    drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+    drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
 
     return $form;
   }
@@ -262,7 +262,7 @@ function nodewords_settings_form() {
     uasort($options, 'strnatcmp');
   }
   else {
-    drupal_set_message(t('There are no modules that implement meta tags. You need to enable at least one module between nodewords_basic.module, nodewords_extra.module, and nodewords_verification_tags.module that are listed under <em>Meta tags</em> in the <a href="@modules-page">modules page</a>.', array('@modules-page' => url('admin/build/modules'))), 'error');
+    drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version. You need to enable at least one module between nodewords_basic.module, nodewords_extra.module, and nodewords_verification_tags.module that are listed under <em>Meta tags</em> in the <a href="@modules-page">modules page</a>.', array('@modules-page' => url('admin/build/modules'))), 'error');
   }
 
   $form['edit'] = array(
@@ -356,16 +356,44 @@ function nodewords_settings_form() {
     $form['metatags_creation']['nodewords_max_size']['#description'] .= ' ' . t('Most of the search engines are now indexing 350 characters, which is not the maximum length actually set for the meta tags. See <a href="@google-blog">Official Google Blog: Two new improvements to Google results pages</a> for more information.', array('@google-blog' => 'http://googleblog.blogspot.com/2009/03/two-new-improvements-to-google-results.html'));
   }
 
-  $form['metatags_creation']['node_teaser'] = array(
+  $form['metatags_creation']['metatags_generation'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Node teaser options'),
-    '#description' => t('These options are for the generation of meta tags content from the node teaser.'),
+    '#title' => t('Meta tags content generation options'),
+    '#description' => t('These options change how a meta tag content is generated from the node content. These settings apply to specific meta tags.'),
     '#collapsible' => TRUE,
   );
 
-  $form['metatags_creation']['node_teaser']['nodewords_use_alt_attribute'] = array(
+  $options = array(
+    NODEWORDS_GENERATION_NONE => t('Do not generate meta tags content'),
+    NODEWORDS_GENERATION_WHEN_EMPTY => t('Generate meta tag content when the meta tag content is empty'),
+  );
+
+  $form['metatags_creation']['metatags_generation']['nodewords_metatags_generation_method'] = array(
+    '#type' => 'radios',
+    '#options' => $options,
+    '#default_value' => variable_get(
+      'nodewords_metatags_generation_method', NODEWORDS_GENERATION_NONE
+    ),
+  );
+
+  $options = array(
+    NODEWORDS_GENERATION_BODY => t('Create meta tags content from the node body'),
+    NODEWORDS_GENERATION_TEASER => t('Create meta tags content from the node teaser'),
+    NODEWORDS_GENERATION_TEASER_BODY => t('Create meta tags content from the node teaser, or the node body when the node teaser is empty'),
+  );
+
+  $form['metatags_creation']['metatags_generation']['nodewords_metatags_generation_source'] = array(
+    '#type' => 'radios',
+    '#title' => t('Generation source'),
+    '#options' => $options,
+    '#default_value' => variable_get(
+      'nodewords_metatags_generation_source', NODEWORDS_GENERATION_TEASER
+    ),
+  );
+
+  $form['metatags_creation']['metatags_generation']['nodewords_use_alt_attribute'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Include the attribute ALT of images in the description meta tag created from the node teaser'),
+    '#title' => t('Replace the tag IMG content with the attribute ALT'),
     '#default_value' => variable_get('nodewords_use_alt_attribute', TRUE),
   );
 
@@ -374,15 +402,15 @@ function nodewords_settings_form() {
     'img_assist' => 'img_assist.module',
   );
 
-  $form['metatags_creation']['node_teaser']['nodewords_filter_modules_output'] = array(
+  $form['metatags_creation']['metatags_generation']['nodewords_filter_modules_output'] = array(
     '#type' => 'checkboxes',
-    '#title' => t('Filter the text added by third-party modules'),
+    '#title' => t('Filter the text added by third-party modules in the node teaser'),
     '#options' => $options,
     '#default_value' => variable_get('nodewords_filter_modules_output', array()),
     '#checkall' => TRUE,
   );
 
-  $form['metatags_creation']['node_teaser']['nodewords_filter_regexp'] = array(
+  $form['metatags_creation']['metatags_generation']['nodewords_filter_regexp'] = array(
     '#type' => 'textfield',
     '#title' => t('Custom regular expression'),
     '#description' => t('A regular expression used to filter the text added in the node teaser from a third-party module. The regular expression uses the <a href="http://www.php.net/manual/en/pcre.pattern.php">Perl compatible</a> syntax.'),
@@ -431,12 +459,11 @@ function nodewords_filter_regexpr_valida
  *
  */
 function nodewords_max_size_validate($element, &$form_state) {
-
   if (!empty($element['#value'])) {
     $value = trim($element['#value']);
 
     if (empty($value) || (!empty($value) && (!is_numeric($value) || $value <= 0))) {
-      form_error($element, t('The value must be a number greater than zero.'));
+      form_error($element, t('The maximum length must be a number greater than zero.'));
     }
   }
 }
@@ -458,7 +485,7 @@ function nodewords_tags_form(&$form_stat
   );
 
   if (empty($form['nodewords'])) {
-    drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+    drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
   }
   else {
     $form['nodewords']['#tree'] = TRUE;
Index: nodewords.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords.install,v
retrieving revision 1.10.2.145
diff -u -p -r1.10.2.145 nodewords.install
--- nodewords.install	25 Dec 2009 03:09:03 -0000	1.10.2.145
+++ nodewords.install	28 Dec 2009 20:59:33 -0000
@@ -220,7 +220,6 @@ function nodewords_update_6100() {
   }
 
   // Delete the old Drupal variable used.
-  variable_del('nodewords');
 
   $ret[] = array(
     'success' => TRUE,
@@ -278,8 +277,6 @@ function nodewords_update_6102() {
     }
   }
 
-  variable_del('nodewords_global');
-
   $ret[] = array(
     'success' => TRUE,
     'query' => check_plain('The default meta tags values have been updated; verify they have the correct values at ' . url('admin/content/nodewords/meta-tags/default', array('absolute' => TRUE))),
@@ -656,9 +653,6 @@ function nodewords_update_6131() {
     }
   }
 
-  variable_del('nodewords-repeat');
-  variable_del('nodewords-use_front');
-
   $ret[] = array(
     'success' => TRUE,
     'query' => 'Updated the module settings.',
@@ -802,11 +796,6 @@ function nodewords_update_6143() {
 
     $ret[] = array(
       'success' => TRUE,
-      'query' => "UPDATE {variable} SET value = 350 WHERE name = 'nodewords_max_size'",
-    );
-
-    $ret[] = array(
-      'success' => TRUE,
       'query' => check_plain('The default maximum meta tags length has been extended to 350 characters to improve Google results pages. See http://googleblog.blogspot.com/2009/03/two-new-improvements-to-google-results.html for more information.'),
     );
   }
@@ -930,30 +919,17 @@ function nodewords_update_6147() {
  */
 function nodewords_update_6149() {
   $ret = array();
-  $value = variable_get('nodewords_basic_use_alt_attribute', NULL);
 
+  $value = variable_get('nodewords_basic_use_alt_attribute', NULL);
   if (isset($value)) {
     variable_set('nodewords_use_alt_attribute', $value);
     variable_del('nodewords_basic_use_alt_attribute');
-
-    $ret[] = array(
-      'success' => TRUE,
-      'query' => 'Updated the module settings.',
-    );
   }
 
-  $value = variable_get('nodewords_collapse_fieldset', NULL);
-
-  if (isset($value)) {
-    variable_del('nodewords_collapse_fieldset');
-
-    if (empty($ret)) {
-      $ret[] = array(
-        'success' => TRUE,
-        'query' => 'Updated the module settings.',
-      );
-    }
-  }
+  $ret[] = array(
+    'success' => TRUE,
+    'query' => 'Updated the module settings.',
+  );
 
   return $ret;
 }
@@ -1289,17 +1265,57 @@ function nodewords_update_6162() {
     array('type', 'id', 'name')
   );
 
-  variable_del('nodewords_update_6139');
-  variable_del('nodewords_update_6145');
-  variable_del('nodewords_update_6147');
-  variable_del('nodewords_update_6156');
-  variable_del('nodewords_update_6159');
   variable_set('nodewords_update_6162', TRUE);
 
   return $ret;
 }
 
 /**
+ * Implements hook_update_N().
+ */
+function nodewords_update_6164() {
+  $node_types = array_keys(node_get_types('names'));
+  $ret = array();
+
+  $value = variable_get('nodewords_basic_use_teaser', NULL);
+  if (isset($value)) {
+    variable_set('nodewords_use_teaser', $value);
+  }
+
+  $value = variable_get('nodewords_basic_user_teaser', NULL);
+  if (isset($value)) {
+    variable_set('nodewords_user_teaser', $value);
+  }
+
+  foreach ($node_types as $node_type) {
+    $value = variable_get('nodewords_basic_use_teaser_' . $node_type, NULL);
+    if (isset($value)) {
+      variable_set('nodewords_use_teaser_' . $node_type, $value);
+      variable_del('nodewords_basic_use_teaser_' . $node_type);
+    }
+
+    $value = variable_get('nodewords_basic_user_teaser_' . $node_type, NULL);
+    if (isset($value)) {
+      variable_del('nodewords_basic_user_teaser_' . $node_type);
+    }
+  }
+
+  $value = variable_get('nodewords_use_teaser', NULL);
+  if (isset($value) && $value) {
+    variable_set('metatags_generation_method', 2);
+  }
+
+  variable_set('nodewords_6164', TRUE);
+
+  $ret[] = array(
+    'success' => TRUE,
+    'query' => 'Updated the module settings',
+  );
+
+  return $ret;
+}
+
+/**
  * Implements hook_uninstall().
  */
 function nodewords_uninstall() {
@@ -1309,7 +1325,8 @@ function nodewords_uninstall() {
   variable_del('nodewords-repeat');
   variable_del('nodewords-use_front');
   variable_del('nodewords_base_url');
-  variable_del('nodewords_basic_use_teaser');
+  variable_del('nodewords_metatags_generation_method');
+  variable_del('nodewords_metatags_generation_source');
   variable_del('nodewords_collapse_fieldset');
   variable_del('nodewords_edit');
   variable_del('nodewords_enable_user_metatags');
@@ -1322,14 +1339,31 @@ function nodewords_uninstall() {
   variable_del('nodewords_list_robots');
   variable_del('nodewords_max_size');
   variable_del('nodewords_update_6113');
+  variable_del('nodewords_update_6139');
+  variable_del('nodewords_update_6145');
+  variable_del('nodewords_update_6147');
+  variable_del('nodewords_update_6156');
+  variable_del('nodewords_update_6159');
   variable_del('nodewords_update_6162');
+  variable_del('nodewords_update_6163');
+  variable_del('nodewords_update_6164');
   variable_del('nodewords_use_alt_attribute');
   variable_del('nodewords_use_frontpage_tags');
+  variable_del('nodewords_use_teaser');
 
   $node_types = array_keys(node_get_types('names'));
+  $variables = array(
+    'nodewords_metatags_generation_method_',
+    'nodewords_metatags_generation_source_',
+    'nodewords_edit_metatags_',
+    'nodewords_filter_modules_output_',
+    'nodewords_filter_regexp_',
+    'nodewords_use_teaser_',
+  );
 
   foreach ($node_types as $node_type) {
-    variable_del('nodewords_edit_metatags_' . $node_type);
-    variable_del('nodewords_basic_use_teaser_' . $node_type);
+    foreach ($variables as $variable) {
+      variable_del($variable . $node_type);
+    }
   }
 }
Index: nodewords.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodewords/nodewords.module,v
retrieving revision 1.57.2.271
diff -u -p -r1.57.2.271 nodewords.module
--- nodewords.module	25 Dec 2009 03:09:03 -0000	1.57.2.271
+++ nodewords.module	28 Dec 2009 20:59:34 -0000
@@ -12,6 +12,16 @@
  */
 
 /**
+ * The minimum API version supported.
+ */
+define('NODEWORDS_MINIMUM_API_VERSION', '1.9');
+
+/**
+ * The current API version implemented.
+ */
+define('NODEWORDS_API_VERSION', '1.9');
+
+/**
  * The type of objects to which the meta tags are associated.
  */
 define('NODEWORDS_TYPE_DEFAULT',    1);
@@ -34,15 +44,12 @@ define('NODEWORDS_HTTP_EQUIV', 1);
 define('NODEWORDS_LINK_REL', 2);
 define('NODEWORDS_LINK_REV', 3);
 
-/**
- * The minimum API version supported.
- */
-define('NODEWORDS_MINIMUM_API_VERSION', '1.1');
+define('NODEWORDS_GENERATION_NONE', 0);
+define('NODEWORDS_GENERATION_WHEN_EMPTY', 1);
 
-/**
- * The current API version implemented.
- */
-define('NODEWORDS_API_VERSION', '1.8');
+define('NODEWORDS_GENERATION_BODY', 1);
+define('NODEWORDS_GENERATION_TEASER', 2);
+define('NODEWORDS_GENERATION_TEASER_BODY', 3);
 
 /**
  * Implements hook_content_extra_fields().
@@ -84,8 +91,8 @@ function nodewords_form_alter(&$form, &$
       )
     );
 
-    if (empty($form['nodewords']) && user_access('administer nodes')) {
-      drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+    if (empty($form['nodewords']) && user_access('administer meta tags')) {
+      drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
     }
   }
 }
@@ -111,6 +118,71 @@ function nodewords_form_node_type_form_a
       '#default_value' => variable_get('nodewords_edit_metatags_' . $form['#node_type']->type, TRUE),
     );
 
+    $form['nodewords']['metatags_generation'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Automatic creation options'),
+      '#description' => t('These options change how a meta tag content is generated from the node content. These settings apply to specific meta tags.'),
+      '#collapsible' => TRUE,
+    );
+
+    $options = array(
+      NODEWORDS_GENERATION_NONE => t('Do not generate meta tags content'),
+      NODEWORDS_GENERATION_WHEN_EMPTY => t('Generate meta tag content when the meta tag content is empty'),
+    );
+
+    $form['nodewords']['metatags_generation']['nodewords_metatags_generation_method'] = array(
+      '#type' => 'radios',
+      '#options' => $options,
+      '#default_value' => variable_get(
+        'nodewords_metatags_generation_method_' . $form['#node_type']->type,
+        variable_get('nodewords_metatags_generation_method' . NODEWORDS_GENERATION_NONE)
+      ),
+    );
+
+    $options = array(
+      NODEWORDS_GENERATION_BODY => t('Create meta tags content from the node body'),
+      NODEWORDS_GENERATION_TEASER => t('Create meta tags content from the node teaser'),
+      NODEWORDS_GENERATION_TEASER_BODY => t('Create meta tags content from the node teaser, or the node body when the node teaser is empty'),
+    );
+
+    $form['nodewords']['metatags_generation']['nodewords_metatags_generation_source'] = array(
+      '#type' => 'radios',
+      '#title' => t('Generation source'),
+      '#options' => $options,
+      '#default_value' => variable_get(
+        'nodewords_metatags_generation_source_' . $form['#node_type']->type,
+        variable_get('nodewords_metatags_generation_source' . NODEWORDS_GENERATION_TEASER)
+      ),
+    );
+
+    $form['nodewords']['metatags_generation']['nodewords_use_alt_attribute'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Replace the tag IMG content with the attribute ALT'),
+      '#default_value' => variable_get('nodewords_use_alt_attribute_' . $form['#node_type']->type, variable_get('nodewords_use_alt_attribute' . TRUE)),
+    );
+
+    $options = array(
+      'imagebrowser' => 'imagebrowser.module',
+      'img_assist' => 'img_assist.module',
+    );
+
+    $form['nodewords']['metatags_generation']['nodewords_filter_modules_output'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Filter the text added by third-party modules in the node teaser'),
+      '#options' => $options,
+      '#default_value' => variable_get('nodewords_filter_modules_output_' . $form['#node_type']->type, variable_get('nodewords_filter_modules_output' . array())),
+      '#checkall' => TRUE,
+    );
+
+    $form['nodewords']['metatags_generation']['nodewords_filter_regexp'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Custom regular expression'),
+      '#description' => t('A regular expression used to filter the text added in the node teaser from a third-party module. The regular expression uses the <a href="http://www.php.net/manual/en/pcre.pattern.php">Perl compatible</a> syntax.'),
+      '#element_validate' => array('nodewords_filter_regexp_validate'),
+      '#default_value' => variable_get('nodewords_filter_regexp_' . $form['#node_type']->type, variable_get('nodewords_filter_regexp' . '')),
+      '#size' => 60,
+    );
+
     foreach (nodewords_get_possible_tags() as $name => $info) {
       $function = $info['tag:function:prefix'] . '_settings_form';
       $options = array(
@@ -152,7 +224,7 @@ function nodewords_form_taxonomy_form_te
     );
 
     if (empty($form['nodewords'])) {
-      drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+      drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
     }
 
     $form['submit']['#weight'] = 45;
@@ -183,7 +255,7 @@ function nodewords_form_taxonomy_form_vo
     );
 
     if (empty($form['nodewords'])) {
-      drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+      drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
     }
 
     $form['submit']['#weight'] = 45;
@@ -535,8 +607,8 @@ function nodewords_user($op, &$edit, &$a
             $tags
           );
 
-          if (empty($form['nodewords']) && user_access('administer users')) {
-            drupal_set_message(t('There are no modules that implement meta tags.'), 'error');
+          if (empty($form['nodewords']) && user_access('administer meta tags')) {
+            drupal_set_message(t('There are no modules that implement meta tags, or that support the current API version.'), 'error');
           }
 
           return $form;
@@ -897,48 +969,109 @@ function nodewords_mass_delete_tags($ids
  * @return
  *   The string to use to populate the meta tag.
  */
-function nodewords_metatag_from_teaser($text, $format, $options = array()) {
+function nodewords_metatag_from_node_content($node, $content, $options = array()) {
   $default_options = array(
     'size' => variable_get('nodewords_max_size', 350),
   );
+  $filters = filter_list_format($node->format);
+  $method = variable_get(
+    'nodewords_metatags_generation_method_' . $node->type,
+    variable_get('nodewords_metatags_generation_method', NODEWORDS_GENERATION_NONE)
+  );
   $options += $default_options;
+  $result = '';
+  $source = variable_get(
+    'nodewords_metatags_generation_source_' . $node->type,
+    variable_get('nodewords_metatags_generation_source', NODEWORDS_GENERATION_TEASER)
+  );
 
-  // We check for the presence of the PHP evaluator filter in the current
-  // format. If the body contains PHP code, we do not split it up to prevent
-  // parse errors.
-  if (isset($format)) {
-    $filters = filter_list_format($format);
-    if (isset($filters['php/0']) && strpos($text, '<?') !== FALSE) {
-      return '';
+  $bool = (
+    $method == NODEWORDS_GENERATION_NONE ||
+    (
+      $method == NODEWORDS_GENERATION_WHEN_EMPTY && !empty($content)
+    )
+  );
+
+  if ($bool) {
+    return $content;
+  }
+
+  if ($source == NODEWORDS_GENERATION_TEASER) {
+    // We check for the presence of the PHP evaluator filter in the current
+    // format. If the text contains PHP code, we do not split it up to prevent
+    // parse errors.
+    if (isset($filters['php/0']) && strpos($node->teaser, '<?') !== FALSE) {
+      $result = '';
+    }
+    else {
+      // Replace the tag IMG with the attribute ALT, and strip off all the
+      // HTML tags.
+      $text = strip_tags(
+        preg_replace_callback('/<img\s[^>]*alt=["\']([^"\']*)["\'][^>]*>/i',
+          '_nodewords_match_callback',
+          $node->teaser
+        )
+      );
+
+      // Remove the strings added from third-party modules.
+      $modules = array_filter(
+        variable_get('nodewords_filter_modules_output', array())
+      );
+      $regexps = array(
+        'imagebrowser' => '/\[ibimage[^\]]*\]/i',
+        'img_assist' => '/\[img_assist[^\]]*\]/i',
+      );
+
+      foreach ($regexps as $module => $regexp) {
+        if (isset($modules[$module])) {
+          $text = preg_replace($regexp, '', $text);
+        }
+      }
+
+      // Remove the text matching the regular expression.
+      if ($regexpr = trim(variable_get('nodewords_filter_regexp', ''))) {
+        $text = preg_replace('/' . $regexp . '/i', '', $text);
+      }
+
+
+      $result = node_teaser(
+        trim(preg_replace('/(\r\n?|\n)/', ' ', $text)),
+        $node->format, $options['size']
+      );
     }
   }
 
-  // Replace the meta tag img with the attribute alt, and strip off all the
-  // HTML tags.
-  $text = strip_tags(
-    preg_replace_callback('/<img\s[^>]*alt=["\']([^"\']*)["\'][^>]*>/i',
-      '_nodewords_teaser_match_callback',
-      $text
+  $bool = (
+    $source == NODEWORDS_GENERATION_BODY ||
+    (
+      $source == NODEWORDS_GENERATION_TEASER_BODY && empty($result)
     )
   );
 
-  // Remove the strings added from third-party modules.
-  $modules = array_filter(variable_get('nodewords_filter_modules_output', array()));
+  if ($bool) {
+    // We check for the presence of the PHP evaluator filter in the current
+    // format. If the text contains PHP code, we do not split it up to prevent
+    // parse errors.
+    if (isset($filters['php/0']) && strpos($node->body, '<?') !== FALSE) {
+      return '';
+    }
 
-  if (isset($modules['imagebrowser'])) {
-    $text = preg_replace('/\[ibimage[^\]]*\]/i', '', $text);
-  }
-  if (isset($modules['img_assist'])) {
-    $text = preg_replace('/\[img_assist[^\]]*\]/i', '', $text);
-  }
+    // Replace the tag IMG with the attribute ALT, and strip off all the
+    // HTML tags.
+    $text = strip_tags(
+      preg_replace_callback('/<img\s[^>]*alt=["\']([^"\']*)["\'][^>]*>/i',
+        '_nodewords_match_callback',
+        $node->body
+      )
+    );
 
-  // Remove the text matching the regular expression.
-  if ($regexp = trim(variable_get('nodewords_filter_regexp', ''))) {
-    $text = preg_replace('/' . $regexp . '/i', '', $text);
+    $result = node_teaser(
+      trim(preg_replace('/(\r\n?|\n)/', ' ', $text)),
+      $node->format, $options['size']
+    );
   }
 
-  // Truncate the string at last space within the given size.
-  return truncate_utf8($text, $options['size'], TRUE);
+  return $result;
 }
 
 /**
@@ -1237,7 +1370,7 @@ function _nodewords_load_all_includes() 
  * Helper function for preg_match_callback(), called when replacing the tag img
  * in the teaser, when using it as meta tag DESCRIPTION content.
  */
-function _nodewords_teaser_match_callback($matches) {
+function _nodewords_match_callback($matches) {
   static $bool;
 
   if (!isset($bool)) {
