diff --git a/pathfilter.info b/pathfilter.info
index 6c72817..209b032 100644
--- a/pathfilter.info
+++ b/pathfilter.info
@@ -1,4 +1,5 @@
 ; $Id$
 name = Path Filter
 description = "Input filter to convert internal paths, such as &quot;internal:node/99&quot;, to their corresponding absolute URL or relative path."
-core = 6.x
+core = 7.x
+files[] = pathfilter.module
diff --git a/pathfilter.install b/pathfilter.install
deleted file mode 100644
index c0f57dc..0000000
--- a/pathfilter.install
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-// $Id$
-
-/**
- * @file
- * Provides install and uninstall functions for pathfilter.
- *
- * Credits:
- * @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk
- */
-
-/**
- * Implementation of hook_uninstall()
- */
-function pathfilter_uninstall() {
-  // Delete all pathfilter variables
-  db_query("DELETE FROM {variable} WHERE name like 'pathfilter_%%'");
-  
-  // Disable pathfilter from all formats
-  db_query("DELETE FROM {filters} WHERE module = '%s'", 'pathfilter');
-  
-  cache_clear_all('variables', 'cache');
-  watchdog('pathfilter', 'Path filter module removed');
-}
-
-/**
- * Fix absolute/relative setting isn't input format-specific
- */
-function pathfilter_update_6101() {
-  // If old variable is different to default
-  // for each input format set new variable only if pathfilter is enabled
-  if (variable_get('pathfilter_link_type', 'absolute') != 'absolute') {
-    foreach (filter_formats() as $format) {
-      $filters = filter_list_format($format->format);
-      if (isset($filters['pathfilter/0'])) {
-        variable_set('pathfilter_link_absolute_'. $format->format, 0);
-      }
-    }
-  }
-  
-  variable_del('pathfilter_link_type');
-  return array();
-}
diff --git a/pathfilter.module b/pathfilter.module
index a027c36..e1fa26b 100644
--- a/pathfilter.module
+++ b/pathfilter.module
@@ -14,143 +14,61 @@
  *
  * [1] http://api.drupal.org/api/4.7/function/url
  *
