Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.24
diff -u -p -r1.24 node.admin.inc
--- modules/node/node.admin.inc	19 Jul 2008 19:04:24 -0000	1.24
+++ modules/node/node.admin.inc	12 Sep 2008 23:08:00 -0000
@@ -47,6 +47,14 @@ function node_configure() {
     '#description' => t('Must users preview posts before submitting?'),
   );
 
+  $form['node_read_more_position'] = array(
+    '#type' => 'radios',
+    '#title' => t("Position of 'Read more' link"),
+    '#default_value' => variable_get('node_read_more_position', 0),
+    '#options' => array(t('Inline with teaser'), t('Below the teaser')),
+    '#description' => t("Where should the 'Read more' link be placed? Inline, at the end of the teaser, or together with the other links below the teaser."),
+  );
+
   $form['#validate'] = array('node_configure_validate');
 
   return system_settings_form($form);
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.974
diff -u -p -r1.974 node.module
--- modules/node/node.module	6 Sep 2008 08:36:20 -0000	1.974
+++ modules/node/node.module	12 Sep 2008 23:08:04 -0000
@@ -135,6 +135,9 @@ function node_theme() {
     'node_submitted' => array(
       'arguments' => array('node' => NULL),
     ),
+    'node_read_more_link' => array(
+      'arguments' => array('node' => NULL),
+    ),
   );
 }
 
@@ -1053,6 +1056,10 @@ function node_view($node, $teaser = FALS
   $content = drupal_render($node->content);
   if ($teaser) {
     $node->teaser = $content;
+    // Check whether there is more to read, then add the 'Read more' link.
+    if (!empty($node->readmore) && !variable_get('node_read_more_position', 0)) {
+      $node->teaser =  _node_read_more_link($node);
+    }
     unset($node->body);
   }
   else {
@@ -1067,6 +1074,52 @@ function node_view($node, $teaser = FALS
 }
 
 /**
+ * Place the 'Read more' link on a suitable position in the teaser.
+ *
+ * @param $teaser
+ *  The teaser in which the link has to be placed.
+ * @param $link
+ *   The link pointing to the full node.
+ *
+ * @return
+ *   The teaser with the link appended.
+ */
+function _node_read_more_link($node) {
+  $link = theme('node_read_more_link', $node);
+  $teaser = $node->teaser;
+
+  // This is a list of all the block tags, taken from _filter_autop().
+  $block_tags = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|p|h[1-6]|hr)';
+
+  // Get last position of the last closing marker and if found, insert the link
+  // before the marker, otherwise simply append link to teaser.
+  if (preg_match('!</?' . $block_tags . '[^>]*>$!i', $teaser, $match, PREG_OFFSET_CAPTURE)) {
+    $teaser = substr_replace($teaser, $link, $match[0][1], 0);
+  }
+  else {
+    $teaser .= $link;
+  }
+
+  return $teaser;
+}
+
+/**
+ * Theme the 'Read more' link.
+ *
+ * @ingroup themeable
+ */
+function theme_node_read_more_link($node) {
+  $title = t('Read the rest of !title.', array('!title' => $node->title));
+
+  // Replace spaces with &nbsp; so that it is not split between lines
+  $text = str_replace(' ', '&nbsp;', t('Read more'));
+
+  $link = l($text, 'node/' . $node->nid, array('html' => TRUE, 'attributes' => array('title' => $title)));
+
+  return ' <span class="read-more">' . $link . '</span>';
+}
+
+/**
  * Apply filters and build the node's standard elements.
  */
 function node_prepare($node, $teaser = FALSE) {
@@ -1428,7 +1481,7 @@ function node_link($type, $node = NULL, 
   $links = array();
 
   if ($type == 'node') {
-    if ($teaser == 1 && $node->teaser && !empty($node->readmore)) {
+    if ($teaser == 1 && $node->teaser && !empty($node->readmore) && variable_get('node_read_more_position', 0)) {
       $links['node_read_more'] = array(
         'title' => t('Read more'),
         'href' => "node/$node->nid",
