init plugins

This commit is contained in:
joyqi 2013-12-06 09:22:36 +08:00
parent c62847a42e
commit 5ced5651aa
235 changed files with 30678 additions and 0 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto
# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.php text eol=lf
*.js text eol=lf
*.css text eol=lf
*.html text eol=lf
*.xml text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
.*.swp
.*.swo
._*
.DS_Store
/Debug/
/ImgCache/
/Backup_rar/
/Debug/
/debug/
/upload/
/avatar/
/.idea/
.svn/
*.orig
*.aps
*.APS
*.chm
*.exp
*.pdb
*.rar
.smbdelete*
*.sublime*
.sass-cache
config.rb
/config.inc.php
/usr/uploads/

213
Akismet/Plugin.php Normal file
View File

@ -0,0 +1,213 @@
<?php
/**
* Akismet 反垃圾评论插件 for Typecho
*
* @package Akismet
* @author qining
* @version 1.1.4
* @link http://typecho.org
*/
class Akismet_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
if (false == Typecho_Http_Client::get()) {
throw new Typecho_Plugin_Exception(_t('对不起, 您的主机不支持 php-curl 扩展而且没有打开 allow_url_fopen 功能, 无法正常使用此功能'));
}
Typecho_Plugin::factory('Widget_Feedback')->comment = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Feedback')->trackback = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_XmlRpc')->pingback = array('Akismet_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Comments_Edit')->mark = array('Akismet_Plugin', 'mark');
return _t('请配置此插件的API KEY, 以使您的反垃圾策略生效');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$key = new Typecho_Widget_Helper_Form_Element_Textarea('key', NULL, NULL, _t('服务密钥'), _t('此密钥需要向服务提供商注册<br />
它是一个用于表明您合法用户身份的字符串'));
$form->addInput($key->addRule('required', _t('您必须填写一个服务密钥'))
->addRule(array('Akismet_Plugin', 'validate'), _t('您使用的服务密钥错误')));
$url = new Typecho_Widget_Helper_Form_Element_Text('url', NULL, 'http://rest.akismet.com',
_t('服务地址'), _t('这是反垃圾评论服务提供商的服务器地址<br />
我们推荐您使用 <a href="http://akismet.com">Akismet</a> 或者 <a href="http://antispam.typepad.com">Typepad</a> 的反垃圾服务'));
$form->addInput($url->addRule('url', _t('您使用的地址格式错误')));
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 验证api的key值
*
* @access public
* @param string $key 服务密钥
* @return boolean
*/
public static function validate($key)
{
$options = Typecho_Widget::widget('Widget_Options');
$url = Typecho_Request::getInstance()->url;
$data = array(
'key' => $key,
'blog' => $options->siteUrl
);
$client = Typecho_Http_Client::get('Curl', 'Socket');
if (false != $client) {
$client->setData($data)
->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')
->send(Typecho_Common::url('/1.1/verify-key', $url));
if ('valid' == $client->getResponseBody()) {
return true;
}
}
return false;
}
/**
* 标记评论状态时的插件接口
*
* @access public
* @param array $comment 评论数据的结构体
* @param Typecho_Widget $commentWidget 评论组件
* @param string $status 评论状态
* @return void
*/
public static function mark($comment, $commentWidget, $status)
{
if ('spam' == $comment['status'] && $status != 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-ham');
} else if ('spam' != $comment['status'] && $status == 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-spam');
}
}
/**
* 评论过滤器
*
* @access public
* @param array $comment 评论结构
* @param Typecho_Widget $post 被评论的文章
* @param array $result 返回的结果上下文
* @param string $api api地址
* @return void
*/
public static function filter($comment, $post, $result, $api = 'comment-check')
{
$comment = empty($result) ? $comment : $result;
$options = Typecho_Widget::widget('Widget_Options');
$url = $options->plugin('Akismet')->url;
$key = $options->plugin('Akismet')->key;
$allowedServerVars = 'comment-check' == $api ? array(
'SCRIPT_URI',
'HTTP_HOST',
'HTTP_USER_AGENT',
'HTTP_ACCEPT',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_CHARSET',
'HTTP_KEEP_ALIVE',
'HTTP_CONNECTION',
'HTTP_CACHE_CONTROL',
'HTTP_PRAGMA',
'HTTP_DATE',
'HTTP_EXPECT',
'HTTP_MAX_FORWARDS',
'HTTP_RANGE',
'CONTENT_TYPE',
'CONTENT_LENGTH',
'SERVER_SIGNATURE',
'SERVER_SOFTWARE',
'SERVER_NAME',
'SERVER_ADDR',
'SERVER_PORT',
'REMOTE_PORT',
'GATEWAY_INTERFACE',
'SERVER_PROTOCOL',
'REQUEST_METHOD',
'QUERY_STRING',
'REQUEST_URI',
'SCRIPT_NAME',
'REQUEST_TIME'
) : array();
$data = array(
'blog' => $options->siteUrl,
'user_ip' => $comment['ip'],
'user_agent' => $comment['agent'],
'referrer' => Typecho_Request::getInstance()->getReferer(),
'permalink' => $post->permalink,
'comment_type' => $comment['type'],
'comment_author' => $comment['author'],
'comment_author_email' => $comment['mail'],
'comment_author_url' => $comment['url'],
'comment_content' => $comment['text']
);
foreach ($allowedServerVars as $val) {
if (array_key_exists($val, $_SERVER)) {
$data[$val] = $_SERVER[$val];
}
}
try {
$client = Typecho_Http_Client::get();
if (false != $client && $key) {
$params = parse_url($url);
$url = $params['scheme'] . '://' . $key . '.' . $params['host'] . (isset($params['path']) ? $params['path'] : NULL);
$client->setHeader('User-Agent', $options->generator . ' | Akismet/1.1')
->setTimeout(5)
->setData($data)
->send(Typecho_Common::url('/1.1/' . $api, $url));
if ('true' == $client->getResponseBody()) {
$comment['status'] = 'spam';
}
}
} catch (Typecho_Http_Client_Exception $e) {
//do nothing
error_log($e->getMessage());
}
return $comment;
}
}

124
BlockComment/Plugin.php Normal file
View File

@ -0,0 +1,124 @@
<?php
/**
* 增加评论黑名单(根据 IP 地址过滤)
*
* @package Block Comment
* @author 明城
* @version 0.0.1
* @link http://typecho.org
*/
class BlockComment_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Feedback')->comment = array('BlockComment_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Feedback')->trackback = array('BlockComment_Plugin', 'filter');
Typecho_Plugin::factory('Widget_XmlRpc')->pingback = array('BlockComment_Plugin', 'filter');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$hosts = new Typecho_Widget_Helper_Form_Element_Textarea('hosts', NULL, NULL,
_t('地址列表'), _t('每行单个地址,请仔细匹配以免误封杀'));
$form->addInput($hosts);
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 标记评论状态时的插件接口
*
* @access public
* @param array $comment 评论数据的结构体
* @param Typecho_Widget $commentWidget 评论组件
* @param string $status 评论状态
* @return void
*/
public static function mark($comment, $commentWidget, $status)
{
if ('spam' == $comment['status'] && $status != 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-ham');
} else if ('spam' != $comment['status'] && $status == 'spam') {
self::filter($comment, $commentWidget, NULL, 'submit-spam');
}
}
/**
* 评论过滤器
*
* @access public
* @param array $comment 评论结构
* @param Typecho_Widget $post 被评论的文章
* @param array $result 返回的结果上下文
* @param string $api api地址
* @return void
*/
public static function filter($comment, $post, $result, $api = 'comment-check')
{
$comment = empty($result) ? $comment : $result;
$options = Typecho_Widget::widget('Widget_Options');
$hosts = $options->plugin('BlockComment')->hosts;
$data = array(
'blog' => $options->siteUrl,
'user_ip' => $comment['ip'],
'user_agent' => $comment['agent'],
'referrer' => Typecho_Request::getInstance()->getReferer(),
'permalink' => $post->permalink,
'comment_type' => $comment['type'],
'comment_author' => $comment['author'],
'comment_author_email' => $comment['mail'],
'comment_author_url' => $comment['url'],
'comment_content' => $comment['text']
);
foreach(split("\n", $hosts) as $key => $value){
$value = trim($value);
if (strlen($value)) {
$regex = sprintf("/^%s/i", preg_quote($value));
// 如果提交者符合指定的 IP则扔进垃圾评论中
if (preg_match($regex, $data['user_ip'])) {
$comment['status'] = 'spam';
break;
}
}
}
return $comment;
}
}

768
ConnectToTwitter/OAuth.php Normal file
View File

@ -0,0 +1,768 @@
<?php
// vim: foldmethod=marker
/* Generic exception class
*/
class OAuthException extends Exception {/*{{{*/
// pass
}/*}}}*/
class OAuthConsumer {/*{{{*/
public $key;
public $secret;
function __construct($key, $secret, $callback_url=NULL) {/*{{{*/
$this->key = $key;
$this->secret = $secret;
$this->callback_url = $callback_url;
}/*}}}*/
function __toString() {/*{{{*/
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
}/*}}}*/
}/*}}}*/
class OAuthToken {/*{{{*/
// access tokens and request tokens
public $key;
public $secret;
/**
* key = the token
* secret = the token secret
*/
function __construct($key, $secret) {/*{{{*/
$this->key = $key;
$this->secret = $secret;
}/*}}}*/
/**
* generates the basic string serialization of a token that a server
* would respond to request_token and access_token calls with
*/
function to_string() {/*{{{*/
return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) .
"&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret);
}/*}}}*/
function __toString() {/*{{{*/
return $this->to_string();
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod {/*{{{*/
public function check_signature(&$request, $consumer, $token, $signature) {
$built = $this->build_signature($request, $consumer, $token);
return $built == $signature;
}
}/*}}}*/
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {/*{{{*/
function get_name() {/*{{{*/
return "HMAC-SHA1";
}/*}}}*/
public function build_signature($request, $consumer, $token) {/*{{{*/
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
$key_parts = array(
$consumer->secret,
($token) ? $token->secret : ""
);
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
$key = implode('&', $key_parts);
return base64_encode( hash_hmac('sha1', $base_string, $key, true));
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {/*{{{*/
public function get_name() {/*{{{*/
return "PLAINTEXT";
}/*}}}*/
public function build_signature($request, $consumer, $token) {/*{{{*/
$sig = array(
OAuthUtil::urlencode_rfc3986($consumer->secret)
);
if ($token) {
array_push($sig, OAuthUtil::urlencode_rfc3986($token->secret));
} else {
array_push($sig, '');
}
$raw = implode("&", $sig);
// for debug purposes
$request->base_string = $raw;
return OAuthUtil::urlencode_rfc3986($raw);
}/*}}}*/
}/*}}}*/
class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {/*{{{*/
public function get_name() {/*{{{*/
return "RSA-SHA1";
}/*}}}*/
protected function fetch_public_cert(&$request) {/*{{{*/
// not implemented yet, ideas are:
// (1) do a lookup in a table of trusted certs keyed off of consumer
// (2) fetch via http using a url provided by the requester
// (3) some sort of specific discovery code based on request
//
// either way should return a string representation of the certificate
throw Exception("fetch_public_cert not implemented");
}/*}}}*/
protected function fetch_private_cert(&$request) {/*{{{*/
// not implemented yet, ideas are:
// (1) do a lookup in a table of trusted certs keyed off of consumer
//
// either way should return a string representation of the certificate
throw Exception("fetch_private_cert not implemented");
}/*}}}*/
public function build_signature(&$request, $consumer, $token) {/*{{{*/
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
// Fetch the private key cert based on the request
$cert = $this->fetch_private_cert($request);
// Pull the private key ID from the certificate
$privatekeyid = openssl_get_privatekey($cert);
// Sign using the key
$ok = openssl_sign($base_string, $signature, $privatekeyid);
// Release the key resource
openssl_free_key($privatekeyid);
return base64_encode($signature);
} /*}}}*/
public function check_signature(&$request, $consumer, $token, $signature) {/*{{{*/
$decoded_sig = base64_decode($signature);
$base_string = $request->get_signature_base_string();
// Fetch the public key cert based on the request
$cert = $this->fetch_public_cert($request);
// Pull the public key ID from the certificate
$publickeyid = openssl_get_publickey($cert);
// Check the computed signature against the one passed in the query
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
// Release the key resource
openssl_free_key($publickeyid);
return $ok == 1;
} /*}}}*/
}/*}}}*/
class OAuthRequest {/*{{{*/
private $parameters;
private $http_method;
private $http_url;
// for debug purposes
public $base_string;
public static $version = '1.0';
function __construct($http_method, $http_url, $parameters=NULL) {/*{{{*/
@$parameters or $parameters = array();
$this->parameters = $parameters;
$this->http_method = $http_method;
$this->http_url = $http_url;
}/*}}}*/
/**
* attempt to build up a request from what was passed to the server
*/
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {/*{{{*/
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https';
@$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI'];
@$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
$request_headers = OAuthRequest::get_headers();
// let the library user override things however they'd like, if they know
// which parameters to use then go for it, for example XMLRPC might want to
// do this
if ($parameters) {
$req = new OAuthRequest($http_method, $http_url, $parameters);
} else {
// collect request parameters from query string (GET) and post-data (POST) if appropriate (note: POST vars have priority)
$req_parameters = $_GET;
if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) {
$req_parameters = array_merge($req_parameters, $_POST);
}
// next check for the auth header, we need to do some extra stuff
// if that is the case, namely suck in the parameters from GET or POST
// so that we can include them in the signature
if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
$header_parameters = OAuthRequest::split_header($request_headers['Authorization']);
$parameters = array_merge($req_parameters, $header_parameters);
$req = new OAuthRequest($http_method, $http_url, $parameters);
} else $req = new OAuthRequest($http_method, $http_url, $req_parameters);
}
return $req;
}/*}}}*/
/**
* pretty much a helper function to set up the request
*/
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {/*{{{*/
@$parameters or $parameters = array();
$defaults = array("oauth_version" => OAuthRequest::$version,
"oauth_nonce" => OAuthRequest::generate_nonce(),
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
"oauth_consumer_key" => $consumer->key);
$parameters = array_merge($defaults, $parameters);
if ($token) {
$parameters['oauth_token'] = $token->key;
}
return new OAuthRequest($http_method, $http_url, $parameters);
}/*}}}*/
public function set_parameter($name, $value) {/*{{{*/
$this->parameters[$name] = $value;
}/*}}}*/
public function get_parameter($name) {/*{{{*/
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
}/*}}}*/
public function get_parameters() {/*{{{*/
return $this->parameters;
}/*}}}*/
/**
* Returns the normalized parameters of the request
*
* This will be all (except oauth_signature) parameters,
* sorted first by key, and if duplicate keys, then by
* value.
*
* The returned string will be all the key=value pairs
* concated by &.
*
* @return string
*/
public function get_signable_parameters() {/*{{{*/
// Grab all parameters
$params = $this->parameters;
// Remove oauth_signature if present
if (isset($params['oauth_signature'])) {
unset($params['oauth_signature']);
}
// Urlencode both keys and values
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
$params = array_combine($keys, $values);
// Sort by keys (natsort)
uksort($params, 'strcmp');
// Generate key=value pairs
$pairs = array();
foreach ($params as $key=>$value ) {
if (is_array($value)) {
// If the value is an array, it's because there are multiple
// with the same key, sort them, then add all the pairs
natsort($value);
foreach ($value as $v2) {
$pairs[] = $key . '=' . $v2;
}
} else {
$pairs[] = $key . '=' . $value;
}
}
// Return the pairs, concated with &
return implode('&', $pairs);
}/*}}}*/
/**
* Returns the base string of this request
*
* The base string defined as the method, the url
* and the parameters (normalized), each urlencoded
* and the concated with &.
*/
public function get_signature_base_string() {/*{{{*/
$parts = array(
$this->get_normalized_http_method(),
$this->get_normalized_http_url(),
$this->get_signable_parameters()
);
$parts = OAuthUtil::urlencode_rfc3986($parts);
return implode('&', $parts);
}/*}}}*/
/**
* just uppercases the http method
*/
public function get_normalized_http_method() {/*{{{*/
return strtoupper($this->http_method);
}/*}}}*/
/**
* parses the url and rebuilds it to be
* scheme://host/path
*/
public function get_normalized_http_url() {/*{{{*/
$parts = parse_url($this->http_url);
$port = @$parts['port'];
$scheme = $parts['scheme'];
$host = $parts['host'];
$path = @$parts['path'];
$port or $port = ($scheme == 'https') ? '443' : '80';
if (($scheme == 'https' && $port != '443')
|| ($scheme == 'http' && $port != '80')) {
$host = "$host:$port";
}
return "$scheme://$host$path";
}/*}}}*/
/**
* builds a url usable for a GET request
*/
public function to_url() {/*{{{*/
$out = $this->get_normalized_http_url() . "?";
$out .= $this->to_postdata();
return $out;
}/*}}}*/
/**
* builds the data one would send in a POST request
*
* TODO(morten.fangel):
* this function might be easily replaced with http_build_query()
* and corrections for rfc3986 compatibility.. but not sure
*/
public function to_postdata() {/*{{{*/
$total = array();
foreach ($this->parameters as $k => $v) {
if (is_array($v)) {
foreach ($v as $va) {
$total[] = OAuthUtil::urlencode_rfc3986($k) . "[]=" . OAuthUtil::urlencode_rfc3986($va);
}
} else {
$total[] = OAuthUtil::urlencode_rfc3986($k) . "=" . OAuthUtil::urlencode_rfc3986($v);
}
}
$out = implode("&", $total);
return $out;
}/*}}}*/
/**
* builds the Authorization: header
*/
public function to_header() {/*{{{*/
$out ='Authorization: OAuth realm=""';
$total = array();
foreach ($this->parameters as $k => $v) {
if (substr($k, 0, 5) != "oauth") continue;
if (is_array($v)) throw new OAuthException('Arrays not supported in headers');
$out .= ',' . OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"';
}
return $out;
}/*}}}*/
public function __toString() {/*{{{*/
return $this->to_url();
}/*}}}*/
public function sign_request($signature_method, $consumer, $token) {/*{{{*/
$this->set_parameter("oauth_signature_method", $signature_method->get_name());
$signature = $this->build_signature($signature_method, $consumer, $token);
$this->set_parameter("oauth_signature", $signature);
}/*}}}*/
public function build_signature($signature_method, $consumer, $token) {/*{{{*/
$signature = $signature_method->build_signature($this, $consumer, $token);
return $signature;
}/*}}}*/
/**
* util function: current timestamp
*/
private static function generate_timestamp() {/*{{{*/
return time();
}/*}}}*/
/**
* util function: current nonce
*/
private static function generate_nonce() {/*{{{*/
$mt = microtime();
$rand = mt_rand();
return md5($mt . $rand); // md5s look nicer than numbers
}/*}}}*/
/**
* util function for turning the Authorization: header into
* parameters, has to do some unescaping
*/
private static function split_header($header) {/*{{{*/
$pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
$offset = 0;
$params = array();
while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
$match = $matches[0];
$header_name = $matches[2][0];
$header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
$params[$header_name] = OAuthUtil::urldecode_rfc3986( $header_content );
$offset = $match[1] + strlen($match[0]);
}
if (isset($params['realm'])) {
unset($params['realm']);
}
return $params;
}/*}}}*/
/**
* helper to try to sort out headers for people who aren't running apache
*/
private static function get_headers() {/*{{{*/
if (function_exists('apache_request_headers')) {
// we need this to get the actual Authorization: header
// because apache tends to tell us it doesn't exist
return apache_request_headers();
}
// otherwise we don't have apache and are just going to have to hope
// that $_SERVER actually contains what we need
$out = array();
foreach ($_SERVER as $key => $value) {
if (substr($key, 0, 5) == "HTTP_") {
// this is chaos, basically it is just there to capitalize the first
// letter of every word that is not an initial HTTP and strip HTTP
// code from przemek
$key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))));
$out[$key] = $value;
}
}
return $out;
}/*}}}*/
}/*}}}*/
class OAuthServer {/*{{{*/
protected $timestamp_threshold = 300; // in seconds, five minutes
protected $version = 1.0; // hi blaine
protected $signature_methods = array();
protected $data_store;
function __construct($data_store) {/*{{{*/
$this->data_store = $data_store;
}/*}}}*/
public function add_signature_method($signature_method) {/*{{{*/
$this->signature_methods[$signature_method->get_name()] =
$signature_method;
}/*}}}*/
// high level functions
/**
* process a request_token request
* returns the request token on success
*/
public function fetch_request_token(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
// no token required for the initial token request
$token = NULL;
$this->check_signature($request, $consumer, $token);
$new_token = $this->data_store->new_request_token($consumer);
return $new_token;
}/*}}}*/
/**
* process an access_token request
* returns the access token on success
*/
public function fetch_access_token(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
// requires authorized request token
$token = $this->get_token($request, $consumer, "request");
$this->check_signature($request, $consumer, $token);
$new_token = $this->data_store->new_access_token($token, $consumer);
return $new_token;
}/*}}}*/
/**
* verify an api call, checks all the parameters
*/
public function verify_request(&$request) {/*{{{*/
$this->get_version($request);
$consumer = $this->get_consumer($request);
$token = $this->get_token($request, $consumer, "access");
$this->check_signature($request, $consumer, $token);
return array($consumer, $token);
}/*}}}*/
// Internals from here
/**
* version 1
*/
private function get_version(&$request) {/*{{{*/
$version = $request->get_parameter("oauth_version");
if (!$version) {
$version = 1.0;
}
if ($version && $version != $this->version) {
throw new OAuthException("OAuth version '$version' not supported");
}
return $version;
}/*}}}*/
/**
* figure out the signature with some defaults
*/
private function get_signature_method(&$request) {/*{{{*/
$signature_method =
@$request->get_parameter("oauth_signature_method");
if (!$signature_method) {
$signature_method = "PLAINTEXT";
}
if (!in_array($signature_method,
array_keys($this->signature_methods))) {
throw new OAuthException(
"Signature method '$signature_method' not supported try one of the following: " . implode(", ", array_keys($this->signature_methods))
);
}
return $this->signature_methods[$signature_method];
}/*}}}*/
/**
* try to find the consumer for the provided request's consumer key
*/
private function get_consumer(&$request) {/*{{{*/
$consumer_key = @$request->get_parameter("oauth_consumer_key");
if (!$consumer_key) {
throw new OAuthException("Invalid consumer key");
}
$consumer = $this->data_store->lookup_consumer($consumer_key);
if (!$consumer) {
throw new OAuthException("Invalid consumer");
}
return $consumer;
}/*}}}*/
/**
* try to find the token for the provided request's token key
*/
private function get_token(&$request, $consumer, $token_type="access") {/*{{{*/
$token_field = @$request->get_parameter('oauth_token');
$token = $this->data_store->lookup_token(
$consumer, $token_type, $token_field
);
if (!$token) {
throw new OAuthException("Invalid $token_type token: $token_field");
}
return $token;
}/*}}}*/
/**
* all-in-one function to check the signature on a request
* should guess the signature method appropriately
*/
private function check_signature(&$request, $consumer, $token) {/*{{{*/
// this should probably be in a different method
$timestamp = @$request->get_parameter('oauth_timestamp');
$nonce = @$request->get_parameter('oauth_nonce');
$this->check_timestamp($timestamp);
$this->check_nonce($consumer, $token, $nonce, $timestamp);
$signature_method = $this->get_signature_method($request);
$signature = $request->get_parameter('oauth_signature');
$valid_sig = $signature_method->check_signature(
$request,
$consumer,
$token,
$signature
);
if (!$valid_sig) {
throw new OAuthException("Invalid signature");
}
}/*}}}*/
/**
* check that the timestamp is new enough
*/
private function check_timestamp($timestamp) {/*{{{*/
// verify that timestamp is recentish
$now = time();
if ($now - $timestamp > $this->timestamp_threshold) {
throw new OAuthException("Expired timestamp, yours $timestamp, ours $now");
}
}/*}}}*/
/**
* check that the nonce is not repeated
*/
private function check_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
// verify that the nonce is uniqueish
$found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp);
if ($found) {
throw new OAuthException("Nonce already used: $nonce");
}
}/*}}}*/
}/*}}}*/
class OAuthDataStore {/*{{{*/
function lookup_consumer($consumer_key) {/*{{{*/
// implement me
}/*}}}*/
function lookup_token($consumer, $token_type, $token) {/*{{{*/
// implement me
}/*}}}*/
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
// implement me
}/*}}}*/
function new_request_token($consumer) {/*{{{*/
// return a new token attached to this consumer
}/*}}}*/
function new_access_token($token, $consumer) {/*{{{*/
// return a new access token attached to this consumer
// for the user associated with this token if the request token
// is authorized
// should also invalidate the request token
}/*}}}*/
}/*}}}*/
/* A very naive dbm-based oauth storage
*/
class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
private $dbh;
function __construct($path = "oauth.gdbm") {/*{{{*/
$this->dbh = dba_popen($path, 'c', 'gdbm');
}/*}}}*/
function __destruct() {/*{{{*/
dba_close($this->dbh);
}/*}}}*/
function lookup_consumer($consumer_key) {/*{{{*/
$rv = dba_fetch("consumer_$consumer_key", $this->dbh);
if ($rv === FALSE) {
return NULL;
}
$obj = unserialize($rv);
if (!($obj instanceof OAuthConsumer)) {
return NULL;
}
return $obj;
}/*}}}*/
function lookup_token($consumer, $token_type, $token) {/*{{{*/
$rv = dba_fetch("${token_type}_${token}", $this->dbh);
if ($rv === FALSE) {
return NULL;
}
$obj = unserialize($rv);
if (!($obj instanceof OAuthToken)) {
return NULL;
}
return $obj;
}/*}}}*/
function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
if (dba_exists("nonce_$nonce", $this->dbh)) {
return TRUE;
} else {
dba_insert("nonce_$nonce", "1", $this->dbh);
return FALSE;
}
}/*}}}*/
function new_token($consumer, $type="request") {/*{{{*/
$key = md5(time());
$secret = time() + time();
$token = new OAuthToken($key, md5(md5($secret)));
if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
throw new OAuthException("doooom!");
}
return $token;
}/*}}}*/
function new_request_token($consumer) {/*{{{*/
return $this->new_token($consumer, "request");
}/*}}}*/
function new_access_token($token, $consumer) {/*{{{*/
$token = $this->new_token($consumer, 'access');
dba_delete("request_" . $token->key, $this->dbh);
return $token;
}/*}}}*/
}/*}}}*/
class OAuthUtil {/*{{{*/
public static function urlencode_rfc3986($input) {/*{{{*/
if (is_array($input)) {
return array_map(array('OAuthUtil','urlencode_rfc3986'), $input);
} else if (is_scalar($input)) {
return str_replace('+', ' ',
str_replace('%7E', '~', rawurlencode($input)));
} else {
return '';
}
}/*}}}*/
// This decode function isn't taking into consideration the above
// modifications to the encoding process. However, this method doesn't
// seem to be used anywhere so leaving it as is.
public static function urldecode_rfc3986($string) {/*{{{*/
return rawurldecode($string);
}/*}}}*/
}/*}}}*/