- * Credits:   
- * @author Ray Zimmerman (drupal.org user "RayZ")
- * @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk
+ * Author:  Ray Zimmerman (drupal.org user "RayZ")
+ * Ported to D7: Brett Lischalk (drupal.org user "blischalk")
+ *
  */
 
 /**
- * Implementation of hook_filter_tips().
- */
-function pathfilter_filter_tips($delta, $format, $long = FALSE) {
-  switch ($delta) {
-    case 0:
-      if ($long) {
-        $output = '<p>'. t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path. Given a site located at http://example.com/mysite, assuming clean URLs are enabled and "internal:admin/user" becomes "http://example.com/mysite/admin/user" and "internal:node/99" becomes "http://example.com/mysite/node/99". If \'node/99\' has a URL alias assigned, such as \'news/latest\' the alias will be substituted giving "http://example.com/mysite/news/latest".') .'</p>';
-        $output .= '<p>'. t('Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.') .'</p>';
-        return $output;
-      }
-      else {
-        return t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path. Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.');
-      }
-      break;
-  }
+* Implement hook_filter_info().
+*/
+function pathfilter_filter_info() {
+  $filters = array();
+  $filters['pathfilter'] = array(
+    'title' => t('URL Path Filter'),
+    'description' => t('Replaces "internal:node/nid" with the appropriate absolute url'),
+    'process callback' => '_pathfilter_filter_process',
+    'default settings' => array(
+      'pathfilter_link_type' => 'absolute',
+    ),
+    'settings callback' => '_pathfilter_settings',
+    'tips callback' => '_pathfilter_filter_tips',
+    );
+  return $filters;
 }
 
 /**
- * Implementation of hook_filter().
- */
-function pathfilter_filter($op, $delta = 0, $format = -1, $text = '') {
-  // The "list" operation provides the module an opportunity to declare
-  // both how many filters it defines and a human-readable name for each filter.
-  // Note that the returned name should be passed through t() for translation.
-  if ($op == 'list') {
-    return array(0 => t('Internal path filter'));
-  }
-
-  // All operations besides "list" provide a $delta argument so we know which
-  // filter they refer to.
-  switch ($delta) {
-    case 0:
-      switch ($op) {
-        // This description is shown in the administrative interface, unlike
-        // the filter tips which are shown in the content editing interface.
-        case 'description':
-          $output = t('Internal paths in single or double quotes, written as "internal:node/99", for example, are replaced with the appropriate absolute URL or path.');
-          $output .= t(' Paths to files in single or double quotes, written as "files:somefile.ext", for example, are replaced with the appropriate URL that can be used to download the file.');
-          return $output;
-          
-        // The actual filtering is performed here. The supplied text should be
-        // returned, once any necessary substitutions have taken place.
-        case 'process':
-          $patterns = array();
-          $replacement = array();
-          $patterns[] = '/(["\'])(internal):([^"#\?\']+)\??([^"#\']+)?#?([^"\']+)?\1/';
-          $patterns[] = '/(["\'])(files):([^"\']+)\1/';
-          
-          // use the 'currying' technique to allow us to pass the format into
-          // the callback function.
-          $callback = _pathfilter_curry(_pathfilter_process, 2);
-          return preg_replace_callback($patterns, $callback($format), $text);
-
-        // Filter settings for pathfilter.
-        case 'settings':
-          return _pathfilter_settings($format);
-          
-        default:
-          return $text;
-      }
-      break;
-  }
-}
-
-/*
- * A 'currying' function that allows paramaters to be passed into the
- * preg_replace_callback callback. Taken from
- * http://ie2.php.net/manual/en/function.preg-replace-callback.php#88013
- */
-function _pathfilter_curry($func, $arity) {
-  return create_function('', "
-    \$args = func_get_args();
-    if(count(\$args) >= $arity)
-      return call_user_func_array('$func', \$args);
-    \$args = var_export(\$args, 1);
-    return create_function('','
-      \$a = func_get_args();
-      \$z = ' . \$args . ';
-      \$a = array_merge(\$z,\$a);
-      return call_user_func_array(\'$func\', \$a);
-    ');
-  ");
+* pathfilter filter process callback
+*
+* The actual filtering is performed here. The supplied text should be
+* returned, once any necessary substitutions have taken place.
+*/
+function _pathfilter_filter_process($text, $filter, $format) {
+  $absolute = isset($filter->settings['pathfilter_link_type']) ? 'TRUE' : 'FALSE';
+  return preg_replace('/"internal:([^"#\?]+)\??([^"#]+)?#?([^"]+)?"/e', "'\"'. url('$1', array('query' => '$2' ? '$2' : NULL, 'fragment' => '$3' ? '$3' : NULL, 'absolute' => ". $absolute .")) .'\"'", $text);
 }
 
-function _pathfilter_process($format, $matches) {
-  switch ($matches[2]) {
-    case 'internal':
-      return _pathfilter_process_internal($format, $matches);
-      break;
-      
-    case 'files':
-      return _pathfilter_process_files($matches);
-  }
-}
-
-function _pathfilter_process_internal($format, $matches) {
-  $absolute = variable_get('pathfilter_link_absolute_'. $format, 1) ? TRUE : FALSE;
-  if (module_exists('i18n')) {
-    if (preg_match('/(node\/([0-9]+))$/', $matches[3], $match)) {
-      // if we have a drupal node url, ensure we get the translated url alias
-      $languages = language_list('enabled');
-      $languages = $languages[1];
-      $language = $languages[i18n_node_get_lang($match[2])];
-      $link = url($match[1], array('language' => $language, 'query' => $matches[4], 'fragment' => $matches[5], 'absolute' => $absolute ));
-    }
-  }
-  $link = $link? $link : url($matches[3], array('query' => $matches[4], 'fragment' => $matches[5], 'absolute' => $absolute ));
-  return $matches[1] . $link . $matches[1];
-}
-
-function _pathfilter_process_files($matches) {
-  return $matches[1] . file_create_url($matches[3]) . $matches[1];
+/**
+* Filter tips callback for creative juice filter.
+*
+* The tips callback allows filters to provide help text to users during the content
+* editing process. Short tips are provided on the content editing screen, while
+* long tips are provided on a separate linked page. Short tips are optional,
+* but long tips are highly recommended.
+*/
+function _pathfilter_filter_tips($filter, $format, $long = FALSE) {
+  return t('Replaces "internal:node/nid" with the appropriate absolute url');
 }
-
 /**
  * Helper settings function for hook_filter('settings').
  */
-function _pathfilter_settings($format) {
-  $form = array();
-  $form['pathfilter'] = array(
-    '#type' => 'fieldset', 
-    '#title' => t('Internal path filter'), 
-    '#collapsible' => TRUE, 
-    '#collapsed' => FALSE,
-  );
-  $form['pathfilter']['pathfilter_link_absolute_'. $format] = array(
+function _pathfilter_settings($form, $form_state, $filter, $format, $defaults) {
+  $settings['pathfilter_link_type'] = array(
     '#type' => 'radios',
     '#title' => t('Convert internal paths to'),
-    '#options' => array(1 => t('Absolute URL (including http://www.example.com)'), 0 => t('Absolute path (relative to document root)')),
-    '#default_value' => variable_get('pathfilter_link_absolute_'. $format, 1),
-    '#description' => t('Should internal paths be transformed to absolute URLs, such as %absolute_url or absolute paths, like %absolute_path. Note that your changes may not appear until the cache has been cleared.', array('%absolute_url' => 'http://www.example.com/my-page', '%absolute_path' => '/my-page')),
+    '#options' => array('absolute' => t('Absolute links'), 'relative' => t('Relative links')),
+    '#default_value' => isset($filter->settings['pathfilter_link_type']) ? $filter->settings['pathfilter_link_type'] : $defaults['pathfilter_link_type'],
+    '#description' => t('Should internal paths be transformed to absolute URLs, such as %absolute or relative paths, like %relative. Note that your changes may not appear until the cache has been cleared.', array('%absolute' => 'http://www.example.com/my-page', '%relative' => '/my-page')),
   );
-  return $form;
-}
\ No newline at end of file
+  return $settings;
+}
diff --git a/tests/pathfilter.test b/tests/pathfilter.test
deleted file mode 100644
index ed17cd6..0000000
--- a/tests/pathfilter.test
+++ /dev/null
@@ -1,194 +0,0 @@
-<?php
-// $Id$
-
-/**
- * @file
- * Tests for Path Filter
- * 
- * Credits:
- * @author Tom Kirkpatrick (drupal.org user "mrfelton"), www.kirkdesigns.co.uk
- */
-
-define(PATHFILTER_OK, 1);
-define(PATHFILTER_NOT_OK, 0);
-
-class PathfilterTestCase extends DrupalWebTestCase {
-    
-  function getInfo() {
-    return array(
-      'name' => t('Path Filter tests'),
-      'desc' => t('Tests Path Filter link parsing'),
-      'group' => t('Path Filter')
-    );
-  }
-
-  /**
-   * Implementation of setUp().
-   */
-  function setUp() {
-    parent::setUp();
-  }
-  
-  /**
-   * Get a sample file of the specified type.
-   */
-  function getTestFile($type, $size = NULL) {
-    // Get a file to upload.
-    $file = current($this->drupalGetTestFiles($type, $size));
-
-    // SimpleTest files incorrectly use "filename" instead of "filepath".
-    $file->filepath = $file->filename;
-    $file->filename = basename($file->filepath);
-    $file->filesize = filesize($file->filepath);
-
-    return $file;
-  }
-  
-  /**
-   * Upload a file to a node.
-   */
-  function uploadNodeFile($file, $field_name, $nid_or_type, $new_revision = TRUE) {
-    $edit = array(
-      'title' => $this->randomName(),
-      'revision' => (string) (int) $new_revision,
-    );
-
-    if (is_numeric($nid_or_type)) {
-      $node = node_load($nid_or_type);
-      $delta = isset($node->$field_name) ? count($node->$field_name) : 0;
-      $edit['files[' . $field_name . '_' . $delta . ']'] = realpath($file->filepath);
-      $this->drupalPost('node/' . $nid_or_type . '/edit', $edit, t('Save'));
-    }
-    else {
-      $edit['files[' . $field_name . '_0]'] = realpath($file->filepath);
-      $type = str_replace('_', '-', $nid_or_type);
-      $this->drupalPost('node/add/' . $type, $edit, t('Save'));
-    }
-
-    $matches = array();
-    preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
-    return $matches[1];
-  }
-
-  function CompareSnippets($snippets) {
-    foreach ($snippets as $before => $after) {
-      $result = pathfilter_filter('process', 0, 1, $before);    
-      if ($after) {
-        $this->assertTrue($result == $after, 'Parsing: '.$before .'<br/> Expected: '. $after. '<br/> But got: '. $result);
-      }
-      else {
-        $this->assertTrue($result == $before, 'Pathfilter should not parse: '. $before.'<br/> But got: '.$result);
-      }
-    }
-  }
-  
-  /**
-  * test_pathfilter
-  **/
-  function testInternalRelative() {
-    variable_set('pathfilter_link_absolute_1', 0);
-    
-    // Create node for testing.
-    $node = $this->drupalCreateNode();
-
-    $snippets = array(      
-      '"internal:admin/user"'                 => '"/admin/user"',
-      '\'internal:admin/user\''               => "'/admin/user'", // single quotes
-      '"internal:node/nid"'                   => '"/node/nid"',
-      '"internal:node/'. $node->nid .'"'        => '"'. drupal_get_path_alias('/node/'. $node->nid) .'"',
-      '"internal:node/nid?page=1#section2"'   => '"/node/nid?page=1#section2"',
-    );
-    $this->CompareSnippets($snippets);
-  }
-  
-/**
-  * test_pathfilter
-  * 
-  * TODO: Write a description of the tests!
-  **/
-  function testInternalAbsolute() {
-    global $base_url;
-    variable_set('pathfilter_link_absolute_1', 1);
-    
-    // Create node for testing.
-    $node = $this->drupalCreateNode();
-    
-    $snippets = array(
-      '"internal:admin/user"'                 => '"'. $base_url .'/admin/user"',
-      '\'internal:admin/user\''               => '\''. $base_url .'/admin/user\'', // single quotes
-      '"internal:node/nid"'                   => '"'. $base_url .'/node/nid"',
-      '"internal:node/'. $node->nid .'"'        => '"'. $base_url .'/'. drupal_get_path_alias('node/'. $node->nid) .'"',
-      '"internal:node/nid?page=1#section2"'   => '"'. $base_url .'/node/nid?page=1#section2"',
-    );
-    $this->CompareSnippets($snippets);
-  }
-
-  /**
-  * test_pathfilter
-  * 
-  * TODO: Write a description of the tests!
-  **/
-  function testFiles() {
-    global $base_url;
-
-    $snippets = array(
-      "'files:images/somefile.jpg'" => "'". file_create_url('images/somefile.jpg') ."'", // single quotes
-      '"files:images/somefile.jpg"' => '"'. file_create_url('images/somefile.jpg') .'"', // double quotes
-    );
-    $this->CompareSnippets($snippets);
-  }
-  
-  
-  /**
-  * test_pathfilter
-  * 
-  * TODO: Write a description of the tests!
-  **/
-  function testFilesInvalidMatches() {
-    $snippets = array(
-      '"internal:admin/user\''              => PATHFILTER_NOT_OK, // mismatched quotes
-      '\'internal:admin/user"'              => PATHFILTER_NOT_OK, // mismatched quotes
-      '"files:images/somefile.jpg'."'"      => PATHFILTER_NOT_OK, // mismatched quotes
-    );
-    $this->CompareSnippets($snippets);
-  }
-  
-
-    
-  /**
-  * testFid
-  * 
-  * TODO: Write a description of the tests!
-  **/
-/*  function testFid() {
-    global $base_url;
-
-    $field_name = 'field_' . strtolower($this->randomName());
-    $type = $this->drupalCreateContentType();
-    
-    $test_file = $this->getTestFile('text');
-
-    // Create a new node with the uploaded file.
-    // FIXME: How can we attach files to a node? (this was taken from filefield tests, but needs adapting)
-    $nid = $this->uploadNodeFile($test_file, 'files', $type->name);
-
-    // Check that the file exists on disk and in the database.
-    $node = node_load($nid, NULL, TRUE);
-    $node_file = $node->files[0];
-    
-    $snippets = array(
-      '"fid::1"' => PATHFILTER_NOT_OK,
-      '"fid:'. $test_file->fid .'"' => '"'. $base_url .'/'. $test_file->filepath.'"',
-    );
-    
-    foreach ($snippets as $before => $after) {
-      $result = pathfilter_filter('process', 0, -1, $before);    
-      if ($after) {
-        $this->assertTrue($result == $after, 'Parsing: '.$before .'<br/> Expected: '. $after. '<br/> But got: '. $result);
-      }
-      else {
-        $this->assertTrue($result == $before, 'Pathfilter should not parse: '. $before.'<br/> But got: '.$result);
-      }
-    }
-  }  */
-}
