diff -uNr a/mp-wp/manifest b/mp-wp/manifest --- a/mp-wp/manifest 4ad5c0b7eda9c670f311a23da92114ab10bf30b9990b46882047aea3ab569395f643cb4aa6144ee0ba74b9821df1e69b26d299c1f0e9c11631a78c46f95913bd +++ b/mp-wp/manifest e70855d060aefbd26f51cf60e39e553e7666f8f76d49adeb95999ab34401f1984e808082f7f34690ebc31fb93f5da192aa0d74b7f5eabd3e62fae3f2054720f4 @@ -5,3 +5,4 @@ 569483 mp-wp_remove-tinymce-and-other-crud billymg Remove tinymce, most of the importers, the self-update feature, and the google gears and press-this plugins 602064 mp-wp_apply-htmlspecialchars-to-post-edit-content billymg Run post content through htmlspecialchars() before loading into the post edit UI 605926 mp-wp_comments_filtering diana_coman Recent comments widget should show only people's comments (no track/pingbacks); theme default changed to show trackbacks/pingbacks as last/at the bottom in an article's comments list. +614805 mp-wp_add-embedded-vpatch-formatting billymg Add the ability to embed vpatches within article content. Embedded vpatch blocks will be formatted with diff syntax highlighting and anchored line numbers diff -uNr a/mp-wp/wp-content/plugins/footnotes.php b/mp-wp/wp-content/plugins/footnotes.php --- a/mp-wp/wp-content/plugins/footnotes.php 8e2449d4ac26ea05f080cec9d025ef8a8585221ee30da439b37ff1578d084e1c63cbe3f89e3d6868c19d0fa9f73a9af99b444251e7a854f6c87e316628d94859 +++ b/mp-wp/wp-content/plugins/footnotes.php 1109723713df46f7ec135f0640d3acba475974f439d722b379581dd262b5f7bf42295ca1e57600d6bb9636a2e9d35965d3841d74fc15d5bf3952cfada98f363b @@ -1,49 +1,28 @@ styles = array( 'decimal' => '1,2...10', @@ -56,17 +35,16 @@ ); // Define default options - $this->default_options = array('superscript'=>true, + $this->options = array('superscript'=>true, 'pre_backlink'=>' [', 'backlink'=>'↩', 'post_backlink'=>']', 'pre_identifier'=>'', - 'list_style_type'=>'decimal', + 'list_style_type'=>'lower-roman', 'list_style_symbol'=>'†', 'post_identifier'=>'', 'pre_footnotes'=>'', 'post_footnotes'=>'', - 'style_rules'=>'ol.footnotes{font-size:0.8em; color:#666666;}', 'no_display_home'=>false, 'no_display_archive'=>false, 'no_display_date'=>false, @@ -74,58 +52,80 @@ 'no_display_search'=>false, 'no_display_feed'=>false, 'combine_identical_notes'=>false, - 'priority'=>11, - 'version'=>WP_FOOTNOTES_VERSION); + 'codeblocks_priority'=>9, // highest value that comes before wpautop filter + 'footnotes_priority'=>11); - // Get the current settings or setup some defaults if needed - if (!$this->current_options = get_option('swas_footnote_options')){ - $this->current_options = $this->default_options; - update_option('swas_footnote_options', $this->current_options); - } else { - // Set any unset options - if ($this->current_options['version'] != WP_FOOTNOTES_VERSION) { - foreach ($this->default_options as $key => $value) { - if (!isset($this->current_options[$key])) { - $this->current_options[$key] = $value; - } - } - $this->current_options['version'] = WP_FOOTNOTES_VERSION; - update_option('swas_footnote_options', $this->current_options); - } + // Hook me up + add_action('the_content', array($this, 'process_codeblocks'), $this->options['codeblocks_priority']); + add_action('the_content', array($this, 'process_footnotes'), $this->options['footnotes_priority']); + add_action('wp_head', array($this, 'insert_styles')); + } + + /** + * Searches the text and apply markup to codeblocks. + * Adds line number links and diff syntax highlighting. + * @param $data string The content of the post. + * @return string The new content with formatted codeblocks. + */ + function process_codeblocks($data) { + global $post; + + // Regex extraction of all codeblocks (or return if there are none) + if ( + !preg_match_all( + "/(".preg_quote(self::MP_WP_CODEBLOCK_OPEN).")(.*)(".preg_quote(self::MP_WP_CODEBLOCK_CLOSE, '/').")/Us", + $data, + $codeblocks, + PREG_SET_ORDER + ) + ) { + return $data; } -/* - if (!empty($_POST['save_options'])){ - $footnotes_options['superscript'] = (array_key_exists('superscript', $_POST)) ? true : false; - $footnotes_options['pre_backlink'] = $_POST['pre_backlink']; - $footnotes_options['backlink'] = $_POST['backlink']; - $footnotes_options['post_backlink'] = $_POST['post_backlink']; - $footnotes_options['pre_identifier'] = $_POST['pre_identifier']; - $footnotes_options['list_style_type'] = $_POST['list_style_type']; - $footnotes_options['post_identifier'] = $_POST['post_identifier']; - $footnotes_options['list_style_symbol'] = $_POST['list_style_symbol']; - $footnotes_options['pre_footnotes'] = stripslashes($_POST['pre_footnotes']); - $footnotes_options['post_footnotes'] = stripslashes($_POST['post_footnotes']); - $footnotes_options['style_rules'] = stripslashes($_POST['style_rules']); - $footnotes_options['no_display_home'] = (array_key_exists('no_display_home', $_POST)) ? true : false; - $footnotes_options['no_display_archive'] = (array_key_exists('no_display_archive', $_POST)) ? true : false; - $footnotes_options['no_display_date'] = (array_key_exists('no_display_date', $_POST)) ? true : false; - $footnotes_options['no_display_category'] = (array_key_exists('no_display_category', $_POST)) ? true : false; - $footnotes_options['no_display_search'] = (array_key_exists('no_display_search', $_POST)) ? true : false; - $footnotes_options['no_display_feed'] = (array_key_exists('no_display_feed', $_POST)) ? true : false; - $footnotes_options['combine_identical_notes'] = (array_key_exists('combine_identical_notes', $_POST)) ? true : false; - $footnotes_options['priority'] = $_POST['priority']; - update_option('swas_footnote_options', $footnotes_options); - }elseif(!empty($_POST['reset_options'])){ - update_option('swas_footnote_options', ''); - update_option('swas_footnote_options', $this->default_options); + for ($i = 0; $i < count($codeblocks); $i++) { + $codeblocks[$i]['snippet'] = $this->format_snippet($codeblocks[$i][2], $i+1); } -*/ - // Hook me up - add_action('the_content', array($this, 'process'), $this->current_options['priority']); - add_action('admin_menu', array($this, 'add_options_page')); // Insert the Admin panel. - add_action('wp_head', array($this, 'insert_styles')); + foreach ($codeblocks as $key => $value) { + $data = substr_replace($data, $value['snippet'], strpos($data,$value[0]),strlen($value[0])); + } + + return $data; + } + + function format_snippet($snippet, $snippet_number) { + $formatted_snippet = htmlspecialchars($snippet); + $code_lines = explode("\r\n", $formatted_snippet); + + foreach ($code_lines as $idx => $line) { + $line_number = sprintf('S%d-L%d', $snippet_number, $idx+1); + $line_link = sprintf('%d', $line_number, $line_number, $idx+1); + $line_open = sprintf('%s', $line_link); + $line_close = ''; + + if (substr($line, 0, 5) == 'diff ') { + $code_lines[$idx] = sprintf('%s%s%s', $line_open, $line, $line_close); + } elseif (substr($line, 0, 4) == '--- ' || substr($line, 0, 4) == '+++ ' || substr($line, 0, 3) == '@@ ') { + $code_lines[$idx] = sprintf('%s%s%s', $line_open, $line, $line_close); + } elseif (substr($line, 0, 1) == '-') { + $code_lines[$idx] = sprintf('%s%s%s', $line_open, $line, $line_close); + } elseif (substr($line, 0, 1) == '+') { + $code_lines[$idx] = sprintf('%s%s%s', $line_open, $line, $line_close); + } else { + $code_lines[$idx] = sprintf('%s%s%s', $line_open, $line, $line_close); + } + } + + $formatted_snippet = implode("\n", $code_lines); + + $formatted_snippet = sprintf( + '%s%s%s', + '
',
+			$formatted_snippet,
+			'
' + ); + + return $formatted_snippet; } /** @@ -134,25 +134,28 @@ * @param $data string The content of the post. * @return string The new content with footnotes generated. */ - function process($data) { + function process_footnotes($data) { global $post; // Check for and setup the starting number $start_number = (preg_match("||",$data,$start_number_array)==1) ? $start_number_array[1] : 1; - // Regex extraction of all footnotes (or return if there are none) - if (!preg_match_all("/(".preg_quote(WP_FOOTNOTES_OPEN)."|)(.*)(".preg_quote(WP_FOOTNOTES_CLOSE)."|<\/footnote>)/Us", $data, $identifiers, PREG_SET_ORDER)) { + // Remove codeblocks from content to be parsed for footnotes + $data_sans_codeblocks = preg_replace("/(
)(.*)(<\/pre>)/Us", '', $data);
+
+		// Regex extraction of all footnotes from non-codeblock content (or return if there are none)
+		if (!preg_match_all("/(".preg_quote(self::MP_WP_FOOTNOTES_OPEN)."|)(.*)(".preg_quote(self::MP_WP_FOOTNOTES_CLOSE)."|<\/footnote>)/Us", $data_sans_codeblocks, $identifiers, PREG_SET_ORDER)) {
 			return $data;
 		}
 
 		// Check whether we are displaying them or not
 		$display = true;