144
ConnectToTwitter/Plugin.php Normal file
View File

@ -0,0 +1,144 @@
<?php
/**
* 支持用twitter帐号在blog中留言并同步到twitter上
*
* @package Connect to Twittter
* @author blankyao
* @version 1.0.0 Beta
* @link http://www.blankyao.cn
* @todo 文章自动推送到twitter twitter帐号注册
*/
include 'twitterOAuth.php';
class ConnectToTwitter_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate() {
Typecho_Plugin::factory('Widget_Feedback')->finishComment = array('ConnectToTwitter_Plugin', 'postToTwitter');
Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('ConnectToTwitter_Plugin', 'initComment');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate() {
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$consumerKey = new Typecho_Widget_Helper_Form_Element_Text('consumerKey', NULL, '',
_t('Consumer Key'), _t('Your application consumer key from Twitter.com. '));
$form->addInput($consumerKey->addRule('required', _t('You must give the Consumer Key from Twitter.com')));
$consumerSecret = new Typecho_Widget_Helper_Form_Element_Text('consumerSecret', NULL, '',
_t('Consumer Secret'), _t('Your application consumer secret from Twitter.com. '));
$form->addInput($consumerSecret->addRule('required', _t('You must give the Consumer Key from Twitter.com')));
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
public static function initComment($api)
{
session_start();
$options = Typecho_Widget::widget('Widget_Options');
$config = $options->plugin('ConnectToTwitter');
//发送请求到twitter
if(isset($api->request->connect_to_twitter))
{
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret);
$tok = $to->getRequestToken();
Typecho_Cookie::set('oauth_request_token', $tok['oauth_token']);
Typecho_Cookie::set('oauth_request_token_secret', $tok['oauth_token_secret']);
/* Build the authorization URL */
$request_link = $to->getAuthorizeURL($tok['oauth_token']);
header('Location:'.$request_link);
}
//从twitter返回
if(isset($api->request->oauth_token)) {
if(Typecho_Cookie::get('oauth_request_token') && Typecho_Cookie::get('oauth_request_token_secret'))
{
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_request_token'), Typecho_Cookie::get('oauth_request_token_secret'));
$tok = $to->getAccessToken();
Typecho_Cookie::set('oauth_access_token', $tok['oauth_token'], time()+60*60*24*30);
Typecho_Cookie::set('oauth_access_token_secret', $tok['oauth_token_secret'], time()+60*60*24*30);
$info_json = $to->OAuthRequest('https://twitter.com/account/verify_credentials.json', array(), 'GET');
$info = Typecho_Json::decode($info_json, true);
self::twitterLogin($info, $api);
}
}
}
//登录暂时做为setcookie,以后要和用户帐号相关联
public static function twitterLogin($info, $api)
{
if (!empty($info['screen_name'])) {
Typecho_Cookie::set('__typecho_remember_author', $info['screen_name'], time()+60*60*24*30);
}
if (!empty($info['url'])) {
Typecho_Cookie::set('__typecho_remember_url', $info['url'], time()+60*60*24*30);
}
}
//发送信息到twitter
public static function postToTwitter($api)
{
if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret') && $api->request->post_to_twitter) {
$options = Typecho_Widget::widget('Widget_Options');
$config = $options->plugin('ConnectToTwitter');
$to = new TwitterOAuth($config->consumerKey, $config->consumerSecret, Typecho_Cookie::get('oauth_access_token'), Typecho_Cookie::get('oauth_access_token_secret'));
$url_array = array();
$url_array = explode('?', $api->request->getReferer());
$url = $url_array[0] . '#comment-' . $api->coid;
$post = $api->text . ' ( from ' . $url . ' ) ';
$twitter = $to->OAuthRequest('https://twitter.com/statuses/update.xml', array('status' => $post), 'POST');
}
return $comment;
}
function showButton()
{
if(Typecho_Cookie::get('oauth_access_token') && Typecho_Cookie::get('oauth_access_token_secret')) {
echo '<p><input type="checkbox" checked="" value="yes" id="post_to_twitter" name="post_to_twitter"/><label for="post_to_twitter">同时把留言更新到你的 Twitter</label></p>';
} else {
echo '<p><a href="?connect_to_twitter=yes"><img src="http://s3.amazonaws.com/static.whitleymedia/twitconnect.png" /></a></p>';
}
}
}

