View source
<?php
require_once 'geshifilter.inc';
function _geshifilter_filter_settings($format) {
$form = array();
$form['geshifilter'] = array(
'#type' => 'fieldset',
'#title' => t('GeSHi filter'),
'#collapsible' => TRUE,
);
if (geshifilter_use_format_specific_options()) {
$form['geshifilter']['general_tags'] = _geshifilter_general_highlight_tags_settings($format);
$form['geshifilter']['per_language_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Per language tags'),
'#collapsible' => TRUE,
'table' => geshifilter_per_language_settings($format, 'enabled', FALSE, TRUE),
);
}
else {
$form['geshifilter']['info'] = array(
'#value' => '<p>' . t('GeSHi filter is configured to use global tag settings. For separate settings per input format, enable this option in the <a href="!geshi_admin_url">general GeSHi filter settings</a>.', array(
'!geshi_admin_url' => url('admin/settings/geshifilter'),
)) . '</p>',
);
}
$form['#validate']['geshifilter_per_language_settings_validate'] = array();
return $form;
}
function _geshifilter_admin_general_settings() {
$form = array();
$geshi_library = _geshifilter_check_geshi_library();
$form['geshifilter_library'] = array(
'#type' => 'fieldset',
'#title' => defined('GESHI_VERSION') ? t('GeSHi library version @version detected', array(
'@version' => GESHI_VERSION,
)) : t('GeSHi library'),
'#description' => t('The GeSHi filter requires the GeSHi library (which needs to be <a href="!geshi">downloaded</a> and installed seperately).', array(
'!geshi' => url('http://qbnz.com/highlighter/'),
)),
'#collapsible' => TRUE,
'#collapsed' => $geshi_library['success'],
);
$form['geshifilter_library']['geshifilter_geshi_dir'] = array(
'#type' => 'textfield',
'#title' => t('Path to GeSHi library'),
'#default_value' => _geshifilter_get_geshi_dir(),
'#description' => t('Specify the path to the GeSHi library directory (which contains a file called <em>geshi.php</em>).'),
);
if (!$geshi_library['loaded']) {
$form['geshifilter_geshi_library_error'] = array(
'#type' => 'value',
'#value' => $geshi_library['message'],
);
$form['#pre_render']['geshifilter'] = 'geshifilter_admin_general_settings_pre_render';
}
if ($geshi_library['loaded']) {
$form['geshifilter_tag_options'] = array(
'#type' => 'fieldset',
'#title' => t('GeSHi filter tags and delimiters'),
'#collapsible' => TRUE,
);
$form['geshifilter_tag_options']['geshifilter_format_specific_options'] = array(
'#type' => 'checkbox',
'#title' => t('Use input format specific tag settings.'),
'#default_value' => geshifilter_use_format_specific_options(),
'#description' => t('Enable seperate tag settings of the GeSHi filter for each <a href="!input_formats">input format</a> instead of global tag settings.', array(
'!input_formats' => url('admin/settings/filters'),
)),
);
if (!geshifilter_use_format_specific_options()) {
$form['geshifilter_tag_options']['geshifilter_general_tags'] = _geshifilter_general_highlight_tags_settings();
}
$form['geshifilter_highlighting_options'] = array(
'#type' => 'fieldset',
'#title' => t('Syntax highlighting options'),
'#collapsible' => TRUE,
);
$languages = _geshifilter_get_enabled_languages();
$form['geshifilter_highlighting_options']['geshifilter_default_highlighting'] = array(
'#type' => 'select',
'#title' => t('Default highlighting mode'),
'#default_value' => variable_get('geshifilter_default_highlighting', GESHIFILTER_DEFAULT_PLAINTEXT),
'#options' => array(
t('No highlighting') => array(
GESHIFILTER_DEFAULT_DONOTHING => t('Do nothing'),
GESHIFILTER_DEFAULT_PLAINTEXT => t('As plain text'),
),
t('Languages') => $languages,
),
'#description' => t('Select the default highlighting mode to use when no language is defined with a language attribute in the tag.'),
);
$form['geshifilter_highlighting_options']['geshifilter_default_line_numbering'] = array(
'#type' => 'select',
'#title' => t('Default line numbering'),
'#default_value' => variable_get('geshifilter_default_line_numbering', GESHIFILTER_LINE_NUMBERS_DEFAULT_NONE),
'#options' => array(
GESHIFILTER_LINE_NUMBERS_DEFAULT_NONE => t('no line numbers'),
GESHIFILTER_LINE_NUMBERS_DEFAULT_NORMAL => t('normal line numbers'),
GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY5 => t('fancy line numbers (every @n lines)', array(
'@n' => GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY5,
)),
GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY10 => t('fancy line numbers (every @n lines)', array(
'@n' => GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY10,
)),
GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY20 => t('fancy line numbers (every @n lines)', array(
'@n' => GESHIFILTER_LINE_NUMBERS_DEFAULT_FANCY20,
)),
),
'#description' => t('Select the default line numbering scheme: no line numbers, normal line numbers or fancy line numbers. With fancy line numbers every n<sup>th</sup> line number is highlighted. (GeSHi documentation: <a href="!link">Line numbers</a>).', array(
'!link' => 'http://qbnz.com/highlighter/geshi-doc.html#line-numbers',
)),
);
$form['geshifilter_highlighting_options']['geshifilter_use_highlight_string_for_php'] = array(
'#type' => 'checkbox',
'#title' => t('Use built-in PHP function <code>highlight_string()</code> for PHP source code.'),
'#description' => t('When enabled, PHP source code will be syntax highlighted with the built-in PHP function <code><a href="!highlight_string">highlight_string()</a></code> instead of with the GeSHi library. GeSHi features like for example line numbering and usage of an external CSS stylesheet are not available.', array(
'!highlight_string' => 'http://php.net/manual/en/function.highlight-string.php',
)),
'#default_value' => variable_get('geshifilter_use_highlight_string_for_php', FALSE),
);
$form['geshifilter_highlighting_options']['geshifilter_enable_keyword_urls'] = array(
'#type' => 'checkbox',
'#title' => t('Enable GeSHi keyword URLs'),
'#description' => t('For some languages GeSHi can link language keywords (e.g. standard library functions) to their online documentation. (GeSHi documentation: <a href="!link">Keyword URLs</a>).', array(
'!link' => 'http://qbnz.com/highlighter/geshi-doc.html#keyword-urls',
)),
'#default_value' => variable_get('geshifilter_enable_keyword_urls', TRUE),
);
$form['geshifilter_styling'] = array(
'#type' => 'fieldset',
'#title' => t('Styling, layout and CSS'),
'#collapsible' => TRUE,
);
$form['geshifilter_styling']['geshifilter_css_mode'] = array(
'#type' => 'radios',
'#title' => t('CSS mode for syntax highlighting'),
'#options' => array(
GESHIFILTER_CSS_INLINE => t('Inline CSS style attributes.'),
GESHIFILTER_CSS_CLASSES_AUTOMATIC => t('Use CSS classes and an automatically managed external CSS style sheet.'),
GESHIFILTER_CSS_CLASSES_ONLY => t('Only add CSS classes to the markup.'),
),
'#default_value' => variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE),
'#description' => t('Inline CSS is easier to set up, does not depend on an external style sheets and is consequently more robust to copy/paste operations like content aggregation. However, usage of CSS classes and an external stylesheet requires much less markup code and bandwidth. The external style sheet can be managed automatically by the GeSHi filter module, but this feature requires the public <a href="!filesystem">download method</a>. If the GeSHi filter is configured to only add the CSS classes to the markup, the administrator or themer is responsible for adding the appropriate CSS rules to the pages (e.g. based on <a href="!cssdefaults">these defaults</a>). (GeSHi documentation: <a href="!geshidoc">Using CSS Classes</a>).', array(
'!geshidoc' => 'http://qbnz.com/highlighter/geshi-doc.html#using-css-classes',
'!filesystem' => url('admin/settings/file-system'),
'!cssdefaults' => url('admin/settings/geshifilter/generate_css'),
)),
);
$form['geshifilter_styling']['geshifilter_code_container'] = array(
'#type' => 'radios',
'#title' => t('Code container'),
'#description' => t('Define the container element to use for code blocks. (GeSHi documentation: <a href="!link">The Code Container</a>).', array(
'!link' => 'http://qbnz.com/highlighter/geshi-doc.html#the-code-container',
)),
'#options' => array(
GESHI_HEADER_PRE => t('Use @cnt container (efficient whitespace coding, no automatic line wrapping)', array(
'@cnt' => '<pre>',
)),
GESHI_HEADER_DIV => t('Use @cnt container (enables automatic line wrapping)', array(
'@cnt' => '<div>',
)),
GESHI_HEADER_NONE => t('Use no container'),
),
'#default_value' => variable_get('geshifilter_code_container', GESHI_HEADER_PRE),
);
}
$form = system_settings_form($form);
return $form;
}
function geshifilter_admin_general_settings_pre_render($form_id, $form) {
if ($form_id == 'geshifilter_admin_general_settings') {
if (isset($form['geshifilter_geshi_library_error'])) {
form_set_error('geshifilter_geshi_dir', $form['geshifilter_geshi_library_error']['#value']);
}
}
}
function geshifilter_admin_general_settings_validate($form_id, $form_values) {
if ($form_id == 'geshifilter_admin_general_settings') {
$geshi_library = _geshifilter_check_geshi_library(FALSE, $form_values['geshifilter_geshi_dir'], FALSE);
if (!$geshi_library['success']) {
form_set_error('geshifilter_geshi_dir', $geshi_library['message']);
}
if ($form_values['geshifilter_css_mode'] == GESHIFILTER_CSS_CLASSES_AUTOMATIC && !_geshifilter_managed_external_stylesheet_possible()) {
form_set_error('geshifilter_css_mode', t('GeSHi filter can not automatically manage an external CSS style sheet when the download method is private.'));
}
}
}
function geshifilter_admin_general_settings_submit($form_id, $form_values) {
if (_geshifilter_get_geshi_dir() != $form_values['geshifilter_geshi_dir']) {
variable_del('geshifilter_available_languages_cache');
}
system_settings_form_submit($form_id, $form_values);
if (variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE) == GESHIFILTER_CSS_CLASSES_AUTOMATIC) {
_geshifilter_generate_languages_css_file();
}
_geshifilter_clear_filter_cache();
}
function _geshifilter_admin_per_language_settings($view = 'enabled') {
$form = array();
$geshi_library = _geshifilter_check_geshi_library();
if (!$geshi_library['success']) {
drupal_set_message($geshi_library['message'], 'error');
return;
}
$add_checkbox = TRUE;
$add_tag_option = !geshifilter_use_format_specific_options();
$form['language_settings'] = geshifilter_per_language_settings(NULL, $view, $add_checkbox, $add_tag_option);
$form['rescan_languages'] = array(
'#type' => 'markup',
'#value' => '<p>' . l(t('Flush cache of available languages'), 'geshifilter/clearavailablelanguagescache', NULL, drupal_get_destination()) . '</p>',
);
$form = system_settings_form($form);
$form['#validate']['geshifilter_per_language_settings_validate'] = array();
return $form;
}
function geshifilter_per_language_settings_validate($form_id, $form_values) {
$format = isset($form_values['format']) ? $form_values['format'] : NULL;
$f = $format === NULL ? '' : "_{$format}";
$languages = _geshifilter_get_available_languages();
foreach ($languages as $language1 => $language_data1) {
$field = "geshifilter_language_enabled_{$language1}";
if (!(isset($form_values[$field]) ? $form_values[$field] : variable_get($field, FALSE))) {
continue;
}
$field = "geshifilter_language_tags_{$language1}{$f}";
if (isset($form_values[$field])) {
$tags1 = _geshifilter_tag_split($form_values[$field]);
}
else {
$tags1 = _geshifilter_tag_split(geshifilter_language_tags($language1, $format));
}
$field = "geshifilter_tags{$f}";
$generic_tags = isset($form_values[$field]) ? $form_values[$field] : geshifilter_tags($format);
$tags1 = array_merge($tags1, _geshifilter_tag_split($generic_tags));
foreach ($languages as $language2 => $language_data2) {
$field = "geshifilter_language_enabled_{$language2}";
if ($language1 == $language2 || !(isset($form_values[$field]) ? $form_values[$field] : variable_get($field, FALSE))) {
continue;
}
$field = "geshifilter_language_tags_{$language2}{$f}";
if (isset($form_values[$field])) {
$tags2 = _geshifilter_tag_split($form_values[$field]);
}
else {
continue;
}
foreach ($tags1 as $tag1) {
foreach ($tags2 as $tag2) {
if ($tag1 == $tag2) {
form_set_error("geshifilter_language_tags_{$language2}{$f}", t('The language tags should differ between languages and from the generic tags.'));
}
}
}
}
}
}
function geshifilter_admin_per_language_settings_submit($form_id, $form_values) {
system_settings_form_submit($form_id, $form_values);
if (variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE) == GESHIFILTER_CSS_CLASSES_AUTOMATIC) {
_geshifilter_generate_languages_css_file();
}
_geshifilter_clear_filter_cache();
}
function _geshifilter_general_highlight_tags_settings($format = NULL) {
$form = array();
$f = $format === NULL ? '' : "_{$format}";
$form["geshifilter_tags{$f}"] = array(
'#type' => 'textfield',
'#title' => t('Generic syntax highlighting tags'),
'#default_value' => geshifilter_tags($format),
'#description' => t('Tags that should activate the GeSHi syntax highlighting. Specify a space-separated list of tagnames.'),
);
$form["geshifilter_brackets{$f}"] = array(
'#type' => 'select',
'#title' => t('Tag style'),
'#options' => array(
GESHIFILTER_BRACKETS_ANGLE => '<foo>',
GESHIFILTER_BRACKETS_SQUARE => '[foo]',
GESHIFILTER_BRACKETS_BOTH => t('!angle or !square', array(
'!angle' => '<foo>',
'!square' => '[foo]',
)),
),
'#default_value' => _geshifilter_brackets($format),
'#description' => t('Select which brackets should be used for the source code container tags.'),
);
$form['geshifilter']["geshifilter_enable_php_delimiters{$f}"] = array(
'#type' => 'checkbox',
'#title' => t('Also apply syntax highlighting to <?php ... ?> style PHP source code blocks.'),
'#description' => t('When enabled, PHP source code enclosed in <?php...?> or <%...%> will also be processed.'),
'#default_value' => _geshifilter_php_delimeters($format),
);
return $form;
}
function geshifilter_per_language_settings($format, $view, $add_checkbox, $add_tag_option) {
$form = array(
'#theme' => 'geshifilter_per_language_settings',
);
$form['header'] = array(
'#type' => 'value',
'#value' => array(),
);
$form['header']['#value'][] = t('Language');
$form['header']['#value'][] = t('GeSHi language code');
if ($add_tag_option) {
$form['header']['#value'][] = t('Tag/language attribute value');
}
$form['languages'] = array();
$languages = _geshifilter_get_available_languages();
foreach ($languages as $language => $language_data) {
$enabled = variable_get("geshifilter_language_enabled_{$language}", FALSE);
if ($view == 'enabled' && !$enabled || $view == 'disabled' && $enabled) {
continue;
}
$form['languages'][$language] = array();
if ($add_checkbox) {
$form['languages'][$language]["geshifilter_language_enabled_{$language}"] = array(
'#type' => 'checkbox',
'#default_value' => $enabled,
'#title' => $language_data['fullname'],
);
}
else {
$form['languages'][$language]['fullname'] = array(
'#type' => 'markup',
'#value' => $language_data['fullname'],
);
}
$form['languages'][$language]['name'] = array(
'#type' => 'markup',
'#value' => $language,
);
if ($add_tag_option) {
$f = $format === NULL ? '' : "_{$format}";
$form['languages'][$language]["geshifilter_language_tags_{$language}{$f}"] = array(
'#type' => 'textfield',
'#default_value' => geshifilter_language_tags($language, $format),
'#size' => 20,
);
}
}
return $form;
}
function theme_geshifilter_per_language_settings($form) {
$rows = array();
foreach (element_children($form['languages']) as $language) {
$row = array();
foreach (element_children($form['languages'][$language]) as $key) {
$row[] = drupal_render($form['languages'][$language][$key]);
}
$rows[] = $row;
}
$header = array();
foreach ($form['header']['#value'] as $cell) {
if ($cell == t('Enabled')) {
$header[] = array(
'data' => $cell,
) + theme('table_select_header_cell');
}
else {
$header[] = $cell;
}
}
return theme('table', $header, $rows);
}
function _geshifilter_clear_filter_cache() {
$message = FALSE;
foreach (filter_formats() as $format => $input_format) {
$filters = filter_list_format($format);
if (isset($filters['geshifilter/0'])) {
cache_clear_all($format . ':', 'cache_filter', TRUE);
$message = TRUE;
}
}
if ($message) {
drupal_set_message(t('GeSHi filter cleared the filter cache for the appropriate input formats.'));
}
}
function _geshifilter_generate_languages_css_rules() {
$output = '';
$geshi_library = _geshifilter_check_geshi_library();
if ($geshi_library['loaded']) {
require_once 'geshifilter.pages.inc';
$languages = _geshifilter_get_enabled_languages();
foreach ($languages as $langcode => $language_full_name) {
$geshi = _geshifilter_GeSHi_factory('', $langcode);
_geshifilter_override_geshi_defaults($geshi, $langcode);
$output .= $geshi
->get_stylesheet(FALSE) . "\n";
unset($geshi);
}
}
else {
drupal_set_message(t('Error while generating CSS rules: could not load GeSHi library.'), 'error');
}
return $output;
}
function _geshifilter_generate_languages_css_file() {
$languages = _geshifilter_get_enabled_languages();
$path = file_directory_path() . '/geshifilter';
file_check_directory($path, FILE_CREATE_DIRECTORY);
$stylesheet_file = $path . '/geshifilter-languages-' . substr(md5(serialize($languages)), 0, 8) . '.css';
if (!file_exists($stylesheet_file)) {
$stylesheet = _geshifilter_generate_languages_css_rules();
$ret = file_save_data($stylesheet, $stylesheet_file, FILE_EXISTS_REPLACE);
if ($ret) {
variable_set('geshifilter_languages_css', $ret);
drupal_set_message(t('Generated external CSS file %file.', array(
'%file' => $ret,
)));
}
else {
drupal_set_message(t('Could not generate external CSS file. Check the settings of your <a href="!filesystem">file system</a>.', array(
'!filesystem' => url('admin/settings/file-system'),
)), 'error');
}
}
}