-		if ($this->current_options['no_display_home'] && is_home()) $display = false;
-		if ($this->current_options['no_display_archive'] && is_archive()) $display = false;
-		if ($this->current_options['no_display_date'] && is_date()) $display = false;
-		if ($this->current_options['no_display_category'] && is_category()) $display = false;
-		if ($this->current_options['no_display_search'] && is_search()) $display = false;
-		if ($this->current_options['no_display_feed'] && is_feed()) $display = false;
+		if ($this->options['no_display_home'] && is_home()) $display = false;
+		if ($this->options['no_display_archive'] && is_archive()) $display = false;
+		if ($this->options['no_display_date'] && is_date()) $display = false;
+		if ($this->options['no_display_category'] && is_category()) $display = false;
+		if ($this->options['no_display_search'] && is_search()) $display = false;
+		if ($this->options['no_display_feed'] && is_feed()) $display = false;
 
 		$footnotes = array();
 
@@ -160,7 +163,7 @@
 		if ( array_key_exists(get_post_meta($post->ID, 'footnote_style', true), $this->styles) ) {
 			$style = get_post_meta($post->ID, 'footnote_style', true);
 		} else {
-			$style = $this->current_options['list_style_type'];
+			$style = $this->options['list_style_type'];
 		}
 
 		// Create 'em