View File

@ -0,0 +1,146 @@
<?php
/*
* Abraham Williams (abraham@abrah.am) http://abrah.am
*
* Basic lib to work with Twitter's OAuth beta. This is untested and should not
* be used in production code. Twitter's beta could change at anytime.
*
* Code based on:
* Fire Eagle code - http://github.com/myelin/fireeagle-php-lib
* twitterlibphp - http://github.com/poseurtech/twitterlibphp
*/
/* Load OAuth lib. You can find it at http://oauth.net */
require_once('OAuth.php');
/**
* Twitter OAuth class
*/
class TwitterOAuth {/*{{{*/
/* Contains the last HTTP status code returned */
private $http_status;
/* Contains the last API call */
private $last_api_call;
/* Set up the API root URL */
public static $TO_API_ROOT = "https://twitter.com";
/**
* Set API URLS
*/
function requestTokenURL() { return self::$TO_API_ROOT.'/oauth/request_token'; }
function authorizeURL() { return self::$TO_API_ROOT.'/oauth/authorize'; }
function accessTokenURL() { return self::$TO_API_ROOT.'/oauth/access_token'; }
/**
* Debug helpers
*/
function lastStatusCode() { return $this->http_status; }
function lastAPICall() { return $this->last_api_call; }
/**
* construct TwitterOAuth object
*/
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {/*{{{*/
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
} else {
$this->token = NULL;
}
}/*}}}*/
/**
* Get a request_token from Twitter
*
* @returns a key/value array containing oauth_token and oauth_token_secret
*/
function getRequestToken() {/*{{{*/
$r = $this->oAuthRequest($this->requestTokenURL());
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}/*}}}*/
/**
* Parse a URL-encoded OAuth response
*
* @return a key/value array
*/
function oAuthParseResponse($responseString) {
$r = array();
foreach (explode('&', $responseString) as $param) {
$pair = explode('=', $param, 2);
if (count($pair) != 2) continue;
$r[urldecode($pair[0])] = urldecode($pair[1]);
}
return $r;
}
/**
* Get the authorize URL
*
* @returns a string
*/
function getAuthorizeURL($token) {/*{{{*/
if (is_array($token)) $token = $token['oauth_token'];
return $this->authorizeURL() . '?oauth_token=' . $token;
}/*}}}*/
/**
* Exchange the request token and secret for an access token and
* secret, to sign API calls.
*
* @returns array("oauth_token" => the access token,
* "oauth_token_secret" => the access secret)
*/
function getAccessToken($token = NULL) {/*{{{*/
$r = $this->oAuthRequest($this->accessTokenURL());
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}/*}}}*/
/**
* Format and sign an OAuth / API request
*/
function oAuthRequest($url, $args = array(), $method = NULL) {/*{{{*/
if (empty($method)) $method = empty($args) ? "GET" : "POST";
$req = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $args);
$req->sign_request($this->sha1_method, $this->consumer, $this->token);
switch ($method) {
case 'GET': return $this->http($req->to_url());
case 'POST': return $this->http($req->get_normalized_http_url(), $req->to_postdata());
}
}/*}}}*/
/**
* Make an HTTP request
*
* @return API results
*/
function http($url, $post_data = null) {/*{{{*/
$ch = curl_init();
if (defined("CURL_CA_BUNDLE_PATH")) curl_setopt($ch, CURLOPT_CAINFO, CURL_CA_BUNDLE_PATH);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//////////////////////////////////////////////////
///// Set to 1 to verify Twitter's SSL Cert //////
//////////////////////////////////////////////////
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
if (isset($post_data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
$response = curl_exec($ch);
$this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->last_api_call = $url;
curl_close ($ch);
return $response;
}/*}}}*/
}/*}}}*/

1599
Creole/Creole_Wiki.php Normal file

File diff suppressed because it is too large Load Diff

262
Creole/Parse.inc.php Normal file
View File

@ -0,0 +1,262 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Baseline rule class for extension into a "real" parser component.
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Parse.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Baseline rule class for extension into a "real" parser component.
*
* Text_Wiki_Rule classes do not stand on their own; they are called by a
* Text_Wiki object, typcially in the transform() method. Each rule class
* performs three main activities: parse, process, and render.
*
* The parse() method takes a regex and applies it to the whole block of
* source text at one time. Each match is sent as $matches to the
* process() method.
*
* The process() method acts on the matched text from the source, and
* then processes the source text is some way. This may mean the
* creation of a delimited token using addToken(). In every case, the
* process() method returns the text that should replace the matched text
* from parse().
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Parse {
/**
*
* Configuration options for this parser rule.
*
* @access public
*
* @var string
*
*/
var $conf = array();
/**
*
* Regular expression to find matching text for this rule.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = null;
/**
*
* The name of this rule for new token array elements.
*
* @access public
*
* @var string
*
*/
var $rule = null;
/**
*
* A reference to the calling Text_Wiki object.
*
* This is needed so that each rule has access to the same source
* text, token set, URLs, interwiki maps, page names, etc.
*
* @access public
*
* @var object
*/
var $wiki = null;
/**
*
* Constructor for this parser rule.
*
* @access public
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
*/
function Text_Wiki_Parse(&$obj)
{
// set the reference to the calling Text_Wiki object;
// this allows us access to the shared source text, token
// array, etc.
$this->wiki =& $obj;
// set the name of this rule; generally used when adding
// to the tokens array. strip off the Text_Wiki_Parse_ portion.
// text_wiki_parse_
// 0123456789012345
$tmp = substr(get_class($this), 16);
$this->rule = ucwords(strtolower($tmp));
// override config options for the rule if specified
if (isset($this->wiki->parseConf[$this->rule]) &&
is_array($this->wiki->parseConf[$this->rule])) {
$this->conf = array_merge(
$this->conf,
$this->wiki->parseConf[$this->rule]
);
}
}
/**
*
* Abstrct method to parse source text for matches.
*
* Applies the rule's regular expression to the source text, passes
* every match to the process() method, and replaces the matched text
* with the results of the processing.
*
* @access public
*
* @see Text_Wiki_Parse::process()
*
*/
function parse()
{
$this->wiki->source = preg_replace_callback(
$this->regex,
array(&$this, 'process'),
$this->wiki->source
);
}
/**
*
* Abstract method to generate replacements for matched text.
*
* @access public
*
* @param array $matches An array of matches from the parse() method
* as generated by preg_replace_callback. $matches[0] is the full
* matched string, $matches[1] is the first matched pattern,
* $matches[2] is the second matched pattern, and so on.
*
* @return string The processed text replacement; defaults to the
* full matched string (i.e., no changes to the text).
*
* @see Text_Wiki_Parse::parse()
*
*/
function process(&$matches)
{
return $matches[0];
}
/**
*
* Simple method to safely get configuration key values.
*
* @access public
*
* @param string $key The configuration key.
*
* @param mixed $default If the key does not exist, return this value
* instead.
*
* @return mixed The configuration key value (if it exists) or the
* default value (if not).
*
*/
function getConf($key, $default = null)
{
if (isset($this->conf[$key])) {
return $this->conf[$key];
} else {
return $default;
}
}
/**
*
* Extract 'attribute="value"' portions of wiki markup.
*
* This kind of markup is typically used only in macros, but is useful
* anywhere.
*
* The syntax is pretty strict; there can be no spaces between the
* option name, the equals, and the first double-quote; the value
* must be surrounded by double-quotes. You can escape characters in
* the value with a backslash, and the backslash will be stripped for
* you.
*
* @access public
*
* @param string $text The "attributes" portion of markup.
*
* @return array An associative array of key-value pairs where the
* key is the option name and the value is the option value.
*
*/
function getAttrs($text)
{
// find the =" sections;
$tmp = explode('="', trim($text));
// basic setup
$k = count($tmp) - 1;
$attrs = array();
$key = null;
// loop through the sections
foreach ($tmp as $i => $val) {
// first element is always the first key
if ($i == 0) {
$key = trim($val);
continue;
}
// find the last double-quote in the value.
// the part to the left is the value for the last key,
// the part to the right is the next key name
$pos = strrpos($val, '"');
$attrs[$key] = stripslashes(substr($val, 0, $pos));
$key = trim(substr($val, $pos+1));
}
return $attrs;
}
}
?>

67
Creole/Parse/Address.php Normal file
View File

@ -0,0 +1,67 @@
<?php
/**
*
* Parses for signatures.
* This class implements a Text_Wiki rule to find sections of the source
* text that are signatures. A signature is any line starting with exactly
* two - signs.
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Address.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Address extends Text_Wiki_Parse {
/**
*
* The regular expression used to find source text matching this
* rule.
*
* @access public
*
* @var string
*
*/
var $regex = '/^--([^-].*)$/m';
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'start' => The starting point of the signature.
*
* 'end' => The ending point of the signature.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return "\n" . $start . trim($matches[1]) . $end;
}
}
?>

