aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrett Profitt <brett.profitt@gmail.com>2011-04-26 15:03:02 -0400
committerBrett Profitt <brett.profitt@gmail.com>2011-04-26 15:03:02 -0400
commitc80ba5aa03264dd64c20ed8ae222e87f9371a44d (patch)
tree9355d87a9ab4570b9e54685ad9869cd4fedd392f
parent581c2d35ae053aed07a607b8bb844603c48b7c2f (diff)
parent632cf13234d04a3f6b7acf67866a82e0bebde55c (diff)
downloadelgg-c80ba5aa03264dd64c20ed8ae222e87f9371a44d.tar.gz
elgg-c80ba5aa03264dd64c20ed8ae222e87f9371a44d.tar.bz2
Merge remote branch 'upstream/master'
-rw-r--r--engine/classes/ElggPlugin.php39
-rw-r--r--engine/classes/ElggPluginPackage.php19
-rw-r--r--engine/lib/admin.php70
-rw-r--r--engine/lib/annotations.php21
-rw-r--r--engine/lib/elgglib.php42
-rw-r--r--engine/lib/input.php2
-rw-r--r--engine/lib/metastrings.php77
-rw-r--r--engine/lib/plugins.php2
-rw-r--r--engine/lib/statistics.php6
-rw-r--r--engine/lib/views.php15
-rw-r--r--engine/tests/api/metastrings.php2
-rw-r--r--engine/tests/api/plugins.php10
-rw-r--r--engine/tests/test_files/plugin_18/manifest.xml2
-rw-r--r--languages/en.php4
-rw-r--r--mod/developers/languages/en.php9
-rw-r--r--mod/developers/start.php16
-rw-r--r--mod/developers/views/default/forms/developers/settings.php2
-rw-r--r--mod/developers/views/default/page/theme_preview.php38
-rw-r--r--mod/developers/views/default/theme_preview/buttons.php41
-rw-r--r--mod/developers/views/default/theme_preview/components.php12
-rw-r--r--mod/developers/views/default/theme_preview/components/image_block.php6
-rw-r--r--mod/developers/views/default/theme_preview/components/list.php19
-rw-r--r--mod/developers/views/default/theme_preview/components/messages.php5
-rw-r--r--mod/developers/views/default/theme_preview/components/table.php12
-rw-r--r--mod/developers/views/default/theme_preview/forms.php361
-rw-r--r--mod/developers/views/default/theme_preview/general.php59
-rw-r--r--mod/developers/views/default/theme_preview/grid.php25
-rw-r--r--mod/developers/views/default/theme_preview/icons.php58
-rw-r--r--mod/developers/views/default/theme_preview/icons/avatars.php36
-rw-r--r--mod/developers/views/default/theme_preview/icons/loader.php1
-rw-r--r--mod/developers/views/default/theme_preview/icons/sprites.php61
-rw-r--r--mod/developers/views/default/theme_preview/modules.php6
-rw-r--r--mod/developers/views/default/theme_preview/modules/modules.php23
-rw-r--r--mod/developers/views/default/theme_preview/modules/widgets.php (renamed from mod/developers/views/default/theme_preview/widgets.php)2
-rw-r--r--mod/developers/views/default/theme_preview/navigation.php70
-rw-r--r--mod/developers/views/default/theme_preview/navigation/breadcrumbs.php6
-rw-r--r--mod/developers/views/default/theme_preview/navigation/default.php11
-rw-r--r--mod/developers/views/default/theme_preview/navigation/extras.php18
-rw-r--r--mod/developers/views/default/theme_preview/navigation/filter.php13
-rw-r--r--mod/developers/views/default/theme_preview/navigation/horizontal.php12
-rw-r--r--mod/developers/views/default/theme_preview/navigation/owner_block.php11
-rw-r--r--mod/developers/views/default/theme_preview/navigation/page.php21
-rw-r--r--mod/developers/views/default/theme_preview/navigation/pagination.php8
-rw-r--r--mod/developers/views/default/theme_preview/navigation/site.php18
-rw-r--r--mod/developers/views/default/theme_preview/navigation/tabs.php10
-rw-r--r--mod/developers/views/default/theme_preview/objects.php76
-rw-r--r--mod/developers/views/default/theme_preview/typography.php10
-rw-r--r--mod/developers/views/default/theme_preview/typography/headings.php6
-rw-r--r--mod/developers/views/default/theme_preview/typography/misc.php16
-rw-r--r--mod/developers/views/default/theme_preview/typography/paragraph.php19
-rw-r--r--mod/messages/readme.txt23
-rwxr-xr-xvendors/markdown/License.text36
-rwxr-xr-xvendors/markdown/PHP Markdown Extra Readme.text786
-rwxr-xr-xvendors/markdown/markdown.php2932
-rw-r--r--views/default/css/elements/forms.php219
-rw-r--r--views/default/css/elements/typography.php7
-rw-r--r--views/default/forms/profile/fields/add.php2
-rw-r--r--views/default/input/autocomplete.php2
-rw-r--r--views/default/navigation/menu/elements/item.php5
-rw-r--r--views/default/object/plugin/advanced.php19
-rw-r--r--views/default/object/plugin/simple.php13
-rw-r--r--views/default/page/components/gallery.php40
62 files changed, 4835 insertions, 677 deletions
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
index 34e8e6732..20a8673de 100644
--- a/engine/classes/ElggPlugin.php
+++ b/engine/classes/ElggPlugin.php
@@ -30,7 +30,6 @@ class ElggPlugin extends ElggObject {
$this->access_id = ACCESS_PUBLIC;
}
-
/**
* Loads the plugin by GUID or path.
*
@@ -91,7 +90,6 @@ class ElggPlugin extends ElggObject {
}
}
-
/**
* Save the plugin object. Make sure required values exist.
*
@@ -138,7 +136,6 @@ class ElggPlugin extends ElggObject {
return sanitise_filepath($this->path);
}
-
/**
* Sets the location of this plugin.
*
@@ -149,6 +146,23 @@ class ElggPlugin extends ElggObject {
return $this->attributes['title'] = $id;
}
+ /**
+ * Returns an array of available markdown files for this plugin
+ *
+ * @return array
+ */
+ public function getAvailableTextFiles() {
+ $filenames = $this->package->getTextFilenames();
+
+ $files = array();
+ foreach ($filenames as $filename) {
+ if ($this->canReadFile($filename)) {
+ $files[$filename] = "$this->path/$filename";
+ }
+ }
+
+ return $files;
+ }
// Load Priority
@@ -162,7 +176,6 @@ class ElggPlugin extends ElggObject {
return $this->$name;
}
-
/**
* Sets the priority of the plugin
*
@@ -324,7 +337,6 @@ class ElggPlugin extends ElggObject {
return $this->set($name, $value);
}
-
/**
* Removes a plugin setting name and value.
*
@@ -336,7 +348,6 @@ class ElggPlugin extends ElggObject {
return remove_private_setting($this->guid, $name);
}
-
/**
* Removes all settings for this plugin.
*
@@ -496,7 +507,6 @@ class ElggPlugin extends ElggObject {
return remove_private_setting($user->guid, $name);
}
-
/**
* Removes all User Settings for this plugin
*
@@ -517,7 +527,6 @@ class ElggPlugin extends ElggObject {
return delete_data($q);
}
-
/**
* Removes this plugin's user settings for all users.
*
@@ -566,7 +575,6 @@ class ElggPlugin extends ElggObject {
return true;
}
-
/**
* Is this plugin active?
*
@@ -591,7 +599,6 @@ class ElggPlugin extends ElggObject {
return check_entity_relationship($this->guid, 'active_plugin', $site->guid);
}
-
/**
* Checks if this plugin can be activated on the current
* Elgg installation.
@@ -640,7 +647,7 @@ class ElggPlugin extends ElggObject {
// if there are any on_enable functions, start the plugin now and run them
// Note: this will not run re-run the init hooks!
if ($return) {
- if ($this->canIncludeFile('activate.php')) {
+ if ($this->canReadFile('activate.php')) {
$flags = ELGG_PLUGIN_INCLUDE_START | ELGG_PLUGIN_REGISTER_CLASSES
| ELGG_PLUGIN_REGISTER_LANGUAGES | ELGG_PLUGIN_REGISTER_VIEWS;
@@ -660,7 +667,6 @@ class ElggPlugin extends ElggObject {
return false;
}
-
/**
* Deactivates the plugin.
*
@@ -682,7 +688,7 @@ class ElggPlugin extends ElggObject {
// run any deactivate code
if ($return) {
- if ($this->canIncludeFile('deactivate.php')) {
+ if ($this->canReadFile('deactivate.php')) {
$return = $this->includeFile('deactivate.php');
}
}
@@ -694,7 +700,6 @@ class ElggPlugin extends ElggObject {
}
}
-
/**
* Start the plugin.
*
@@ -750,7 +755,7 @@ class ElggPlugin extends ElggObject {
$filepath = "$this->path/$filename";
- if (!$this->canIncludeFile($filename)) {
+ if (!$this->canReadFile($filename)) {
$msg = elgg_echo('ElggPlugin:Exception:CannotIncludeFile',
array($filename, $this->getID(), $this->guid, $this->path));
throw new PluginException($msg);
@@ -765,8 +770,8 @@ class ElggPlugin extends ElggObject {
* @param string $filename The name of the file
* @return bool
*/
- protected function canIncludeFile($filename) {
- return file_exists($this->path.'/'.$filename);
+ protected function canReadFile($filename) {
+ return is_readable($this->path . '/' . $filename);
}
/**
diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php
index b2ec20549..4daab381e 100644
--- a/engine/classes/ElggPluginPackage.php
+++ b/engine/classes/ElggPluginPackage.php
@@ -28,6 +28,15 @@ class ElggPluginPackage {
);
/**
+ * The optional files that can be read and served through the markdown page handler
+ * @var array
+ */
+ private $textFiles = array(
+ 'README.txt', 'CHANGES.txt',
+ 'INSTALL.txt', 'COPYRIGHT.txt', 'LICENSE.txt'
+ );
+
+ /**
* Valid types for provides.
*
* @var array
@@ -286,6 +295,16 @@ class ElggPluginPackage {
return false;
}
+ /****************
+ * Readme Files *
+ ***************/
+
+ /**
+ * Returns an array of present and readable text files
+ */
+ public function getTextFilenames() {
+ return $this->textFiles;
+ }
/***********************
* Dependencies system *
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index a9a0382cc..06418c44f 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -303,6 +303,7 @@ function admin_init() {
elgg_register_page_handler('admin', 'admin_settings_page_handler');
elgg_register_page_handler('admin_plugin_screenshot', 'admin_plugin_screenshot_page_handler');
+ elgg_register_page_handler('admin_plugin_text_file', 'admin_markdown_page_handler');
}
/**
@@ -446,7 +447,8 @@ function admin_settings_page_handler($page) {
* @return true
*/
function admin_plugin_screenshot_page_handler($pages) {
- admin_gatekeeper(); // only admins can use this - security feature
+ // only admins can use this for security
+ admin_gatekeeper();
$plugin_id = elgg_extract(0, $pages);
// only thumbnail or full.
@@ -485,6 +487,72 @@ function admin_plugin_screenshot_page_handler($pages) {
}
/**
+ * Formats and serves out markdown files from plugins.
+ *
+ * URLs in format like admin_plugin_text_file/<plugin_id>/filename.ext
+ *
+ * The only valid files are:
+ * * README.txt
+ * * CHANGES.txt
+ * * INSTALL.txt
+ * * COPYRIGHT.txt
+ * * LICENSE.txt
+ *
+ * @param type $page
+ */
+function admin_markdown_page_handler($pages) {
+ admin_gatekeeper();
+
+ elgg_set_context('admin');
+
+ elgg_unregister_css('elgg');
+ $url = elgg_get_simplecache_url('js', 'admin');
+ elgg_register_js('elgg.admin', $url);
+ elgg_load_js('elgg.admin');
+ elgg_load_library('elgg:markdown');
+
+ $plugin_id = elgg_extract(0, $pages);
+ $plugin = elgg_get_plugin_from_id($plugin_id);
+ $filename = elgg_extract(1, $pages);
+
+ $error = false;
+
+ if (!$plugin) {
+ $error = elgg_echo('admin:plugins:markdown:unknown_plugin');
+ }
+
+ $text_files = $plugin->getAvailableTextFiles();
+
+ if (!array_key_exists($filename, $text_files)) {
+ $error = elgg_echo('admin:plugins:markdown:unknown_file');
+ }
+
+ $file = $text_files[$filename];
+ $file_contents = file_get_contents($file);
+
+ if (!$file_contents) {
+ $error = elgg_echo('admin:plugins:markdown:unknown_file');
+ }
+
+ if ($error) {
+ $title = $error;
+ $body = elgg_view_layout('admin', array('content' => $error, 'title' => $title));
+ echo elgg_view_page($title, $body, 'admin');
+ return true;
+ }
+
+ $title = $plugin->manifest->getName() . ": $filename";
+ $text = Markdown($file_contents);
+
+ $body = elgg_view_layout('admin', array(
+ 'content' => $text,
+ 'title' => $title
+ ));
+
+ echo elgg_view_page($title, $body, 'admin');
+}
+
+/**
* Adds default admin widgets to the admin dashboard.
*
* @return void
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php
index 7a4e62921..80ffbe74e 100644
--- a/engine/lib/annotations.php
+++ b/engine/lib/annotations.php
@@ -388,13 +388,10 @@ function elgg_list_entities_from_annotations($options = array()) {
/**
* Get entities ordered by a mathematical calculation on annotation values
*
- * @todo I think at some point this could run through elgg_get_annotations() and pass a the callback
- * as entity_row_to_elggstar
- *
* @param array $options An options array:
* 'annotation_calculation' => The calculation to use. Must be a valid MySQL function.
* Defaults to sum. Result selected as 'annotation_calculation'.
- * 'order_by' => The order for the sorting. Defaults to 'calculation desc'.
+ * 'order_by' => The order for the sorting. Defaults to 'annotation_calculation desc'.
* 'annotation_names' => The names of annotations on the entity.
* 'annotation_values' => The values of annotations on the entity.
*
@@ -404,9 +401,10 @@ function elgg_list_entities_from_annotations($options = array()) {
* @return mixed
*/
function elgg_get_entities_from_annotation_calculation($options) {
+ $db_prefix = elgg_get_config('dbprefix');
$defaults = array(
- 'calculation' => 'sum',
- 'order_by' => 'calculation desc'
+ 'calculation' => 'sum',
+ 'order_by' => 'annotation_calculation desc'
);
$options = array_merge($defaults, $options);
@@ -415,14 +413,13 @@ function elgg_get_entities_from_annotation_calculation($options) {
// you must cast this as an int or it sorts wrong.
$options['selects'][] = 'e.*';
- $options['selects'][] = "$function(cast(v.string as signed)) as calculation";
+ $options['selects'][] = "$function(cast(a_msv.string as signed)) as annotation_calculation";
- // need our own join to get the values.
-// $options['joins'][] = "JOIN {$db_prefix}metastrings msv ON a.value_id = msv.id";
-// $options['joins'][] = "JOIN {$db_prefix}entities ae ON a.entity_guid = ae.guid";
+ // need our own join to get the values because the lower level functions don't
+ // add all the joins if it's a different callback.
+ $options['joins'][] = "JOIN {$db_prefix}metastrings a_msv ON n_table.value_id = a_msv.id";
- $options['wheres'][] = get_access_sql_suffix('n_table');
-// $options['wheres'][] = "e.guid = a.entity_guid";
+ // don't need access control because it's taken care of by elgg_get_annotations.
$options['group_by'] = 'n_table.entity_guid';
$options['callback'] = 'entity_row_to_elggstar';
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 6c94133df..e67f8b627 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -202,6 +202,7 @@ function elgg_unregister_js($name) {
*
* @param string $name Identifier of the JavaScript resource
*
+ * @return void
* @since 1.8.0
*/
function elgg_load_js($name) {
@@ -254,6 +255,7 @@ function elgg_unregister_css($name) {
*
* @param string $name Identifier of the CSS file
*
+ * @return void
* @since 1.8.0
*/
function elgg_load_css($name) {
@@ -354,8 +356,9 @@ function elgg_unregister_external_file($type, $name) {
* Load an external resource for use on this page
*
* @param string $type Type of file: js or css
- * @param string $name
+ * @param string $name The identifier for the file
*
+ * @return void
* @since 1.8.0
*/
function elgg_load_external_file($type, $name) {
@@ -1152,13 +1155,16 @@ function elgg_dump($value, $to_screen = TRUE, $level = 'NOTICE') {
*
* @see CODING.txt
*
- * @param str $msg Message to log / display.
- * @param str $dep_version Human-readable *release* version: 1.7, 1.7.3
+ * @param str $msg Message to log / display.
+ * @param str $dep_version Human-readable *release* version: 1.7, 1.7.3
+ * @param int $backtrace_level How many levels back to display the backtrace. Useful if calling from
+ * functions that are called from other places (like elgg_view()). Set
+ * to -1 for a full backtrace.
*
* @return bool
* @since 1.7.0
*/
-function elgg_deprecated_notice($msg, $dep_version) {
+function elgg_deprecated_notice($msg, $dep_version, $backtrace_level = 1) {
// if it's a major release behind, visual and logged
// if it's a 1 minor release behind, visual and logged
// if it's for current minor release, logged.
@@ -1192,9 +1198,26 @@ function elgg_deprecated_notice($msg, $dep_version) {
// Get a file and line number for the log. Never show this in the UI.
// Skip over the function that sent this notice and see who called the deprecated
// function itself.
+ $msg .= " Called from ";
+ $stack = array();
$backtrace = debug_backtrace();
- $caller = $backtrace[1];
- $msg .= " (Called from {$caller['file']}:{$caller['line']})";
+ // never show this call.
+ array_shift($backtrace);
+ $i = count($backtrace);
+
+ foreach ($backtrace as $trace) {
+ $stack[] = "[#$i] {$trace['file']}:{$trace['line']}";
+ $i--;
+
+ if ($backtrace_level > 0) {
+ if ($backtrace_level <= 1) {
+ break;
+ }
+ $backtrace_level--;
+ }
+ }
+
+ $msg .= implode("<br /> -> ", $stack);
elgg_log($msg, 'WARNING');
@@ -1623,8 +1646,9 @@ function is_not_null($string) {
* names by singular names.
*
* @param array $options The options array. $options['keys'] = 'values';
- * @param array $singulars A list of sinular words to pluralize by adding 's'.
+ * @param array $singulars A list of singular words to pluralize by adding 's'.
*
+ * @access private
* @return array
* @since 1.7.0
*/
@@ -1744,8 +1768,8 @@ function elgg_css_page_handler($page) {
*
* /<css||js>/name/of/view.<last_cache>.<css||js>
*
- * @param array $page The page array
- * @param string $type The type: js or css
+ * @param array $page The page array
+ * @param string $type The type: js or css
*
* @return mixed
*/
diff --git a/engine/lib/input.php b/engine/lib/input.php
index 25416b868..84752bc7d 100644
--- a/engine/lib/input.php
+++ b/engine/lib/input.php
@@ -237,7 +237,7 @@ function input_livesearch_page_handler($page) {
exit;
}
- if (!$q = get_input('q')) {
+ if (!$q = get_input('term', get_input('q'))) {
exit;
}
diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php
index 655617ac6..d444121d0 100644
--- a/engine/lib/metastrings.php
+++ b/engine/lib/metastrings.php
@@ -211,23 +211,29 @@ function delete_orphaned_metastrings() {
*
* @param array $options Array in format:
*
- * metastring_names => NULL|ARR metastring names
+ * metastring_names => NULL|ARR metastring names
*
- * metastring_values => NULL|ARR metastring values
+ * metastring_values => NULL|ARR metastring values
*
- * metastring_ids => NULL|ARR metastring ids
+ * metastring_ids => NULL|ARR metastring ids
*
- * metastring_case_sensitive => BOOL Overall Case sensitive
+ * metastring_case_sensitive => BOOL Overall Case sensitive
*
- * metastring_owner_guids => NULL|ARR guids for metadata owners
+ * metastring_owner_guids => NULL|ARR Guids for metadata owners
*
- * metastring_created_time_lower => INT Lower limit for created time.
+ * metastring_created_time_lower => INT Lower limit for created time.
*
- * metastring_created_time_upper => INT Upper limit for created time.
+ * metastring_created_time_upper => INT Upper limit for created time.
*
- * metastring_calculation => STR Perform the MySQL function on the metastring values returned.
+ * metastring_calculation => STR Perform the MySQL function on the metastring values
+ * returned.
+ * This differs from egef_annotation_calculation in that
+ * it returns only the calculation of all annotation values.
+ * You can sum, avg, count, etc. egef_annotation_calculation()
+ * returns ElggEntities ordered by a calculation on their
+ * annotation values.
*
- * metastring_type => STR metadata or annotation(s)
+ * metastring_type => STR metadata or annotation(s)
*
* @return mixed
* @access private
@@ -373,14 +379,35 @@ function elgg_get_metastring_based_objects($options) {
}
$joins = $options['joins'];
-
$joins[] = "JOIN {$db_prefix}entities e ON n_table.entity_guid = e.guid";
- $joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id";
- $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id";
+ // evaluate selects
+ if (!is_array($options['selects'])) {
+ $options['selects'] = array($options['selects']);
+ }
- // remove identical join clauses
- $joins = array_unique($joins);
+ $selects = $options['selects'];
+
+ // allow count shortcut
+ if ($options['count']) {
+ $options['metastring_calculation'] = 'count';
+ }
+
+ // For performance reasons we don't want the joins required for metadata / annotations
+ // unless we're going through one of their callbacks.
+ // this means we expect the functions passing different callbacks to pass their required joins.
+ // If we're doing a calculation
+ $custom_callback = ($options['callback'] == 'row_to_elggmetadata'
+ || $options['callback'] == 'row_to_elggannotation');
+ $is_calculation = $options['metastring_calculation'] ? true : false;
+
+ if ($custom_callback || $is_calculation) {
+ $joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id";
+ $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id";
+
+ $selects[] = 'n.string as name';
+ $selects[] = 'v.string as value';
+ }
foreach ($joins as $i => $join) {
if ($join === FALSE) {
@@ -400,28 +427,24 @@ function elgg_get_metastring_based_objects($options) {
$joins = array_merge($joins, $metastring_clauses['joins']);
}
- // check for calculations
- if ($options['count']) {
- $options['metastring_calculation'] = 'count';
- }
-
if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) {
+ $selects = array_unique($selects);
// evalutate selects
- if ($options['selects']) {
- $selects = '';
- foreach ($options['selects'] as $select) {
- $selects .= ", $select";
+ $select_str = '';
+ if ($selects) {
+ foreach ($selects as $select) {
+ $select_str .= ", $select";
}
- } else {
- $selects = '';
}
- $query = "SELECT DISTINCT n_table.*, n.string as name,
- v.string as value{$selects} FROM {$db_prefix}$type n_table";
+ $query = "SELECT DISTINCT n_table.*{$select_str} FROM {$db_prefix}$type n_table";
} else {
$query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";
}
+ // remove identical join clauses
+ $joins = array_unique($joins);
+
// add joins
foreach ($joins as $j) {
$query .= " $j ";
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index 3a144abc5..0947b7a8e 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -1088,6 +1088,8 @@ function plugin_init() {
elgg_register_action('admin/plugins/deactivate_all', '', 'admin');
elgg_register_action('admin/plugins/set_priority', '', 'admin');
+
+ elgg_register_library('elgg:markdown', elgg_get_root_path() . 'vendors/markdown/markdown.php');
}
elgg_register_event_handler('init', 'system', 'plugin_init');
diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php
index 4e822e8af..cd2b7a6a1 100644
--- a/engine/lib/statistics.php
+++ b/engine/lib/statistics.php
@@ -100,7 +100,11 @@ function get_online_users() {
$objects = find_active_users(600, 10, $offset);
if ($objects) {
- return elgg_view_entity_list($objects, $count, $offset, 10, false);
+ return elgg_view_entity_list($objects, array(
+ 'count' => $count,
+ 'offset' => $offset,
+ 'limit' => 10
+ ));
}
}
diff --git a/engine/lib/views.php b/engine/lib/views.php
index e2cf6b5c3..45b2c35f8 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -395,8 +395,10 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
}
// full_view is the new preferred key for full view on entities @see elgg_view_entity()
- if (isset($vars['full'])) {
- elgg_deprecated_notice("Use \$vars['full_view'] instead of \$vars['full']", 1.8);
+ // check if full_view is set because that means we've already rewritten it and this is
+ // coming from another view passing $vars directly.
+ if (isset($vars['full']) && !isset($vars['full_view'])) {
+ elgg_deprecated_notice("Use \$vars['full_view'] instead of \$vars['full']", 1.8, 2);
$vars['full_view'] = $vars['full'];
}
if (isset($vars['full_view'])) {
@@ -404,16 +406,17 @@ function elgg_view($view, $vars = array(), $bypass = false, $debug = false, $vie
}
// internalname => name (1.8)
- if (isset($vars['internalname'])) {
- elgg_deprecated_notice('You should pass $vars[\'name\'] now instead of $vars[\'internalname\']', 1.8);
+ if (isset($vars['internalname']) && !isset($vars['name'])) {
+ elgg_deprecated_notice('You should pass $vars[\'name\'] now instead of $vars[\'internalname\']', 1.8, 2);
$vars['name'] = $vars['internalname'];
+ $test=false;
} elseif (isset($vars['name'])) {
$vars['internalname'] = $vars['name'];
}
// internalid => id (1.8)
- if (isset($vars['internalid'])) {
- elgg_deprecated_notice('You should pass $vars[\'id\'] now instead of $vars[\'internalid\']', 1.8);
+ if (isset($vars['internalid']) && !isset($vars['name'])) {
+ elgg_deprecated_notice('You should pass $vars[\'id\'] now instead of $vars[\'internalid\']', 1.8, 2);
$vars['id'] = $vars['internalid'];
} elseif (isset($vars['id'])) {
$vars['internalid'] = $vars['id'];
diff --git a/engine/tests/api/metastrings.php b/engine/tests/api/metastrings.php
index e5cfe80e1..9b5d7ee4e 100644
--- a/engine/tests/api/metastrings.php
+++ b/engine/tests/api/metastrings.php
@@ -164,7 +164,7 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
}
$options = array();
- $this->assertFalse(elgg_is_valid_options_for_batch_operation($options), $type);
+ $this->assertFalse(elgg_is_valid_options_for_batch_operation($options, $type));
foreach ($required as $key) {
$options = array();
diff --git a/engine/tests/api/plugins.php b/engine/tests/api/plugins.php
index 853af45e9..00b0d4513 100644
--- a/engine/tests/api/plugins.php
+++ b/engine/tests/api/plugins.php
@@ -105,8 +105,6 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
array('type' => 'plugin', 'name' => 'facebook_connect', 'version' => 1.0),
),
- 'on_activate' => array('setup_function'),
- 'on_deactivate' => array('teardown_function'),
'admin_interface' => 'simple',
'activate_on_install' => true
);
@@ -279,14 +277,6 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
$this->assertEqual($this->manifest17->getConflicts(), array());
}
- public function testElggPluginManifestGetOnActivate() {
- $this->assertEqual($this->manifest18->getOnActivate(), array('setup_function'));
- }
-
- public function testElggPluginManifestGetOnDeactivate() {
- $this->assertEqual($this->manifest18->getOnDeactivate(), array('teardown_function'));
- }
-
public function testElggPluginManifestGetAdminInterface() {
$this->assertEqual($this->manifest18->getAdminInterface(), 'simple');
}
diff --git a/engine/tests/test_files/plugin_18/manifest.xml b/engine/tests/test_files/plugin_18/manifest.xml
index c6cf4f807..23f0fa0bf 100644
--- a/engine/tests/test_files/plugin_18/manifest.xml
+++ b/engine/tests/test_files/plugin_18/manifest.xml
@@ -34,8 +34,6 @@
<category>ServiceAPI</category>
- <on_activate>setup_function</on_activate>
- <on_deactivate>teardown_function</on_deactivate>
<admin_interface>simple</admin_interface>
<activate_on_install>true</activate_on_install>
diff --git a/languages/en.php b/languages/en.php
index 6e24edb2d..5fbf50142 100644
--- a/languages/en.php
+++ b/languages/en.php
@@ -613,6 +613,10 @@ $english = array(
'admin:plugins:category:extension' => 'Extensions',
'admin:plugins:category:service' => 'Service/API',
+ 'admin:plugins:markdown:unknown_plugin' => 'Unknown plugin.',
+ 'admin:plugins:markdown:unknown_file' => 'Unknown file.',
+
+
'admin:notices:could_not_delete' => 'Could not delete notice.',
'admin:options' => 'Admin options',
diff --git a/mod/developers/languages/en.php b/mod/developers/languages/en.php
index 41bdcdddb..a2db69bc4 100644
--- a/mod/developers/languages/en.php
+++ b/mod/developers/languages/en.php
@@ -26,13 +26,14 @@ $english = array(
'developers:debug:notice' => 'Notice',
// theme preview
- 'theme_preview:general' => 'General',
- 'theme_preview:navigation' => 'Navigation',
+ 'theme_preview:buttons' => 'Buttons',
+ 'theme_preview:components' => 'Components',
'theme_preview:forms' => 'Forms',
- 'theme_preview:objects' => 'Objects',
'theme_preview:grid' => 'Grid',
- 'theme_preview:widgets' => 'Widgets',
'theme_preview:icons' => 'Icons',
+ 'theme_preview:modules' => 'Modules',
+ 'theme_preview:navigation' => 'Navigation',
+ 'theme_preview:typography' => 'Typography',
);
add_translation('en', $english);
diff --git a/mod/developers/start.php b/mod/developers/start.php
index dc8e6f66e..c05432e30 100644
--- a/mod/developers/start.php
+++ b/mod/developers/start.php
@@ -45,13 +45,14 @@ function developers_theme_preview_controller($page) {
}
$pages = array(
- 'general',
- 'navigation',
+ 'buttons',
+ 'components',
'forms',
- 'objects',
'grid',
- 'widgets',
'icons',
+ 'modules',
+ 'navigation',
+ 'typography',
);
foreach ($pages as $page_name) {
@@ -65,5 +66,10 @@ function developers_theme_preview_controller($page) {
$title = elgg_echo("theme_preview:{$page[0]}");
$body = elgg_view("theme_preview/{$page[0]}");
- echo elgg_view_page($title, $body, 'theme_preview');
+ $layout = elgg_view_layout('one_sidebar', array(
+ 'title' => $title,
+ 'content' => $body,
+ ));
+
+ echo elgg_view_page($title, $layout, 'theme_preview');
}
diff --git a/mod/developers/views/default/forms/developers/settings.php b/mod/developers/views/default/forms/developers/settings.php
index 371a2de2b..a442ca0ce 100644
--- a/mod/developers/views/default/forms/developers/settings.php
+++ b/mod/developers/views/default/forms/developers/settings.php
@@ -5,7 +5,7 @@
* @uses $vars['values']
*/
-$form_body = '<p>' . elgg_echo('elgg_dev_tools:settings:explanation') . '</p>';
+echo '<p>' . elgg_echo('elgg_dev_tools:settings:explanation') . '</p>';
foreach ($vars['data'] as $name => $info) {
echo '<div>';
diff --git a/mod/developers/views/default/page/theme_preview.php b/mod/developers/views/default/page/theme_preview.php
index 97df551ae..5b31fd789 100644
--- a/mod/developers/views/default/page/theme_preview.php
+++ b/mod/developers/views/default/page/theme_preview.php
@@ -14,48 +14,18 @@ header("Content-type: text/html; charset=UTF-8");
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title><?php echo $vars['title']; ?></title>
- <link rel="stylesheet" href="<?php echo $elgg; ?>" type="text/css" />
- <style>
- .elgg-page-body { margin: 20px }
- .elgg-page-header:after {content:'.'; display:block; clear:both; height:0; visibility: hidden}
- .elgg-page-header .elgg-menu-page > li {float:left; padding: 5px}
- .elgg-page-header .elgg-menu-page > li > a {padding: 2px 4px}
- .elgg-page-header .elgg-menu-page > li.elgg-state-selected > a {background-color:#0054A7;}
- </style>
- <!--[if gt IE 6]>
- <link rel="stylesheet" type="text/css" href="<?php echo $ie_url; ?>" />
- <![endif]-->
- <!--[if IE 6]>
- <link rel="stylesheet" type="text/css" href="<?php echo $ie6_url; ?>" />
- <![endif]-->
-
-<?php
-foreach (elgg_get_loaded_js() as $script) {
-?>
- <script type="text/javascript" src="<?php echo $script; ?>"></script>
-<?php
-}
-?>
-
+ <?php echo elgg_view('page/elements/head', $vars); ?>
</head>
<body>
-<div class="elgg-page">
+<div class="elgg-page elgg-page-default">
<div class="elgg-page-header">
<div class="elgg-inner">
- <?php echo elgg_view_menu('page'); ?>
+ <h1 class="elgg-heading-site">Theme Preview</h1>
</div>
</div>
<div class="elgg-page-body">
<div class="elgg-inner">
- <?php echo elgg_view_title($vars['title']); ?>
- <?php echo $vars['body']; ?>
- </div>
- </div>
- <div class="elgg-page-header">
- <div class="elgg-inner">
- <?php echo elgg_view_menu('page'); ?>
+ <?php echo elgg_view('page/elements/body', $vars); ?>
</div>
</div>
</div>
diff --git a/mod/developers/views/default/theme_preview/buttons.php b/mod/developers/views/default/theme_preview/buttons.php
new file mode 100644
index 000000000..718d88617
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/buttons.php
@@ -0,0 +1,41 @@
+<table class="elgg-table">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Default</th>
+ <th>Disabled (.elgg-state-disabled)</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>Base (.elgg-button)</th>
+ <td><a href="#" class="elgg-button">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-state-disabled">anchor</a></td>
+ </tr>
+ <tr>
+ <th>Action (.elgg-button-action)</th>
+ <td><a href="#" class="elgg-button elgg-button-action">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-button-action elgg-state-disabled">anchor</a></td>
+ </tr>
+ <tr>
+ <th>Cancel (.elgg-button-cancel)</th>
+ <td><a href="#" class="elgg-button elgg-button-cancel">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-button-cancel elgg-state-disabled">anchor</a></td>
+ </tr>
+ <tr>
+ <th>Submit (.elgg-button-submit)</th>
+ <td><a href="#" class="elgg-button elgg-button-submit">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-button-submit elgg-state-disabled">anchor</a></td>
+ </tr>
+ <tr>
+ <th>Special (.elgg-button-special)</th>
+ <td><a href="#" class="elgg-button elgg-button-special">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-button-special elgg-state-disabled">anchor</a></td>
+ </tr>
+ <tr>
+ <th>Delete (.elgg-button-delete)</th>
+ <td><a href="#" class="elgg-button elgg-button-delete">anchor</a></td>
+ <td><a href="#" class="elgg-button elgg-button-delete elgg-state-disabled">anchor</a></td>
+ </tr>
+ </tbody>
+</table> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/components.php b/mod/developers/views/default/theme_preview/components.php
new file mode 100644
index 000000000..ab5a6e941
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/components.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * CSS Objects: list, module, image_block, table, messages
+ */
+
+echo elgg_view_module('info', 'Image Block (.elgg-image-block)', elgg_view('theme_preview/components/image_block'));
+
+echo elgg_view_module('info', 'List (.elgg-list)', elgg_view('theme_preview/components/list'));
+
+echo elgg_view_module('info', 'Table (.elgg-table)', elgg_view('theme_preview/components/table'));
+
+echo elgg_view_module('info', 'Messages (.elgg-message)', elgg_view('theme_preview/components/messages'));
diff --git a/mod/developers/views/default/theme_preview/components/image_block.php b/mod/developers/views/default/theme_preview/components/image_block.php
new file mode 100644
index 000000000..0bb16428b
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/components/image_block.php
@@ -0,0 +1,6 @@
+<?php
+$ipsum = elgg_view('developers/ipsum');
+
+$user = new ElggUser();
+$image = elgg_view_entity_icon($user, 'small');
+echo elgg_view_image_block($image, "$ipsum $ipsum $ipsum $ipsum $ipsum $ipsum $ipsum");
diff --git a/mod/developers/views/default/theme_preview/components/list.php b/mod/developers/views/default/theme_preview/components/list.php
new file mode 100644
index 000000000..8096bda04
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/components/list.php
@@ -0,0 +1,19 @@
+<?php
+
+$obj1 = new ElggObject();
+$obj1->title = "Object 1";
+$obj1->description = $ipsum;
+
+$obj2 = new ElggObject();
+$obj2->title = "Object 2";
+$obj2->description = $ipsum;
+
+$obj3 = new ElggObject();
+$obj3->title = "Object 3";
+$obj3->description = $ipsum;
+
+$obj4 = new ElggObject();
+$obj4->title = "Object 4";
+$obj4->description = $ipsum;
+
+echo elgg_view('page/components/list', array('items' => array($obj1, $obj2, $obj3, $obj4)));
diff --git a/mod/developers/views/default/theme_preview/components/messages.php b/mod/developers/views/default/theme_preview/components/messages.php
new file mode 100644
index 000000000..ac4d2bfd7
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/components/messages.php
@@ -0,0 +1,5 @@
+<ul>
+ <li class="elgg-message elgg-state-success mas">Success message (.elgg-state-success)</li>
+ <li class="elgg-message elgg-state-error mas">Error message (.elgg-state-error)</li>
+ <li class="elgg-message elgg-state-notice mas">Notice message (.elgg-state-notice)</li>
+</ul>
diff --git a/mod/developers/views/default/theme_preview/components/table.php b/mod/developers/views/default/theme_preview/components/table.php
new file mode 100644
index 000000000..e9ef32143
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/components/table.php
@@ -0,0 +1,12 @@
+<table class="elgg-table">
+<?php
+ echo "<thead><tr><th>column 1</th><th>column 2</th></tr></thead>";
+ for ($i = 1; $i < 5; $i++) {
+ echo '<tr>';
+ for ($j = 1; $j < 3; $j++) {
+ echo "<td>value $j</td>";
+ }
+ echo '</tr>';
+ }
+?>
+</table> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/forms.php b/mod/developers/views/default/theme_preview/forms.php
index bf637d6f0..60183ead9 100644
--- a/mod/developers/views/default/theme_preview/forms.php
+++ b/mod/developers/views/default/theme_preview/forms.php
@@ -1,222 +1,139 @@
-<?php
-/**
- * Form CSS
- */
-
-$url = current_page_url();
-
-$ipsum = elgg_view('developers/ipsum');
-
-?>
-<style>
- td, th {padding: 5px;}
-</style>
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
- <h2>Form</h2>
- <form action="#">
- <fieldset>
- <legend>Form legend</legend>
- <div>
- <label for="f1">Text input:</label>
- <?php echo elgg_view('input/text', array(
- 'name' => 'f1',
- 'id' => 'f1',
- 'value' => 'input text',
- ));
- ?>
- </div>
- <div>
- <label for="f2">Password input:</label>
- <?php echo elgg_view('input/password', array(
- 'name' => 'f2',
- 'id' => 'f2',
- 'value' => 'password',
- ));
- ?>
- </div>
- <div>
- <label for="f3">Radio input:</label><br />
- <?php echo elgg_view('input/radio', array(
- 'name' => 'f3',
- 'id' => 'f3',
- 'options' => array('a' => 1, 'b' => 2),
- ));
- ?>
- </div>
- <div>
- <label for="f4">Checkboxes input:</label><br />
- <?php echo elgg_view('input/checkboxes', array(
- 'name' => 'f4',
- 'id' => 'f4',
- 'options' => array('a' => 1, 'b' => 2),
- ));
- ?>
- </div>
- <div>
- <label for="f5">Dropdown input:</label><br />
- <?php echo elgg_view('input/dropdown', array(
- 'name' => 'f5',
- 'id' => 'f5',
- 'options' => array('option 1', 'option 2'),
- ));
- ?>
- </div>
- <div>
- <label for="f6">Access input:</label>
- <?php echo elgg_view('input/access', array(
- 'name' => 'f6',
- 'id' => 'f6',
- 'value' => ACCESS_PUBLIC,
- ));
- ?>
- </div>
- <div>
- <label for="f7">File input:</label>
- <?php echo elgg_view('input/file', array(
- 'name' => 'f7',
- 'id' => 'f7',
- ));
- ?>
- </div>
- <div>
- <label for="f8">URL input:</label>
- <?php echo elgg_view('input/url', array(
- 'name' => 'f8',
- 'id' => 'f8',
- 'value' => 'http://elgg.org/',
- ));
- ?>
- </div>
- <div>
- <label for="f9">Tags input:</label>
- <?php echo elgg_view('input/tags', array(
- 'name' => 'f9',
- 'id' => 'f9',
- 'value' => 'one, two, three',
- ));
- ?>
- </div>
- <div>
- <label for="f10">Email input:</label>
- <?php echo elgg_view('input/email', array(
- 'name' => 'f10',
- 'id' => 'f10',
- 'value' => 'noone@elgg.org',
- ));
- ?>
- </div>
- <div>
- <label for="f11">Autocomplete input:</label>
- <?php echo elgg_view('input/autocomplete', array(
- 'name' => 'f11',
- 'id' => 'f11',
- 'match_on' => 'users',
- ));
- ?>
- </div>
- <div>
- <label for="f12">Date picker input:</label>
- <?php echo elgg_view('input/datepicker', array(
- 'name' => 'f12',
- 'id' => 'f12',
- ));
- ?>
- </div>
- <div>
- <label for="f13">User picker input:</label>
- <?php echo elgg_view('input/userpicker', array(
- 'name' => 'f13',
- 'id' => 'f13',
- ));
- ?>
- </div>
- <div>
- <label for="f14">Long text input:</label>
- <?php echo elgg_view('input/longtext', array(
- 'name' => 'f14',
- 'id' => 'f14',
- 'value' => $ipsum,
- ));
- ?>
- </div>
- <div>
- <label for="f15">Plain text input:</label>
- <?php echo elgg_view('input/plaintext', array(
- 'name' => 'f15',
- 'id' => 'f15',
- 'value' => $ipsum,
- ));
- ?>
- </div>
- </fieldset>
- </form>
-
- <div class="mtl">
- <h2>Buttons</h2>
- <table>
- <thead>
- <tr>
- <th>Anchors</th>
- <th>Default</th>
- <th>Hover</th>
- <th>Focus</th>
- <th>Active</th>
- <th>Disabled</th>
- <th>Selected</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <th>Default</th>
- <td><a href="#" class="elgg-button">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-state-disabled">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-state-selected">anchor</a></td>
- </tr>
- <tr>
- <th>Action</th>
- <td><a href="#" class="elgg-button elgg-button-action">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-action elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-action elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-action elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-action elgg-state-disabled">anchor</a></td>
- </tr>
- <tr>
- <th>Cancel</th>
- <td><a href="#" class="elgg-button elgg-button-cancel">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-cancel elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-cancel elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-cancel elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-cancel elgg-state-disabled">anchor</a></td>
- </tr>
- <tr>
- <th>Submit</th>
- <td><a href="#" class="elgg-button elgg-button-submit">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-submit elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-submit elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-submit elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-submit elgg-state-disabled">anchor</a></td>
- </tr>
- <tr>
- <th>Special</th>
- <td><a href="#" class="elgg-button elgg-button-special">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-special elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-special elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-special elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-special elgg-state-disabled">anchor</a></td>
- </tr>
- <tr>
- <th>Delete</th>
- <td><a href="#" class="elgg-button elgg-button-delete">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-delete elgg-state-hover">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-delete elgg-state-focus">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-delete elgg-state-active">anchor</a></td>
- <td><a href="#" class="elgg-button elgg-button-delete elgg-state-disabled">anchor</a></td>
- </tr>
- </tbody>
- </table>
- </div>
-</div>
+<form action="#">
+ <fieldset>
+ <legend>Fieldset Legend</legend>
+ <div>
+ <label for="f1">Text input (.elgg-input-text):</label>
+ <?php echo elgg_view('input/text', array(
+ 'name' => 'f1',
+ 'id' => 'f1',
+ 'value' => 'input text',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f2">Password input (.elgg-input-password):</label>
+ <?php echo elgg_view('input/password', array(
+ 'name' => 'f2',
+ 'id' => 'f2',
+ 'value' => 'password',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f3">Radio input (.elgg-input-radio):</label><br />
+ <?php echo elgg_view('input/radio', array(
+ 'name' => 'f3',
+ 'id' => 'f3',
+ 'options' => array('a' => 1, 'b' => 2),
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f4">Checkboxes input (.elgg-input-checkboxes):</label><br />
+ <?php echo elgg_view('input/checkboxes', array(
+ 'name' => 'f4',
+ 'id' => 'f4',
+ 'options' => array('a (.elgg-input-checkbox)' => 1, 'b (.elgg-input-checkbox)' => 2),
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f5">Dropdown input (.elgg-input-dropdown):</label><br />
+ <?php echo elgg_view('input/dropdown', array(
+ 'name' => 'f5',
+ 'id' => 'f5',
+ 'options' => array('option 1', 'option 2'),
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f6">Access input (.elgg-input-access):</label><br />
+ <?php echo elgg_view('input/access', array(
+ 'name' => 'f6',
+ 'id' => 'f6',
+ 'value' => ACCESS_PUBLIC,
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f7">File input (.elgg-input-file):</label>
+ <?php echo elgg_view('input/file', array(
+ 'name' => 'f7',
+ 'id' => 'f7',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f8">URL input (.elgg-input-url):</label>
+ <?php echo elgg_view('input/url', array(
+ 'name' => 'f8',
+ 'id' => 'f8',
+ 'value' => 'http://elgg.org/',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f9">Tags input (.elgg-input-tags):</label>
+ <?php echo elgg_view('input/tags', array(
+ 'name' => 'f9',
+ 'id' => 'f9',
+ 'value' => 'one, two, three',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f10">Email input (.elgg-input-email):</label>
+ <?php echo elgg_view('input/email', array(
+ 'name' => 'f10',
+ 'id' => 'f10',
+ 'value' => 'noone@elgg.org',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f11">Autocomplete input (.elgg-input-autocomplete):</label>
+ <?php echo elgg_view('input/autocomplete', array(
+ 'name' => 'f11',
+ 'id' => 'f11',
+ 'match_on' => 'users',
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f12">Date input (.elgg-input-date):</label>
+ <?php echo elgg_view('input/date', array(
+ 'name' => 'f12',
+ 'id' => 'f12',
+ 'value' => '12/12/2012'
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f13">User picker input (.elgg-user-picker):</label>
+ <?php echo elgg_view('input/userpicker', array(
+ 'name' => 'f13',
+ 'id' => 'f13',
+ 'value' => array(new ElggUser(), new ElggUser(), new ElggUser()),
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f15">Plain textarea input (.elgg-input-plaintext):</label>
+ <?php echo elgg_view('input/plaintext', array(
+ 'name' => 'f15',
+ 'id' => 'f15',
+ 'value' => $ipsum,
+ ));
+ ?>
+ </div>
+ <div>
+ <label for="f14">Long textarea input (.elgg-input-longtext):</label>
+ <?php echo elgg_view('input/longtext', array(
+ 'name' => 'f14',
+ 'id' => 'f14',
+ 'value' => $ipsum,
+ ));
+ ?>
+ </div>
+ </fieldset>
+</form> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/general.php b/mod/developers/views/default/theme_preview/general.php
deleted file mode 100644
index bd11b35db..000000000
--- a/mod/developers/views/default/theme_preview/general.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/**
- * General CSS
- */
-
-$ipsum = elgg_view('developers/ipsum');
-
-?>
-
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
- <h2>Headings</h2>
- <div class="mbl">
- <h1>Level 1 heading</h1>
- <h2>Level 2 heading</h2>
- <h3>Level 3 heading</h3>
- <h4>Level 4 heading</h4>
- <h5>Level 5 heading</h5>
- <h6>Level 6 heading</h6>
- </div>
- <h2>Paragraph</h2>
- <div class="mbl">
- <p>Lorem ipsum dolor sit amet, <a href="#" title="test link">test link</a>
- adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
- faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
- nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
- mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu
- volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
- eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
- consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
- quis tellus.</p>
-
- <p>Lorem ipsum dolor sit amet, <em>emphasis</em>
- consectetuer
- adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
- faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
- nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
- mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu
- volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
- eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
- consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
- quis tellus.</p>
- </div>
- <h2>Misc</h2>
- <p>
- I am <a href="?abc123">the a tag</a> example<br />
- I am <abbr title="test">the abbr tag</abbr> example<br />
- I am <acronym>the acronym tag</acronym> example<br />
- I am <b>the b tag</b> example<br />
- I am <code>the code tag</code> example<br />
- I am <del>the del tag</del> example<br />
- I am <em>the em tag</em> example<br />
- I am <i>the i tag</i> example<br />
- I am <strong>the strong tag</strong> example<br />
- </p>
- <blockquote><p>Paragraph inside Blockquote: <?php echo $ipsum; ?></p></blockquote>
- <pre><strong>Preformated:</strong>Testing one row
- and another</pre>
-</div>
diff --git a/mod/developers/views/default/theme_preview/grid.php b/mod/developers/views/default/theme_preview/grid.php
index 95e14cfd5..030e752e7 100644
--- a/mod/developers/views/default/theme_preview/grid.php
+++ b/mod/developers/views/default/theme_preview/grid.php
@@ -4,16 +4,13 @@
*/
?>
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
-
<style>
h3 {text-align: center;}
-.preview-outline {border: 1px solid #cccccc; padding: 5px;}
+.elgg-col > .elgg-inner {border: 1px solid #cccccc; padding: 5px;}
</style>
<div class="elgg-col elgg-col-1of5">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/5</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
@@ -21,44 +18,44 @@ h3 {text-align: center;}
</div>
</div>
<div class="elgg-col elgg-col-3of5">
- <div class="preview-outline clearfix">
+ <div class="elgg-inner clearfix">
<h3>3/5</h3>
<div class="elgg-col elgg-col-1of2">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="elgg-col elgg-col-1of2">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="elgg-col elgg-col-1of3">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/3</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="elgg-col elgg-col-2of3">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>2/3</h3>
<div class="elgg-col elgg-col-1of2">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="elgg-col elgg-col-1of2">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/2</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="elgg-col elgg-col-1of1">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
@@ -68,7 +65,7 @@ h3 {text-align: center;}
</div>
</div>
<div class="elgg-col elgg-col-1of5 elgg-col-last">
- <div class="preview-outline">
+ <div class="elgg-inner">
<h3>1/5</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
diff --git a/mod/developers/views/default/theme_preview/icons.php b/mod/developers/views/default/theme_preview/icons.php
index 8178a9da7..e1684c110 100644
--- a/mod/developers/views/default/theme_preview/icons.php
+++ b/mod/developers/views/default/theme_preview/icons.php
@@ -3,56 +3,8 @@
* Icons CSS
*/
-?>
-<style>li {margin: 10px; float: left;} ul {background-color: #e0e0e0;}</style>
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
- <h2>Icon Sprites</h2>
- <ul class="mbl clearfix">
- <?php
- $icons = array(
- 'settings' => 'Settings',
- 'friends' => 'Friends',
- 'help' => 'Help',
- 'delete' => 'Delete',
- 'thumbs-up' => 'Thumbs Up',
- 'thumbs-up-alt' => 'Thumbs Up Alternate',
- 'following' => 'Following',
- 'dragger' => 'Dragger',
- 'rss' => 'RSS',
- 'arrow-s' => 'Arrow S',
- 'hover-menu' => 'Hover Menu',
- );
-
- foreach ($icons as $icon_id => $icon_label) {
- echo "<li>" . elgg_view_icon($icon_id) . $icon_label . "</li>";
- }
-
- ?>
- </ul>
- <h2>Ajax loader</h2>
- <div class="mbl">
- <?php echo elgg_view('graphics/ajax_loader', array('hidden' => false)); ?>
- </div>
- <h2>Avatars</h2>
- <div class="mbl">
- <?php
- $user = new ElggUser();
- $sizes = array('large', 'medium', 'small', 'tiny');
- echo '<table>';
- echo '<tr>';
- foreach ($sizes as $size) {
- echo "<td class=\"center\"><h4>$size</h4></td>";
- }
- echo '</tr>';
- echo '<tr>';
- foreach ($sizes as $size) {
- echo '<td class="phs">';
- echo elgg_view_entity_icon($user, $size, array('hover' => false));
- echo '</td>';
- }
- echo '</tr>';
- echo '</table>';
- ?>
- </div>
-</div>
+echo elgg_view_module('info', 'Icon Sprites (.elgg-icon)', elgg_view('theme_preview/icons/sprites'));
+
+echo elgg_view_module('info', 'Ajax Loader (.elgg-ajax-loader)', elgg_view('theme_preview/icons/loader'));
+
+echo elgg_view_module('info', 'Avatars (.elgg-avatar)', elgg_view('theme_preview/icons/avatars'));
diff --git a/mod/developers/views/default/theme_preview/icons/avatars.php b/mod/developers/views/default/theme_preview/icons/avatars.php
new file mode 100644
index 000000000..cbce5bc7d
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/icons/avatars.php
@@ -0,0 +1,36 @@
+<?php
+ $user = new ElggUser();
+ $group = new ElggGroup();
+
+ $sizes = array('large', 'medium', 'small', 'tiny');
+?>
+<table class="elgg-table">
+ <tr>
+ <th></th>
+ <?php
+ foreach ($sizes as $size) {
+ echo "<th>$size</th>";
+ }
+ ?>
+ </tr>
+ <tr>
+ <th>User</th>
+ <?php
+ foreach ($sizes as $size) {
+ echo '<td>';
+ echo elgg_view_entity_icon($user, $size, array('hover' => false));
+ echo '</td>';
+ }
+ ?>
+ </tr>
+ <tr>
+ <th>Group</th>
+ <?php
+ foreach ($sizes as $size) {
+ echo '<td>';
+ echo elgg_view_entity_icon($group, $size, array('hover' => false));
+ echo '</td>';
+ }
+ ?>
+ </tr>
+</table>
diff --git a/mod/developers/views/default/theme_preview/icons/loader.php b/mod/developers/views/default/theme_preview/icons/loader.php
new file mode 100644
index 000000000..e542da27c
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/icons/loader.php
@@ -0,0 +1 @@
+<?php echo elgg_view('graphics/ajax_loader', array('hidden' => false)); ?> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/icons/sprites.php b/mod/developers/views/default/theme_preview/icons/sprites.php
new file mode 100644
index 000000000..134dd9aca
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/icons/sprites.php
@@ -0,0 +1,61 @@
+<?php
+$icons = array(
+ 'arrow-left',
+ 'arrow-right',
+ 'arrow-two-head',
+ 'calendar',
+ 'checkmark',
+ 'clip',
+ 'cursor-drag-arrow',
+ 'delete-alt',
+ 'delete',
+ 'download',
+ 'facebook',
+ 'home',
+ 'hover-menu',
+ 'link',
+ 'mail-alt',
+ 'mail',
+ 'print-alt',
+ 'print',
+ 'push-pin-alt',
+ 'push-pin',
+ 'redo',
+ 'refresh',
+ 'round-arrow-left',
+ 'round-arrow-right',
+ 'round-checkmark',
+ 'round-minus',
+ 'round-plus',
+ 'rss',
+ 'search-focus',
+ 'search',
+ 'settings-alt',
+ 'settings',
+ 'share',
+ 'shop-cart',
+ 'speech-bubble-alt',
+ 'speech-bubble',
+ 'star-alt',
+ 'star-empty',
+ 'star',
+ 'tag',
+ 'thumbs-down-alt',
+ 'thumbs-down',
+ 'thumbs-up-alt',
+ 'thumbs-up',
+ 'trash',
+ 'twitter',
+ 'undo',
+ 'user',
+ 'users',
+);
+?>
+
+<ul class="elgg-gallery">
+<?php
+ foreach ($icons as $icon) {
+ echo "<li title=\".elgg-icon-$icon\" style=\"margin:10px\">" . elgg_view_icon($icon) . "</li>";
+ }
+?>
+</ul> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/modules.php b/mod/developers/views/default/theme_preview/modules.php
new file mode 100644
index 000000000..3e0acb3a5
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/modules.php
@@ -0,0 +1,6 @@
+<?php
+
+echo elgg_view_module('info', 'Modules (.elgg-module)', elgg_view('theme_preview/modules/modules'));
+
+echo elgg_view_module('info', 'Widgets (.elgg-widget)', elgg_view('theme_preview/modules/widgets'));
+
diff --git a/mod/developers/views/default/theme_preview/modules/modules.php b/mod/developers/views/default/theme_preview/modules/modules.php
new file mode 100644
index 000000000..e0d39c0da
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/modules/modules.php
@@ -0,0 +1,23 @@
+<?php
+
+$ipsum = elgg_view('developers/ipsum');
+
+?>
+<div class="elgg-grid">
+ <div class="elgg-col elgg-col-1of2">
+ <div class="pam">
+ <?php
+ echo elgg_view_module('aside', 'Aside (.elgg-module-aside)', $ipsum);
+ echo elgg_view_module('popup', 'Popup (.elgg-module-popup)', $ipsum);
+ ?>
+ </div>
+ </div>
+ <div class="elgg-col elgg-col-1of2">
+ <div class="pam">
+ <?php
+ echo elgg_view_module('info', 'Info (.elgg-module-info)', $ipsum);
+ echo elgg_view_module('featured', 'Featured (.elgg-module-featured)', $ipsum);
+ ?>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/widgets.php b/mod/developers/views/default/theme_preview/modules/widgets.php
index eafbcef6f..8c9fd6483 100644
--- a/mod/developers/views/default/theme_preview/widgets.php
+++ b/mod/developers/views/default/theme_preview/modules/widgets.php
@@ -50,7 +50,7 @@ for ($column_index = 1; $column_index <= $num_columns; $column_index++) {
</div>
<script type="text/javascript">
// widgets do not have guids so we override the edit toggle and delete button
- $(document).ready(function() {
+ $(function() {
$('.elgg-widget-edit-button').unbind('click');
$('.elgg-widget-edit-button').click(function() {
$(this).closest('.elgg-module-widget').find('.elgg-widget-edit').slideToggle('medium');
diff --git a/mod/developers/views/default/theme_preview/navigation.php b/mod/developers/views/default/theme_preview/navigation.php
index 10cffd230..b80634317 100644
--- a/mod/developers/views/default/theme_preview/navigation.php
+++ b/mod/developers/views/default/theme_preview/navigation.php
@@ -2,64 +2,20 @@
/**
* Navigation CSS
*/
+echo elgg_view_module('info', "Tabs", elgg_view('theme_preview/navigation/tabs'));
-$url = current_page_url();
+echo elgg_view_module('info', "Pagination", elgg_view('theme_preview/navigation/pagination'));
-elgg_push_breadcrumb('First', "$url#");
-elgg_push_breadcrumb('Second', "$url#");
-elgg_push_breadcrumb('Third');
+echo elgg_view_module('info', "Site Menu (.elgg-menu-site)", elgg_view('theme_preview/navigation/site'));
+
+echo elgg_view_module('info', "Breadcrumbs (.elgg-breadcrumbs)", elgg_view('theme_preview/navigation/breadcrumbs'));
+
+echo elgg_view_module('info', "Page Menu (.elgg-menu-page)", elgg_view('theme_preview/navigation/page'));
+
+echo elgg_view_module('info', "Filter Menu (.elgg-menu-filter)", elgg_view('theme_preview/navigation/filter'));
+
+echo elgg_view_module('info', "Extras Menu (.elgg-menu-extras)", elgg_view('theme_preview/navigation/extras'));
+
+echo elgg_view_module('info', "Owner Block Menu (.elgg-menu-owner-block)", elgg_view('theme_preview/navigation/owner_block'));
?>
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
- <h2>Breadcrumbs</h2>
- <div class="mbl">
- <?php echo elgg_view('navigation/breadcrumbs'); ?>
- </div>
- <h2>Tabs</h2>
- <div class="mbl">
- <?php
- $tabs = array(
- array('title' => 'First', 'url' => "$url#"),
- array('title' => 'Second', 'url' => "$url#", 'selected' => true),
- array('title' => 'Third', 'url' => "$url#"),
- );
- echo elgg_view('navigation/tabs', array('tabs' => $tabs));
- ?>
- </div>
- <h2>Pagination</h2>
- <div class="mbl">
- <?php
- $params = array(
- 'count' => 1000,
- 'limit' => 10,
- 'offset' => 230,
- );
- echo elgg_view('navigation/pagination', $params);
- ?>
- </div>
- <h2>Site Menu</h2>
- <div class="mbl">
- <div class="elgg-page-header" style="height: 40px;">
- <?php
- $params = array();
- $params['menu'] = array();
- $params['menu']['default'] = array();
- for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
- }
- $params['menu']['default'][2]->setSelected(true);
- echo elgg_view('navigation/menu/site', $params);
- ?>
- </div>
- </div>
- <h2>Page Menu</h2>
- <div class="mbl pam" style="width: 200px; background-color: #ccc;">
- <?php
- $m = new ElggMenuItem(10, "Child", "$url#");
- $m->setParent($params['menu']['default'][1]);
- $params['menu']['default'][1]->addChild($m);
- echo elgg_view('navigation/menu/page', $params);
- ?>
- </div>
-</div>
diff --git a/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php b/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php
new file mode 100644
index 000000000..eb3dd47a3
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php
@@ -0,0 +1,6 @@
+<?php
+elgg_push_breadcrumb('First', "#");
+elgg_push_breadcrumb('Second', "#");
+elgg_push_breadcrumb('Third');
+
+echo elgg_view('navigation/breadcrumbs');
diff --git a/mod/developers/views/default/theme_preview/navigation/default.php b/mod/developers/views/default/theme_preview/navigation/default.php
new file mode 100644
index 000000000..fd67b8094
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/default.php
@@ -0,0 +1,11 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/extras.php b/mod/developers/views/default/theme_preview/navigation/extras.php
new file mode 100644
index 000000000..6982cf57d
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/extras.php
@@ -0,0 +1,18 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['class'] = 'elgg-menu-extras';
+
+
+?>
+
+<div class="elgg-sidebar">
+<?php
+ echo elgg_view('navigation/menu/default', $params);
+?>
+</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/filter.php b/mod/developers/views/default/theme_preview/navigation/filter.php
new file mode 100644
index 000000000..f27edf150
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/filter.php
@@ -0,0 +1,13 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+$params['name'] = 'filter';
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/horizontal.php b/mod/developers/views/default/theme_preview/navigation/horizontal.php
new file mode 100644
index 000000000..69e75c063
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/horizontal.php
@@ -0,0 +1,12 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['menu']['default'][2]->setSelected(true);
+$params['class'] = 'elgg-menu-hz';
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/owner_block.php b/mod/developers/views/default/theme_preview/navigation/owner_block.php
new file mode 100644
index 000000000..6bf79fe7e
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/owner_block.php
@@ -0,0 +1,11 @@
+<?php
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['menu']['default'][2]->setSelected(true);
+$params['class'] = 'elgg-menu-owner-block';
+
+echo elgg_view('navigation/menu/default', $params); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/page.php b/mod/developers/views/default/theme_preview/navigation/page.php
new file mode 100644
index 000000000..fb3f075dc
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/page.php
@@ -0,0 +1,21 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+ $params['menu']['alt'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+$m = new ElggMenuItem(10, "Child", "$url#");
+$m->setParent($params['menu']['default'][1]);
+$params['menu']['default'][1]->addChild($m);
+?>
+
+<div class="elgg-sidebar">
+<?php
+ echo elgg_view('navigation/menu/page', $params);
+?>
+</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/pagination.php b/mod/developers/views/default/theme_preview/navigation/pagination.php
new file mode 100644
index 000000000..90ae48edf
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/pagination.php
@@ -0,0 +1,8 @@
+<?php
+$params = array(
+ 'count' => 1000,
+ 'limit' => 10,
+ 'offset' => 230,
+);
+
+echo elgg_view('navigation/pagination', $params); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/site.php b/mod/developers/views/default/theme_preview/navigation/site.php
new file mode 100644
index 000000000..df8dc1b70
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/site.php
@@ -0,0 +1,18 @@
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "$url#");
+}
+$params['menu']['default'][2]->setSelected(true);
+?>
+
+<div class="elgg-page-header">
+ <div class="elgg-inner">
+ <?php
+ echo elgg_view('navigation/menu/site', $params);
+ ?>
+ </div>
+</div>
diff --git a/mod/developers/views/default/theme_preview/navigation/tabs.php b/mod/developers/views/default/theme_preview/navigation/tabs.php
new file mode 100644
index 000000000..b2638bb37
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/navigation/tabs.php
@@ -0,0 +1,10 @@
+<?php
+$params = array(
+ 'tabs' => array(
+ array('title' => 'First', 'url' => "$url#"),
+ array('title' => 'Second', 'url' => "$url#", 'selected' => true),
+ array('title' => 'Third', 'url' => "$url#"),
+ )
+);
+
+echo elgg_view('navigation/tabs', $params); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/objects.php b/mod/developers/views/default/theme_preview/objects.php
deleted file mode 100644
index c67348c0d..000000000
--- a/mod/developers/views/default/theme_preview/objects.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-/**
- * CSS Objects: list, module, image_block
- */
-
-$url = current_page_url();
-
-$ipsum = elgg_view('developers/ipsum');
-
-?>
-
-<div class="elgg-page mal">
- <?php echo elgg_view('theme_preview/header', $vars); ?>
- <h2>Modules</h2>
- <div class="mbl clearfix">
- <div class="elgg-col elgg-col-1of2">
- <div class="pam">
- <?php
- echo elgg_view_module('aside', 'elgg-module-aside', $ipsum);
- echo elgg_view_module('popup', 'elgg-module-popup', $ipsum);
- ?>
- </div>
- </div>
- <div class="elgg-col elgg-col-1of2">
- <div class="pam">
- <?php
- echo elgg_view_module('info', 'elgg-module-info', $ipsum);
- echo elgg_view_module('featured', 'elgg-module-featured', $ipsum);
- ?>
- </div>
- </div>
- </div>
- <h2>Image Block</h2>
- <div class="mbl clearfix">
- <?php
- $user = new ElggUser();
- $image = elgg_view_entity_icon($user, 'small');
- echo elgg_view_image_block($image, $ipsum);
- ?>
- </div>
- <h2>List</h2>
- <div class="mbl clearfix">
- <?php
- $obj1 = new ElggObject();
- $obj1->title = "Object 1";
- $obj1->description = $ipsum;
- $obj2 = new ElggObject();
- $obj2->title = "Object 2";
- $obj2->description = $ipsum;
- echo elgg_view('page/components/list', array('items' => array($obj1, $obj2)));
- ?>
- </div>
- <h2>Table</h2>
- <div class="mbl clearfix">
- <table class="elgg-table">
- <?php
- echo "<thead><tr><th>column 1</th><th>column 2</th></tr></thead>";
- for ($i = 1; $i < 5; $i++) {
- echo '<tr>';
- for ($j = 1; $j < 3; $j++) {
- echo "<td>value $j</td>";
- }
- echo '</tr>';
- }
- ?>
- </table>
- </div>
- <h2>Messages</h2>
- <div class="mbl clearfix">
- <ul>
- <li class="elgg-message elgg-state-success mas">Success message</li>
- <li class="elgg-message elgg-state-error mas">Error message</li>
- <li class="elgg-message elgg-state-notice mas">Notice message</li>
- </ul>
- </div>
-</div>
diff --git a/mod/developers/views/default/theme_preview/typography.php b/mod/developers/views/default/theme_preview/typography.php
new file mode 100644
index 000000000..6662a9a46
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/typography.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * General CSS
+ */
+
+echo elgg_view_module('info', "Headings", elgg_view('theme_preview/typography/headings'));
+
+echo elgg_view_module('info', "Paragraph", elgg_view('theme_preview/typography/paragraph'));
+
+echo elgg_view_module('info', "Misc", elgg_view('theme_preview/typography/misc')); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/typography/headings.php b/mod/developers/views/default/theme_preview/typography/headings.php
new file mode 100644
index 000000000..1eb96c75c
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/typography/headings.php
@@ -0,0 +1,6 @@
+<h1>Level 1 heading</h1>
+<h2>Level 2 heading</h2>
+<h3>Level 3 heading</h3>
+<h4>Level 4 heading</h4>
+<h5>Level 5 heading</h5>
+<h6>Level 6 heading</h6> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/typography/misc.php b/mod/developers/views/default/theme_preview/typography/misc.php
new file mode 100644
index 000000000..93a279c36
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/typography/misc.php
@@ -0,0 +1,16 @@
+<ul>
+ <li>I am <a href="?abc123">the a tag</a> example</li>
+ <li>I am <abbr title="test">the abbr tag</abbr> example</li>
+ <li>I am <acronym>the acronym tag</acronym> example</li>
+ <li>I am <b>the b tag</b> example</li>
+ <li>I am <code>the code tag</code> example</li>
+ <li>I am <del>the del tag</del> example</li>
+ <li>I am <em>the em tag</em> example</li>
+ <li>I am <i>the i tag</i> example</li>
+ <li>I am <strong>the strong tag</strong> example</li>
+</ul>
+<blockquote><p>Paragraph inside Blockquote: <?php echo $ipsum; ?></p></blockquote>
+<pre>
+ <strong>Preformated:</strong>Testing one row
+ and another
+</pre>
diff --git a/mod/developers/views/default/theme_preview/typography/paragraph.php b/mod/developers/views/default/theme_preview/typography/paragraph.php
new file mode 100644
index 000000000..54d548f46
--- /dev/null
+++ b/mod/developers/views/default/theme_preview/typography/paragraph.php
@@ -0,0 +1,19 @@
+<p>Lorem ipsum dolor sit amet, <a href="#" title="test link">test link</a>
+adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
+faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
+nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
+mattis, massa quis luctus <strong>strong</strong>, turpis mi volutpat justo, eu
+volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
+eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
+consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
+quis tellus.</p>
+
+<p>Lorem ipsum dolor sit amet, <em>emphasis</em> consectetuer
+adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
+faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
+nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
+mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu
+volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
+eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
+consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
+quis tellus.</p> \ No newline at end of file
diff --git a/mod/messages/readme.txt b/mod/messages/readme.txt
deleted file mode 100644
index 9d267f3fb..000000000
--- a/mod/messages/readme.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Elgg messages readme
- *
- * @package ElggMessages
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
- * @author Dave Tosh <dave@elgg.org>
- * @link http://elgg.org/
- */
-
-Install: drop the plugin into your mod folder, that is it.
-
-Notes:
-
-Each message has a series of metadata which is used to control how the message displays.
-
-The metadata toggles are:
-
-hiddenFrom - used to 'delete' from the sentbox
-hiddenTo - used to 'delete' from the inbox
-readYet - 0 means no, 1 means yes it has been read
-
-This is actually a tricky little plugin as there is only ever one instance of a message, how it is viewed
-depends on who is looked at and in what context. \ No newline at end of file
diff --git a/vendors/markdown/License.text b/vendors/markdown/License.text
new file mode 100755
index 000000000..4d6bf8b63
--- /dev/null
+++ b/vendors/markdown/License.text
@@ -0,0 +1,36 @@
+PHP Markdown & Extra
+Copyright (c) 2004-2009 Michel Fortin
+<http://michelf.com/>
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
diff --git a/vendors/markdown/PHP Markdown Extra Readme.text b/vendors/markdown/PHP Markdown Extra Readme.text
new file mode 100755
index 000000000..b72ee998e
--- /dev/null
+++ b/vendors/markdown/PHP Markdown Extra Readme.text
@@ -0,0 +1,786 @@
+PHP Markdown Extra
+==================
+
+Version 1.2.4 - Sat 10 Oct 2009
+
+by Michel Fortin
+<http://michelf.com/>
+
+based on Markdown by John Gruber
+<http://daringfireball.net/>
+
+
+Introduction
+------------
+
+This is a special version of PHP Markdown with extra features. See
+<http://michelf.com/projects/php-markdown/extra/> for details.
+
+Markdown is a text-to-HTML conversion tool for web writers. Markdown
+allows you to write using an easy-to-read, easy-to-write plain text
+format, then convert it to structurally valid XHTML (or HTML).
+
+"Markdown" is two things: a plain text markup syntax, and a software
+tool, written in Perl, that converts the plain text markup to HTML.
+PHP Markdown is a port to PHP of the original Markdown program by
+John Gruber.
+
+PHP Markdown can work as a plug-in for WordPress and bBlog, as a
+modifier for the Smarty templating engine, or as a remplacement for
+textile formatting in any software that support textile.
+
+Full documentation of Markdown's syntax is available on John's
+Markdown page: <http://daringfireball.net/projects/markdown/>
+
+
+Installation and Requirement
+----------------------------
+
+PHP Markdown requires PHP version 4.0.5 or later.
+
+
+### WordPress ###
+
+PHP Markdown works with [WordPress][wp], version 1.2 or later.
+
+ [wp]: http://wordpress.org/
+
+1. To use PHP Markdown with WordPress, place the "makrdown.php" file
+ in the "plugins" folder. This folder is located inside
+ "wp-content" at the root of your site:
+
+ (site home)/wp-content/plugins/
+
+2. Activate the plugin with the administrative interface of
+ WordPress. In the "Plugins" section you will now find Markdown.
+ To activate the plugin, click on the "Activate" button on the
+ same line than Markdown. Your entries will now be formatted by
+ PHP Markdown.
+
+3. To post Markdown content, you'll first have to disable the
+ "visual" editor in the User section of WordPress.
+
+You can configure PHP Markdown to not apply to the comments on your
+WordPress weblog. See the "Configuration" section below.
+
+It is not possible at this time to apply a different set of
+filters to different entries. All your entries will be formated by
+PHP Markdown. This is a limitation of WordPress. If your old entries
+are written in HTML (as opposed to another formatting syntax, like
+Textile), they'll probably stay fine after installing Markdown.
+
+
+### bBlog ###
+
+PHP Markdown also works with [bBlog][bb].
+
+ [bb]: http://www.bblog.com/
+
+To use PHP Markdown with bBlog, rename "markdown.php" to
+"modifier.markdown.php" and place the file in the "bBlog_plugins"
+folder. This folder is located inside the "bblog" directory of
+your site, like this:
+
+ (site home)/bblog/bBlog_plugins/modifier.markdown.php
+
+Select "Markdown" as the "Entry Modifier" when you post a new
+entry. This setting will only apply to the entry you are editing.
+
+
+### Replacing Textile in TextPattern ###
+
+[TextPattern][tp] use [Textile][tx] to format your text. You can
+replace Textile by Markdown in TextPattern without having to change
+any code by using the *Texitle Compatibility Mode*. This may work
+with other software that expect Textile too.
+
+ [tx]: http://www.textism.com/tools/textile/
+ [tp]: http://www.textpattern.com/
+
+1. Rename the "markdown.php" file to "classTextile.php". This will
+ make PHP Markdown behave as if it was the actual Textile parser.
+
+2. Replace the "classTextile.php" file TextPattern installed in your
+ web directory. It can be found in the "lib" directory:
+
+ (site home)/textpattern/lib/
+
+Contrary to Textile, Markdown does not convert quotes to curly ones
+and does not convert multiple hyphens (`--` and `---`) into en- and
+em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
+can solve this problem by installing the "smartypants.php" file from
+[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
+Compatibility Mode function will use SmartyPants automatically without
+further modification.
+
+ [psp]: http://michelf.com/projects/php-smartypants/
+
+
+### In Your Own Programs ###
+
+You can use PHP Markdown easily in your current PHP program. Simply
+include the file and then call the Markdown function on the text you
+want to convert:
+
+ include_once "markdown.php";
+ $my_html = Markdown($my_text);
+
+If you wish to use PHP Markdown with another text filter function
+built to parse HTML, you should filter the text *after* the Markdown
+function call. This is an example with [PHP SmartyPants][psp]:
+
+ $my_html = SmartyPants(Markdown($my_text));
+
+
+### With Smarty ###
+
+If your program use the [Smarty][sm] template engine, PHP Markdown
+can now be used as a modifier for your templates. Rename "markdown.php"
+to "modifier.markdown.php" and put it in your smarty plugins folder.
+
+ [sm]: http://smarty.php.net/
+
+If you are using MovableType 3.1 or later, the Smarty plugin folder is
+located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
+Markdown to work on dynamic pages.
+
+
+### Updating Markdown in Other Programs ###
+
+Many web applications now ship with PHP Markdown, or have plugins to
+perform the conversion to HTML. You can update PHP Markdown -- or
+replace it with PHP Markdown Extra -- in many of these programs by
+swapping the old "markdown.php" file for the new one.
+
+Here is a short non-exhaustive list of some programs and where they
+hide the "markdown.php" file.
+
+| Program | Path to Markdown
+| ------- | ----------------
+| [Pivot][] | `(site home)/pivot/includes/markdown/`
+
+If you're unsure if you can do this with your application, ask the
+developer, or wait for the developer to update his application or
+plugin with the new version of PHP Markdown.
+
+ [Pivot]: http://pivotlog.net/
+
+
+Configuration
+-------------
+
+By default, PHP Markdown produces XHTML output for tags with empty
+elements. E.g.:
+
+ <br />
+
+Markdown can be configured to produce HTML-style tags; e.g.:
+
+ <br>
+
+To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
+definition below the "Global default settings" header at the start of
+the "markdown.php" file.
+
+
+### WordPress-Specific Settings ###
+
+By default, the Markdown plugin applies to both posts and comments on
+your WordPress weblog. To deactivate one or the other, edit the
+`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
+"WordPress settings" header at the start of the "markdown.php" file.
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output PHP Markdown actually produced.
+
+
+Version History
+---------------
+
+1.0.1n (10 Oct 2009):
+
+* Enabled reference-style shortcut links. Now you can write reference-style
+ links with less brakets:
+
+ This is [my website].
+
+ [my website]: http://example.com/
+
+ This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
+ waiting for the feature to be officialized. [But half of the other Markdown
+ implementations are supporting this syntax][half], so it makes sense for
+ compatibility's sake to allow it in PHP Markdown too.
+
+ [half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
+
+* Now accepting many valid email addresses in autolinks that were
+ previously rejected, such as:
+
+ <abc+mailbox/department=shipping@example.com>
+ <!#$%&'*+-/=?^_`.{|}~@example.com>
+ <"abc@def"@example.com>
+ <"Fred Bloggs"@example.com>
+ <jsmith@[192.0.2.1]>
+
+* Now accepting spaces in URLs for inline and reference-style links. Such
+ URLs need to be surrounded by angle brakets. For instance:
+
+ [link text](<http://url/with space> "optional title")
+
+ [link text][ref]
+ [ref]: <http://url/with space> "optional title"
+
+ There is still a quirk which may prevent this from working correctly with
+ relative URLs in inline-style links however.
+
+* Fix for adjacent list of different kind where the second list could
+ end as a sublist of the first when not separated by an empty line.
+
+* Fixed a bug where inline-style links wouldn't be recognized when the link
+ definition contains a line break between the url and the title.
+
+* Fixed a bug where tags where the name contains an underscore aren't parsed
+ correctly.
+
+* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
+
+
+Extra 1.2.4:
+
+* Fixed a problem where unterminated tags in indented code blocks could
+ prevent proper escaping of characaters in the code block.
+
+
+Extra 1.2.3 (31 Dec 2008):
+
+* In WordPress pages featuring more than one post, footnote id prefixes are
+ now automatically applied with the current post ID to avoid clashes
+ between footnotes belonging to different posts.
+
+* Fix for a bug introduced in Extra 1.2 where block-level HTML tags where
+ not detected correctly, thus the addition of erroneous `<p>` tags and
+ interpretation of their content as Markdown-formatted instead of
+ HTML-formatted.
+
+
+Extra 1.2.2 (21 Jun 2008):
+
+* Fixed a problem where abbreviation definitions, footnote
+ definitions and link references were stripped inside
+ fenced code blocks.
+
+* Fixed a bug where characters such as `"` in abbreviation
+ definitions weren't properly encoded to HTML entities.
+
+* Fixed a bug where double quotes `"` were not correctly encoded
+ as HTML entities when used inside a footnote reference id.
+
+
+1.0.1m (21 Jun 2008):
+
+* Lists can now have empty items.
+
+* Rewrote the emphasis and strong emphasis parser to fix some issues
+ with odly placed and overlong markers.
+
+
+Extra 1.2.1 (27 May 2008):
+
+* Fixed a problem where Markdown headers and horizontal rules were
+ transformed into their HTML equivalent inside fenced code blocks.
+
+
+Extra 1.2 (11 May 2008):
+
+* Added fenced code block syntax which don't require indentation
+ and can start and end with blank lines. A fenced code block
+ starts with a line of consecutive tilde (~) and ends on the
+ next line with the same number of consecutive tilde. Here's an
+ example:
+
+ ~~~~~~~~~~~~
+ Hello World!
+ ~~~~~~~~~~~~
+
+* Rewrote parts of the HTML block parser to better accomodate
+ fenced code blocks.
+
+* Footnotes may now be referenced from within another footnote.
+
+* Added programatically-settable parser property `predef_attr` for
+ predefined attribute definitions.
+
+* Fixed an issue where an indented code block preceded by a blank
+ line containing some other whitespace would confuse the HTML
+ block parser into creating an HTML block when it should have
+ been code.
+
+
+1.0.1l (11 May 2008):
+
+* Now removing the UTF-8 BOM at the start of a document, if present.
+
+* Now accepting capitalized URI schemes (such as HTTP:) in automatic
+ links, such as `<HTTP://EXAMPLE.COM/>`.
+
+* Fixed a problem where `<hr@example.com>` was seen as a horizontal
+ rule instead of an automatic link.
+
+* Fixed an issue where some characters in Markdown-generated HTML
+ attributes weren't properly escaped with entities.
+
+* Fix for code blocks as first element of a list item. Previously,
+ this didn't create any code block for item 2:
+
+ * Item 1 (regular paragraph)
+
+ * Item 2 (code block)
+
+* A code block starting on the second line of a document wasn't seen
+ as a code block. This has been fixed.
+
+* Added programatically-settable parser properties `predef_urls` and
+ `predef_titles` for predefined URLs and titles for reference-style
+ links. To use this, your PHP code must call the parser this way:
+
+ $parser = new Markdwon_Parser;
+ $parser->predef_urls = array('linkref' => 'http://example.com');
+ $html = $parser->transform($text);
+
+ You can then use the URL as a normal link reference:
+
+ [my link][linkref]
+ [my link][linkRef]
+
+ Reference names in the parser properties *must* be lowercase.
+ Reference names in the Markdown source may have any case.
+
+* Added `setup` and `teardown` methods which can be used by subclassers
+ as hook points to arrange the state of some parser variables before and
+ after parsing.
+
+
+Extra 1.1.7 (26 Sep 2007):
+
+1.0.1k (26 Sep 2007):
+
+* Fixed a problem introduced in 1.0.1i where three or more identical
+ uppercase letters, as well as a few other symbols, would trigger
+ a horizontal line.
+
+
+Extra 1.1.6 (4 Sep 2007):
+
+1.0.1j (4 Sep 2007):
+
+* Fixed a problem introduced in 1.0.1i where the closing `code` and
+ `pre` tags at the end of a code block were appearing in the wrong
+ order.
+
+* Overriding configuration settings by defining constants from an
+ external before markdown.php is included is now possible without
+ producing a PHP warning.
+
+
+Extra 1.1.5 (31 Aug 2007):
+
+1.0.1i (31 Aug 2007):
+
+* Fixed a problem where an escaped backslash before a code span
+ would prevent the code span from being created. This should now
+ work as expected:
+
+ Litteral backslash: \\`code span`
+
+* Overall speed improvements, especially with long documents.
+
+
+Extra 1.1.4 (3 Aug 2007):
+
+1.0.1h (3 Aug 2007):
+
+* Added two properties (`no_markup` and `no_entities`) to the parser
+ allowing HTML tags and entities to be disabled.
+
+* Fix for a problem introduced in 1.0.1g where posting comments in
+ WordPress would trigger PHP warnings and cause some markup to be
+ incorrectly filtered by the kses filter in WordPress.
+
+
+Extra 1.1.3 (3 Jul 2007):
+
+* Fixed a performance problem when parsing some invalid HTML as an HTML
+ block which was resulting in too much recusion and a segmentation fault
+ for long documents.
+
+* The markdown="" attribute now accepts unquoted values.
+
+* Fixed an issue where underscore-emphasis didn't work when applied on the
+ first or the last word of an element having the markdown="1" or
+ markdown="span" attribute set unless there was some surrounding whitespace.
+ This didn't work:
+
+ <p markdown="1">_Hello_ _world_</p>
+
+ Now it does produce emphasis as expected.
+
+* Fixed an issue preventing footnotes from working when the parser's
+ footnote id prefix variable (fn_id_prefix) is not empty.
+
+* Fixed a performance problem where the regular expression for strong
+ emphasis introduced in version 1.1 could sometime be long to process,
+ give slightly wrong results, and in some circumstances could remove
+ entirely the content for a whole paragraph.
+
+* Fixed an issue were abbreviations tags could be incorrectly added
+ inside URLs and title of links.
+
+* Placing footnote markers inside a link, resulting in two nested links, is
+ no longer allowed.
+
+
+1.0.1g (3 Jul 2007):
+
+* Fix for PHP 5 compiled without the mbstring module. Previous fix to
+ calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
+ not available was only working with PHP 4.
+
+* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
+ were not processed correctly by Markdown.
+
+* Now supports URLs containing literal parentheses for inline links
+ and images, such as:
+
+ [WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
+
+ Such parentheses may be arbitrarily nested, but must be
+ balanced. Unbalenced parentheses are allowed however when the URL
+ when escaped or when the URL is enclosed in angle brakets `<>`.
+
+* Fixed a performance problem where the regular expression for strong
+ emphasis introduced in version 1.0.1d could sometime be long to process,
+ give slightly wrong results, and in some circumstances could remove
+ entirely the content for a whole paragraph.
+
+* Some change in version 1.0.1d made possible the incorrect nesting of
+ anchors within each other. This is now fixed.
+
+* Fixed a rare issue where certain MD5 hashes in the content could
+ be changed to their corresponding text. For instance, this:
+
+ The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
+
+ was incorrectly changed to this in previous versions of PHP Markdown:
+
+ <p>The MD5 value for "+" is "+".</p>
+
+* Now convert escaped characters to their numeric character
+ references equivalent.
+
+ This fix an integration issue with SmartyPants and backslash escapes.
+ Since Markdown and SmartyPants have some escapable characters in common,
+ it was sometime necessary to escape them twice. Previously, two
+ backslashes were sometime required to prevent Markdown from "eating" the
+ backslash before SmartyPants sees it:
+
+ Here are two hyphens: \\--
+
+ Now, only one backslash will do:
+
+ Here are two hyphens: \--
+
+
+Extra 1.1.2 (7 Feb 2007)
+
+* Fixed an issue where headers preceded too closely by a paragraph
+ (with no blank line separating them) where put inside the paragraph.
+
+* Added the missing TextileRestricted method that was added to regular
+ PHP Markdown since 1.0.1d but which I forgot to add to Extra.
+
+
+1.0.1f (7 Feb 2007):
+
+* Fixed an issue with WordPress where manually-entered excerpts, but
+ not the auto-generated ones, would contain nested paragraphs.
+
+* Fixed an issue introduced in 1.0.1d where headers and blockquotes
+ preceded too closely by a paragraph (not separated by a blank line)
+ where incorrectly put inside the paragraph.
+
+* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
+ two consecutive code spans would be merged into one when together they
+ form a valid tag in a multiline paragraph.
+
+* Fixed an long-prevailing issue where blank lines in code blocks would
+ be doubled when the code block is in a list item.
+
+ This was due to the list processing functions relying on artificially
+ doubled blank lines to correctly determine when list items should
+ contain block-level content. The list item processing model was thus
+ changed to avoid the need for double blank lines.
+
+* Fixed an issue with `<% asp-style %>` instructions used as inline
+ content where the opening `<` was encoded as `&lt;`.
+
+* Fixed a parse error occuring when PHP is configured to accept
+ ASP-style delimiters as boundaries for PHP scripts.
+
+* Fixed a bug introduced in 1.0.1d where underscores in automatic links
+ got swapped with emphasis tags.
+
+
+Extra 1.1.1 (28 Dec 2006)
+
+* Fixed a problem where whitespace at the end of the line of an atx-style
+ header would cause tailing `#` to appear as part of the header's content.
+ This was caused by a small error in the regex that handles the definition
+ for the id attribute in PHP Markdown Extra.
+
+* Fixed a problem where empty abbreviations definitions would eat the
+ following line as its definition.
+
+* Fixed an issue with calling the Markdown parser repetitivly with text
+ containing footnotes. The footnote hashes were not reinitialized properly.
+
+
+1.0.1e (28 Dec 2006)
+
+* Added support for internationalized domain names for email addresses in
+ automatic link. Improved the speed at which email addresses are converted
+ to entities. Thanks to Milian Wolff for his optimisations.
+
+* Made deterministic the conversion to entities of email addresses in
+ automatic links. This means that a given email address will always be
+ encoded the same way.
+
+* PHP Markdown will now use its own function to calculate the length of an
+ UTF-8 string in `detab` when `mb_strlen` is not available instead of
+ giving a fatal error.
+
+
+Extra 1.1 (1 Dec 2006)
+
+* Added a syntax for footnotes.
+
+* Added an experimental syntax to define abbreviations.
+
+
+1.0.1d (1 Dec 2006)
+
+* Fixed a bug where inline images always had an empty title attribute. The
+ title attribute is now present only when explicitly defined.
+
+* Link references definitions can now have an empty title, previously if the
+ title was defined but left empty the link definition was ignored. This can
+ be useful if you want an empty title attribute in images to hide the
+ tooltip in Internet Explorer.
+
+* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
+ correctly mapped to one character instead of the number of bytes.
+
+* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
+ was not properly deactivated on comment text, resulting in hard line breaks
+ where Markdown do not prescribes them.
+
+* Added a `TextileRestrited` method to the textile compatibility mode. There
+ is no restriction however, as Markdown does not have a restricted mode at
+ this point. This should make PHP Markdown work again in the latest
+ versions of TextPattern.
+
+* Converted PHP Markdown to a object-oriented design.
+
+* Changed span and block gamut methods so that they loop over a
+ customizable list of methods. This makes subclassing the parser a more
+ interesting option for creating syntax extensions.
+
+* Also added a "document" gamut loop which can be used to hook document-level
+ methods (like for striping link definitions).
+
+* Changed all methods which were inserting HTML code so that they now return
+ a hashed representation of the code. New methods `hashSpan` and `hashBlock`
+ are used to hash respectivly span- and block-level generated content. This
+ has a couple of significant effects:
+
+ 1. It prevents invalid nesting of Markdown-generated elements which
+ could occur occuring with constructs like `*something [link*][1]`.
+ 2. It prevents problems occuring with deeply nested lists on which
+ paragraphs were ill-formed.
+ 3. It removes the need to call `hashHTMLBlocks` twice during the the
+ block gamut.
+
+ Hashes are turned back to HTML prior output.
+
+* Made the block-level HTML parser smarter using a specially-crafted regular
+ expression capable of handling nested tags.
+
+* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
+ be aware of code spans. All these lines should work correctly now:
+
+ <span attr='`ticks`'>bar</span>
+ <span attr='``double ticks``'>bar</span>
+ `<test a="` content of attribute `">`
+
+* Changed the parsing of HTML comments to match simply from `<!--` to `-->`
+ instead using of the more complicated SGML-style rule with paired `--`.
+ This is how most browsers parse comments and how XML defines them too.
+
+* `<address>` has been added to the list of block-level elements and is now
+ treated as an HTML block instead of being wrapped within paragraph tags.
+
+* Now only trim trailing newlines from code blocks, instead of trimming
+ all trailing whitespace characters.
+
+* Fixed bug where this:
+
+ [text](http://m.com "title" )
+
+ wasn't working as expected, because the parser wasn't allowing for spaces
+ before the closing paren.
+
+* Filthy hack to support markdown='1' in div tags.
+
+* _DoAutoLinks() now supports the 'dict://' URL scheme.
+
+* PHP- and ASP-style processor instructions are now protected as
+ raw HTML blocks.
+
+ <? ... ?>
+ <% ... %>
+
+* Fix for escaped backticks still triggering code spans:
+
+ There are two raw backticks here: \` and here: \`, not a code span
+
+
+Extra 1.0 - 5 September 2005
+
+* Added support for setting the id attributes for headers like this:
+
+ Header 1 {#header1}
+ ========
+
+ ## Header 2 ## {#header2}
+
+ This only work only for headers for now.
+
+* Tables will now work correctly as the first element of a definition
+ list. For example, this input:
+
+ Term
+
+ : Header | Header
+ ------- | -------
+ Cell | Cell
+
+ used to produce no definition list and a table where the first
+ header was named ": Header". This is now fixed.
+
+* Fix for a problem where a paragraph following a table was not
+ placed between `<p>` tags.
+
+
+Extra 1.0b4 - 1 August 2005
+
+* Fixed some issues where whitespace around HTML blocks were trigging
+ empty paragraph tags.
+
+* Fixed an HTML block parsing issue that would cause a block element
+ following a code span or block with unmatched opening bracket to be
+ placed inside a paragraph.
+
+* Removed some PHP notices that could appear when parsing definition
+ lists and tables with PHP notice reporting flag set.
+
+
+Extra 1.0b3 - 29 July 2005
+
+* Definition lists now require a blank line before each term. Solves
+ an ambiguity where the last line of lazy-indented definitions could
+ be mistaken by PHP Markdown as a new term in the list.
+
+* Definition lists now support multiple terms per definition.
+
+* Some special tags were replaced in the output by their md5 hash
+ key. Things such as this now work as expected:
+
+ ## Header <?php echo $number ?> ##
+
+
+Extra 1.0b2 - 26 July 2005
+
+* Definition lists can now take two or more definitions for one term.
+ This should have been the case before, but a bug prevented this
+ from working right.
+
+* Fixed a problem where single column table with a pipe only at the
+ end where not parsed as table. Here is such a table:
+
+ | header
+ | ------
+ | cell
+
+* Fixed problems with empty cells in the first column of a table with
+ no leading pipe, like this one:
+
+ header | header
+ ------ | ------
+ | cell
+
+* Code spans containing pipes did not within a table. This is now
+ fixed by parsing code spans before splitting rows into cells.
+
+* Added the pipe character to the backlash escape character lists.
+
+Extra 1.0b1 (25 Jun 2005)
+
+* First public release of PHP Markdown Extra.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2009 Michel Fortin
+<http://michelf.com/>
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2005 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
diff --git a/vendors/markdown/markdown.php b/vendors/markdown/markdown.php
new file mode 100755
index 000000000..ee3dddbf9
--- /dev/null
+++ b/vendors/markdown/markdown.php
@@ -0,0 +1,2932 @@
+<?php
+#
+# Markdown Extra - A text-to-HTML conversion tool for web writers
+#
+# PHP Markdown & Extra
+# Copyright (c) 2004-2009 Michel Fortin
+# <http://michelf.com/projects/php-markdown/>
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber
+# <http://daringfireball.net/projects/markdown/>
+#
+
+
+define( 'MARKDOWN_VERSION', "1.0.1n" ); # Sat 10 Oct 2009
+define( 'MARKDOWNEXTRA_VERSION', "1.2.4" ); # Sat 10 Oct 2009
+
+
+#
+# Global default settings:
+#
+
+# Change to ">" for HTML output
+@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />");
+
+# Define the width of a tab for code blocks.
+@define( 'MARKDOWN_TAB_WIDTH', 4 );
+
+# Optional title attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_TITLE', "" );
+@define( 'MARKDOWN_FN_BACKLINK_TITLE', "" );
+
+# Optional class attribute for footnote links and backlinks.
+@define( 'MARKDOWN_FN_LINK_CLASS', "" );
+@define( 'MARKDOWN_FN_BACKLINK_CLASS', "" );
+
+
+#
+# WordPress settings:
+#
+
+# Change to false to remove Markdown from posts and/or comments.
+@define( 'MARKDOWN_WP_POSTS', true );
+@define( 'MARKDOWN_WP_COMMENTS', true );
+
+
+
+### Standard Function Interface ###
+
+@define( 'MARKDOWN_PARSER_CLASS', 'MarkdownExtra_Parser' );
+
+function Markdown($text) {
+#
+# Initialize the parser and return the result of its transform method.
+#
+ # Setup static parser variable.
+ static $parser;
+ if (!isset($parser)) {
+ $parser_class = MARKDOWN_PARSER_CLASS;
+ $parser = new $parser_class;
+ }
+
+ # Transform text using parser.
+ return $parser->transform($text);
+}
+
+
+### WordPress Plugin Interface ###
+
+/*
+Plugin Name: Markdown Extra
+Plugin URI: http://michelf.com/projects/php-markdown/
+Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>
+Version: 1.2.4
+Author: Michel Fortin
+Author URI: http://michelf.com/
+*/
+
+if (isset($wp_version)) {
+ # More details about how it works here:
+ # <http://michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
+
+ # Post content and excerpts
+ # - Remove WordPress paragraph generator.
+ # - Run Markdown on excerpt, then remove all tags.
+ # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
+ if (MARKDOWN_WP_POSTS) {
+ remove_filter('the_content', 'wpautop');
+ remove_filter('the_content_rss', 'wpautop');
+ remove_filter('the_excerpt', 'wpautop');
+ add_filter('the_content', 'mdwp_MarkdownPost', 6);
+ add_filter('the_content_rss', 'mdwp_MarkdownPost', 6);
+ add_filter('get_the_excerpt', 'mdwp_MarkdownPost', 6);
+ add_filter('get_the_excerpt', 'trim', 7);
+ add_filter('the_excerpt', 'mdwp_add_p');
+ add_filter('the_excerpt_rss', 'mdwp_strip_p');
+
+ remove_filter('content_save_pre', 'balanceTags', 50);
+ remove_filter('excerpt_save_pre', 'balanceTags', 50);
+ add_filter('the_content', 'balanceTags', 50);
+ add_filter('get_the_excerpt', 'balanceTags', 9);
+ }
+
+ # Add a footnote id prefix to posts when inside a loop.
+ function mdwp_MarkdownPost($text) {
+ static $parser;
+ if (!$parser) {
+ $parser_class = MARKDOWN_PARSER_CLASS;
+ $parser = new $parser_class;
+ }
+ if (is_single() || is_page() || is_feed()) {
+ $parser->fn_id_prefix = "";
+ } else {
+ $parser->fn_id_prefix = get_the_ID() . ".";
+ }
+ return $parser->transform($text);
+ }
+
+ # Comments
+ # - Remove WordPress paragraph generator.
+ # - Remove WordPress auto-link generator.
+ # - Scramble important tags before passing them to the kses filter.
+ # - Run Markdown on excerpt then remove paragraph tags.
+ if (MARKDOWN_WP_COMMENTS) {
+ remove_filter('comment_text', 'wpautop', 30);
+ remove_filter('comment_text', 'make_clickable');
+ add_filter('pre_comment_content', 'Markdown', 6);
+ add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
+ add_filter('pre_comment_content', 'mdwp_show_tags', 12);
+ add_filter('get_comment_text', 'Markdown', 6);
+ add_filter('get_comment_excerpt', 'Markdown', 6);
+ add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
+
+ global $mdwp_hidden_tags, $mdwp_placeholders;
+ $mdwp_hidden_tags = explode(' ',
+ '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
+ $mdwp_placeholders = explode(' ', str_rot13(
+ 'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
+ 'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
+ }
+
+ function mdwp_add_p($text) {
+ if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
+ $text = '<p>'.$text.'</p>';
+ $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
+ }
+ return $text;
+ }
+
+ function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
+
+ function mdwp_hide_tags($text) {
+ global $mdwp_hidden_tags, $mdwp_placeholders;
+ return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
+ }
+ function mdwp_show_tags($text) {
+ global $mdwp_hidden_tags, $mdwp_placeholders;
+ return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
+ }
+}
+
+
+### bBlog Plugin Info ###
+
+function identify_modifier_markdown() {
+ return array(
+ 'name' => 'markdown',
+ 'type' => 'modifier',
+ 'nicename' => 'PHP Markdown Extra',
+ 'description' => 'A text-to-HTML conversion tool for web writers',
+ 'authors' => 'Michel Fortin and John Gruber',
+ 'licence' => 'GPL',
+ 'version' => MARKDOWNEXTRA_VERSION,
+ 'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>',
+ );
+}
+
+
+### Smarty Modifier Interface ###
+
+function smarty_modifier_markdown($text) {
+ return Markdown($text);
+}
+
+
+### Textile Compatibility Mode ###
+
+# Rename this file to "classTextile.php" and it can replace Textile everywhere.
+
+if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
+ # Try to include PHP SmartyPants. Should be in the same directory.
+ @include_once 'smartypants.php';
+ # Fake Textile class. It calls Markdown instead.
+ class Textile {
+ function TextileThis($text, $lite='', $encode='') {
+ if ($lite == '' && $encode == '') $text = Markdown($text);
+ if (function_exists('SmartyPants')) $text = SmartyPants($text);
+ return $text;
+ }
+ # Fake restricted version: restrictions are not supported for now.
+ function TextileRestricted($text, $lite='', $noimage='') {
+ return $this->TextileThis($text, $lite);
+ }
+ # Workaround to ensure compatibility with TextPattern 4.0.3.
+ function blockLite($text) { return $text; }
+ }
+}
+
+
+
+#
+# Markdown Parser Class
+#
+
+class Markdown_Parser {
+
+ # Regex to match balanced [brackets].
+ # Needed to insert a maximum bracked depth while converting to PHP.
+ var $nested_brackets_depth = 6;
+ var $nested_brackets_re;
+
+ var $nested_url_parenthesis_depth = 4;
+ var $nested_url_parenthesis_re;
+
+ # Table of hash values for escaped characters:
+ var $escape_chars = '\`*_{}[]()>#+-.!';
+ var $escape_chars_re;
+
+ # Change to ">" for HTML output.
+ var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
+ var $tab_width = MARKDOWN_TAB_WIDTH;
+
+ # Change to `true` to disallow markup or entities.
+ var $no_markup = false;
+ var $no_entities = false;
+
+ # Predefined urls and titles for reference links and images.
+ var $predef_urls = array();
+ var $predef_titles = array();
+
+
+ function Markdown_Parser() {
+ #
+ # Constructor function. Initialize appropriate member variables.
+ #
+ $this->_initDetab();
+ $this->prepareItalicsAndBold();
+
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
+ str_repeat('\])*', $this->nested_brackets_depth);
+
+ $this->nested_url_parenthesis_re =
+ str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
+ str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
+
+ $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
+
+ # Sort document, block, and span gamut in ascendent priority order.
+ asort($this->document_gamut);
+ asort($this->block_gamut);
+ asort($this->span_gamut);
+ }
+
+
+ # Internal hashes used during transformation.
+ var $urls = array();
+ var $titles = array();
+ var $html_hashes = array();
+
+ # Status flag to avoid invalid nesting.
+ var $in_anchor = false;
+
+
+ function setup() {
+ #
+ # Called before the transformation process starts to setup parser
+ # states.
+ #
+ # Clear global hashes.
+ $this->urls = $this->predef_urls;
+ $this->titles = $this->predef_titles;
+ $this->html_hashes = array();
+
+ $in_anchor = false;
+ }
+
+ function teardown() {
+ #
+ # Called after the transformation process to clear any variable
+ # which may be taking up memory unnecessarly.
+ #
+ $this->urls = array();
+ $this->titles = array();
+ $this->html_hashes = array();
+ }
+
+
+ function transform($text) {
+ #
+ # Main function. Performs some preprocessing on the input text
+ # and pass it through the document gamut.
+ #
+ $this->setup();
+
+ # Remove UTF-8 BOM and marker character in input, if present.
+ $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
+
+ # Standardize line endings:
+ # DOS to Unix and Mac to Unix
+ $text = preg_replace('{\r\n?}', "\n", $text);
+
+ # Make sure $text ends with a couple of newlines:
+ $text .= "\n\n";
+
+ # Convert all tabs to spaces.
+ $text = $this->detab($text);
+
+ # Turn block-level HTML blocks into hash entries
+ $text = $this->hashHTMLBlocks($text);
+
+ # Strip any lines consisting only of spaces and tabs.
+ # This makes subsequent regexen easier to write, because we can
+ # match consecutive blank lines with /\n+/ instead of something
+ # contorted like /[ ]*\n+/ .
+ $text = preg_replace('/^[ ]+$/m', '', $text);
+
+ # Run document gamut methods.
+ foreach ($this->document_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ $this->teardown();
+
+ return $text . "\n";
+ }
+
+ var $document_gamut = array(
+ # Strip link definitions, store in hashes.
+ "stripLinkDefinitions" => 20,
+
+ "runBasicBlockGamut" => 30,
+ );
+
+
+ function stripLinkDefinitions($text) {
+ #
+ # Strips link definitions from text, stores the URLs and titles in
+ # hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: ^[id]: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+ [ ]*
+ \n? # maybe *one* newline
+ [ ]*
+ (?:
+ <(.+?)> # url = $2
+ |
+ (\S+?) # url = $3
+ )
+ [ ]*
+ \n? # maybe one newline
+ [ ]*
+ (?:
+ (?<=\s) # lookbehind for whitespace
+ ["(]
+ (.*?) # title = $4
+ [")]
+ [ ]*
+ )? # title is optional
+ (?:\n+|\Z)
+ }xm',
+ array(&$this, '_stripLinkDefinitions_callback'),
+ $text);
+ return $text;
+ }
+ function _stripLinkDefinitions_callback($matches) {
+ $link_id = strtolower($matches[1]);
+ $url = $matches[2] == '' ? $matches[3] : $matches[2];
+ $this->urls[$link_id] = $url;
+ $this->titles[$link_id] =& $matches[4];
+ return ''; # String that will replace the block
+ }
+
+
+ function hashHTMLBlocks($text) {
+ if ($this->no_markup) return $text;
+
+ $less_than_tab = $this->tab_width - 1;
+
+ # Hashify HTML blocks:
+ # We only want to do this for block-level HTML tags, such as headers,
+ # lists, and tables. That's because we still want to wrap <p>s around
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+ # phrase emphasis, and spans. The list of tags we're looking for is
+ # hard-coded:
+ #
+ # * List "a" is made of tags which can be both inline or block-level.
+ # These will be treated block-level when the start tag is alone on
+ # its line, otherwise they're not matched here and will be taken as
+ # inline later.
+ # * List "b" is made of tags which are always block-level;
+ #
+ $block_tags_a_re = 'ins|del';
+ $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
+ 'script|noscript|form|fieldset|iframe|math';
+
+ # Regular expression for the content of a block tag.
+ $nested_tags_level = 4;
+ $attr = '
+ (?> # optional tag attributes
+ \s # starts with whitespace
+ (?>
+ [^>"/]+ # text outside quotes
+ |
+ /+(?!>) # slash not followed by ">"
+ |
+ "[^"]*" # text inside double quotes (tolerate ">")
+ |
+ \'[^\']*\' # text inside single quotes (tolerate ">")
+ )*
+ )?
+ ';
+ $content =
+ str_repeat('
+ (?>
+ [^<]+ # content without tag
+ |
+ <\2 # nested opening tag
+ '.$attr.' # attributes
+ (?>
+ />
+ |
+ >', $nested_tags_level). # end of opening tag
+ '.*?'. # last level nested tag content
+ str_repeat('
+ </\2\s*> # closing nested tag
+ )
+ |
+ <(?!/\2\s*> # other tags with a different name
+ )
+ )*',
+ $nested_tags_level);
+ $content2 = str_replace('\2', '\3', $content);
+
+ # First, look for nested blocks, e.g.:
+ # <div>
+ # <div>
+ # tags for inner block must be indented.
+ # </div>
+ # </div>
+ #
+ # The outermost tags must start at the left margin for this to match, and
+ # the inner nested divs must be indented.
+ # We need to do this before the next, more liberal match, because the next
+ # match will start at the first `<div>` and stop at the first `</div>`.
+ $text = preg_replace_callback('{(?>
+ (?>
+ (?<=\n\n) # Starting after a blank line
+ | # or
+ \A\n? # the beginning of the doc
+ )
+ ( # save in $1
+
+ # Match from `\n<tag>` to `</tag>\n`, handling nested tags
+ # in between.
+
+ [ ]{0,'.$less_than_tab.'}
+ <('.$block_tags_b_re.')# start tag = $2
+ '.$attr.'> # attributes followed by > and \n
+ '.$content.' # content, support nesting
+ </\2> # the matching end tag
+ [ ]* # trailing spaces/tabs
+ (?=\n+|\Z) # followed by a newline or end of document
+
+ | # Special version for tags of group a.
+
+ [ ]{0,'.$less_than_tab.'}
+ <('.$block_tags_a_re.')# start tag = $3
+ '.$attr.'>[ ]*\n # attributes followed by >
+ '.$content2.' # content, support nesting
+ </\3> # the matching end tag
+ [ ]* # trailing spaces/tabs
+ (?=\n+|\Z) # followed by a newline or end of document
+
+ | # Special case just for <hr />. It was easier to make a special
+ # case than to make the other regex more complicated.
+
+ [ ]{0,'.$less_than_tab.'}
+ <(hr) # start tag = $2
+ '.$attr.' # attributes
+ /?> # the matching end tag
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ | # Special case for standalone HTML comments:
+
+ [ ]{0,'.$less_than_tab.'}
+ (?s:
+ <!-- .*? -->
+ )
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ | # PHP and ASP-style processor instructions (<? and <%)
+
+ [ ]{0,'.$less_than_tab.'}
+ (?s:
+ <([?%]) # $2
+ .*?
+ \2>
+ )
+ [ ]*
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
+
+ )
+ )}Sxmi',
+ array(&$this, '_hashHTMLBlocks_callback'),
+ $text);
+
+ return $text;
+ }
+ function _hashHTMLBlocks_callback($matches) {
+ $text = $matches[1];
+ $key = $this->hashBlock($text);
+ return "\n\n$key\n\n";
+ }
+
+
+ function hashPart($text, $boundary = 'X') {
+ #
+ # Called whenever a tag must be hashed when a function insert an atomic
+ # element in the text stream. Passing $text to through this function gives
+ # a unique text-token which will be reverted back when calling unhash.
+ #
+ # The $boundary argument specify what character should be used to surround
+ # the token. By convension, "B" is used for block elements that needs not
+ # to be wrapped into paragraph tags at the end, ":" is used for elements
+ # that are word separators and "X" is used in the general case.
+ #
+ # Swap back any tag hash found in $text so we do not have to `unhash`
+ # multiple times at the end.
+ $text = $this->unhash($text);
+
+ # Then hash the block.
+ static $i = 0;
+ $key = "$boundary\x1A" . ++$i . $boundary;
+ $this->html_hashes[$key] = $text;
+ return $key; # String that will replace the tag.
+ }
+
+
+ function hashBlock($text) {
+ #
+ # Shortcut function for hashPart with block-level boundaries.
+ #
+ return $this->hashPart($text, 'B');
+ }
+
+
+ var $block_gamut = array(
+ #
+ # These are all the transformations that form block-level
+ # tags like paragraphs, headers, and list items.
+ #
+ "doHeaders" => 10,
+ "doHorizontalRules" => 20,
+
+ "doLists" => 40,
+ "doCodeBlocks" => 50,
+ "doBlockQuotes" => 60,
+ );
+
+ function runBlockGamut($text) {
+ #
+ # Run block gamut tranformations.
+ #
+ # We need to escape raw HTML in Markdown source before doing anything
+ # else. This need to be done for each block, and not only at the
+ # begining in the Markdown function since hashed blocks can be part of
+ # list items and could have been indented. Indented blocks would have
+ # been seen as a code block in a previous pass of hashHTMLBlocks.
+ $text = $this->hashHTMLBlocks($text);
+
+ return $this->runBasicBlockGamut($text);
+ }
+
+ function runBasicBlockGamut($text) {
+ #
+ # Run block gamut tranformations, without hashing HTML blocks. This is
+ # useful when HTML blocks are known to be already hashed, like in the first
+ # whole-document pass.
+ #
+ foreach ($this->block_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ # Finally form paragraph and restore hashed blocks.
+ $text = $this->formParagraphs($text);
+
+ return $text;
+ }
+
+
+ function doHorizontalRules($text) {
+ # Do Horizontal Rules:
+ return preg_replace(
+ '{
+ ^[ ]{0,3} # Leading space
+ ([-*_]) # $1: First marker
+ (?> # Repeated marker group
+ [ ]{0,2} # Zero, one, or two spaces.
+ \1 # Marker character
+ ){2,} # Group repeated at least twice
+ [ ]* # Tailing spaces
+ $ # End of line.
+ }mx',
+ "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
+ $text);
+ }
+
+
+ var $span_gamut = array(
+ #
+ # These are all the transformations that occur *within* block-level
+ # tags like paragraphs, headers, and list items.
+ #
+ # Process character escapes, code spans, and inline HTML
+ # in one shot.
+ "parseSpan" => -30,
+
+ # Process anchor and image tags. Images must come first,
+ # because ![foo][f] looks like an anchor.
+ "doImages" => 10,
+ "doAnchors" => 20,
+
+ # Make links out of things like `<http://example.com/>`
+ # Must come after doAnchors, because you can use < and >
+ # delimiters in inline links like [this](<url>).
+ "doAutoLinks" => 30,
+ "encodeAmpsAndAngles" => 40,
+
+ "doItalicsAndBold" => 50,
+ "doHardBreaks" => 60,
+ );
+
+ function runSpanGamut($text) {
+ #
+ # Run span gamut tranformations.
+ #
+ foreach ($this->span_gamut as $method => $priority) {
+ $text = $this->$method($text);
+ }
+
+ return $text;
+ }
+
+
+ function doHardBreaks($text) {
+ # Do hard breaks:
+ return preg_replace_callback('/ {2,}\n/',
+ array(&$this, '_doHardBreaks_callback'), $text);
+ }
+ function _doHardBreaks_callback($matches) {
+ return $this->hashPart("<br$this->empty_element_suffix\n");
+ }
+
+
+ function doAnchors($text) {
+ #
+ # Turn Markdown link shortcuts into XHTML <a> tags.
+ #
+ if ($this->in_anchor) return $text;
+ $this->in_anchor = true;
+
+ #
+ # First, handle reference-style links: [link text] [id]
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ \[
+ ('.$this->nested_brackets_re.') # link text = $2
+ \]
+
+ [ ]? # one optional space
+ (?:\n[ ]*)? # one optional newline followed by spaces
+
+ \[
+ (.*?) # id = $3
+ \]
+ )
+ }xs',
+ array(&$this, '_doAnchors_reference_callback'), $text);
+
+ #
+ # Next, inline-style links: [link text](url "optional title")
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ \[
+ ('.$this->nested_brackets_re.') # link text = $2
+ \]
+ \( # literal paren
+ [ \n]*
+ (?:
+ <(.+?)> # href = $3
+ |
+ ('.$this->nested_url_parenthesis_re.') # href = $4
+ )
+ [ \n]*
+ ( # $5
+ ([\'"]) # quote char = $6
+ (.*?) # Title = $7
+ \6 # matching quote
+ [ \n]* # ignore any spaces/tabs between closing quote and )
+ )? # title is optional
+ \)
+ )
+ }xs',
+ array(&$this, '_doAnchors_inline_callback'), $text);
+
+ #
+ # Last, handle reference-style shortcuts: [link text]
+ # These must come last in case you've also got [link text][1]
+ # or [link text](/foo)
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ \[
+ ([^\[\]]+) # link text = $2; can\'t contain [ or ]
+ \]
+ )
+ }xs',
+ array(&$this, '_doAnchors_reference_callback'), $text);
+
+ $this->in_anchor = false;
+ return $text;
+ }
+ function _doAnchors_reference_callback($matches) {
+ $whole_match = $matches[1];
+ $link_text = $matches[2];
+ $link_id =& $matches[3];
+
+ if ($link_id == "") {
+ # for shortcut links like [this][] or [this].
+ $link_id = $link_text;
+ }
+
+ # lower-case and turn embedded newlines into spaces
+ $link_id = strtolower($link_id);
+ $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+ if (isset($this->urls[$link_id])) {
+ $url = $this->urls[$link_id];
+ $url = $this->encodeAttribute($url);
+
+ $result = "<a href=\"$url\"";
+ if ( isset( $this->titles[$link_id] ) ) {
+ $title = $this->titles[$link_id];
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+
+ $link_text = $this->runSpanGamut($link_text);
+ $result .= ">$link_text</a>";
+ $result = $this->hashPart($result);
+ }
+ else {
+ $result = $whole_match;
+ }
+ return $result;
+ }
+ function _doAnchors_inline_callback($matches) {
+ $whole_match = $matches[1];
+ $link_text = $this->runSpanGamut($matches[2]);
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
+ $title =& $matches[7];
+
+ $url = $this->encodeAttribute($url);
+
+ $result = "<a href=\"$url\"";
+ if (isset($title)) {
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+
+ $link_text = $this->runSpanGamut($link_text);
+ $result .= ">$link_text</a>";
+
+ return $this->hashPart($result);
+ }
+
+
+ function doImages($text) {
+ #
+ # Turn Markdown image shortcuts into <img> tags.
+ #
+ #
+ # First, handle reference-style labeled images: ![alt text][id]
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ !\[
+ ('.$this->nested_brackets_re.') # alt text = $2
+ \]
+
+ [ ]? # one optional space
+ (?:\n[ ]*)? # one optional newline followed by spaces
+
+ \[
+ (.*?) # id = $3
+ \]
+
+ )
+ }xs',
+ array(&$this, '_doImages_reference_callback'), $text);
+
+ #
+ # Next, handle inline images: ![alt text](url "optional title")
+ # Don't forget: encode * and _
+ #
+ $text = preg_replace_callback('{
+ ( # wrap whole match in $1
+ !\[
+ ('.$this->nested_brackets_re.') # alt text = $2
+ \]
+ \s? # One optional whitespace character
+ \( # literal paren
+ [ \n]*
+ (?:
+ <(\S*)> # src url = $3
+ |
+ ('.$this->nested_url_parenthesis_re.') # src url = $4
+ )
+ [ \n]*
+ ( # $5
+ ([\'"]) # quote char = $6
+ (.*?) # title = $7
+ \6 # matching quote
+ [ \n]*
+ )? # title is optional
+ \)
+ )
+ }xs',
+ array(&$this, '_doImages_inline_callback'), $text);
+
+ return $text;
+ }
+ function _doImages_reference_callback($matches) {
+ $whole_match = $matches[1];
+ $alt_text = $matches[2];
+ $link_id = strtolower($matches[3]);
+
+ if ($link_id == "") {
+ $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+ }
+
+ $alt_text = $this->encodeAttribute($alt_text);
+ if (isset($this->urls[$link_id])) {
+ $url = $this->encodeAttribute($this->urls[$link_id]);
+ $result = "<img src=\"$url\" alt=\"$alt_text\"";
+ if (isset($this->titles[$link_id])) {
+ $title = $this->titles[$link_id];
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\"";
+ }
+ $result .= $this->empty_element_suffix;
+ $result = $this->hashPart($result);
+ }
+ else {
+ # If there's no such link ID, leave intact:
+ $result = $whole_match;
+ }
+
+ return $result;
+ }
+ function _doImages_inline_callback($matches) {
+ $whole_match = $matches[1];
+ $alt_text = $matches[2];
+ $url = $matches[3] == '' ? $matches[4] : $matches[3];
+ $title =& $matches[7];
+
+ $alt_text = $this->encodeAttribute($alt_text);
+ $url = $this->encodeAttribute($url);
+ $result = "<img src=\"$url\" alt=\"$alt_text\"";
+ if (isset($title)) {
+ $title = $this->encodeAttribute($title);
+ $result .= " title=\"$title\""; # $title already quoted
+ }
+ $result .= $this->empty_element_suffix;
+
+ return $this->hashPart($result);
+ }
+
+
+ function doHeaders($text) {
+ # Setext-style headers:
+ # Header 1
+ # ========
+ #
+ # Header 2
+ # --------
+ #
+ $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+ array(&$this, '_doHeaders_callback_setext'), $text);
+
+ # atx-style headers:
+ # # Header 1
+ # ## Header 2
+ # ## Header 2 with closing hashes ##
+ # ...
+ # ###### Header 6
+ #
+ $text = preg_replace_callback('{
+ ^(\#{1,6}) # $1 = string of #\'s
+ [ ]*
+ (.+?) # $2 = Header text
+ [ ]*
+ \#* # optional closing #\'s (not counted)
+ \n+
+ }xm',
+ array(&$this, '_doHeaders_callback_atx'), $text);
+
+ return $text;
+ }
+ function _doHeaders_callback_setext($matches) {
+ # Terrible hack to check we haven't found an empty list item.
+ if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+ return $matches[0];
+
+ $level = $matches[2]{0} == '=' ? 1 : 2;
+ $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+ function _doHeaders_callback_atx($matches) {
+ $level = strlen($matches[1]);
+ $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+
+
+ function doLists($text) {
+ #
+ # Form HTML ordered (numbered) and unordered (bulleted) lists.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Re-usable patterns to match list item bullets and number markers:
+ $marker_ul_re = '[*+-]';
+ $marker_ol_re = '\d+[.]';
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+ $markers_relist = array(
+ $marker_ul_re => $marker_ol_re,
+ $marker_ol_re => $marker_ul_re,
+ );
+
+ foreach ($markers_relist as $marker_re => $other_marker_re) {
+ # Re-usable pattern to match any entirel ul or ol list:
+ $whole_list_re = '
+ ( # $1 = whole list
+ ( # $2
+ ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
+ ('.$marker_re.') # $4 = first list item marker
+ [ ]+
+ )
+ (?s:.+?)
+ ( # $5
+ \z
+ |
+ \n{2,}
+ (?=\S)
+ (?! # Negative lookahead for another list item marker
+ [ ]*
+ '.$marker_re.'[ ]+
+ )
+ |
+ (?= # Lookahead for another kind of list
+ \n
+ \3 # Must have the same indentation
+ '.$other_marker_re.'[ ]+
+ )
+ )
+ )
+ '; // mx
+
+ # We use a different prefix before nested lists than top-level lists.
+ # See extended comment in _ProcessListItems().
+
+ if ($this->list_level) {
+ $text = preg_replace_callback('{
+ ^
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doLists_callback'), $text);
+ }
+ else {
+ $text = preg_replace_callback('{
+ (?:(?<=\n)\n|\A\n?) # Must eat the newline
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doLists_callback'), $text);
+ }
+ }
+
+ return $text;
+ }
+ function _doLists_callback($matches) {
+ # Re-usable patterns to match list item bullets and number markers:
+ $marker_ul_re = '[*+-]';
+ $marker_ol_re = '\d+[.]';
+ $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+ $list = $matches[1];
+ $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
+
+ $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+
+ $list .= "\n";
+ $result = $this->processListItems($list, $marker_any_re);
+
+ $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+ return "\n". $result ."\n\n";
+ }
+
+ var $list_level = 0;
+
+ function processListItems($list_str, $marker_any_re) {
+ #
+ # Process the contents of a single ordered or unordered list, splitting it
+ # into individual list items.
+ #
+ # The $this->list_level global keeps track of when we're inside a list.
+ # Each time we enter a list, we increment it; when we leave a list,
+ # we decrement. If it's zero, we're not in a list anymore.
+ #
+ # We do this because when we're not inside a list, we want to treat
+ # something like this:
+ #
+ # I recommend upgrading to version
+ # 8. Oops, now this line is treated
+ # as a sub-list.
+ #
+ # As a single paragraph, despite the fact that the second line starts
+ # with a digit-period-space sequence.
+ #
+ # Whereas when we're inside a list (or sub-list), that line will be
+ # treated as the start of a sub-list. What a kludge, huh? This is
+ # an aspect of Markdown's syntax that's hard to parse perfectly
+ # without resorting to mind-reading. Perhaps the solution is to
+ # change the syntax rules such that sub-lists must start with a
+ # starting cardinal number; e.g. "1." or "a.".
+
+ $this->list_level++;
+
+ # trim trailing blank lines:
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+ $list_str = preg_replace_callback('{
+ (\n)? # leading line = $1
+ (^[ ]*) # leading whitespace = $2
+ ('.$marker_any_re.' # list marker and space = $3
+ (?:[ ]+|(?=\n)) # space only required if item is not empty
+ )
+ ((?s:.*?)) # list item text = $4
+ (?:(\n+(?=\n))|\n) # tailing blank line = $5
+ (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+ }xm',
+ array(&$this, '_processListItems_callback'), $list_str);
+
+ $this->list_level--;
+ return $list_str;
+ }
+ function _processListItems_callback($matches) {
+ $item = $matches[4];
+ $leading_line =& $matches[1];
+ $leading_space =& $matches[2];
+ $marker_space = $matches[3];
+ $tailing_blank_line =& $matches[5];
+
+ if ($leading_line || $tailing_blank_line ||
+ preg_match('/\n{2,}/', $item))
+ {
+ # Replace marker with the appropriate whitespace indentation
+ $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+ $item = $this->runBlockGamut($this->outdent($item)."\n");
+ }
+ else {
+ # Recursion for sub-lists:
+ $item = $this->doLists($this->outdent($item));
+ $item = preg_replace('/\n+$/', '', $item);
+ $item = $this->runSpanGamut($item);
+ }
+
+ return "<li>" . $item . "</li>\n";
+ }
+
+
+ function doCodeBlocks($text) {
+ #
+ # Process Markdown `<pre><code>` blocks.
+ #
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ array(&$this, '_doCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doCodeBlocks_callback($matches) {
+ $codeblock = $matches[1];
+
+ $codeblock = $this->outdent($codeblock);
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+ # trim leading newlines and trailing newlines
+ $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+ $codeblock = "<pre><code>$codeblock\n</code></pre>";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+
+
+ function makeCodeSpan($code) {
+ #
+ # Create a code span markup for $code. Called from handleSpanToken.
+ #
+ $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+ return $this->hashPart("<code>$code</code>");
+ }
+
+
+ var $em_relist = array(
+ '' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![.,:;]\s)',
+ '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
+ '_' => '(?<=\S|^)(?<!_)_(?!_)',
+ );
+ var $strong_relist = array(
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![.,:;]\s)',
+ '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
+ '__' => '(?<=\S|^)(?<!_)__(?!_)',
+ );
+ var $em_strong_relist = array(
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![.,:;]\s)',
+ '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
+ '___' => '(?<=\S|^)(?<!_)___(?!_)',
+ );
+ var $em_strong_prepared_relist;
+
+ function prepareItalicsAndBold() {
+ #
+ # Prepare regular expressions for searching emphasis tokens in any
+ # context.
+ #
+ foreach ($this->em_relist as $em => $em_re) {
+ foreach ($this->strong_relist as $strong => $strong_re) {
+ # Construct list of allowed token expressions.
+ $token_relist = array();
+ if (isset($this->em_strong_relist["$em$strong"])) {
+ $token_relist[] = $this->em_strong_relist["$em$strong"];
+ }
+ $token_relist[] = $em_re;
+ $token_relist[] = $strong_re;
+
+ # Construct master expression from list.
+ $token_re = '{('. implode('|', $token_relist) .')}';
+ $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+ }
+ }
+ }
+
+ function doItalicsAndBold($text) {
+ $token_stack = array('');
+ $text_stack = array('');
+ $em = '';
+ $strong = '';
+ $tree_char_em = false;
+
+ while (1) {
+ #
+ # Get prepared regular expression for seraching emphasis tokens
+ # in current context.
+ #
+ $token_re = $this->em_strong_prepared_relist["$em$strong"];
+
+ #
+ # Each loop iteration search for the next emphasis token.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $text_stack[0] .= $parts[0];
+ $token =& $parts[1];
+ $text =& $parts[2];
+
+ if (empty($token)) {
+ # Reached end of text span: empty stack without emitting.
+ # any more emphasis.
+ while ($token_stack[0]) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ break;
+ }
+
+ $token_len = strlen($token);
+ if ($tree_char_em) {
+ # Reached closing marker while inside a three-char emphasis.
+ if ($token_len == 3) {
+ # Three-char closing marker, close em and strong.
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<strong><em>$span</em></strong>";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ $strong = '';
+ } else {
+ # Other closing marker: close one em or strong and
+ # change current token state to match the other
+ $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+ $tag = $token_len == 2 ? "strong" : "em";
+ $span = $text_stack[0];
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span</$tag>";
+ $text_stack[0] = $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ $tree_char_em = false;
+ } else if ($token_len == 3) {
+ if ($em) {
+ # Reached closing marker for both em and strong.
+ # Closing strong marker:
+ for ($i = 0; $i < 2; ++$i) {
+ $shifted_token = array_shift($token_stack);
+ $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span</$tag>";
+ $text_stack[0] .= $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ } else {
+ # Reached opening three-char emphasis marker. Push on token
+ # stack; will be handled by the special condition above.
+ $em = $token{0};
+ $strong = "$em$em";
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $tree_char_em = true;
+ }
+ } else if ($token_len == 2) {
+ if ($strong) {
+ # Unwind any dangling emphasis marker:
+ if (strlen($token_stack[0]) == 1) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ # Closing strong marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<strong>$span</strong>";
+ $text_stack[0] .= $this->hashPart($span);
+ $strong = '';
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $strong = $token;
+ }
+ } else {
+ # Here $token_len == 1
+ if ($em) {
+ if (strlen($token_stack[0]) == 1) {
+ # Closing emphasis marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<em>$span</em>";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ } else {
+ $text_stack[0] .= $token;
+ }
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $em = $token;
+ }
+ }
+ }
+ return $text_stack[0];
+ }
+
+
+ function doBlockQuotes($text) {
+ $text = preg_replace_callback('/
+ ( # Wrap whole match in $1
+ (?>
+ ^[ ]*>[ ]? # ">" at the start of a line
+ .+\n # rest of the first line
+ (.+\n)* # subsequent consecutive lines
+ \n* # blanks
+ )+
+ )
+ /xm',
+ array(&$this, '_doBlockQuotes_callback'), $text);
+
+ return $text;
+ }
+ function _doBlockQuotes_callback($matches) {
+ $bq = $matches[1];
+ # trim one level of quoting - trim whitespace-only lines
+ $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+ $bq = $this->runBlockGamut($bq); # recurse
+
+ $bq = preg_replace('/^/m', " ", $bq);
+ # These leading spaces cause problem with <pre> content,
+ # so we need to fix that:
+ $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
+ array(&$this, '_doBlockQuotes_callback2'), $bq);
+
+ return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
+ }
+ function _doBlockQuotes_callback2($matches) {
+ $pre = $matches[1];
+ $pre = preg_replace('/^ /m', '', $pre);
+ return $pre;
+ }
+
+
+ function formParagraphs($text) {
+ #
+ # Params:
+ # $text - string to process with html <p> tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap <p> tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+ # Is a paragraph.
+ $value = $this->runSpanGamut($value);
+ $value = preg_replace('/^([ ]*)/', "<p>", $value);
+ $value .= "</p>";
+ $grafs[$key] = $this->unhash($value);
+ }
+ else {
+ # Is a block.
+ # Modify elements of @grafs in-place...
+ $graf = $value;
+ $block = $this->html_hashes[$graf];
+ $graf = $block;
+// if (preg_match('{
+// \A
+// ( # $1 = <div> tag
+// <div \s+
+// [^>]*
+// \b
+// markdown\s*=\s* ([\'"]) # $2 = attr quote char
+// 1
+// \2
+// [^>]*
+// >
+// )
+// ( # $3 = contents
+// .*
+// )
+// (</div>) # $4 = closing tag
+// \z
+// }xs', $block, $matches))
+// {
+// list(, $div_open, , $div_content, $div_close) = $matches;
+//
+// # We can't call Markdown(), because that resets the hash;
+// # that initialization code should be pulled into its own sub, though.
+// $div_content = $this->hashHTMLBlocks($div_content);
+//
+// # Run document gamut methods on the content.
+// foreach ($this->document_gamut as $method => $priority) {
+// $div_content = $this->$method($div_content);
+// }
+//
+// $div_open = preg_replace(
+// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+// $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+// }
+ $grafs[$key] = $graf;
+ }
+ }
+
+ return implode("\n\n", $grafs);
+ }
+
+
+ function encodeAttribute($text) {
+ #
+ # Encode text for a double-quoted HTML attribute. This function
+ # is *not* suitable for attributes enclosed in single quotes.
+ #
+ $text = $this->encodeAmpsAndAngles($text);
+ $text = str_replace('"', '&quot;', $text);
+ return $text;
+ }
+
+
+ function encodeAmpsAndAngles($text) {
+ #
+ # Smart processing for ampersands and angle brackets that need to
+ # be encoded. Valid character entities are left alone unless the
+ # no-entities mode is set.
+ #
+ if ($this->no_entities) {
+ $text = str_replace('&', '&amp;', $text);
+ } else {
+ # Ampersand-encoding based entirely on Nat Irons's Amputator
+ # MT plugin: <http://bumppo.net/projects/amputator/>
+ $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
+ '&amp;', $text);;
+ }
+ # Encode remaining <'s
+ $text = str_replace('<', '&lt;', $text);
+
+ return $text;
+ }
+
+
+ function doAutoLinks($text) {
+ $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
+ array(&$this, '_doAutoLinks_url_callback'), $text);
+
+ # Email addresses: <address@domain.foo>
+ $text = preg_replace_callback('{
+ <
+ (?:mailto:)?
+ (
+ (?:
+ [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
+ |
+ ".*?"
+ )
+ \@
+ (?:
+ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+ |
+ \[[\d.a-fA-F:]+\] # IPv4 & IPv6
+ )
+ )
+ >
+ }xi',
+ array(&$this, '_doAutoLinks_email_callback'), $text);
+
+ return $text;
+ }
+ function _doAutoLinks_url_callback($matches) {
+ $url = $this->encodeAttribute($matches[1]);
+ $link = "<a href=\"$url\">$url</a>";
+ return $this->hashPart($link);
+ }
+ function _doAutoLinks_email_callback($matches) {
+ $address = $matches[1];
+ $link = $this->encodeEmailAddress($address);
+ return $this->hashPart($link);
+ }
+
+
+ function encodeEmailAddress($addr) {
+ #
+ # Input: an email address, e.g. "foo@example.com"
+ #
+ # Output: the email address as a mailto link, with each character
+ # of the address encoded as either a decimal or hex entity, in
+ # the hopes of foiling most address harvesting spam bots. E.g.:
+ #
+ # <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+ # &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+ # &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
+ # &#101;&#46;&#x63;&#111;&#x6d;</a></p>
+ #
+ # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+ # With some optimizations by Milian Wolff.
+ #
+ $addr = "mailto:" . $addr;
+ $chars = preg_split('/(?<!^)(?!$)/', $addr);
+ $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
+
+ foreach ($chars as $key => $char) {
+ $ord = ord($char);
+ # Ignore non-ascii chars.
+ if ($ord < 128) {
+ $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+ # roughly 10% raw, 45% hex, 45% dec
+ # '@' *must* be encoded. I insist.
+ if ($r > 90 && $char != '@') /* do nothing */;
+ else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
+ else $chars[$key] = '&#'.$ord.';';
+ }
+ }
+
+ $addr = implode('', $chars);
+ $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+ $addr = "<a href=\"$addr\">$text</a>";
+
+ return $addr;
+ }
+
+
+ function parseSpan($str) {
+ #
+ # Take the string $str and parse it into tokens, hashing embeded HTML,
+ # escaped characters and handling code spans.
+ #
+ $output = '';
+
+ $span_re = '{
+ (
+ \\\\'.$this->escape_chars_re.'
+ |
+ (?<![`\\\\])
+ `+ # code span marker
+ '.( $this->no_markup ? '' : '
+ |
+ <!-- .*? --> # comment
+ |
+ <\?.*?\?> | <%.*?%> # processing instruction
+ |
+ <[/!$]?[-a-zA-Z0-9:_]+ # regular tags
+ (?>
+ \s
+ (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+ )?
+ >
+ ').'
+ )
+ }xs';
+
+ while (1) {
+ #
+ # Each loop iteration seach for either the next tag, the next
+ # openning code span marker, or the next escaped character.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ # Create token from text preceding tag.
+ if ($parts[0] != "") {
+ $output .= $parts[0];
+ }
+
+ # Check if we reach the end.
+ if (isset($parts[1])) {
+ $output .= $this->handleSpanToken($parts[1], $parts[2]);
+ $str = $parts[2];
+ }
+ else {
+ break;
+ }
+ }
+
+ return $output;
+ }
+
+
+ function handleSpanToken($token, &$str) {
+ #
+ # Handle $token provided by parseSpan by determining its nature and
+ # returning the corresponding value that should replace it.
+ #
+ switch ($token{0}) {
+ case "\\":
+ return $this->hashPart("&#". ord($token{1}). ";");
+ case "`":
+ # Search for end marker in remaining text.
+ if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
+ $str, $matches))
+ {
+ $str = $matches[2];
+ $codespan = $this->makeCodeSpan($matches[1]);
+ return $this->hashPart($codespan);
+ }
+ return $token; // return as text since no ending marker found.
+ default:
+ return $this->hashPart($token);
+ }
+ }
+
+
+ function outdent($text) {
+ #
+ # Remove one level of line-leading tabs or spaces
+ #
+ return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+ }
+
+
+ # String length function for detab. `_initDetab` will create a function to
+ # hanlde UTF-8 if the default function does not exist.
+ var $utf8_strlen = 'mb_strlen';
+
+ function detab($text) {
+ #
+ # Replace tabs with the appropriate amount of space.
+ #
+ # For each line we separate the line in blocks delemited by
+ # tab characters. Then we reconstruct every line by adding the
+ # appropriate number of space between each blocks.
+
+ $text = preg_replace_callback('/^.*\t.*$/m',
+ array(&$this, '_detab_callback'), $text);
+
+ return $text;
+ }
+ function _detab_callback($matches) {
+ $line = $matches[0];
+ $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+
+ # Split in blocks.
+ $blocks = explode("\t", $line);
+ # Add each blocks to the line.
+ $line = $blocks[0];
+ unset($blocks[0]); # Do not add first block twice.
+ foreach ($blocks as $block) {
+ # Calculate amount of space, insert spaces, insert block.
+ $amount = $this->tab_width -
+ $strlen($line, 'UTF-8') % $this->tab_width;
+ $line .= str_repeat(" ", $amount) . $block;
+ }
+ return $line;
+ }
+ function _initDetab() {
+ #
+ # Check for the availability of the function in the `utf8_strlen` property
+ # (initially `mb_strlen`). If the function is not available, create a
+ # function that will loosely count the number of UTF-8 characters with a
+ # regular expression.
+ #
+ if (function_exists($this->utf8_strlen)) return;
+ $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+ "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
+ $text, $m);');
+ }
+
+
+ function unhash($text) {
+ #
+ # Swap back in all the tags hashed by _HashHTMLBlocks.
+ #
+ return preg_replace_callback('/(.)\x1A[0-9]+\1/',
+ array(&$this, '_unhash_callback'), $text);
+ }
+ function _unhash_callback($matches) {
+ return $this->html_hashes[$matches[0]];
+ }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+ # Prefix for footnote ids.
+ var $fn_id_prefix = "";
+
+ # Optional title attribute for footnote links and backlinks.
+ var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+ var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+
+ # Optional class attribute for footnote links and backlinks.
+ var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+ var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+
+ # Predefined abbreviations.
+ var $predef_abbr = array();
+
+
+ function MarkdownExtra_Parser() {
+ #
+ # Constructor function. Initialize the parser object.
+ #
+ # Add extra escapable characters before parent constructor
+ # initialize the table.
+ $this->escape_chars .= ':|';
+
+ # Insert extra document, block, and span transformations.
+ # Parent constructor will do the sorting.
+ $this->document_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "stripFootnotes" => 15,
+ "stripAbbreviations" => 25,
+ "appendFootnotes" => 50,
+ );
+ $this->block_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "doTables" => 15,
+ "doDefLists" => 45,
+ );
+ $this->span_gamut += array(
+ "doFootnotes" => 5,
+ "doAbbreviations" => 70,
+ );
+
+ parent::Markdown_Parser();
+ }
+
+
+ # Extra variables used during extra transformations.
+ var $footnotes = array();
+ var $footnotes_ordered = array();
+ var $abbr_desciptions = array();
+ var $abbr_word_re = '';
+
+ # Give the current footnote number.
+ var $footnote_counter = 1;
+
+
+ function setup() {
+ #
+ # Setting up Extra-specific variables.
+ #
+ parent::setup();
+
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+ $this->footnote_counter = 1;
+
+ foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ }
+ }
+
+ function teardown() {
+ #
+ # Clearing Extra-specific variables.
+ #
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+
+ parent::teardown();
+ }
+
+
+ ### HTML Block Parser ###
+
+ # Tags that are always treated as block tags:
+ var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+
+ # Tags treated as block tags only if the opening tag is alone on it's line:
+ var $context_block_tags_re = 'script|noscript|math|ins|del';
+
+ # Tags where markdown="1" default to span mode:
+ var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+
+ # Tags which must not have their contents modified, no matter where
+ # they appear:
+ var $clean_tags_re = 'script|math';
+
+ # Tags that do not need to be closed.
+ var $auto_close_tags_re = 'hr|img';
+
+
+ function hashHTMLBlocks($text) {
+ #
+ # Hashify HTML Blocks and "clean tags".
+ #
+ # We only want to do this for block-level HTML tags, such as headers,
+ # lists, and tables. That's because we still want to wrap <p>s around
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+ # phrase emphasis, and spans. The list of tags we're looking for is
+ # hard-coded.
+ #
+ # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+ # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1"
+ # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+ # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+ # These two functions are calling each other. It's recursive!
+ #
+ #
+ # Call the HTML-in-Markdown hasher.
+ #
+ list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+
+ return $text;
+ }
+ function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
+ $enclosing_tag_re = '', $span = false)
+ {
+ #
+ # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+ #
+ # * $indent is the number of space to be ignored when checking for code
+ # blocks. This is important because if we don't take the indent into
+ # account, something like this (which looks right) won't work as expected:
+ #
+ # <div>
+ # <div markdown="1">
+ # Hello World. <-- Is this a Markdown code block or text?
+ # </div> <-- Is this a Markdown code block or a real tag?
+ # <div>
+ #
+ # If you don't like this, just don't indent the tag on which
+ # you apply the markdown="1" attribute.
+ #
+ # * If $enclosing_tag_re is not empty, stops at the first unmatched closing
+ # tag with that name. Nested tags supported.
+ #
+ # * If $span is true, text inside must treated as span. So any double
+ # newline will be replaced by a single newline so that it does not create
+ # paragraphs.
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to check for the presense of newlines around a block tag.
+ $newline_before_re = '/(?:^\n?|\n\n)*$/';
+ $newline_after_re =
+ '{
+ ^ # Start of text following the tag.
+ (?>[ ]*<!--.*?-->)? # Optional comment.
+ [ ]*\n # Must be followed by newline.
+ }xs';
+
+ # Regex to match any tag.
+ $block_tag_re =
+ '{
+ ( # $2: Capture hole tag.
+ </? # Any opening or closing tag.
+ (?> # Tag name.
+ '.$this->block_tags_re.' |
+ '.$this->context_block_tags_re.' |
+ '.$this->clean_tags_re.' |
+ (?!\s)'.$enclosing_tag_re.'
+ )
+ (?:
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ <!-- .*? --> # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ <!\[CDATA\[.*?\]\]> # CData Block
+ |
+ # Code span marker
+ `+
+ '. ( !$span ? ' # If not in span.
+ |
+ # Indented code block
+ (?: ^[ ]*\n | ^ | \n[ ]*\n )
+ [ ]{'.($indent+4).'}[^\n]* \n
+ (?>
+ (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+ )*
+ |
+ # Fenced code block marker
+ (?> ^ | \n )
+ [ ]{'.($indent).'}~~~+[ ]*\n
+ ' : '' ). ' # End (if not is span).
+ )
+ }xs';
+
+
+ $depth = 0; # Current depth inside the tag tree.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Loop through every tag until we find the closing tag of the parent
+ # or loop until reaching the end of text if no parent tag specified.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($block_tag_re, $text, 2,
+ PREG_SPLIT_DELIM_CAPTURE);
+
+ # If in Markdown span mode, add a empty-string span-level hash
+ # after each newline to prevent triggering any block element.
+ if ($span) {
+ $void = $this->hashPart("", ':');
+ $newline = "$void\n";
+ $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+ }
+
+ $parsed .= $parts[0]; # Text before current tag.
+
+ # If end of $text has been reached. Stop loop.
+ if (count($parts) < 3) {
+ $text = "";
+ break;
+ }
+
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+ $tag_re = preg_quote($tag); # For use in a regular expression.
+
+ #
+ # Check for: Code span marker
+ #
+ if ($tag{0} == "`") {
+ # Find corresponding end marker.
+ $tag_re = preg_quote($tag);
+ if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
+ $text, $matches))
+ {
+ # End marker found: pass text unchanged until marker.
+ $parsed .= $tag . $matches[0];
+ $text = substr($text, strlen($matches[0]));
+ }
+ else {
+ # Unmatched marker: just skip it.
+ $parsed .= $tag;
+ }
+ }
+ #
+ # Check for: Indented code block.
+ #
+ else if ($tag{0} == "\n" || $tag{0} == " ") {
+ # Indented code block: pass it unchanged, will be handled
+ # later.
+ $parsed .= $tag;
+ }
+ #
+ # Check for: Fenced code block marker.
+ #
+ else if ($tag{0} == "~") {
+ # Fenced code block marker: find matching end marker.
+ $tag_re = preg_quote(trim($tag));
+ if (preg_match('{^(?>.*\n)+?'.$tag_re.' *\n}', $text,
+ $matches))
+ {
+ # End marker found: pass text unchanged until marker.
+ $parsed .= $tag . $matches[0];
+ $text = substr($text, strlen($matches[0]));
+ }
+ else {
+ # No end marker: just skip it.
+ $parsed .= $tag;
+ }
+ }
+ #
+ # Check for: Opening Block level tag or
+ # Opening Context Block tag (like ins and del)
+ # used as a block tag (tag is alone on it's line).
+ #
+ else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+ ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+ preg_match($newline_before_re, $parsed) &&
+ preg_match($newline_after_re, $text) )
+ )
+ {
+ # Need to parse tag and following text using the HTML parser.
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+
+ # Make sure it stays outside of any paragraph by adding newlines.
+ $parsed .= "\n\n$block_text\n\n";
+ }
+ #
+ # Check for: Clean tag (like script, math)
+ # HTML Comments, processing instructions.
+ #
+ else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Need to parse tag and following text using the HTML parser.
+ # (don't check for markdown attribute)
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+
+ $parsed .= $block_text;
+ }
+ #
+ # Check for: Tag with same name as enclosing tag.
+ #
+ else if ($enclosing_tag_re !== '' &&
+ # Same name as enclosing tag.
+ preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
+ {
+ #
+ # Increase/decrease nested tag count.
+ #
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+
+ if ($depth < 0) {
+ #
+ # Going out of parent element. Clean up and break so we
+ # return to the calling function.
+ #
+ $text = $tag . $text;
+ break;
+ }
+
+ $parsed .= $tag;
+ }
+ else {
+ $parsed .= $tag;
+ }
+ } while ($depth >= 0);
+
+ return array($parsed, $text);
+ }
+ function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+ #
+ # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+ #
+ # * Calls $hash_method to convert any blocks.
+ # * Stops when the first opening tag closes.
+ # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+ # (it is not inside clean tags)
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to match `markdown` attribute inside of a tag.
+ $markdown_attr_re = '
+ {
+ \s* # Eat whitespace before the `markdown` attribute
+ markdown
+ \s*=\s*
+ (?>
+ (["\']) # $1: quote delimiter
+ (.*?) # $2: attribute value
+ \1 # matching delimiter
+ |
+ ([^\s>]*) # $3: unquoted attribute value
+ )
+ () # $4: make $3 always defined (avoid warnings)
+ }xs';
+
+ # Regex to match any tag.
+ $tag_re = '{
+ ( # $2: Capture hole tag.
+ </? # Any opening or closing tag.
+ [\w:$]+ # Tag name.
+ (?:
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ <!-- .*? --> # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ <!\[CDATA\[.*?\]\]> # CData Block
+ )
+ }xs';
+
+ $original_text = $text; # Save original text in case of faliure.
+
+ $depth = 0; # Current depth inside the tag tree.
+ $block_text = ""; # Temporary text holder for current text.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Get the name of the starting tag.
+ # (This pattern makes $base_tag_name_re safe without quoting.)
+ #
+ if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+ $base_tag_name_re = $matches[1];
+
+ #
+ # Loop through every tag until we find the corresponding closing tag.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ if (count($parts) < 3) {
+ #
+ # End of $text reached with unbalenced tag(s).
+ # In that case, we return original text unchanged and pass the
+ # first character as filtered to prevent an infinite loop in the
+ # parent function.
+ #
+ return array($original_text{0}, substr($original_text, 1));
+ }
+
+ $block_text .= $parts[0]; # Text before current tag.
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+
+ #
+ # Check for: Auto-close tag (like <hr/>)
+ # Comments and Processing Instructions.
+ #
+ if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Just add the tag to the block as if it was text.
+ $block_text .= $tag;
+ }
+ else {
+ #
+ # Increase/decrease nested tag count. Only do so if
+ # the tag's name match base tag's.
+ #
+ if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+ }
+
+ #
+ # Check for `markdown="1"` attribute and handle it.
+ #
+ if ($md_attr &&
+ preg_match($markdown_attr_re, $tag, $attr_m) &&
+ preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+ {
+ # Remove `markdown` attribute from opening tag.
+ $tag = preg_replace($markdown_attr_re, '', $tag);
+
+ # Check if text inside this tag must be parsed in span mode.
+ $this->mode = $attr_m[2] . $attr_m[3];
+ $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+ preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+
+ # Calculate indent before tag.
+ if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+ $strlen = $this->utf8_strlen;
+ $indent = $strlen($matches[1], 'UTF-8');
+ } else {
+ $indent = 0;
+ }
+
+ # End preceding block with this tag.
+ $block_text .= $tag;
+ $parsed .= $this->$hash_method($block_text);
+
+ # Get enclosing tag name for the ParseMarkdown function.
+ # (This pattern makes $tag_name_re safe without quoting.)
+ preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+ $tag_name_re = $matches[1];
+
+ # Parse the content using the HTML-in-Markdown parser.
+ list ($block_text, $text)
+ = $this->_hashHTMLBlocks_inMarkdown($text, $indent,
+ $tag_name_re, $span_mode);
+
+ # Outdent markdown text.
+ if ($indent > 0) {
+ $block_text = preg_replace("/^[ ]{1,$indent}/m", "",
+ $block_text);
+ }
+
+ # Append tag content to parsed text.
+ if (!$span_mode) $parsed .= "\n\n$block_text\n\n";
+ else $parsed .= "$block_text";
+
+ # Start over a new block.
+ $block_text = "";
+ }
+ else $block_text .= $tag;
+ }
+
+ } while ($depth > 0);
+
+ #
+ # Hash last block text that wasn't processed inside the loop.
+ #
+ $parsed .= $this->$hash_method($block_text);
+
+ return array($parsed, $text);
+ }
+
+
+ function hashClean($text) {
+ #
+ # Called whenever a tag must be hashed when a function insert a "clean" tag
+ # in $text, it pass through this function and is automaticaly escaped,
+ # blocking invalid nested overlap.
+ #
+ return $this->hashPart($text, 'C');
+ }
+
+
+ function doHeaders($text) {
+ #
+ # Redefined to add id attribute support.
+ #
+ # Setext-style headers:
+ # Header 1 {#header1}
+ # ========
+ #
+ # Header 2 {#header2}
+ # --------
+ #
+ $text = preg_replace_callback(
+ '{
+ (^.+?) # $1: Header text
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute
+ [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer
+ }mx',
+ array(&$this, '_doHeaders_callback_setext'), $text);
+
+ # atx-style headers:
+ # # Header 1 {#header1}
+ # ## Header 2 {#header2}
+ # ## Header 2 with closing hashes ## {#header3}
+ # ...
+ # ###### Header 6 {#header2}
+ #
+ $text = preg_replace_callback('{
+ ^(\#{1,6}) # $1 = string of #\'s
+ [ ]*
+ (.+?) # $2 = Header text
+ [ ]*
+ \#* # optional closing #\'s (not counted)
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+ [ ]*
+ \n+
+ }xm',
+ array(&$this, '_doHeaders_callback_atx'), $text);
+
+ return $text;
+ }
+ function _doHeaders_attr($attr) {
+ if (empty($attr)) return "";
+ return " id=\"$attr\"";
+ }
+ function _doHeaders_callback_setext($matches) {
+ if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+ return $matches[0];
+ $level = $matches[3]{0} == '=' ? 1 : 2;
+ $attr = $this->_doHeaders_attr($id =& $matches[2]);
+ $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+ function _doHeaders_callback_atx($matches) {
+ $level = strlen($matches[1]);
+ $attr = $this->_doHeaders_attr($id =& $matches[3]);
+ $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+
+
+ function doTables($text) {
+ #
+ # Form HTML tables.
+ #
+ $less_than_tab = $this->tab_width - 1;
+ #
+ # Find tables with leading pipe.
+ #
+ # | Header 1 | Header 2
+ # | -------- | --------
+ # | Cell 1 | Cell 2
+ # | Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] # Optional leading pipe (present)
+ (.+) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ [ ]* # Allowed whitespace.
+ [|] .* \n # Row content.
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_doTable_leadingPipe_callback'), $text);
+
+ #
+ # Find tables without leading pipe.
+ #
+ # Header 1 | Header 2
+ # -------- | --------
+ # Cell 1 | Cell 2
+ # Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ (\S.*[|].*) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ .* [|] .* \n # Row content
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_DoTable_callback'), $text);
+
+ return $text;
+ }
+ function _doTable_leadingPipe_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove leading pipe for each row.
+ $content = preg_replace('/^ *[|]/m', '', $content);
+
+ return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+ }
+ function _doTable_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove any tailing pipes for each line.
+ $head = preg_replace('/[|] *$/m', '', $head);
+ $underline = preg_replace('/[|] *$/m', '', $underline);
+ $content = preg_replace('/[|] *$/m', '', $content);
+
+ # Reading alignement from header underline.
+ $separators = preg_split('/ *[|] */', $underline);
+ foreach ($separators as $n => $s) {
+ if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"';
+ else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+ else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+ else $attr[$n] = '';
+ }
+
+ # Parsing span elements, including code spans, character escapes,
+ # and inline HTML tags, so that pipes inside those gets ignored.
+ $head = $this->parseSpan($head);
+ $headers = preg_split('/ *[|] */', $head);
+ $col_count = count($headers);
+
+ # Write column headers.
+ $text = "<table>\n";
+ $text .= "<thead>\n";
+ $text .= "<tr>\n";
+ foreach ($headers as $n => $header)
+ $text .= " <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
+ $text .= "</tr>\n";
+ $text .= "</thead>\n";
+
+ # Split content by row.
+ $rows = explode("\n", trim($content, "\n"));
+
+ $text .= "<tbody>\n";
+ foreach ($rows as $row) {
+ # Parsing span elements, including code spans, character escapes,
+ # and inline HTML tags, so that pipes inside those gets ignored.
+ $row = $this->parseSpan($row);
+
+ # Split row by cell.
+ $row_cells = preg_split('/ *[|] */', $row, $col_count);
+ $row_cells = array_pad($row_cells, $col_count, '');
+
+ $text .= "<tr>\n";
+ foreach ($row_cells as $n => $cell)
+ $text .= " <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
+ $text .= "</tr>\n";
+ }
+ $text .= "</tbody>\n";
+ $text .= "</table>";
+
+ return $this->hashBlock($text) . "\n";
+ }
+
+
+ function doDefLists($text) {
+ #
+ # Form HTML definition lists.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Re-usable pattern to match any entire dl list:
+ $whole_list_re = '(?>
+ ( # $1 = whole list
+ ( # $2
+ [ ]{0,'.$less_than_tab.'}
+ ((?>.*\S.*\n)+) # $3 = defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?s:.+?)
+ ( # $4
+ \z
+ |
+ \n{2,}
+ (?=\S)
+ (?! # Negative lookahead for another term
+ [ ]{0,'.$less_than_tab.'}
+ (?: \S.*\n )+? # defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?! # Negative lookahead for another definition
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ )
+ )
+ )'; // mx
+
+ $text = preg_replace_callback('{
+ (?>\A\n?|(?<=\n\n))
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doDefLists_callback'), $text);
+
+ return $text;
+ }
+ function _doDefLists_callback($matches) {
+ # Re-usable patterns to match list item bullets and number markers:
+ $list = $matches[1];
+
+ # Turn double returns into triple returns, so that we can make a
+ # paragraph for the last item in a list, if necessary:
+ $result = trim($this->processDefListItems($list));
+ $result = "<dl>\n" . $result . "\n</dl>";
+ return $this->hashBlock($result) . "\n\n";
+ }
+
+
+ function processDefListItems($list_str) {
+ #
+ # Process the contents of a single definition list, splitting it
+ # into individual term and definition list items.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # trim trailing blank lines:
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+ # Process definition terms.
+ $list_str = preg_replace_callback('{
+ (?>\A\n?|\n\n+) # leading line
+ ( # definition terms = $1
+ [ ]{0,'.$less_than_tab.'} # leading whitespace
+ (?![:][ ]|[ ]) # negative lookahead for a definition
+ # mark (colon) or more whitespace.
+ (?> \S.* \n)+? # actual term (not whitespace).
+ )
+ (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed
+ # with a definition mark.
+ }xm',
+ array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+ # Process actual definitions.
+ $list_str = preg_replace_callback('{
+ \n(\n+)? # leading line = $1
+ ( # marker space = $2
+ [ ]{0,'.$less_than_tab.'} # whitespace before colon
+ [:][ ]+ # definition mark (colon)
+ )
+ ((?s:.+?)) # definition text = $3
+ (?= \n+ # stop at next definition mark,
+ (?: # next term or end of text
+ [ ]{0,'.$less_than_tab.'} [:][ ] |
+ <dt> | \z
+ )
+ )
+ }xm',
+ array(&$this, '_processDefListItems_callback_dd'), $list_str);
+
+ return $list_str;
+ }
+ function _processDefListItems_callback_dt($matches) {
+ $terms = explode("\n", trim($matches[1]));
+ $text = '';
+ foreach ($terms as $term) {
+ $term = $this->runSpanGamut(trim($term));
+ $text .= "\n<dt>" . $term . "</dt>";
+ }
+ return $text . "\n";
+ }
+ function _processDefListItems_callback_dd($matches) {
+ $leading_line = $matches[1];
+ $marker_space = $matches[2];
+ $def = $matches[3];
+
+ if ($leading_line || preg_match('/\n{2,}/', $def)) {
+ # Replace marker with the appropriate whitespace indentation
+ $def = str_repeat(' ', strlen($marker_space)) . $def;
+ $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+ $def = "\n". $def ."\n";
+ }
+ else {
+ $def = rtrim($def);
+ $def = $this->runSpanGamut($this->outdent($def));
+ }
+
+ return "\n<dd>" . $def . "</dd>\n";
+ }
+
+
+ function doFencedCodeBlocks($text) {
+ #
+ # Adding the fenced code block syntax to regular Markdown:
+ #
+ # ~~~
+ # Code block
+ # ~~~
+ #
+ $less_than_tab = $this->tab_width;
+
+ $text = preg_replace_callback('{
+ (?:\n|\A)
+ # 1: Opening marker
+ (
+ ~{3,} # Marker: three tilde or more.
+ )
+ [ ]* \n # Whitespace and newline following marker.
+
+ # 2: Content
+ (
+ (?>
+ (?!\1 [ ]* \n) # Not a closing marker.
+ .*\n+
+ )+
+ )
+
+ # Closing marker.
+ \1 [ ]* \n
+ }xm',
+ array(&$this, '_doFencedCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doFencedCodeBlocks_callback($matches) {
+ $codeblock = $matches[2];
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+ $codeblock = preg_replace_callback('/^\n+/',
+ array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+ $codeblock = "<pre><code>$codeblock</code></pre>";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+ function _doFencedCodeBlocks_newlines($matches) {
+ return str_repeat("<br$this->empty_element_suffix",
+ strlen($matches[0]));
+ }
+
+
+ #
+ # Redefining emphasis markers so that emphasis by underscore does not
+ # work in the middle of a word.
+ #
+ var $em_relist = array(
+ '' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?=\S|$)(?![.,:;]\s)',
+ '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
+ '_' => '(?<=\S|^)(?<!_)_(?![a-zA-Z0-9_])',
+ );
+ var $strong_relist = array(
+ '' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?=\S|$)(?![.,:;]\s)',
+ '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
+ '__' => '(?<=\S|^)(?<!_)__(?![a-zA-Z0-9_])',
+ );
+ var $em_strong_relist = array(
+ '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?=\S|$)(?![.,:;]\s)',
+ '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
+ '___' => '(?<=\S|^)(?<!_)___(?![a-zA-Z0-9_])',
+ );
+
+
+ function formParagraphs($text) {
+ #
+ # Params:
+ # $text - string to process with html <p> tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap <p> tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ $value = trim($this->runSpanGamut($value));
+
+ # Check if this should be enclosed in a paragraph.
+ # Clean tag hashes & block tag hashes are left alone.
+ $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+
+ if ($is_p) {
+ $value = "<p>$value</p>";
+ }
+ $grafs[$key] = $value;
+ }
+
+ # Join grafs in one text, then unhash HTML tags.
+ $text = implode("\n\n", $grafs);
+
+ # Finish by removing any tag hashes still present in $text.
+ $text = $this->unhash($text);
+
+ return $text;
+ }
+
+
+ ### Footnotes
+
+ function stripFootnotes($text) {
+ #
+ # Strips link definitions from text, stores the URLs and titles in
+ # hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [^id]: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1
+ [ ]*
+ \n? # maybe *one* newline
+ ( # text = $2 (no blank lines allowed)
+ (?:
+ .+ # actual text
+ |
+ \n # newlines but
+ (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+ (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
+ # by non-indented content
+ )*
+ )
+ }xm',
+ array(&$this, '_stripFootnotes_callback'),
+ $text);
+ return $text;
+ }
+ function _stripFootnotes_callback($matches) {
+ $note_id = $this->fn_id_prefix . $matches[1];
+ $this->footnotes[$note_id] = $this->outdent($matches[2]);
+ return ''; # String that will replace the block
+ }
+
+
+ function doFootnotes($text) {
+ #
+ # Replace footnote references in $text [^id] with a special text-token
+ # which will be replaced by the actual footnote marker in appendFootnotes.
+ #
+ if (!$this->in_anchor) {
+ $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+ }
+ return $text;
+ }
+
+
+ function appendFootnotes($text) {
+ #
+ # Append footnote list to text.
+ #
+ $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+ array(&$this, '_appendFootnotes_callback'), $text);
+
+ if (!empty($this->footnotes_ordered)) {
+ $text .= "\n\n";
+ $text .= "<div class=\"footnotes\">\n";
+ $text .= "<hr". $this->empty_element_suffix ."\n";
+ $text .= "<ol>\n\n";
+
+ $attr = " rev=\"footnote\"";
+ if ($this->fn_backlink_class != "") {
+ $class = $this->fn_backlink_class;
+ $class = $this->encodeAttribute($class);
+ $attr .= " class=\"$class\"";
+ }
+ if ($this->fn_backlink_title != "") {
+ $title = $this->fn_backlink_title;
+ $title = $this->encodeAttribute($title);
+ $attr .= " title=\"$title\"";
+ }
+ $num = 0;
+
+ while (!empty($this->footnotes_ordered)) {
+ $footnote = reset($this->footnotes_ordered);
+ $note_id = key($this->footnotes_ordered);
+ unset($this->footnotes_ordered[$note_id]);
+
+ $footnote .= "\n"; # Need to append newline before parsing.
+ $footnote = $this->runBlockGamut("$footnote\n");
+ $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+ array(&$this, '_appendFootnotes_callback'), $footnote);
+
+ $attr = str_replace("%%", ++$num, $attr);
+ $note_id = $this->encodeAttribute($note_id);
+
+ # Add backlink to last paragraph; create new paragraph if needed.
+ $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
+ if (preg_match('{</p>$}', $footnote)) {
+ $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
+ } else {
+ $footnote .= "\n\n<p>$backlink</p>";
+ }
+
+ $text .= "<li id=\"fn:$note_id\">\n";
+ $text .= $footnote . "\n";
+ $text .= "</li>\n\n";
+ }
+
+ $text .= "</ol>\n";
+ $text .= "</div>";
+ }
+ return $text;
+ }
+ function _appendFootnotes_callback($matches) {
+ $node_id = $this->fn_id_prefix . $matches[1];
+
+ # Create footnote marker only if it has a corresponding footnote *and*
+ # the footnote hasn't been used by another marker.
+ if (isset($this->footnotes[$node_id])) {
+ # Transfert footnote content to the ordered list.
+ $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+ unset($this->footnotes[$node_id]);
+
+ $num = $this->footnote_counter++;
+ $attr = " rel=\"footnote\"";
+ if ($this->fn_link_class != "") {
+ $class = $this->fn_link_class;
+ $class = $this->encodeAttribute($class);
+ $attr .= " class=\"$class\"";
+ }
+ if ($this->fn_link_title != "") {
+ $title = $this->fn_link_title;
+ $title = $this->encodeAttribute($title);
+ $attr .= " title=\"$title\"";
+ }
+
+ $attr = str_replace("%%", $num, $attr);
+ $node_id = $this->encodeAttribute($node_id);
+
+ return
+ "<sup id=\"fnref:$node_id\">".
+ "<a href=\"#fn:$node_id\"$attr>$num</a>".
+ "</sup>";
+ }
+
+ return "[^".$matches[1]."]";
+ }
+
+
+ ### Abbreviations ###
+
+ function stripAbbreviations($text) {
+ #
+ # Strips abbreviations from text, stores titles in hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [id]*: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1
+ (.*) # text = $2 (no blank lines allowed)
+ }xm',
+ array(&$this, '_stripAbbreviations_callback'),
+ $text);
+ return $text;
+ }
+ function _stripAbbreviations_callback($matches) {
+ $abbr_word = $matches[1];
+ $abbr_desc = $matches[2];
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ return ''; # String that will replace the block
+ }
+
+
+ function doAbbreviations($text) {
+ #
+ # Find defined abbreviations in text and wrap them in <abbr> elements.
+ #
+ if ($this->abbr_word_re) {
+ // cannot use the /x modifier because abbr_word_re may
+ // contain significant spaces:
+ $text = preg_replace_callback('{'.
+ '(?<![\w\x1A])'.
+ '(?:'.$this->abbr_word_re.')'.
+ '(?![\w\x1A])'.
+ '}',
+ array(&$this, '_doAbbreviations_callback'), $text);
+ }
+ return $text;
+ }
+ function _doAbbreviations_callback($matches) {
+ $abbr = $matches[0];
+ if (isset($this->abbr_desciptions[$abbr])) {
+ $desc = $this->abbr_desciptions[$abbr];
+ if (empty($desc)) {
+ return $this->hashPart("<abbr>$abbr</abbr>");
+ } else {
+ $desc = $this->encodeAttribute($desc);
+ return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
+ }
+ } else {
+ return $matches[0];
+ }
+ }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl
+by John Gruber. This special "Extra" version of PHP Markdown features
+further enhancements to the syntax for making additional constructs
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+<http://daringfireball.net/projects/markdown/>
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+<michel.fortin@michelf.com>
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+---------------
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2009 Michel Fortin
+<http://michelf.com/>
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+<http://daringfireball.net/>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
+
+*/
+?> \ No newline at end of file
diff --git a/views/default/css/elements/forms.php b/views/default/css/elements/forms.php
index d783b5123..0230cbc54 100644
--- a/views/default/css/elements/forms.php
+++ b/views/default/css/elements/forms.php
@@ -28,12 +28,10 @@ input, textarea {
color: #666;
font: 120% Arial, Helvetica, sans-serif;
padding: 5px;
- width: 100%;
-
+ width: 100%;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
@@ -237,4 +235,217 @@ input[type="radio"] {
}
.user-picker-entry .elgg-button-delete {
margin-right:10px;
-} \ No newline at end of file
+}
+/* ***************************************
+ Datepicker
+**************************************** */
+
+#ui-datepicker-div, .ui-datepicker-inline, .ui-datepicker-calendar{
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 14px;
+ padding: 0;
+ margin: 0;
+ background: #E4ECF5;
+ width: 220px;
+ color: black;
+}
+#ui-datepicker-div {
+ display: none;
+ border: 1px solid #777;
+ z-index: 9999; /*must have*/
+}
+.ui-datepicker-inline {
+ float: left;
+ display: block;
+ border: 0;
+}
+.ui-datepicker-rtl {
+ direction: rtl;
+}
+.ui-datepicker-dialog {
+ padding: 5px !important;
+ border: 4px ridge #ddd !important;
+}
+button.ui-datepicker-trigger {
+ width: 25px;
+}
+img.ui-datepicker-trigger {
+ margin: 2px;
+ vertical-align: middle;
+}
+.ui-datepicker-prompt {
+ float: left;
+ padding: 2px;
+ background: #ddd;
+ color: #000;
+}
+* html .ui-datepicker-prompt {
+ width: 185px;
+}
+.ui-datepicker-control, .ui-datepicker-links, .ui-datepicker-header, .ui-datepicker {
+ clear: both;
+ float: left;
+ width: 218px;
+ color: #fff;
+}
+.ui-datepicker-control {
+ background: #400;
+ padding: 2px 0px;
+}
+.ui-datepicker-links {
+ background: #000;
+ padding: 2px 0px;
+}
+.ui-datepicker-control, .ui-datepicker-links {
+ font-weight: bold;
+ font-size: 80%;
+}
+.ui-datepicker-links label { /* disabled links */
+ padding: 2px 5px;
+ color: #888;
+}
+.ui-datepicker-clear, .ui-datepicker-prev {
+ float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-clear, .ui-datepicker-rtl .ui-datepicker-prev {
+ float: right;
+ text-align: right;
+}
+.ui-datepicker-current {
+ float: left;
+ width: 30%;
+ text-align: center;
+}
+.ui-datepicker-close, .ui-datepicker-next {
+ float: right;
+ text-align: right;
+ padding: 0px 0px 2px 0px;
+}
+.ui-datepicker-rtl .ui-datepicker-close, .ui-datepicker-rtl {
+ float: left;
+ text-align: left;
+}
+.ui-datepicker-header {
+ padding: 1px 0 3px;
+ background: #4690D6;
+ text-align: center;
+ font-weight: bold;
+ height: 1.3em;
+ padding: 0 2px 3px 0;
+}
+.ui-datepicker-header select {
+ background: #333;
+ color: #fff;
+ border: 0px;
+ font-weight: bold;
+}
+.ui-datepicker {
+ background: #ccc;
+ text-align: center;
+ font-size: 100%;
+}
+.ui-datepicker a {
+ display: block;
+ width: 30px;
+}
+.ui-datepicker-title-row {
+ background: #777;
+}
+.ui-datepicker-days-row {
+ background: #eee;
+ color: #666;
+}
+.ui-datepicker-week-col {
+ background: #777;
+ color: #fff;
+}
+.ui-datepicker-days-cell {
+ color: #000;
+ border: 1px solid #ddd;
+}
+.ui-datepicker-days-cell a{
+ display: block;
+}
+.ui-datepicker-week-end-cell {
+ background: #ddd;
+}
+.ui-datepicker-title-row .ui-datepicker-week-end-cell {
+ background: #777;
+}
+.ui-datepicker-days-cell-over {
+ background: #fff;
+ border: 1px solid #777;
+}
+.ui-datepicker-unselectable {
+ color: #E4ECF5;
+}
+.ui-datepicker-today {
+ background: #4690D6 !important;
+}
+.ui-datepicker-current-day {
+ background: #999 !important;
+}
+.ui-datepicker-status {
+ background: #ddd;
+ width: 100%;
+ font-size: 80%;
+ text-align: center;
+}
+
+/* ________ Datepicker Links _______
+
+** Reset link properties and then override them with !important */
+#ui-datepicker-div a, .ui-datepicker-inline a {
+ cursor: pointer;
+ margin: 0;
+ padding: 0;
+ background: none;
+ color: #000;
+ align: center !important;
+}
+.ui-datepicker-inline .ui-datepicker-links a {
+ padding: 0 5px !important;
+}
+.ui-datepicker-control a, .ui-datepicker-links a {
+ padding: 2px 5px !important;
+ color: #eee !important;
+}
+.ui-datepicker-title-row a {
+ color: #eee !important;
+}
+.ui-datepicker-control a:hover {
+ background: #fdd !important;
+ color: #333 !important;
+}
+.ui-datepicker-links a:hover, .ui-datepicker-title-row a:hover {
+ background: #ddd !important;
+ color: #333 !important;
+}
+
+/* ___________ MULTIPLE MONTHS _________*/
+
+.ui-datepicker-multi .ui-datepicker {
+ border: 1px solid #777;
+}
+.ui-datepicker-one-month {
+ float: left;
+ width: 185px;
+}
+.ui-datepicker-new-row {
+ clear: left;
+}
+
+/* ___________ IE6 IFRAME FIX ________ */
+
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}
+
diff --git a/views/default/css/elements/typography.php b/views/default/css/elements/typography.php
index a50f85c8c..f080a29b2 100644
--- a/views/default/css/elements/typography.php
+++ b/views/default/css/elements/typography.php
@@ -34,9 +34,6 @@ p:last-child {
margin-bottom: 0;
}
-dt { font-weight: bold }
-dd { margin: 0 0 1em 1em }
-
pre, code {
font-family: Monaco, "Courier New", Courier, monospace;
font-size: 12px;
@@ -138,6 +135,10 @@ h6 { font-size: 0.8em; }
.elgg-output {
margin-top: 10px;
}
+
+.elgg-output dt { font-weight: bold }
+.elgg-output dd { margin: 0 0 1em 1em }
+
.elgg-output ul, ol {
margin: 0 1.5em 1.5em 0;
padding-left: 1.5em;
diff --git a/views/default/forms/profile/fields/add.php b/views/default/forms/profile/fields/add.php
index c700cf7f5..7961037e6 100644
--- a/views/default/forms/profile/fields/add.php
+++ b/views/default/forms/profile/fields/add.php
@@ -9,7 +9,7 @@ $label_text = elgg_echo('profile:label');
$type_text = elgg_echo('profile:type');
$label_control = elgg_view('input/text', array('name' => 'label'));
-$type_control = elgg_view('input/pulldown', array('name' => 'type', 'options_values' => array(
+$type_control = elgg_view('input/dropdown', array('name' => 'type', 'options_values' => array(
'text' => elgg_echo('text'),
'longtext' => elgg_echo('longtext'),
'tags' => elgg_echo('tags'),
diff --git a/views/default/input/autocomplete.php b/views/default/input/autocomplete.php
index b16d08fc3..0a4057ddf 100644
--- a/views/default/input/autocomplete.php
+++ b/views/default/input/autocomplete.php
@@ -35,7 +35,7 @@ elgg_load_js('elgg.autocomplete');
<script type="text/javascript">
elgg.provide('elgg.autocomplete');
-elgg.autocomplete.url = "<?php elgg_get_site_url() . 'livesearch?' . $ac_url_params; ?>";
+elgg.autocomplete.url = "<?php echo elgg_get_site_url() . 'livesearch?' . $ac_url_params; ?>";
</script>
<input type="text" <?php echo elgg_format_attributes($vars); ?> />
diff --git a/views/default/navigation/menu/elements/item.php b/views/default/navigation/menu/elements/item.php
index 893bbd205..55ddc2fe4 100644
--- a/views/default/navigation/menu/elements/item.php
+++ b/views/default/navigation/menu/elements/item.php
@@ -21,8 +21,11 @@ if ($children) {
}
$item_class = $item->getItemClass();
+
+//allow people to specify name with underscores
+$name = str_replace('_', '-', $item->getName());
if ($item_class) {
- $class = "class=\"$item_class\"";
+ $class = "class=\"elgg-menu-item-$name $item_class\"";
}
echo "<li $class>";
diff --git a/views/default/object/plugin/advanced.php b/views/default/object/plugin/advanced.php
index 4b5a3ba48..a346d4ff1 100644
--- a/views/default/object/plugin/advanced.php
+++ b/views/default/object/plugin/advanced.php
@@ -150,6 +150,24 @@ $website = elgg_view('output/url', array(
$copyright = elgg_view('output/text', array('value' => $plugin->manifest->getCopyright()));
$license = elgg_view('output/text', array('value' => $plugin->manifest->getLicense()));
+// show links to text files
+$files = $plugin->getAvailableTextFiles();
+
+$docs = '';
+if ($files) {
+ $docs = '<ul>';
+ foreach ($files as $file => $path) {
+ $url = 'admin_plugin_text_file/' . $plugin->getID() . "/$file";
+ $link = elgg_view('output/url', array(
+ 'text' => $file,
+ 'href' => $url
+ ));
+ $docs .= "<li>$link</li>";
+
+ }
+ $docs .= '</ul>';
+}
+
?>
<div class="elgg-state-draggable elgg-plugin <?php echo $active_class ?>" id="elgg-plugin-<?php echo $plugin->guid; ?>">
@@ -190,6 +208,7 @@ if (elgg_view_exists($settings_view)) {
<div class="plugin_description"><?php echo $description; ?></div>
<p class="plugin_author"><?php echo $author . ' - ' . $website; ?></p>
+ <?php echo $docs; ?>
<div class="pts">
<?php
diff --git a/views/default/object/plugin/simple.php b/views/default/object/plugin/simple.php
index 0361666ff..d57d81934 100644
--- a/views/default/object/plugin/simple.php
+++ b/views/default/object/plugin/simple.php
@@ -42,6 +42,19 @@ if ($website) {
$plugin_footer .= "<li><a href=\"$website\">" . elgg_echo('admin:plugins:plugin_website') . '</a></li>';
}
+// show links to text files
+$files = $plugin->getAvailableTextFiles();
+
+foreach ($files as $file => $path) {
+ $url = 'admin_plugin_text_file/' . $plugin->getID() . "/$file";
+ $link = elgg_view('output/url', array(
+ 'text' => $file,
+ 'href' => $url
+ ));
+ $plugin_footer .= "<li>$link</li>";
+
+}
+
if (elgg_view_exists("settings/$plugin_id/edit")) {
$settings_href = elgg_get_site_url() . "admin/plugin_settings/$plugin_id";
$plugin_footer .= "<li><a class='plugin_settings link' href='$settings_href'>" . elgg_echo('settings') . "</a></li>";
diff --git a/views/default/page/components/gallery.php b/views/default/page/components/gallery.php
index 1ba896836..e86b9f885 100644
--- a/views/default/page/components/gallery.php
+++ b/views/default/page/components/gallery.php
@@ -3,8 +3,6 @@
* Gallery view
*
* @uses $vars['items']
- *
- * @todo not complete - number of columns
*/
$items = $vars['items'];
@@ -21,8 +19,6 @@ $pagination = elgg_extract('pagination', $vars, true);
$offset_key = elgg_extract('offset_key', $vars, 'offset');
$position = elgg_extract('position', $vars, 'after');
-$num_columns = 4;
-
if ($pagination && $count) {
$nav .= elgg_view('navigation/pagination', array(
'offset' => $offset,
@@ -37,33 +33,15 @@ if ($position == 'before' || $position == 'both') {
}
?>
-<table class="elgg-gallery">
-<?php
-
-$col = 0;
-foreach ($items as $item) {
- if ($col == 0) {
- echo '<tr>';
- }
- $col++;
-
- echo '<td>';
- echo elgg_view_list_item($item, $vars);
- echo "</td>";
-
- if ($col == $num_columns) {
- echo '</tr>';
- $col = 0;
- }
-}
-
-if ($col > 0) {
- echo '</tr>';
-}
-
-?>
-
-</table>
+<ul class="elgg-gallery">
+ <?php
+ foreach ($items as $item) {
+ echo '<li>';
+ echo elgg_view_list_item($item, $vars);
+ echo "</li>";
+ }
+ ?>
+</ul>
<?php
if ($position == 'after' || $position == 'both') {