Index: geshifilter.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/geshifilter/geshifilter.admin.inc,v retrieving revision 1.20 diff -u -b -u -p -r1.20 geshifilter.admin.inc --- geshifilter.admin.inc 27 Jun 2009 12:54:15 -0000 1.20 +++ geshifilter.admin.inc 27 Jun 2009 16:45:09 -0000 @@ -246,6 +246,7 @@ function geshifilter_admin_general_setti if (variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE) == GESHIFILTER_CSS_CLASSES_AUTOMATIC) { _geshifilter_generate_languages_css_file(); } + // Always clear the filter cache. _geshifilter_clear_filter_cache(); } @@ -486,7 +487,8 @@ function _geshifilter_flush_language_def */ function _geshifilter_clear_filter_cache() { $message = FALSE; - // iterate over input formats + + // Iterate over input formats and clear the ones GeSHi filter is active in. foreach (filter_formats() as $format => $input_format) { // Get the filters in this input format $filters = filter_list_format($format); @@ -496,7 +498,12 @@ function _geshifilter_clear_filter_cache $message = TRUE; } } - // show a message that the filter cache was cleared + + // Clear the geshifilter entries in the cache_filter table, + // created by geshifilter_geshi_process(). + cache_clear_all('geshifilter:', 'cache_filter', TRUE); + + // Show a message that the filter cache was cleared. if ($message) { drupal_set_message(t('GeSHi filter cleared the filter cache for the appropriate input formats.')); } Index: geshifilter.pages.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/geshifilter/geshifilter.pages.inc,v retrieving revision 1.10 diff -u -b -u -p -r1.10 geshifilter.pages.inc --- geshifilter.pages.inc 4 Jan 2009 17:44:38 -0000 1.10 +++ geshifilter.pages.inc 27 Jun 2009 16:45:09 -0000 @@ -311,6 +311,15 @@ function geshifilter_geshi_process($sour drupal_set_message($geshi_library['message'], 'error'); return $source_code; } + + // Check for a cached version of this source code and return it if available. + // @todo: Use a dedicated table instead of using cache_filter? If so, + // also take care of the flushing in _geshifilter_clear_filter_cache(). + $cache_id = "geshifilter:$lang:$line_numbering:$line_numbering:$inline_mode" . md5($source_code); + if ($cached = cache_get($cache_id, 'cache_filter')) { + return $cached->data; + } + // remove leading/trailing newlines $source_code = trim($source_code, "\n\r"); // create GeSHi object @@ -341,6 +350,11 @@ function geshifilter_geshi_process($sour } $source_code = '
'. $geshi->parse_code() .'
'; } + + // Store in cache with a minimum expiration time of 1 day. + cache_set($cache_id, $source_code, 'cache_filter', time() + (60 * 60 * 24)); + + return $source_code; } Index: geshifield/geshifield.info =================================================================== RCS file: geshifield/geshifield.info diff -N geshifield/geshifield.info --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ geshifield/geshifield.info 27 Jun 2009 16:45:09 -0000 @@ -0,0 +1,7 @@ +; $Id$ +name = "GeSHi field" +description = "Provides a CCK field for source code with GeSHI syntax highlighting." +package = "Filters" +core = 6.x +dependencies[] = content +dependencies[] = geshifilter Index: geshifield/geshifield.install =================================================================== RCS file: geshifield/geshifield.install diff -N geshifield/geshifield.install --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ geshifield/geshifield.install 27 Jun 2009 16:45:09 -0000 @@ -0,0 +1,36 @@ + array( + 'arguments' => array('element' => NULL), + ), + 'geshifield_formatter_default' => array( + 'arguments' => array('element' => NULL), + ), + 'geshifield_formatter_nohighlighting' => array( + 'arguments' => array('element' => NULL), + ), + 'geshifield_formatter_trimmed' => array( + 'arguments' => array('element' => NULL), + ), + ); +} + + +/** + * Implementation of hook_field_info(). + */ +function geshifield_field_info() { + return array( + 'geshifield' => array( + // @todo: better label? "Source code field"? + 'label' => t('GeSHi field'), + 'description' => t('Source code text field with GeSHi syntax highlighting.'), + ) + ); +} + +/** + * Implementation of hook_field_settings(). + */ +function geshifield_field_settings($op, $field) { + switch ($op) { + case 'database columns': + $columns = array( + 'sourcecode' => array( + 'type' => 'text', + 'size' => 'big', + 'not null' => FALSE, + 'sortable' => TRUE, + 'views' => TRUE, //@todo what does this do? + ), + 'language' => array( + 'type' => 'varchar', + 'length' => 32, + 'not null' => FALSE, + 'sortable' => TRUE, + 'views' => TRUE, //@todo what does this do? + ), + ); + return $columns; + } +} + + +/** + * Implementation of hook_field(). + */ +function geshifield_field($op, &$node, $field, &$items, $teaser, $page) { + // Nothing to do here. + // Typically only the validition operation is needed in this hook + // but for geshifield even this is not needed. +} + +/** + * Implementation of hook_content_is_empty(). + */ +function geshifield_content_is_empty($item, $field) { + return empty($item['sourcecode']); +} + +/** + * Implementation of hook_widget_info(). + */ +function geshifield_widget_info() { + return array( + 'geshifield_textarea' => array( + 'label' => t('Source code text area'), + 'field types' => array('geshifield'), + // Let CCK core handle multiple values. + 'multiple values' => CONTENT_HANDLE_CORE, + 'callbacks' => array( + // Do not provide default values through CCK core's + // default value handling. @todo: or should we? + 'default value' => CONTENT_CALLBACK_NONE, + ), + ), + ); + // @todo provide a file upload widget too. +} + +/** + * Implementation of hook_elements(). + */ +function geshifield_elements() { + $elements = array( + 'geshifield_textarea' => array( + '#input' => TRUE, + '#process' => array('geshifield_textarea_process' ), + ), + ); + return $elements; +} + +/** + * Process callback for geshifield_textarea widget. + */ +function geshifield_textarea_process($element, $edit, &$form_state, $form) { + module_load_include('inc', 'geshifilter'); + + $defaults = $element['#value']; + $field = content_fields($element['#field_name'], $element['#type_name']); + + $enabled_languages = _geshifilter_get_enabled_languages(); + // @todo: also add "no highlighting" options. + + $element['sourcecode'] = array( + '#type' => 'textarea', + '#title' => t('Source code'), + '#default_value' => $defaults['sourcecode'], + '#required' => $field['required'], + '#rows' => $field['widget']['rows'], + '#description' => t($field['widget']['description']), + ); + + $element['language'] = array( + '#type' => 'select', + '#title' => t('Syntax highlighting mode'), + '#default_value' => $defaults['language'], + '#options' => $enabled_languages, + '#description' => t('Select the syntax highlighting mode to use for the source code.'), + ); + + return $element; +} + +/** + * Theming function for the geshifield_textarea widget + */ +function theme_geshifield_textarea(&$element) { + return theme( 'form_element', $element, $element['#children'] ); +} + +/** + * Implementation of hook_widget_settings(). + */ +function geshifield_widget_settings($op, $widget) { + switch ($op) { + case 'form': + $form = array(); + $form['rows'] = array( + '#type' => 'textfield', + '#title' => t('Default number of rows in text area'), + '#description' => t('The default number of rows to provide in the text area for entering the source code.'), + '#default_value' => isset($widget['rows']) ? $widget['rows'] : 20, + '#required' => TRUE, + ); + // @todo add an option for the default language + return $form; + break; + + case 'validate': + if (!is_numeric($widget['rows']) || intval($widget['rows']) != $widget['rows'] || $widget['rows'] <= 0 || $widget['rows'] > 100) { + form_set_error('rows', t('The number of rows must be an integer between 1 and 100.')); + } + break; + + case 'save': + return array('rows'); + break; + } +} + +/** + * Implementation of hook_widget(). + */ +function geshifield_widget(&$form, &$form_state, $field, $items, $delta = 0) { + $element = array( + '#type' => $field['widget']['type'], + '#default_value' => isset($items[$delta]) ? $items[$delta] : '', + ); + return $element; +} + +/** + * Implementation of hook_field_formatter_info(). + */ +function geshifield_field_formatter_info() { + $formatters = array( + 'default' => array( + 'label' => t('Default'), + 'field types' => array('geshifield'), + ), + 'nohighlighting' => array( + 'label' => t('No syntax highlighting'), + 'field types' => array('geshifield'), + ), + 'trimmed' => array( + 'label' => t('Trimmed'), + 'field types' => array('geshifield'), + ), + ); + return $formatters; +} + + +function theme_geshifield_formatter_default($element) { + // @todo: These theme functions seem to be called more than expected for some reason. + module_load_include('inc', 'geshifilter', 'geshifilter.pages'); + return geshifilter_geshi_process($element['#item']['sourcecode'], $element['#item']['language']); +} + +function theme_geshifield_formatter_nohighlighting($element) { + module_load_include('inc', 'geshifilter', 'geshifilter.pages'); + return geshifilter_geshi_process($element['#item']['sourcecode'], 'text'); +} + +function theme_geshifield_formatter_trimmed($element) { + module_load_include('inc', 'geshifilter', 'geshifilter.pages'); + return geshifilter_geshi_process(node_teaser($element['#item']['sourcecode']), $element['#item']['language']); +}