176
Creole/Parse/Blockquote.php Normal file
View File

@ -0,0 +1,176 @@
<?php
/**
*
* Parse for block-quoted text.
*
* Find source text marked as a blockquote, identified by any number of
* greater-than signs '>' at the start of the line, followed by an
* optional space, and then the quote text; each '>' indicates an
* additional level of quoting.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Blockquote.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Blockquote extends Text_Wiki_Parse {
/**
*
* Regex for parsing the source text.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n(([>:]).*\n)(?!([>:]))/Us';
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'type' =>
* 'start' : the start of a blockquote
* 'end' : the end of a blockquote
*
* 'level' => the indent level (0 for the first level, 1 for the
* second, etc)
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* list text and list elements.
*
*/
function process(&$matches)
{
// the replacement text we will return to parse()
$return = '';
// the list of post-processing matches
$list = array();
// $matches[1] is the text matched as a list set by parse();
// create an array called $list that contains a new set of
// matches for the various list-item elements.
preg_match_all(
'=^([>:]+)(.*?\n)=ms',
$matches[1],
$list,
PREG_SET_ORDER
);
// a stack of starts and ends; we keep this so that we know what
// indent level we're at.
$stack = array();
// loop through each list-item element.
foreach ($list as $key => $val) {
// $val[0] is the full matched list-item line
// $val[1] is the number of initial '>' chars (indent level)
// $val[2] is the quote text
// we number levels starting at 1, not zero
$level = strlen($val[1]);
// get the text of the line
$text = trim($val[2]);
// add a level to the list?
while ($level > count($stack)) {
$css = ($val[1][count($stack)] == ':') ? 'remark' : '';
// the current indent level is greater than the number
// of stack elements, so we must be starting a new
// level. push the new level onto the stack with a
// dummy value (boolean true)...
array_push($stack, true);
$return .= "\n\n";
// ...and add a start token to the return.
$return .= $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'level' => $level - 1,
'css' => $css
)
);
$return .= "\n\n";
}
// remove a level?
while (count($stack) > $level) {
// as long as the stack count is greater than the
// current indent level, we need to end list types.
// continue adding end-list tokens until the stack count
// and the indent level are the same.
array_pop($stack);
$return .= "\n\n";
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'end',
'level' => count($stack)
)
);
$return .= "\n\n";
}
// add the line text.
$return .= $text . "\n";
}
// the last line may have been indented. go through the stack
// and create end-tokens until the stack is empty.
$return .= "\n\n";
while (count($stack) > 0) {
array_pop($stack);
$return .= "\n\n";
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'end',
'level' => count($stack)
)
);
$return .= "\n\n";
}
// we're done! send back the replacement text.
return "\n\n$return\n\n";
}
}
?>

81
Creole/Parse/Box.php Normal file
View File

@ -0,0 +1,81 @@
<?php
/**
*
* Parses for bold text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by three
* single-quotes. On parsing, the text itself is left in place, but the
* starting and ending instances of three single-quotes are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
*
*/
class Text_Wiki_Parse_Box extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n\[\d+\].*/s';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken($this->rule, array('type' => 'start', 'css' => 'footnotes'));
$end = $this->wiki->addToken($this->rule, array('type' => 'end'));
return $start . $matches[0] . "\n" . $end . "\n\n";
}
}
?>

73
Creole/Parse/Break.php Normal file
View File

@ -0,0 +1,73 @@
<?php
/**
*
* Parses for explicit line breaks.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Break.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
/**
*
* Parses for explicit line breaks.
*
* This class implements a Text_Wiki_Parse to mark forced line breaks in the
* source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
*/
class Text_Wiki_Parse_Break extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/[ \n]*([\\\][\\\]|\%\%\%)[ \n]*/";
var $regex = "/ *([\\\][\\\]|\%\%\%)\n?/";
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A delimited token to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken($this->rule);
}
}
?>

78
Creole/Parse/Center.php Normal file
View File

@ -0,0 +1,78 @@
<?php
/**
*
* Parses for centered text.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a center element, as defined by text on a line by itself prefixed
* with an exclamation mark (!).
* The centered text itself is left in the source, but is prefixed and
* suffixed with delimited tokens marking its start and end.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Center.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Center extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^! *(.*?)$/m';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* centered text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the centered text.
*
*/
function process(&$matches)
{
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => 'start'
)
);
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => 'end'
)
);
return $start . trim($matches[1]) . $end . "\n\n";
}
}
?>

78
Creole/Parse/Delete.php Normal file
View File

@ -0,0 +1,78 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* underlined as defined by text surrounded by two '_'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Delete extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/__(.*?)__/";
var $regex = "/(?:\-\-(.+?)\-\-|(?:(?<=[\W-\xFF])\-(?![ \-]))(.+?)(?:(?<![ \-])\_(?=[\W-\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
'Delete', // $this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
'Delete', // $this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>

View File

@ -0,0 +1,68 @@
<?php
/**
*
* Parses for Text_Wiki delimiter characters already in the source text.
*
* This class implements a Text_Wiki_Parse to find instances of the delimiter
* character already embedded in the source text; it extracts them and replaces
* them with a delimited token, then renders them as the delimiter itself
* when the target format is XHTML.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Delimiter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Delimiter extends Text_Wiki_Parse {
/**
*
* Constructor. Overrides the Text_Wiki_Parse constructor so that we
* can set the $regex property dynamically (we need to include the
* Text_Wiki $delim character.
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
* @param string $name The token name to use for this rule.
*
*/
function Text_Wiki_Parse_Delimiter(&$obj)
{
parent::Text_Wiki_Parse($obj);
$this->regex = '/' . $this->wiki->delim . '/';
}
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'text' => The full matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken(
$this->rule,
array('text' => $this->wiki->delim)
);
}
}
?>

78
Creole/Parse/Emphasis.php Normal file
View File

@ -0,0 +1,78 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* emphasis (italics) as defined by text surrounded by two slashes.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two single-quotes are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Emphasis extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/\/\/(.*?)\/\//";
var $regex = "/(?:\/\/(.+?)\/\/|(?:(?<=[\W_\xFF])\/(?![ \/]))(.+?)(?:(?<![ \/])\/(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* emphasized.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>

83
Creole/Parse/Footnote.php Normal file
View File

@ -0,0 +1,83 @@
<?php
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by two
* stars. On parsing, the text itself is left in place, but the
* starting and ending instances of two stars are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Footnote.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Footnote extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/(\n)*\[([0-9]+)\]/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$id = $matches[2];
if ($matches[1] == "\n") {
$matches[1] = "\n\n";
$name = "fn$id";
$href = "#ref$id";
}
else {
$name = "ref$id";
$href = "#fn$id";
}
$token = $this->wiki->addToken(
'Url',
array('text' => "[$id]", 'href' => $href, 'name' => $name, 'type' => 'inline')
);
return $matches[1] . $token;
}
}
?>

97
Creole/Parse/Heading.php Normal file
View File