@@ -175,7 +178,7 @@
 
 
 			// if we're combining identical notes check if we've already got one like this & record keys
-			if ($this->current_options['combine_identical_notes']){
+			if ($this->options['combine_identical_notes']){
 				for ($j=0; $jID;
 			$id_num = ($style == 'decimal') ? $value['use_footnote']+$start_number : $this->convert_num($value['use_footnote']+$start_number, $style, count($footnotes));
 			$id_href = ( ($use_full_link) ? get_permalink($post->ID) : '' ) . "#footnote_".$value['use_footnote']."_".$post->ID;
-
-//			$id_title = str_replace('"', """, htmlentities(strip_tags($value['text']), ENT_QUOTES, 'UTF-8'));
-
 			$id_title = str_replace('"', '`', strip_tags($value['text']));
-			$id_replace = $this->current_options['pre_identifier'].''.$id_num.''.$this->current_options['post_identifier'];
-			if ($this->current_options['superscript']) $id_replace = ''.$id_replace.'';
+			$id_replace = $this->options['pre_identifier'].''.$id_num.''.$this->options['post_identifier'];
+			if ($this->options['superscript']) $id_replace = ''.$id_replace.'';
 			if ($display) $data = substr_replace($data, $id_replace, strpos($data,$value[0]),strlen($value[0]));
 			else $data = substr_replace($data, '', strpos($data,$value[0]),strlen($value[0]));
 		}
@@ -219,14 +219,14 @@
 		// Display footnotes
 		if ($display) {
 			$start = ($start_number != 1) ? 'start="'.$start_number.'" ' : '';
-			$data = $data.$this->current_options['pre_footnotes'];
+			$data = $data.$this->options['pre_footnotes'];
 
 			$data = $data . '
    '; foreach ($footnotes as $key => $value) { $data = $data.'
  1. current_options['list_style_type']) { + } elseif($style != $this->options['list_style_type']) { $data = $data . ' style="list-style-type:' . $style . ';"'; } $data = $data . '>'; @@ -236,56 +236,39 @@ $data = $data.$value['text']; if (!is_feed()){ foreach($value['identifiers'] as $identifier){ - $data = $data.$this->current_options['pre_backlink'].''.$this->current_options['backlink'].''.$this->current_options['post_backlink']; + $data = $data.$this->options['pre_backlink'].''.$this->options['backlink'].''.$this->options['post_backlink']; } } $data = $data . '
  2. '; } - $data = $data . '
' . $this->current_options['post_footnotes']; + $data = $data . '' . $this->options['post_footnotes']; } return $data; } - /** - * Really insert the options page. - */ - function footnotes_options_page() { - $this->current_options = get_option('swas_footnote_options'); - foreach ($this->current_options as $key=>$setting) { - $new_setting[$key] = htmlentities($setting); - } - $this->current_options = $new_setting; - unset($new_setting); - include (dirname(__FILE__) . '/options.php'); - } - - /** - * Insert the options page into the admin area. - */ - function add_options_page() { - // Add a new menu under Options: - add_options_page('Footnotes', 'Footnotes', 8, __FILE__, array($this, 'footnotes_options_page')); - } - - function upgrade_post($data){ - $data = str_replace('',WP_FOOTNOTES_OPEN,$data); - $data = str_replace('',WP_FOOTNOTES_CLOSE,$data); - return $data; - } - - function insert_styles(){ + function insert_styles() { ?> current_options['list_style_symbol']; + $sym .= $this->options['list_style_symbol']; } return $sym; } @@ -318,7 +301,7 @@ * @param string $case Upper or lower case. * @return string The roman numeral */ - function roman($num, $case= 'upper'){ + function roman($num, $case= 'upper') { $num = (int) $num; $conversion = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1); $roman = ''; @@ -331,7 +314,7 @@ return ($case == 'lower') ? strtolower($roman) : $roman; } - function alpha($num, $case='upper'){ + function alpha($num, $case='upper') { $j = 1; for ($i = 'A'; $i <= 'ZZ'; $i++){ if ($j == $num){