add('name', PLUGIN_EVENT_NL2BR_NAME); $propbag->add('description', PLUGIN_EVENT_NL2BR_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Serendipity Team'); $propbag->add('version', '2.0'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('cachable_events', array('frontend_display' => true)); $propbag->add('event_hooks', array('frontend_display' => true, 'css' => true) ); $propbag->add('groups', array('MARKUP')); $this->markup_elements = array( array( 'name' => 'ENTRY_BODY', 'element' => 'body', ), array( 'name' => 'EXTENDED_BODY', 'element' => 'extended', ), array( 'name' => 'COMMENT', 'element' => 'comment', ), array( 'name' => 'HTML_NUGGET', 'element' => 'html_nugget', ) ); $conf_array = array('isolate', 'p_tags'); foreach($this->markup_elements as $element) { $conf_array[] = $element['name']; } $propbag->add('configuration', $conf_array); } function install() { serendipity_plugin_api::hook_event('backend_cache_entries', $this->title); } function uninstall() { serendipity_plugin_api::hook_event('backend_cache_purge', $this->title); serendipity_plugin_api::hook_event('backend_cache_entries', $this->title); } function generate_content(&$title) { $title = $this->title; } function introspect_config_item($name, &$propbag) { switch($name) { case 'isolate': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_NL2BR_ISOLATE_TAGS); $propbag->add('description', PLUGIN_EVENT_NL2BR_ISOLATE_TAGS_DESC); $propbag->add('default', ''); break; case 'p_tags': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_NL2BR_PTAGS); $propbag->add('description', PLUGIN_EVENT_NL2BR_PTAGS_DESC); $propbag->add('default', 'false'); break; default: $propbag->add('type', 'boolean'); $propbag->add('name', constant($name)); $propbag->add('description', sprintf(APPLY_MARKUP_TO, constant($name))); $propbag->add('default', 'true'); } return true; } function isolate($src, $regexp = NULL) { if($regexp) return preg_replace_callback($regexp, array($this, 'isolate'), $src); global $_buf; $_buf[] = $src[0]; return "\001" . (count($_buf) - 1); } function restore($text) { global $_buf; return preg_replace('~\001(\d+)~e', '$_buf[$1]', $text); } function event_hook($event, &$bag, &$eventData) { global $serendipity; static $isolate = null; static $p_tags = null; global $_buf; $hooks = &$bag->get('event_hooks'); if ($p_tags === null) { $p_tags = serendipity_db_bool($this->get_config('p_tags')); } if (isset($hooks[$event])) { switch($event) { case 'frontend_display': if ($isolate === null) { $isolate = $this->get_config('isolate'); $tags = (array)explode(',', $isolate); $isolate = array(); foreach($tags AS $tag) { $tag = trim($tag); if (!empty($tag)) { $isolate[] = $tag; } } if (count($isolate) < 1) { $isolate = false; } } foreach ($this->markup_elements as $temp) { if (serendipity_db_bool($this->get_config($temp['name'], true)) && isset($eventData[$temp['element']]) && !$eventData['properties']['ep_disable_markup_' . $this->instance] && !in_array($this->instance, (array)$serendipity['POST']['properties']['disable_markups']) && !$eventData['properties']['ep_no_nl2br'] && !isset($serendipity['POST']['properties']['ep_no_nl2br'])) { $element = $temp['element']; if ($p_tags) { $eventData[$element] = $this->nl2p($eventData[$element]); } else if ($isolate) { $eventData[$element] = $this->isolate($eventData[$element], '~[<\[](' . implode('|', $isolate) . ').*?[>\]].*?[<\[]/\1[>\]]~si'); $eventData[$element] = nl2br($eventData[$element]); $eventData[$element] = $this->restore($eventData[$element]); } else { $eventData[$element] = nl2br($eventData[$element]); } } } return true; break; case 'css': ?> p.whiteline { margin-top: 0em; margin-bottom: 1em; } p.break { margin-top: 0em; margin-bottom: 0em; } '; $small_p = '

'; $insert = true; $i = count($text); $whiteline = false; if ($text[$i-1] == "\n") { //prevent unnexessary p-tag at the end unset($text[$i-1]); } //main operation: convert \n to big_p and small_p while ($i > 0) { if ($insert) { $i = $this->next_nl_block($i, $text); if ($i == 0) { //prevent replacing of first character break; } if ($whiteline == true) { $text[$i] = '

' . $big_p; } else { $text[$i] = '

' . $small_p; } $whiteline = false; $insert = false; } else { if ($text[$i-1] === "\n") { //newline is follower of a newline $whiteline = true; } $insert = true; } } if ($whiteline) { $start_tag = $big_p; } else { $start_tag = $small_p; } if ($complex) { $textstring = $this->tidy_block_elements($text); $textstring = $this->formate_block_elements($textstring); $textstring = $this->isolate_block_elements($textstring); $textstring = $start_tag . $textstring . '

'; return $this->clean_code($textstring); } return $start_tag . implode($text) . '

'; } /* * Remove unnecessary paragraphs * Unnecessary are those which start and end immediately. * They only get created by isolate_block_elements * @param mixed text * @return string * */ function clean_code ($text) { if (is_array($text)) { $text = implode($text); } return str_replace(array('

','

', '

'),"", $text); } function purge_p($text) { $text = str_replace('

', "", $text); return str_replace(array('

','

', '

', '

'),"\n", $text); } /* * Use nl2p on text within blockelements, useful e.g. with blockquotes * @param array text * @return string * */ function formate_block_elements($textstring) { $block_elements = array('end_tags($start_tag); //first see if block-element really exists $start_tag_position = strpos($textstring, $start_tag); while ($start_tag_position !== false) { $start_tag_end = strpos($textstring, '>', $start_tag_position)+1; $blocktext = $this->get_string_till($textstring, $end_tag, $start_tag_end); $blocktext_length = strlen($blocktext); $formatted_blocktext = $this->nl2p($blocktext); //insert formatted_blocktext into old blockelement $textstring = substr_replace($textstring, $formatted_blocktext, $start_tag_end, $blocktext_length); //next blockelement $start_tag_position = strpos($textstring, $start_tag, $start_tag_end+strlen($formatted_blocktext)); } } return $textstring; } /** * Make sure none of these block_elements are within a

* @param string text * @return string * */ function isolate_block_elements($textstring) { $block_elements = array('end_tags($start_tag); $textstring = str_replace("$start_tag", "

$start_tag", $textstring); $textstring = str_replace("$end_tag", "$end_tag

", $textstring); } } return $textstring; } /** * Remove all

-tags from block-elements * Note: Walking from left to right * @param array text * @return string * */ function tidy_block_elements($text) { $remove = false; $textstring = implode($text); $block_elements = array('end_tags($start_tag); //first see if block-element really exists $start_tag_position = strpos($textstring, $start_tag); while ($start_tag_position !== false) { $start_tag_end = strpos($textstring, '>', $start_tag_position)+1; $blocktext = $this->get_string_till($textstring, $end_tag, $start_tag_end); $blocktext_length = strlen($blocktext); $formatted_blocktext = $this->purge_p($blocktext); //insert formatted_blocktext into old blockelement $textstring = substr_replace($textstring, $formatted_blocktext, $start_tag_end, $blocktext_length); //next blockelement $start_tag_position = strpos($textstring, $start_tag, $start_tag_end+strlen($formatted_blocktext)); } } return $textstring; } function get_string_till($text, $end_tag, $offset=0){ if (strpos($text, $end_tag, $offset) === false) { return ""; } $len = strpos($text, $end_tag, $offset) - $offset; return substr($text, $offset, $len); } /* * Return corresponding end-tag:

*/ function end_tags($start_tag) { return str_replace("<", ""; } /** * Find next newline seperated by text from current position * @param int start * $param array text */ function next_nl_block($i, $text) { $skipped = false; for ($i--; $i>0; $i-- ) { if (!$skipped){ //see if you skipped over a non-newline (heading to the next block) if (strpos($text[$i], "\n") === false) { $skipped = true; } }else if (strpos($text[$i], "\n") !== false) { break; } } return $i; } } /* vim: set sts=4 ts=4 expandtab : */