@ -0,0 +1,97 @@
<?php
/**
*
* Parses for heading text.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a heading element, as defined by text on a line by itself prefixed
* with a number of equasl signs (=), determining the heading level.
* Equal signs at the end of the line are silently removed.
* The heading text itself is left in the source, but is prefixed and
* suffixed with delimited tokens marking the start and end of the heading.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Heading.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Heading extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^(={1,6}) *(.*?) *=*$/m';
var $conf = array(
'id_prefix' => 'toc'
);
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* heading text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the heading text.
*
*/
function process(&$matches)
{
// keep a running count for header IDs. we use this later
// when constructing TOC entries, etc.
static $id;
if (! isset($id)) {
$id = 0;
}
$prefix = htmlspecialchars($this->getConf('id_prefix'));
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'level' => strlen($matches[1]),
'text' => trim($matches[2]),
'id' => $prefix . $id ++
)
);
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => 'end',
'level' => strlen($matches[1])
)
);
return $start . trim($matches[2]) . $end . "\n\n";
}
}
?>

58
Creole/Parse/Horiz.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
*
* Parses for horizontal ruling lines.
*
* This class implements a Text_Wiki_Parse to find source text marked to
* be a horizontal rule, as defined by four dashed on their own line.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Horiz.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Horiz extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/^([-]{4,})$/m';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token marking the horizontal rule.
*
*/
function process(&$matches)
{
return "\n" . $this->wiki->addToken($this->rule) . "\n";
}
}
?>

66
Creole/Parse/Image.php Normal file
View File

@ -0,0 +1,66 @@
<?php
/**
*
* Parse for images in the source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Image.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Image extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/{{(.*)(\|(.*))?}}/U';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token marking the horizontal rule.
*
*/
function process(&$matches)
{
$src = trim($matches[1]);
$src = ltrim($src, '/');
$alt = isset($matches[3]) ? trim($matches[3]) : null;
if (!$alt) $alt = $src;
return $this->wiki->addToken(
$this->rule,
array(
'src' => $src,
'attr' => array('alt' => $alt, 'title' => $alt)
)
);
}
}
?>

244
Creole/Parse/List.php Normal file
View File

@ -0,0 +1,244 @@
<?php
/**
*
* Parses for bulleted and numbered lists.
*
* This class implements a Text_Wiki_Parse to find source text marked as
* a bulleted or numbered list. In short, if a line starts with '*' then
* it is a bullet list item; if a line starts with '#' then it is a
* number list item. Multiple * or # indicate an indented sub-list.
* The list items must be on sequential lines, and are ended by blank lines.
* Using a non-* non-# character at the beginning of a line ends the list.
* Note that single newline characters may be eaten beforehand by other rules.
*
* @category Text
*
* @package Text_Wiki
*
* @author Justin Patrin <papercrane@reversefold.com>
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: List.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_List extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n((\*[^\#\-\*]|\-[^\-\d\*\#]|\#[^\#\-\*]).*?)\n(?![\*\-#])/s';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' =>
* 'bullet_start' : the start of a bullet list
* 'bullet_end' : the end of a bullet list
* 'number_start' : the start of a number list
* 'number_end' : the end of a number list
* 'item_start' : the start of item text (bullet or number)
* 'item_end' : the end of item text (bullet or number)
* 'unknown' : unknown type of list or item
*
* 'level' => the indent level (0 for the first level, 1 for the
* second, etc)
*
* 'count' => the list item number at this level. not needed for
* xhtml, but very useful for PDF and RTF.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* list text and list elements.
*
*/
function process(&$matches)
{
// the replacement text we will return
$return = '';
// the list of post-processing matches
$list = array();
// a stack of list-start and list-end types; we keep this
// so that we know what kind of list we're working with
// (bullet or number) and what indent level we're at.
$stack = array();
// the item count is the number of list items for any
// given list-type on the stack
$itemcount = array();
// have we processed the very first list item?
$pastFirst = false;
// populate $list with this set of matches. $matches[1] is the
// text matched as a list set by parse().
preg_match_all(
'/^((\*|\-|#)+) *(.*?)$/ms',
$matches[1],
$list,
PREG_SET_ORDER
);
if (count($list) === 1 && $matches[0][0] === '*' && $matches[0][1] !== ' ' && strpos($matches[0], '*', 1)) {
return $matches[0];
}
// loop through each list-item element.
foreach ($list as $key => $val) {
// $val[0] is the full matched list-item line
// $val[1] is the level (number)
// $val[2] is the type (* or #)
// $val[3] is the list item text
// how many levels are we indented? (1 means the "root"
// list level, no indenting.)
$stars = $val[1];
$level = strlen($stars);
$last = $stars[strlen($stars) - 1];
// get the list item type
if ($last == '*' || $last == '-') {
$type = 'bullet';
} elseif ($last == '#') {
$type = 'number';
} else {
$type = 'unknown';
}
// get the text of the list item
$text = $val[3];
// remove a level from the list?
while (count($stack) > $level || (count($stack) == $level && $type != $stack[$level - 1])) {
// so we don't keep counting the stack, we set up a temp
// var for the count. -1 becuase we're going to pop the
// stack in the next command. $tmp will then equal the
// current level of indent.
$tmp = count($stack) - 1;
// as long as the stack count is greater than the
// current indent level, we need to end list types.
// continue adding end-list tokens until the stack count
// and the indent level are the same.
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => array_pop($stack) . '_list_end',
'level' => $tmp
)
);
// reset to the current (previous) list type so that
// the new list item matches the proper list type.
if ($tmp) {
$oldtype = $stack[$tmp - 1];
}
// reset the item count for the popped indent level
unset($itemcount[$tmp + 1]);
}
// add a level to the list?
if ($level > count($stack)) {
// the current indent level is greater than the
// number of stack elements, so we must be starting
// a new list. push the new list type onto the
// stack...
array_push($stack, $type);
// ...and add a list-start token to the return.
$return .= $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_list_start',
'level' => $level - 1
)
);
}
// add to the item count for this list (taking into account
// which level we are at).
if (! isset($itemcount[$level])) {
// first count
$itemcount[$level] = 0;
} else {
// increment count
$itemcount[$level]++;
}
// is this the very first item in the list?
if (! $pastFirst) {
$first = true;
$pastFirst = true;
} else {
$first = false;
}
// create a list-item starting token.
$start = $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_item_start',
'level' => $level,
'count' => $itemcount[$level],
'first' => $first
)
);
// create a list-item ending token.
$end = $this->wiki->addToken(
$this->rule,
array(
'type' => $type . '_item_end',
'level' => $level,
'count' => $itemcount[$level]
)
);
// add the starting token, list-item text, and ending token
// to the return.
$return .= "\n" . $start . $text . $end;
}
// the last list-item may have been indented. go through the
// list-type stack and create end-list tokens until the stack
// is empty.
while (count($stack) > 0) {
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => array_pop($stack) . '_list_end',
'level' => count($stack)
)
);
}
// we're done! send back the replacement text.
return "\n\n" . $return . "\n\n";
}
}
?>

60
Creole/Parse/Newline.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/**
*
* Parses for implied line breaks indicated by newlines.
* Newlines are not considered if followed by another newline
* or by one of these chars: * | - # = {
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Newline.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Newline extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = '/(?<!\n)\n(?![\n\#\=\|\-\>\:]|\*[^\*\#]|\*+ )/m';
var $regex = '/(?<!\n)\n(?!\n|\#|\*|\=|\||\>|\:|\!|\-\D)/m';
/**
*
* Generates a replacement token for the matched text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A delimited token to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
return ' '; // $this->wiki->addToken($this->rule);
}
}
?>

139
Creole/Parse/Paragraph.php Normal file
View File

@ -0,0 +1,139 @@
<?php
/**
*
* Parses for paragraph blocks.
* This class implements a Text_Wiki rule to find sections of the source
* text that are paragraphs. A paragraph is any line not starting with a
* token delimiter, followed by two newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Paragraph.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Paragraph extends Text_Wiki_Parse {
/**
*
* The regular expression used to find source text matching this
* rule.
*
* @access public
*
* @var string
*
*/
var $regex = "/^.+?\n/m"; // (?=[\n\-\|#{=])
var $conf = array(
'skip' => array(
'address',
'box',
'blockquote',
'code',
'heading',
'center',
'horiz',
'deflist',
'table',
'list',
'paragraph',
'preformatted',
'toc'
)
);
/**
*
* Generates a token entry for the matched text. Token options are:
*
* 'start' => The starting point of the paragraph.
*
* 'end' => The ending point of the paragraph.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A delimited token number to be used as a placeholder in
* the source text.
*
*/
function process(&$matches)
{
$delim = $this->wiki->delim;
// was anything there?
if (trim($matches[0]) == '') {
return '';
}
// does the match start with a delimiter?
if (substr($matches[0], 0, 1) != $delim) {
// no.
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return $start . trim($matches[0]) . $end;
}
// the line starts with a delimiter. read in the delimited
// token number, check the token, and see if we should
// skip it.
// loop starting at the second character (we already know
// the first is a delimiter) until we find another
// delimiter; the text between them is a token key number.
$key = '';
$len = strlen($matches[0]);
for ($i = 1; $i < $len; $i++) {
$char = $matches[0]{$i};
if ($char == $delim) {
break;
} else {
$key .= $char;
}
}
// look at the token and see if it's skippable (if we skip,
// it will not be marked as a paragraph)
$token_type = strtolower($this->wiki->tokens[$key][0]);
$skip = $this->getConf('skip', array());
if (in_array($token_type, $skip)) {
// this type of token should not have paragraphs applied to it.
// return the entire matched text.
return $matches[0];
} else {
$start = $this->wiki->addToken(
$this->rule, array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule, array('type' => 'end')
);
return $start . trim($matches[0]) . $end;
}
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
/**
*
* "Pre-filter" the source text.
*
* Convert DOS and Mac line endings to Unix, convert tabs to 4-spaces,
* add newlines to the top and end of the source text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Prefilter extends Text_Wiki_Parse {
/**
*
* Simple parsing method.
*
* @access public
*
*/
function parse()
{
// convert DOS line endings
$this->wiki->source = str_replace("\r\n", "\n",
$this->wiki->source);
// convert Macintosh line endings
$this->wiki->source = str_replace("\r", "\n",
$this->wiki->source);
// convert tabs to four-spaces
$this->wiki->source = str_replace("\t", " ",
$this->wiki->source);
// add extra newlines at the top and end; this
// seems to help many rules.
$this->wiki->source = "\n\n" . $this->wiki->source . "\n\n";
}
}
?>

View File

@ -0,0 +1,68 @@
<?php
/**
*
* Parses for preformatted text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Preformatted extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n{{{\n(.*)\n}}}\n/Us';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'text' => The preformatted text.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
// > any line consisting of only indented three closing curly braces
// > will have one space removed from the indentation
// > -- http://www.wikicreole.org/wiki/AddNoWikiEscapeProposal
$find = "/\n( *) }}}/";
$replace = "\n$1}}}";
$matches[1] = preg_replace($find, $replace, $matches[1]);
$token = $this->wiki->addToken(
$this->rule,
array('text' => $matches[1])
);
return "\n\n" . $token . "\n\n";
}
}
?>

61
Creole/Parse/Raw.php Normal file
View File

@ -0,0 +1,61 @@
<?php
/**
*
* Parses for monospaced inline text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Raw.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Raw extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/~~([^ \n])/';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* monospaced text. The text itself is encapsulated into a Raw token.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
return $this->wiki->addToken(
$this->rule,
array('text' => $matches[1], 'type' => 'escape')
);
}
}
?>

83
Creole/Parse/Strong.php Normal file
View File

@ -0,0 +1,83 @@
<?php
/**
*
* Parses for bold text.
*
* This class implements a Text_Wiki_Rule to find source text marked for
* strong emphasis (bold) as defined by text surrounded by two
* stars. On parsing, the text itself is left in place, but the
* starting and ending instances of two stars are replaced with
* tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Strong.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Strong extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/\*\*(.*?)\*\*/";
var $regex = "/(?:\*\*(.+?)\*\*|(?:(?<=[\W_\xFF])\*(?![ \*]))(.+?)(?:(?<![ \*])\*(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* emphasized text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A pair of delimited tokens to be used as a placeholder in
* the source text surrounding the text to be emphasized.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>

