mirror of
https://github.com/UnickSoft/graphonline.git
synced 2026-02-16 10:40:57 +00:00
first commit
This commit is contained in:
544
wiki/scripts/feeds.php
Executable file
544
wiki/scripts/feeds.php
Executable file
@@ -0,0 +1,544 @@
|
||||
<?php if (!defined('PmWiki')) exit();
|
||||
/* Copyright 2005-2010 Patrick R. Michaud (pmichaud@pobox.com)
|
||||
This file is part of PmWiki; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version. See pmwiki.php for full details.
|
||||
|
||||
This script provides a number of syndication feed and xml-based
|
||||
metadata options to PmWiki, including Atom, RSS 2.0, RSS 1.0 (RDF),
|
||||
and the Dublin Core Metadata extensions. This module is typically
|
||||
activated from a local configuration file via a line such as
|
||||
|
||||
if ($action == 'atom') include_once("$FarmD/scripts/feeds.php");
|
||||
if ($action == 'dc') include_once("$FarmD/scripts/feeds.php");
|
||||
|
||||
When enabled, ?action=atom, ?action=rss, and ?action=rdf produce
|
||||
syndication feeds based on any wikitrail contained in the page,
|
||||
or, for Category pages, on the pages in the category. The feeds
|
||||
are generated using pagelist, thus one can include parameters such
|
||||
as count=, list=, order=, etc. in the url to adjust the feed output.
|
||||
|
||||
?action=dc will normally generate Dublin Core Metadata for the
|
||||
current page only, but placing a group=, trail=, or link= argument
|
||||
in the url causes it to generate metadata for all pages in the
|
||||
associated group, trail, or backlink.
|
||||
|
||||
There are a large number of customizations available, most of which
|
||||
are controlled by the $FeedFmt array. Elements $FeedFmt look like
|
||||
|
||||
$FeedFmt['atom']['feed']['rights'] = 'All Rights Reserved';
|
||||
|
||||
where the first index corresponds to the action (?action=atom),
|
||||
the second index indicates a per-feed or per-item element, and
|
||||
the third index is the name of the element being generated.
|
||||
The above setting would therefore generate a
|
||||
"<rights>All Rights Reserved</rights>" in the feed for
|
||||
?action=atom. If the value of an entry begins with a '<',
|
||||
then feeds.php doesn't automatically add the tag around it.
|
||||
Elements can also be callable functions which are called to
|
||||
generate the appropriate output.
|
||||
|
||||
For example, to set the RSS 2.0 <author> element to the
|
||||
value of the last author to modify a page, one can set
|
||||
(in local/config.php):
|
||||
|
||||
$FeedFmt['rss']['item']['author'] = '$LastModifiedBy';
|
||||
|
||||
To use the RSS 2.0 <description> element to contain the
|
||||
change summary of the most recent edit, set
|
||||
|
||||
$FeedFmt['rss']['item']['description'] = '$LastModifiedSummary';
|
||||
|
||||
Feeds.php can also be combined with attachments to support
|
||||
podcasting via ?action=rss. Any page such as "PageName"
|
||||
that has an mp3 attachment with the same name as the page
|
||||
("PageName.mp3") will have an appropriate <enclosure> element
|
||||
in the feed output. The set of allowed attachments can be
|
||||
extended using the $RSSEnclosureFmt array:
|
||||
|
||||
$RSSEnclosureFmt = array('{$Name}.mp3', '{$Name}.mp4');
|
||||
|
||||
References:
|
||||
http://www.atomenabled.org/developers/syndication/
|
||||
http://dublincore.org/documents/dcmes-xml/
|
||||
http://en.wikipedia.org/wiki/Podcasting
|
||||
*/
|
||||
|
||||
## Settings for ?action=atom
|
||||
SDVA($FeedFmt['atom']['feed'], array(
|
||||
'_header' => 'Content-type: text/xml; charset="$Charset"',
|
||||
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">'."\n",
|
||||
'_end' => "</feed>\n",
|
||||
'title' => '$WikiTitle',
|
||||
'link' => '<link rel="self" href="{$PageUrl}?action=atom" />',
|
||||
'id' => '{$PageUrl}?action=atom',
|
||||
'updated' => '$FeedISOTime',
|
||||
'author' => "<author><name>$WikiTitle</name></author>\n",
|
||||
'generator' => '$Version',
|
||||
'logo' => '$PageLogoUrl'));
|
||||
SDVA($FeedFmt['atom']['item'], array(
|
||||
'_start' => "<entry>\n",
|
||||
'id' => '{$PageUrl}',
|
||||
'title' => '{$Title}',
|
||||
'updated' => '$ItemISOTime',
|
||||
'link' => "<link rel=\"alternate\" href=\"{\$PageUrl}\" />\n",
|
||||
'author' => "<author><name>{\$LastModifiedBy}</name></author>\n",
|
||||
'summary' => '{$Description}',
|
||||
'category' => "<category term=\"\$Category\" />\n",
|
||||
'_end' => "</entry>\n"));
|
||||
|
||||
## Settings for ?action=dc
|
||||
SDVA($FeedFmt['dc']['feed'], array(
|
||||
'_header' => 'Content-type: text/xml; charset="$Charset"',
|
||||
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
|
||||
<!DOCTYPE rdf:RDF PUBLIC "-//DUBLIN CORE//DCMES DTD 2002/07/31//EN"
|
||||
"http://dublincore.org/documents/2002/07/31/dcmes-xml/dcmes-xml-dtd.dtd">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n",
|
||||
'_end' => "</rdf:RDF>\n"));
|
||||
SDVA($FeedFmt['dc']['item'], array(
|
||||
'_start' => "<rdf:Description rdf:about=\"{\$PageUrl}\">\n",
|
||||
'dc:title' => '{$Title}',
|
||||
'dc:identifier' => '{$PageUrl}',
|
||||
'dc:date' => '$ItemISOTime',
|
||||
'dc:type' => 'Text',
|
||||
'dc:format' => 'text/html',
|
||||
'dc:description' => '{$Description}',
|
||||
'dc:subject' => "<dc:subject>\$Category</dc:subject>\n",
|
||||
'dc:publisher' => '$WikiTitle',
|
||||
'dc:author' => '{$LastModifiedBy}',
|
||||
'_end' => "</rdf:Description>\n"));
|
||||
|
||||
## RSS 2.0 settings for ?action=rss
|
||||
SDVA($FeedFmt['rss']['feed'], array(
|
||||
'_header' => 'Content-type: text/xml; charset="$Charset"',
|
||||
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>'."\n",
|
||||
'_end' => "</channel>\n</rss>\n",
|
||||
'title' => '$WikiTitle | {$Group} / {$Title}',
|
||||
'link' => '{$PageUrl}?action=rss',
|
||||
'description' => '{$Group}.{$Title}',
|
||||
'lastBuildDate' => '$FeedRSSTime'));
|
||||
SDVA($FeedFmt['rss']['item'], array(
|
||||
'_start' => "<item>\n",
|
||||
'_end' => "</item>\n",
|
||||
'title' => '{$Group} / {$Title}',
|
||||
'link' => '{$PageUrl}',
|
||||
'description' => '{$Description}',
|
||||
'dc:contributor' => '{$LastModifiedBy}',
|
||||
'dc:date' => '$ItemISOTime',
|
||||
'pubDate' => '$ItemRSSTime',
|
||||
'enclosure' => 'RSSEnclosure'));
|
||||
|
||||
## RDF 1.0, for ?action=rdf
|
||||
SDVA($FeedFmt['rdf']['feed'], array(
|
||||
'_header' => 'Content-type: text/xml; charset="$Charset"',
|
||||
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
|
||||
<rdf:RDF xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel rdf:about="{$PageUrl}?action=rdf">'."\n",
|
||||
'title' => '$WikiTitle | {$Group} / {$Title}',
|
||||
'link' => '{$PageUrl}?action=rdf',
|
||||
'description' => '{$Group}.{$Title}',
|
||||
'dc:date' => '$FeedISOTime',
|
||||
'items' => "<items>\n<rdf:Seq>\n\$FeedRDFSeq</rdf:Seq>\n</items>\n",
|
||||
'_items' => "</channel>\n",
|
||||
'_end' => "</rdf:RDF>\n"));
|
||||
SDVA($FeedFmt['rdf']['item'], array(
|
||||
'_start' => "<item rdf:about=\"{\$PageUrl}\">\n",
|
||||
'_end' => "</item>\n",
|
||||
'title' => '$WikiTitle | {$Group} / {$Title}',
|
||||
'link' => '{$PageUrl}',
|
||||
'description' => '{$Description}',
|
||||
'dc:date' => '$ItemISOTime'));
|
||||
|
||||
foreach(array_keys($FeedFmt) as $k) {
|
||||
SDV($HandleActions[$k], 'HandleFeed');
|
||||
SDV($HandleAuth[$k], 'read');
|
||||
}
|
||||
|
||||
function HandleFeed($pagename, $auth = 'read') {
|
||||
global $FeedFmt, $action, $PCache, $FmtV, $TimeISOZFmt, $RSSTimeFmt,
|
||||
$FeedPageListOpt, $FeedCategoryOpt, $FeedTrailOpt,
|
||||
$FeedDescPatterns, $CategoryGroup, $EntitiesTable;
|
||||
SDV($RSSTimeFmt, 'D, d M Y H:i:s \G\M\T');
|
||||
SDV($FeedDescPatterns,
|
||||
array('/<[^>]*$/' => ' ', '/\\w+$/' => '', '/<[^>]+>/' => ''));
|
||||
$FeedPageListOpt = (array)@$FeedPageListOpt;
|
||||
SDVA($FeedCategoryOpt, array('link' => $pagename));
|
||||
SDVA($FeedTrailOpt, array('trail' => $pagename, 'count' => 10));
|
||||
|
||||
$f = $FeedFmt[$action];
|
||||
$page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
|
||||
if (!$page) Abort("?cannot generate feed");
|
||||
$feedtime = $page['time'];
|
||||
|
||||
# determine list of pages to display
|
||||
if (@($_REQUEST['trail'] || $_REQUEST['group'] || $_REQUEST['link']
|
||||
|| $_REQUEST['name']))
|
||||
$opt = $FeedPageListOpt;
|
||||
else if (preg_match("/^$CategoryGroup\\./", $pagename))
|
||||
$opt = $FeedCategoryOpt;
|
||||
else if ($action != 'dc') $opt = $FeedTrailOpt;
|
||||
else {
|
||||
PCache($pagename, $page);
|
||||
$pagelist = array($pagename);
|
||||
}
|
||||
if (!@$pagelist) {
|
||||
$opt = array_merge($opt, @$_REQUEST);
|
||||
$pagelist = MakePageList($pagename, $opt, 0);
|
||||
}
|
||||
|
||||
# process list of pages in feed
|
||||
$rdfseq = '';
|
||||
$pl = array();
|
||||
foreach($pagelist as $pn) {
|
||||
if (!PageExists($pn)) continue;
|
||||
if (!isset($PCache[$pn]['time']))
|
||||
{ $page = ReadPage($pn, READPAGE_CURRENT); PCache($pn, $page); }
|
||||
$pc = & $PCache[$pn];
|
||||
$pl[] = $pn;
|
||||
$rdfseq .= FmtPageName("<rdf:li resource=\"{\$PageUrl}\" />\n", $pn);
|
||||
if ($pc['time'] > $feedtime) $feedtime = $pc['time'];
|
||||
if (@$opt['count'] && count($pl) >= $opt['count']) break;
|
||||
}
|
||||
$pagelist = $pl;
|
||||
|
||||
$FmtV['$FeedRDFSeq'] = $rdfseq;
|
||||
$FmtV['$FeedISOTime'] = gmstrftime($TimeISOZFmt, $feedtime);
|
||||
$FmtV['$FeedRSSTime'] = gmdate($RSSTimeFmt, $feedtime);
|
||||
# format start of feed
|
||||
$out = FmtPageName($f['feed']['_start'], $pagename);
|
||||
|
||||
# format feed elements
|
||||
foreach($f['feed'] as $k => $v) {
|
||||
if ($k{0} == '_' || !$v) continue;
|
||||
$x = FmtPageName($v, $pagename);
|
||||
if (!$x) continue;
|
||||
$out .= ($v{0} == '<') ? $x : "<$k>$x</$k>\n";
|
||||
}
|
||||
|
||||
# format items in feed
|
||||
if (@$f['feed']['_items'])
|
||||
$out .= FmtPageName($f['feed']['_items'], $pagename);
|
||||
foreach($pagelist as $pn) {
|
||||
$page = &$PCache[$pn];
|
||||
$FmtV['$ItemDesc'] = @$page['description'];
|
||||
$FmtV['$ItemISOTime'] = gmstrftime($TimeISOZFmt, $page['time']);
|
||||
$FmtV['$ItemRSSTime'] = gmdate($RSSTimeFmt, $page['time']);
|
||||
|
||||
$out .= FmtPageName($f['item']['_start'], $pn);
|
||||
foreach((array)@$f['item'] as $k => $v) {
|
||||
if ($k{0} == '_' || !$v) continue;
|
||||
if (is_callable($v)) { $out .= $v($pn, $page, $k); continue; }
|
||||
if (strpos($v, '$LastModifiedBy') !== false && !@$page['author'])
|
||||
continue;
|
||||
if (strpos($v, '$Category') !== false) {
|
||||
if (preg_match_all("/(?<=^|,)$CategoryGroup\\.([^,]+)/",
|
||||
@$page['targets'], $match)) {
|
||||
foreach($match[1] as $c) {
|
||||
$FmtV['$Category'] = $c;
|
||||
$out .= FmtPageName($v, $pn);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$x = FmtPageName($v, $pn);
|
||||
if (!$x) continue;
|
||||
$out .= ($v{0} == '<') ? $x : "<$k>$x</$k>\n";
|
||||
}
|
||||
$out .= FmtPageName($f['item']['_end'], $pn);
|
||||
}
|
||||
$out .= FmtPageName($f['feed']['_end'], $pagename);
|
||||
foreach((array)@$f['feed']['_header'] as $fmt)
|
||||
header(FmtPageName($fmt, $pagename));
|
||||
print str_replace(array_keys($EntitiesTable),
|
||||
array_values($EntitiesTable), $out);
|
||||
}
|
||||
|
||||
## RSSEnclosure is called in ?action=rss to generate <enclosure>
|
||||
## tags for any pages that have an attached "PageName.mp3" file.
|
||||
## The set of attachments to enclose is given by $RSSEnclosureFmt.
|
||||
function RSSEnclosure($pagename, &$page, $k) {
|
||||
global $RSSEnclosureFmt, $UploadFileFmt, $UploadExts;
|
||||
if (!function_exists('MakeUploadName')) return '';
|
||||
SDV($RSSEnclosureFmt, array('{$Name}.mp3'));
|
||||
$encl = '';
|
||||
foreach((array)$RSSEnclosureFmt as $fmt) {
|
||||
$path = FmtPageName($fmt, $pagename);
|
||||
$upname = MakeUploadName($pagename, $path);
|
||||
$filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
|
||||
if (file_exists($filepath)) {
|
||||
$length = filesize($filepath);
|
||||
$type = @$UploadExts[preg_replace('/.*\\./', '', $filepath)];
|
||||
$url = LinkUpload($pagename, 'Attach:', $path, '', '', '$LinkUrl');
|
||||
$encl .= "<$k url='$url' length='$length' type='$type' />";
|
||||
}
|
||||
}
|
||||
return $encl;
|
||||
}
|
||||
|
||||
## Since most feeds don't understand html character entities, we
|
||||
## convert the common ones to their numeric form here.
|
||||
SDVA($EntitiesTable, array(
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
|
||||
' ' => ' ',
|
||||
'¡' => '¡',
|
||||
'¢' => '¢',
|
||||
'£' => '£',
|
||||
'¤' => '¤',
|
||||
'¥' => '¥',
|
||||
'¦' => '¦',
|
||||
'§' => '§',
|
||||
'¨' => '¨',
|
||||
'©' => '©',
|
||||
'ª' => 'ª',
|
||||
'«' => '«',
|
||||
'¬' => '¬',
|
||||
'­' => '­',
|
||||
'®' => '®',
|
||||
'¯' => '¯',
|
||||
'°' => '°',
|
||||
'±' => '±',
|
||||
'²' => '²',
|
||||
'³' => '³',
|
||||
'´' => '´',
|
||||
'µ' => 'µ',
|
||||
'¶' => '¶',
|
||||
'·' => '·',
|
||||
'¸' => '¸',
|
||||
'¹' => '¹',
|
||||
'º' => 'º',
|
||||
'»' => '»',
|
||||
'¼' => '¼',
|
||||
'½' => '½',
|
||||
'¾' => '¾',
|
||||
'¿' => '¿',
|
||||
'À' => 'À',
|
||||
'Á' => 'Á',
|
||||
'Â' => 'Â',
|
||||
'Ã' => 'Ã',
|
||||
'Ä' => 'Ä',
|
||||
'Å' => 'Å',
|
||||
'Æ' => 'Æ',
|
||||
'Ç' => 'Ç',
|
||||
'È' => 'È',
|
||||
'É' => 'É',
|
||||
'Ê' => 'Ê',
|
||||
'Ë' => 'Ë',
|
||||
'Ì' => 'Ì',
|
||||
'Í' => 'Í',
|
||||
'Î' => 'Î',
|
||||
'Ï' => 'Ï',
|
||||
'Ð' => 'Ð',
|
||||
'Ñ' => 'Ñ',
|
||||
'Ò' => 'Ò',
|
||||
'Ó' => 'Ó',
|
||||
'Ô' => 'Ô',
|
||||
'Õ' => 'Õ',
|
||||
'Ö' => 'Ö',
|
||||
'×' => '×',
|
||||
'Ø' => 'Ø',
|
||||
'Ù' => 'Ù',
|
||||
'Ú' => 'Ú',
|
||||
'Û' => 'Û',
|
||||
'Ü' => 'Ü',
|
||||
'Ý' => 'Ý',
|
||||
'Þ' => 'Þ',
|
||||
'ß' => 'ß',
|
||||
'à' => 'à',
|
||||
'á' => 'á',
|
||||
'â' => 'â',
|
||||
'ã' => 'ã',
|
||||
'ä' => 'ä',
|
||||
'å' => 'å',
|
||||
'æ' => 'æ',
|
||||
'ç' => 'ç',
|
||||
'è' => 'è',
|
||||
'é' => 'é',
|
||||
'ê' => 'ê',
|
||||
'ë' => 'ë',
|
||||
'ì' => 'ì',
|
||||
'í' => 'í',
|
||||
'î' => 'î',
|
||||
'ï' => 'ï',
|
||||
'ð' => 'ð',
|
||||
'ñ' => 'ñ',
|
||||
'ò' => 'ò',
|
||||
'ó' => 'ó',
|
||||
'ô' => 'ô',
|
||||
'õ' => 'õ',
|
||||
'ö' => 'ö',
|
||||
'÷' => '÷',
|
||||
'ø' => 'ø',
|
||||
'ù' => 'ù',
|
||||
'ú' => 'ú',
|
||||
'û' => 'û',
|
||||
'ü' => 'ü',
|
||||
'ý' => 'ý',
|
||||
'þ' => 'þ',
|
||||
'ÿ' => 'ÿ',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
|
||||
'"' => '"',
|
||||
#'&' => '&#38;',
|
||||
#'<' => '&#60;',
|
||||
#'>' => '>',
|
||||
''' => ''',
|
||||
'Œ' => 'Œ',
|
||||
'œ' => 'œ',
|
||||
'Š' => 'Š',
|
||||
'š' => 'š',
|
||||
'Ÿ' => 'Ÿ',
|
||||
'ˆ' => 'ˆ',
|
||||
'˜' => '˜',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
'‌' => '‌',
|
||||
'‍' => '‍',
|
||||
'‎' => '‎',
|
||||
'‏' => '‏',
|
||||
'–' => '–',
|
||||
'—' => '—',
|
||||
'‘' => '‘',
|
||||
'’' => '’',
|
||||
'‚' => '‚',
|
||||
'“' => '“',
|
||||
'”' => '”',
|
||||
'„' => '„',
|
||||
'†' => '†',
|
||||
'‡' => '‡',
|
||||
'‰' => '‰',
|
||||
'‹' => '‹',
|
||||
'›' => '›',
|
||||
'€' => '€',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
|
||||
'ƒ' => 'ƒ',
|
||||
'Α' => 'Α',
|
||||
'Β' => 'Β',
|
||||
'Γ' => 'Γ',
|
||||
'Δ' => 'Δ',
|
||||
'Ε' => 'Ε',
|
||||
'Ζ' => 'Ζ',
|
||||
'Η' => 'Η',
|
||||
'Θ' => 'Θ',
|
||||
'Ι' => 'Ι',
|
||||
'Κ' => 'Κ',
|
||||
'Λ' => 'Λ',
|
||||
'Μ' => 'Μ',
|
||||
'Ν' => 'Ν',
|
||||
'Ξ' => 'Ξ',
|
||||
'Ο' => 'Ο',
|
||||
'Π' => 'Π',
|
||||
'Ρ' => 'Ρ',
|
||||
'Σ' => 'Σ',
|
||||
'Τ' => 'Τ',
|
||||
'Υ' => 'Υ',
|
||||
'Φ' => 'Φ',
|
||||
'Χ' => 'Χ',
|
||||
'Ψ' => 'Ψ',
|
||||
'Ω' => 'Ω',
|
||||
'α' => 'α',
|
||||
'β' => 'β',
|
||||
'γ' => 'γ',
|
||||
'δ' => 'δ',
|
||||
'ε' => 'ε',
|
||||
'ζ' => 'ζ',
|
||||
'η' => 'η',
|
||||
'θ' => 'θ',
|
||||
'ι' => 'ι',
|
||||
'κ' => 'κ',
|
||||
'λ' => 'λ',
|
||||
'μ' => 'μ',
|
||||
'ν' => 'ν',
|
||||
'ξ' => 'ξ',
|
||||
'ο' => 'ο',
|
||||
'π' => 'π',
|
||||
'ρ' => 'ρ',
|
||||
'ς' => 'ς',
|
||||
'σ' => 'σ',
|
||||
'τ' => 'τ',
|
||||
'υ' => 'υ',
|
||||
'φ' => 'φ',
|
||||
'χ' => 'χ',
|
||||
'ψ' => 'ψ',
|
||||
'ω' => 'ω',
|
||||
'ϑ' => 'ϑ',
|
||||
'ϒ' => 'ϒ',
|
||||
'ϖ' => 'ϖ',
|
||||
'•' => '•',
|
||||
'…' => '…',
|
||||
'′' => '′',
|
||||
'″' => '″',
|
||||
'‾' => '‾',
|
||||
'⁄' => '⁄',
|
||||
'℘' => '℘',
|
||||
'ℑ' => 'ℑ',
|
||||
'ℜ' => 'ℜ',
|
||||
'™' => '™',
|
||||
'ℵ' => 'ℵ',
|
||||
'←' => '←',
|
||||
'↑' => '↑',
|
||||
'→' => '→',
|
||||
'↓' => '↓',
|
||||
'↔' => '↔',
|
||||
'↵' => '↵',
|
||||
'⇐' => '⇐',
|
||||
'⇑' => '⇑',
|
||||
'⇒' => '⇒',
|
||||
'⇓' => '⇓',
|
||||
'⇔' => '⇔',
|
||||
'∀' => '∀',
|
||||
'∂' => '∂',
|
||||
'∃' => '∃',
|
||||
'∅' => '∅',
|
||||
'∇' => '∇',
|
||||
'∈' => '∈',
|
||||
'∉' => '∉',
|
||||
'∋' => '∋',
|
||||
'∏' => '∏',
|
||||
'∑' => '∑',
|
||||
'−' => '−',
|
||||
'∗' => '∗',
|
||||
'√' => '√',
|
||||
'∝' => '∝',
|
||||
'∞' => '∞',
|
||||
'∠' => '∠',
|
||||
'∧' => '∧',
|
||||
'∨' => '∨',
|
||||
'∩' => '∩',
|
||||
'∪' => '∪',
|
||||
'∫' => '∫',
|
||||
'∴' => '∴',
|
||||
'∼' => '∼',
|
||||
'≅' => '≅',
|
||||
'≈' => '≈',
|
||||
'≠' => '≠',
|
||||
'≡' => '≡',
|
||||
'≤' => '≤',
|
||||
'≥' => '≥',
|
||||
'⊂' => '⊂',
|
||||
'⊃' => '⊃',
|
||||
'⊄' => '⊄',
|
||||
'⊆' => '⊆',
|
||||
'⊇' => '⊇',
|
||||
'⊕' => '⊕',
|
||||
'⊗' => '⊗',
|
||||
'⊥' => '⊥',
|
||||
'⋅' => '⋅',
|
||||
'⌈' => '⌈',
|
||||
'⌉' => '⌉',
|
||||
'⌊' => '⌊',
|
||||
'⌋' => '⌋',
|
||||
'⟨' => '〈',
|
||||
'⟩' => '〉',
|
||||
'◊' => '◊',
|
||||
'♠' => '♠',
|
||||
'♣' => '♣',
|
||||
'♥' => '♥',
|
||||
'♦' => '♦'));
|
||||
|
||||
Reference in New Issue
Block a user