View File

@ -0,0 +1,75 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* superscript as defined by text surrounded by two '^'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Subscript extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/\,\,(.*?)\,\,/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
if (! $this->wiki->checkInnerTags($matches[1])) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $matches[1] . $end;
}
}
?>

View File

@ -0,0 +1,75 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* superscript as defined by text surrounded by two '^'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Superscript extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = "/\^\^(.*?)\^\^/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
if (! $this->wiki->checkInnerTags($matches[1])) {
return $matches[0];
}
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $matches[1] . $end;
}
}
?>

207
Creole/Parse/Table.php Normal file
View File

@ -0,0 +1,207 @@
<?php
/**
*
* Parses for table markup.
*
* This class implements a Text_Wiki_Parse to find source text marked as
* a set of table rows, where a line start (and optionally ends) with a
* single-pipe (|) and uses single-pipes to separate table cells.
* The rows must be on sequential lines (no blank lines between them).
* A blank line indicates the beginning of other text or another table.
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Table.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Table extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/\n((\|).*)(\n)(?!(\|))/Us';
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'type' =>
* 'table_start' : the start of a bullet list
* 'table_end' : the end of a bullet list
* 'row_start' : the start of a number list
* 'row_end' : the end of a number list
* 'cell_start' : the start of item text (bullet or number)
* 'cell_end' : the end of item text (bullet or number)
*
* 'cols' => the number of columns in the table (for 'table_start')
*
* 'rows' => the number of rows in the table (for 'table_start')
*
* 'span' => column span (for 'cell_start')
*
* 'attr' => column attribute flag (for 'cell_start')
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return A series of text and delimited tokens marking the different
* table elements and cell text.
*
*/
function process(&$matches)
{
// our eventual return value
$return = '';
// the number of columns in the table
$num_cols = 0;
// the number of rows in the table
$num_rows = 0;
// rows are separated by newlines in the matched text
$rows = explode("\n", $matches[1]);
// loop through each row
foreach ($rows as $row) {
// increase the row count
$num_rows ++;
// remove first and last (optional) pipe
$row = substr($row, 1);
if ($row[strlen($row) - 1] == '|') {
$row = substr($row, 0, -1);
}
// cells are separated by pipes
$cells = explode("|", $row);
if (count($cells) == 1 && $cells[0][0] == '=' && ($num_rows == 1 || $num_rows == count($rows)) && ! $caption) {
$caption = trim(trim($cells[0], '='));
// start the caption...
$return .= $this->wiki->addToken(
$this->rule,
array ('type' => 'caption_start')
);
// ...add the content...
$return .= $caption;
// ...and end the caption.
$return .= $this->wiki->addToken(
$this->rule,
array ('type' => 'caption_end')
);
}
else {
// update the column count
if (count($cells) > $num_cols) {
$num_cols = count($cells);
}
// start a new row
$return .= $this->wiki->addToken(
$this->rule,
array('type' => 'row_start')
);
for ($i = 0; $i < count($cells); $i++) {
$cell = $cells[$i];
// by default, cells span only one column (their own)
$span = 1;
$attr = '';
while ($i + 1 < count($cells) && ! strlen($cells[$i + 1])) {
$i++;
$span++;
}
if ($cell[0] == '=') {
$attr = 'header';
$cell = trim($cell, '=');
}
// start a new cell...
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'cell_start',
'attr' => $attr,
'span' => $span
)
);
// ...add the content...
$return .= trim($cell);
// ...and end the cell.
$return .= $this->wiki->addToken(
$this->rule,
array (
'type' => 'cell_end',
'attr' => $attr,
'span' => $span
)
);
}
// end the row
$return .= $this->wiki->addToken(
$this->rule,
array('type' => 'row_end')
);
}
}
// we're done!
return
"\n\n".
$this->wiki->addToken(
$this->rule,
array(
'type' => 'table_start',
'rows' => $num_rows,
'cols' => $num_cols
)
).
$return.
$this->wiki->addToken(
$this->rule,
array(
'type' => 'table_end'
)
).
"\n\n";
}
}
?>

37
Creole/Parse/Tighten.php Normal file
View File

@ -0,0 +1,37 @@
<?php
/**
*
* The rule removes all remaining newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
*
* @license LGPL
*
* @version $Id: Tighten.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Tighten extends Text_Wiki_Parse {
/**
*
* Apply tightening directly to the source text.
*
* @access public
*
*/
function parse()
{
$this->wiki->source = str_replace("\n", '',
$this->wiki->source);
}
}
?>

69
Creole/Parse/Trim.php Normal file
View File

@ -0,0 +1,69 @@
<?php
/**
*
* Trim lines in the source text and compress 3 or more newlines to
* 2 newlines.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Trim extends Text_Wiki_Parse {
/**
*
* Simple parsing method.
*
* @access public
*
*/
function parse()
{
// trim lines
$find = "/ *\n */";
$replace = "\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// trim lines with only one dash or star
$find = "/\n[\-\*]\n/";
$replace = "\n\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// finally, compress all instances of 3 or more newlines
// down to two newlines.
$find = "/\n{3,}/m";
$replace = "\n\n";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// numbered lists
$find = "/(\n[\*\#]*)([\d]+[\.\)]|[\w]\))/s";
$replace = "$1#";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// make ordinal numbers superscripted
$find = "/([\d])(st|nd|rd|th|er|e|re|ers|res|nds|de|des|ère|ème|ères|èmes|o|a)([\W])/";
$replace = "$1^^$2^^$3";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// numbers in parentesis are footnotes and references
$find = "/\(([\d][\d]?)\)/";
$replace = "[$1]";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
// add hr before footnotes
$find = "/(\n+\-\-\-\-+\n*)?(\n\[[\d]+\].*)/s";
$replace = "\n\n----\n\n$2";
$this->wiki->source = preg_replace($find, $replace, $this->wiki->source);
}
}
?>

78
Creole/Parse/Tt.php Normal file
View File

@ -0,0 +1,78 @@
<?php
/**
*
* Parses for monospaced inline text.
*
* @category Text
*
* @package Text_Wiki
*
* @author Tomaiuolo Michele <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Tt.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Tt extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
var $regex = '/{{{(.*?)}}}(?!}|{{{)/';
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* monospaced text. The text itself is encapsulated into a Raw token.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
// remove the sequence }}}{{{
$find = "/}}}{{{/";
$replace = "";
$matches[1] = preg_replace($find, $replace, $matches[1]);
$start = $this->wiki->addToken(
$this->rule,
array('type' => 'start')
);
$raw = $this->wiki->addToken(
'Raw',
array('text' => $matches[1])
);
$end = $this->wiki->addToken(
$this->rule,
array('type' => 'end')
);
return $start . $raw . $end;
}
}
?>

View File

@ -0,0 +1,78 @@
<?php
/**
*
* Parses for italic text.
*
* This class implements a Text_Wiki_Parse to find source text marked for
* underlined as defined by text surrounded by two '_'.
* On parsing, the text itself is left in place, but the starting and ending
* instances of two '^' are replaced with tokens.
*
* @category Text
*
* @package Text_Wiki
*
* @author Paul M. Jones <pmjones@php.net>
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
*/
class Text_Wiki_Parse_Underline extends Text_Wiki_Parse {
/**
*
* The regular expression used to parse the source text and find
* matches conforming to this rule. Used by the parse() method.
*
* @access public
*
* @var string
*
* @see parse()
*
*/
//var $regex = "/__(.*?)__/";
var $regex = "/(?:\_\_(.+?)\_\_|(?:(?<=[\W_\xFF])\_(?![ \_]))(.+?)(?:(?<![ \_])\_(?=[\W_\xFF])))/";
/**
*
* Generates a replacement for the matched text. Token options are:
*
* 'type' => ['start'|'end'] The starting or ending point of the
* superscript text. The text itself is left in the source.
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A pair of delimited tokens to be used as a
* placeholder in the source text surrounding the text to be
* superscripted.
*
*/
function process(&$matches)
{
$text = $matches[1] ? $matches[1] : $matches[2];
if (! $this->wiki->checkInnerTags($text)) {
return $matches[0];
}
$start = $this->wiki->addToken(
'Underline', // $this->rule,
array('type' => 'start')
);
$end = $this->wiki->addToken(
'Underline', // $this->rule,
array('type' => 'end')
);
return $start . $text . $end;
}
}
?>

109
Creole/Parse/Url.php Normal file
View File

@ -0,0 +1,109 @@
<?php
/**
*
* Parse for URLS in the source text.
*
* raw -- http://example.com
* no descr. -- [[http://example.com]]
* described -- [[http://example.com|Example Description]]
*
* When rendering a URL token, this will convert URLs pointing to a .gif,
* .jpg, or .png image into an inline <img /> tag (for the 'xhtml'
* format).
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license LGPL
*
* @version $Id: Url.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
*/
class Text_Wiki_Parse_Url extends Text_Wiki_Parse {
/**
*
* Constructor. Overrides the Text_Wiki_Parse constructor so that we
* can set the $regex property dynamically (we need to include the
* Text_Wiki $delim character).
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
* @param string $name The token name to use for this rule.
*
*/
function Text_Wiki_Parse_Url(&$obj)
{
parent::Text_Wiki_Parse($obj);
$this->regex = '/((?:\[\[ *((?:http:\/\/|https:\/\/|ftp:\/\/|mailto:|\/)[^\|\]\n ]*)( *\| *([^\]\n]*))? *\]\])|((http:\/\/|https:\/\/|ftp:\/\/|mailto:)[^\'\"\n ' . $this->wiki->delim . ']*[A-Za-z0-9\/\?\=\&\~\_]))/';
}
/**
*
* Generates a replacement for the matched text.
*
* Token options are:
*
* 'href' => the URL link href portion
*
* 'text' => the displayed text of the URL link
*
* @access public
*
* @param array &$matches The array of matches from parse().
*
* @return string A token to be used as a placeholder
* in the source text for the preformatted text.
*
*/
function process(&$matches)
{
if (isset($matches[2])) $href = trim($matches[2]);
if (isset($matches[4])) $text = trim($matches[4]);
if (isset($matches[5])) $rawurl = $matches[5];
if (empty($href)) $href = $rawurl;
if (empty($text)) {
$text = $href;
if (strpos($text, '/') === FALSE) {
$text = str_replace('http://', '', $text);
$text = str_replace('mailto:', '', $text);
}
return $this->wiki->addToken(
$this->rule,
array(
'type' => 'inline',
'href' => $href,
'text' => $text
)
);
} else {
return $this->wiki->addToken(
$this->rule,
array(
'type' => 'start',
'href' => $href,
'text' => $text
)
) . $text .
$this->wiki->addToken(
$this->rule,
array(
'type' => 'end',
'href' => $href,
'text' => $text
)
);
}
}
}
?>

72
Creole/Plugin.php Normal file
View File

@ -0,0 +1,72 @@
<?php
/**
* 使用 <a href="http://www.wikicreole.org/" target="_blank">Creole 语法</a>发布文章。改进版本支持中文utf-8 编码)、并除去不必要的标签。
*
* @package Creole 解析器(改进版)
* @author 明城<i.feelinglucky@gmail.com>
* @version 0.2
* @link http://www.gracecode.com/
*/
require_once 'Creole/Creole_Wiki.php';
class Creole_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate() {
Typecho_Plugin::factory('Widget_Abstract_Contents')->excerpt = array('Creole_Plugin', 'parse');
Typecho_Plugin::factory('Widget_Abstract_Contents')->content = array('Creole_Plugin', 'parse');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate() {
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 插件实现方法
*
* @access public
* @return void
*/
public static function parse($text, $widget, $lastResult) {
$text = empty($lastResult) ? $text : $lastResult;
$creole_parse = new Creole_Wiki;
return $creole_parse->transform(trim($text));
}
}

218
Creole/Render.inc.php Normal file
View File

@ -0,0 +1,218 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Base rendering class for parsed and tokenized text.
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Render.inc.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Base rendering class for parsed and tokenized text.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render {
/**
*
* Configuration options for this render rule.
*
* @access public
*
* @var string
*
*/
var $conf = array();
/**
*
* The name of this rule's format.
*
* @access public
*
* @var string
*
*/
var $format = null;
/**
*
* The name of this rule's token array elements.
*
* @access public
*
* @var string
*
*/
var $rule = null;
/**
*
* A reference to the calling Text_Wiki object.
*
* This is needed so that each rule has access to the same source
* text, token set, URLs, interwiki maps, page names, etc.
*
* @access public
*
* @var object
*/
var $wiki = null;
/**
*
* Constructor for this render format or rule.
*
* @access public
*
* @param object &$obj The calling "parent" Text_Wiki object.
*
*/
function Text_Wiki_Render(&$obj)
{
// keep a reference to the calling Text_Wiki object
$this->wiki =& $obj;
// get the config-key-name for this object,
// strip the Text_Wiki_Render_ part
// 01234567890123456
$tmp = get_class($this);
$tmp = substr($tmp, 17);
// split into pieces at the _ mark.
// first part is format, second part is rule.
$part = explode('_', $tmp);
$this->format = isset($part[0]) ? ucwords(strtolower($part[0])) : null;
$this->rule = isset($part[1]) ? ucwords(strtolower($part[1])) : null;
// is there a format but no rule?
// then this is the "main" render object, with
// pre() and post() methods.
if ($this->format && ! $this->rule &&
isset($this->wiki->formatConf[$this->format]) &&
is_array($this->wiki->formatConf[$this->format])) {
// this is a format render object
$this->conf = array_merge(
$this->conf,
$this->wiki->formatConf[$this->format]
);
}
// is there a format and a rule?
if ($this->format && $this->rule &&
isset($this->wiki->renderConf[$this->format][$this->rule]) &&
is_array($this->wiki->renderConf[$this->format][$this->rule])) {
// this is a rule render object
$this->conf = array_merge(
$this->conf,
$this->wiki->renderConf[$this->format][$this->rule]
);
}
}
/**
*
* Simple method to safely get configuration key values.
*
* @access public
*
* @param string $key The configuration key.
*
* @param mixed $default If the key does not exist, return this value
* instead.
*
* @return mixed The configuration key value (if it exists) or the
* default value (if not).
*
*/
function getConf($key, $default = null)
{
if (isset($this->conf[$key])) {
return $this->conf[$key];
} else {
return $default;
}
}
/**
*
* Simple method to wrap a configuration in an sprintf() format.
*
* @access public
*
* @param string $key The configuration key.
*
* @param string $format The sprintf() format string.
*
* @return mixed The formatted configuration key value (if it exists)
* or null (if it does not).
*
*/
function formatConf($format, $key)
{
if (isset($this->conf[$key])) {
//$this->conf[$key] needs a textEncode....at least for Xhtml output...
return sprintf($format, $this->conf[$key]);
} else {
return null;
}
}
/**
* Default method to render url
*
* @access public
* @param string $urlChunk a part of an url to render
* @return rendered url
*
*/
function urlEncode($urlChunk)
{
return rawurlencode($urlChunk);
}
/**
* Default method to render text (htmlspecialchars)
*
* @access public
* @param string $text the text to render
* @return rendered text
*
*/
function textEncode($text)
{
return htmlspecialchars($text);
}
}
?>

16
Creole/Render/Plain.php Normal file
View File

@ -0,0 +1,16 @@
<?php
class Text_Wiki_Render_Plain extends Text_Wiki_Render {
function pre()
{
return;
}
function post()
{
return;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
/**
*
* This class renders an anchor target name in XHTML.
*
* @author Manuel Holtgrewe <purestorm at ggnore dot net>
*
* @author Paul M. Jones <pmjones at ciaweb dot net>
*
* @package Text_Wiki
*
*/
class Text_Wiki_Render_Plain_Anchor extends Text_Wiki_Render {
function token($options)
{
return $options['name'];
}
}
?>

View File

@ -0,0 +1,39 @@
<?php
class Text_Wiki_Render_Plain_Blockquote extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$level = $options['level'];
// set up indenting so that the results look nice; we do this
// in two steps to avoid str_pad mathematics. ;-)
$pad = str_pad('', $level + 1, "\t");
$pad = str_replace("\t", ' ', $pad);
// starting
if ($type == 'start') {
return "\n$pad";
}
// ending
if ($type == 'end') {
return "\n$pad";
}
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Bold extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Box rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders a box drawn in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Box extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return '';
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Break extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n";
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Center extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Code extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n" . $options['text'] . "\n\n";
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Colortext extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,59 @@
<?php
class Text_Wiki_Render_Plain_Deflist extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$pad = " ";
switch ($type) {
case 'list_start':
return "\n";
break;
case 'list_end':
return "\n\n";
break;
case 'term_start':
// done!
return $pad;
break;
case 'term_end':
return "\n";
break;
case 'narr_start':
// done!
return $pad . $pad;
break;
case 'narr_end':
return "\n";
break;
default:
return '';
}
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Delete extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Delimiter extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Embed extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return strip_tags($options['text']);
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Emphasis extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,44 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* BBCode: extra Font rules renderer to size the text
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Font.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Font rule render class (used for BBCode)
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
* @see Text_Wiki::Text_Wiki_Render()
*/
class Text_Wiki_Render_Plain_Font extends Text_Wiki_Render {
/**
* Renders a token into text matching the requested format.
* process the font size option
*
* @access public
* @param array $options The "options" portion of the token (second element).
* @return string The text rendered from the token options.
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Freelink extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

View File

@ -0,0 +1,39 @@
<?php
// $Id: Function.php 182 2008-09-14 15:56:00Z i.feelinglucky $
class Text_Wiki_Render_Plain_Function extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
extract($options); // access, return, name, params, throws
$output = "$access $return $name ( ";
foreach ($params as $key => $val) {
$output .= "{$val['type']} {$val['descr']} {$val['default']} ";
}
$output .= ') ';
foreach ($throws as $key => $val) {
$output .= "{$val['type']} {$val['descr']} ";
}
return $output;
}
}
?>

View File

@ -0,0 +1,14 @@
<?php
class Text_Wiki_Render_Plain_Heading extends Text_Wiki_Render {
function token($options)
{
if ($options['type'] == 'end') {
return "\n\n";
} else {
return "\n";
}
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Horiz extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\n";
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Html extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return strip_tags($options['text']);
}
}
?>

View File

@ -0,0 +1,22 @@
<?php
class Text_Wiki_Render_Plain_Image extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,8 @@
<?php
class Text_Wiki_Render_Plain_Include extends Text_Wiki_Render {
function token()
{
return '';
}
}
?>

View File

@ -0,0 +1,29 @@
<?php
class Text_Wiki_Render_Plain_Interwiki extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if (isset($options['url'])) {
// calculated by the parser (e.g. Mediawiki)
$href = $options['url'];
} else {
$href = $options['site'] . ':' . $options['page'];
}
return $options['text'] . ' (' . $href . ')';
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Italic extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,68 @@
<?php
class Text_Wiki_Render_Plain_List extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* This rendering method is syntactically and semantically compliant
* with XHTML 1.1 in that sub-lists are part of the previous list item.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
// make nice variables (type, level, count)
extract($options);
// set up indenting so that the results look nice; we do this
// in two steps to avoid str_pad mathematics. ;-)
$pad = str_pad('', $level, "\t");
$pad = str_replace("\t", ' ', $pad);
switch ($type) {
case 'bullet_list_start':
break;
case 'bullet_list_end':
if ($level == 0) {
return "\n\n";
}
break;
case 'number_list_start':
break;
case 'number_list_end':
if ($level == 0) {
return "\n\n";
}
break;
case 'bullet_item_start':
case 'number_item_start':
return "\n$pad";
break;
case 'bullet_item_end':
case 'number_item_end':
default:
// ignore item endings and all other types.
// item endings are taken care of by the other types
// depending on their place in the list.
return;
break;
}
}
}
?>

View File

@ -0,0 +1,12 @@
<?php
class Text_Wiki_Render_Plain_Newline extends Text_Wiki_Render {
function token($options)
{
return "\n";
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Page rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Page.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders page markers in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Page extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return "\x0C";
}
}
?>

View File

@ -0,0 +1,31 @@
<?php
class Text_Wiki_Render_Plain_Paragraph extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
extract($options); //type
if ($type == 'start') {
return '';
}
if ($type == 'end') {
return "\n\n";
}
}
}
?>

View File

@ -0,0 +1,25 @@
<?php
class Text_Wiki_Render_Plain_Phplookup extends Text_Wiki_Render {
var $conf = array('target' => '_blank');
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return trim($options['text']);
}
}
?>

View File

@ -0,0 +1,49 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Plugin rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Plugin.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders wiki plugins in Plain. (empty)
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Plugin extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
* Plugins produce wiki markup so are processed by parsing, no tokens produced
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return '';
}
}
?>

View File

@ -0,0 +1,40 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Paul M. Jones <pmjones@php.net> |
// +----------------------------------------------------------------------+
//
// $Id: Prefilter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
/**
*
* This class implements a Text_Wiki_Render_Xhtml to "pre-filter" source text so
* that line endings are consistently \n, lines ending in a backslash \
* are concatenated with the next line, and tabs are converted to spaces.
*
* @author Paul M. Jones <pmjones@php.net>
*
* @package Text_Wiki
*
*/
class Text_Wiki_Render_Plain_Prefilter extends Text_Wiki_Render {
function token()
{
return '';
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Preformatted rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Preformatted.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders preformated text in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Preformatted extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Raw extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Revise extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,44 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Smiley rule Plain renderer
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Smiley.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Smiley rule Plain render class
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
* @see Text_Wiki::Text_Wiki_Render()
*/
class Text_Wiki_Render_Plain_Smiley extends Text_Wiki_Render {
/**
* Renders a token into text matching the requested format.
* process the Smileys
*
* @access public
* @param array $options The "options" portion of the token (second element).
* @return string The text rendered from the token options.
*/
function token($options)
{
return $options['symbol'];
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Specialchar rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Specialchar.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders special characters in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_SpecialChar extends Text_Wiki_Render {
var $types = array('~bs~' => '\\',
'~hs~' => ' ',
'~amp~' => '&',
'~ldq~' => '"',
'~rdq~' => '"',
'~lsq~' => "'",
'~rsq~' => "'",
'~c~' => '©',
'~--~' => '-',
'" -- "' => '-',
'&quot; -- &quot;' => '-',
'~lt~' => '<',
'~gt~' => '>');
function token($options)
{
if (isset($this->types[$options['char']])) {
return $this->types[$options['char']];
} else {
return $options['char'];
}
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Strong extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Subscript rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Subscript.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders subscript text in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Subscript extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return '';
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Superscript extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,65 @@
<?php
class Text_Wiki_Render_Plain_Table extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
// make nice variable names (type, attr, span)
extract($options);
$pad = ' ';
switch ($type) {
case 'table_start':
return;
break;
case 'table_end':
return;
break;
case 'caption_start':
return;
break;
case 'caption_end':
return "\n";
break;
case 'row_start':
return;
break;
case 'row_end':
return " ||\n";
break;
case 'cell_start':
return " || ";
break;
case 'cell_end':
return;
break;
default:
return '';
}
}
}
?>

View File

@ -0,0 +1,10 @@
<?php
class Text_Wiki_Render_Plain_Tighten extends Text_Wiki_Render {
function token()
{
return '';
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Titlebar rule end renderer for Plain
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Titlebar.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders a title bar in Plain.
*
* @category Text
* @package Text_Wiki
* @author Bertrand Gugger <bertrand@toggg.com>
* @copyright 2005 bertrand Gugger
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Plain_Titlebar extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
return '***** ';
}
if ($options['type'] == 'end') {
return " *****\n";
}
}
}
?>

View File

@ -0,0 +1,39 @@
<?php
class Text_Wiki_Render_Plain_Toc extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
// type, count, level
extract($options);
if ($type == 'item_start') {
// build some indenting spaces for the text
$indent = ($level - 2) * 4;
$pad = str_pad('', $indent);
return $pad;
}
if ($type == 'item_end') {
return "\n";
}
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_tt extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,23 @@
<?php
class Text_Wiki_Render_Plain_Underline extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return;
}
}
?>

View File

@ -0,0 +1,29 @@
<?php
class Text_Wiki_Render_Plain_Url extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start' || $options['type'] == 'end') {
return '';
} else {
return $options['text'];
}
}
}
?>

View File

@ -0,0 +1,24 @@
<?php
class Text_Wiki_Render_Plain_Wikilink extends Text_Wiki_Render {
/**
*
* Renders a token into plain text.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

109
Creole/Render/Xhtml.php Normal file
View File

@ -0,0 +1,109 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Format class for the Xhtml rendering
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Xhtml.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* Format class for the Xhtml rendering
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml extends Text_Wiki_Render {
var $conf = array(
'translate' => HTML_ENTITIES,
'quotes' => ENT_COMPAT,
//'charset' => 'ISO-8859-1'
'charset' => 'UTF-8'
);
function pre()
{
$this->wiki->source = $this->textEncode($this->wiki->source);
}
function post()
{
return;
}
/**
* Method to render text
*
* @access public
* @param string $text the text to render
* @return rendered text
*
*/
function textEncode($text)
{
// attempt to translate HTML entities in the source.
// get the config options.
$type = $this->getConf('translate', HTML_ENTITIES);
$quotes = $this->getConf('quotes', ENT_COMPAT);
//$charset = $this->getConf('charset', 'ISO-8859-1');
$charset = $this->getConf('charset', 'UTF-8');
// have to check null and false because HTML_ENTITIES is a zero
if ($type === HTML_ENTITIES) {
// keep a copy of the translated version of the delimiter
// so we can convert it back.
$new_delim = htmlentities($this->wiki->delim, $quotes, $charset);
// convert the entities. we silence the call here so that
// errors about charsets don't pop up, per counsel from
// Jan at Horde. (http://pear.php.net/bugs/bug.php?id=4474)
$text = @htmlentities(
$text,
$quotes,
$charset
);
// re-convert the delimiter
$text = str_replace(
$new_delim, $this->wiki->delim, $text
);
} elseif ($type === HTML_SPECIALCHARS) {
// keep a copy of the translated version of the delimiter
// so we can convert it back.
$new_delim = htmlspecialchars($this->wiki->delim, $quotes,
$charset);
// convert the entities. we silence the call here so that
// errors about charsets don't pop up, per counsel from
// Jan at Horde. (http://pear.php.net/bugs/bug.php?id=4474)
$text = @htmlspecialchars(
$text,
$quotes,
$charset
);
// re-convert the delimiter
$text = str_replace(
$new_delim, $this->wiki->delim, $text
);
}
return $text;
}
}
?>

View File

@ -0,0 +1,54 @@
<?php
/**
*
* Address rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
*
* @package Text_Wiki
*
* @author Michele Tomaiuolo <tomamic@yahoo.it>
*
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
*
* @version CVS: $Id: Address.php 182 2008-09-14 15:56:00Z i.feelinglucky $
*
* @link http://pear.php.net/package/Text_Wiki
*
*/
class Text_Wiki_Render_Xhtml_Address extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
$css = $this->formatConf(' class="%s"', 'css');
return "<address$css>";
}
if ($options['type'] == 'end') {
return '</address>';
}
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Anchor rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Anchor.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders an anchor target name in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Anchor extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
function token($options)
{
extract($options); // $type, $name
if ($type == 'start') {
$css = $this->formatConf(' class="%s"', 'css');
$format = "<a$css id=\"%s\">";
return sprintf($format, $this->textEncode($name));
}
if ($type == 'end') {
return '</a>';
}
}
}
?>

View File

@ -0,0 +1,72 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Blockquote rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Blockquote.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders a blockquote in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Blockquote extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$level = $options['level'];
// set up indenting so that the results look nice; we do this
// in two steps to avoid str_pad mathematics. ;-)
$pad = str_pad('', $level, "\t");
$pad = str_replace("\t", ' ', $pad);
// pick the css type
$css = $this->formatConf(' class="%s"', 'css');
if (isset($options['css'])) {
$css = ' class="' . $options['css']. '"';
}
// starting
if ($type == 'start') {
return "$pad<blockquote$css>";
}
// ending
if ($type == 'end') {
return $pad . "</blockquote>\n";
}
}
}
?>

View File

@ -0,0 +1,57 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Bold rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Bold.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders bold text in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Bold extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
$css = $this->formatConf(' class="%s"', 'css');
return "<b$css>";
}
if ($options['type'] == 'end') {
return '</b>';
}
}
}
?>

View File

@ -0,0 +1,62 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Box rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Box.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders a box drawn in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Box extends Text_Wiki_Render {
var $conf = array(
'css' => 'simplebox'
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
if ($options['css']) {
$css = ' class="' . $options['css']. '"';
}
else {
$css = $this->formatConf(' class="%s"', 'css');
}
return "<div $css>";
}
if ($options['type'] == 'end') {
return '</div>';
}
}
}
?>

View File

@ -0,0 +1,52 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Break rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Break.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders line breaks in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Break extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$css = $this->formatConf(' class="%s"', 'css');
return "<br$css />\n";
}
}
?>

View File

@ -0,0 +1,62 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Center rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Center.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders centered content in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Center extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
$css = $this->getConf('css');
if ($css) {
return "<div class=\"$css\">";
}
else {
return '<div style="text-align: center;">';
}
}
if ($options['type'] == 'end') {
return '</div>';
}
}
}
?>

View File

@ -0,0 +1,133 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Code rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Code.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders code blocks in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Code extends Text_Wiki_Render {
var $conf = array(
'css' => null, // class for <pre>
'css_code' => null, // class for generic <code>
'css_php' => null, // class for PHP <code>
'css_html' => null, // class for HTML <code>
'css_filename' => null // class for optional filename <div>
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$text = $options['text'];
$attr = $options['attr'];
$type = strtolower($attr['type']);
$css = $this->formatConf(' class="%s"', 'css');
$css_code = $this->formatConf(' class="%s"', 'css_code');
$css_php = $this->formatConf(' class="%s"', 'css_php');
$css_html = $this->formatConf(' class="%s"', 'css_html');
$css_filename = $this->formatConf(' class="%s"', 'css_filename');
if ($type == 'php') {
if (substr($options['text'], 0, 5) != '<?php') {
// PHP code example:
// add the PHP tags
$text = "<?php\n" . $options['text'] . "\n?>"; // <?php
}
// convert tabs to four spaces
$text = str_replace("\t", " ", $text);
// colorize the code block (also converts HTML entities and adds
// <code>...</code> tags)
ob_start();
highlight_string($text);
$text = ob_get_contents();
ob_end_clean();
// replace <br /> tags with simple newlines.
// replace non-breaking space with simple spaces.
// translate HTML <font> and color to XHTML <span> and style.
// courtesy of research by A. Kalin :-).
$map = array(
'<br />' => "\n",
'&nbsp;' => ' ',
'<font' => '<span',
'</font>' => '</span>',
'color="' => 'style="color:'
);
$text = strtr($text, $map);
// get rid of the last newline inside the code block
// (becuase higlight_string puts one there)
if (substr($text, -8) == "\n</code>") {
$text = substr($text, 0, -8) . "</code>";
}
// replace all <code> tags with classed tags
if ($css_php) {
$text = str_replace('<code>', "<code$css_php>", $text);
}
// done
$text = "<pre$css>$text</pre>";
} elseif ($type == 'html' || $type == 'xhtml') {
// HTML code example:
// add <html> opening and closing tags,
// convert tabs to four spaces,
// convert entities.
$text = str_replace("\t", " ", $text);
$text = "<html>\n$text\n</html>";
$text = $this->textEncode($text);
$text = "<pre$css><code$css_html>$text</code></pre>";
} else {
// generic code example:
// convert tabs to four spaces,
// convert entities.
$text = str_replace("\t", " ", $text);
$text = $this->textEncode($text);
$text = "<pre$css><code$css_code>$text</code></pre>";
}
if ($css_filename && isset($attr['filename'])) {
$text = "<div$css_filename>" .
$attr['filename'] . '</div>' . $text;
}
return "\n$text\n\n";
}
}
?>

View File

@ -0,0 +1,79 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Colortext rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Colortext.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders colored text in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Colortext extends Text_Wiki_Render {
var $colors = array(
'aqua',
'black',
'blue',
'fuchsia',
'gray',
'green',
'lime',
'maroon',
'navy',
'olive',
'purple',
'red',
'silver',
'teal',
'white',
'yellow'
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$color = $options['color'];
if (! in_array($color, $this->colors) && $color{0} != '#') {
$color = '#' . $color;
}
if ($type == 'start') {
return "<span style=\"color: $color;\">";
}
if ($options['type'] == 'end') {
return '</span>';
}
}
}
?>

View File

@ -0,0 +1,87 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Deflist rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Deflist.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders definition lists in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Deflist extends Text_Wiki_Render {
var $conf = array(
'css_dl' => null,
'css_dt' => null,
'css_dd' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
$type = $options['type'];
$pad = " ";
switch ($type) {
case 'list_start':
$css = $this->formatConf(' class="%s"', 'css_dl');
return "<dl$css>\n";
break;
case 'list_end':
return "</dl>\n\n";
break;
case 'term_start':
$css = $this->formatConf(' class="%s"', 'css_dt');
return $pad . "<dt$css>";
break;
case 'term_end':
return "</dt>\n";
break;
case 'narr_start':
$css = $this->formatConf(' class="%s"', 'css_dd');
return $pad . $pad . "<dd$css>";
break;
case 'narr_end':
return "</dd>\n";
break;
default:
return '';
}
}
}
?>

View File

@ -0,0 +1,58 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Underline rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Delete.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders underlined text in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Delete extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
//$css = $this->formatConf(' class="%s"', 'css');
//return "<u$css>";
//return "<span style=\"text-decoration:underline;\">";
return "<del>";
}
if ($options['type'] == 'end') {
return '</del>';
}
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Delimiter rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Delimiter.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class set back the replaced delimiters in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Delimiter extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Embed rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Embed.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class replaces the embedded php output in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Embed extends Text_Wiki_Render {
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
return $options['text'];
}
}
?>

View File

@ -0,0 +1,58 @@
<?php
// vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
/**
* Emphasis rule end renderer for Xhtml
*
* PHP versions 4 and 5
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version CVS: $Id: Emphasis.php 182 2008-09-14 15:56:00Z i.feelinglucky $
* @link http://pear.php.net/package/Text_Wiki
*/
/**
* This class renders emphasized text in XHTML.
*
* @category Text
* @package Text_Wiki
* @author Paul M. Jones <pmjones@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Wiki
*/
class Text_Wiki_Render_Xhtml_Emphasis extends Text_Wiki_Render {
var $conf = array(
'css' => null
);
/**
*
* Renders a token into text matching the requested format.
*
* @access public
*
* @param array $options The "options" portion of the token (second
* element).
*
* @return string The text rendered from the token options.
*
*/
function token($options)
{
if ($options['type'] == 'start') {
$css = $this->formatConf(' class="%s"', 'css');
return "<em$css>";
}
if ($options['type'] == 'end') {
return '</em>';
}
}
}
?>

Some files were not shown because too many files have changed in this diff Show More