From 0b7df0c7783dd372d78080f3233c705e2e8150c6 Mon Sep 17 00:00:00 2001 From: speedie Date: Mon, 12 Jun 2023 01:55:25 +0200 Subject: [PATCH] Remove speedie.site wiki --- LICENSE | 21 - README.md | 60 - config.php | 216 --- icons/close.svg | 12 - icons/delete-dark.svg | 8 - icons/delete.svg | 8 - icons/edit-dark.svg | 8 - icons/edit.svg | 8 - icons/format-text-bold.svg | 8 - icons/format-text-code.svg | 8 - icons/format-text-italic.svg | 13 - icons/home.svg | 8 - icons/internet.png | Bin 886 -> 0 bytes icons/link-dark.svg | 10 - icons/link.svg | 10 - icons/list.svg | 8 - icons/new.svg | 13 - icons/rename-dark.svg | 17 - icons/rename.svg | 17 - icons/upload.svg | 8 - icons/w2-icon.png | Bin 1744 -> 0 bytes images/.gitignore | 4 - index.css | 410 ----- index.css.2 | 362 ---- index.html | 14 + index.php | 944 ---------- locales/de.php | 65 - locales/en.php | 32 - locales/ja.php | 32 - locales/sample.php | 32 - md/Markdown.inc.php | 10 - md/Markdown.php | 1909 -------------------- md/MarkdownExtra.inc.php | 11 - md/MarkdownExtra.php | 1895 ------------------- md/MarkdownInterface.inc.php | 9 - md/MarkdownInterface.php | 38 - pages/Getting Started.md | 183 -- pages/Home.md | 4 - pages/[spmenu] Code documentation.md | 173 -- pages/[spmenu] How to use the buildconf.md | 9 - pages/_sidebar.md | 5 - run.sh | 30 - tests/travis-ci-apache.conf | 21 - 43 files changed, 14 insertions(+), 6639 deletions(-) delete mode 100755 LICENSE delete mode 100755 README.md delete mode 100755 config.php delete mode 100755 icons/close.svg delete mode 100755 icons/delete-dark.svg delete mode 100755 icons/delete.svg delete mode 100755 icons/edit-dark.svg delete mode 100755 icons/edit.svg delete mode 100755 icons/format-text-bold.svg delete mode 100755 icons/format-text-code.svg delete mode 100755 icons/format-text-italic.svg delete mode 100755 icons/home.svg delete mode 100755 icons/internet.png delete mode 100755 icons/link-dark.svg delete mode 100755 icons/link.svg delete mode 100755 icons/list.svg delete mode 100755 icons/new.svg delete mode 100755 icons/rename-dark.svg delete mode 100755 icons/rename.svg delete mode 100755 icons/upload.svg delete mode 100755 icons/w2-icon.png delete mode 100755 images/.gitignore delete mode 100755 index.css delete mode 100755 index.css.2 create mode 100644 index.html delete mode 100755 index.php delete mode 100755 locales/de.php delete mode 100755 locales/en.php delete mode 100755 locales/ja.php delete mode 100755 locales/sample.php delete mode 100755 md/Markdown.inc.php delete mode 100755 md/Markdown.php delete mode 100755 md/MarkdownExtra.inc.php delete mode 100755 md/MarkdownExtra.php delete mode 100755 md/MarkdownInterface.inc.php delete mode 100755 md/MarkdownInterface.php delete mode 100755 pages/Getting Started.md delete mode 100755 pages/Home.md delete mode 100755 pages/[spmenu] Code documentation.md delete mode 100755 pages/[spmenu] How to use the buildconf.md delete mode 100755 pages/_sidebar.md delete mode 100755 run.sh delete mode 100755 tests/travis-ci-apache.conf diff --git a/LICENSE b/LICENSE deleted file mode 100755 index f7bd968..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Steven Frank - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100755 index 37d3756..0000000 --- a/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# W2 wiki - -W2 wiki is a web-based, wiki-like notepad that you can host yourself. - - -## Notable features: - -- Elegant text markup: - - Uses [Markdown Syntax](https://github.com/codeling/w2wiki/blob/master/pages/MarkdownSyntax.md). - - It supports double-brackets [[like this]] to link to another page in the wiki by title - - It supports double-braces {{like this}} to link to an uploaded image -- Minimalistic but functional interface: - - Fits to screen nicely when viewed on iPhone, with custom icon for adding to home screen - - HTML5 compliant output -- Title & content search -- Filesystem storage (no database required) in plain Markdown text files. -- Rudimentary git integration to commit & push each page edit -- Localization support (currently en/ja translations available) -- Image uploading support -- Optionally password-protected -- Unlike cloud / hosted solutions, you retain control of your data -- Written in PHP for portability and hackability -- Extremely compact (only a few .php files and a .css file) - - -## Installation & Configuration - -See [Installation instructions](https://github.com/codeling/w2wiki/blob/master/INSTALL.md). - - -## Security Notice - -In its current form, W2 wiki is not security-hardened; it's recommended to only run on an additionally secured server (e.g. in a small, private network for one user only; and secured behind a VPN and/or HTTPS with basic authentication). - - -## License - -W2 is licensed under the [MIT license](https://github.com/codeling/w2wiki/blob/master/LICENSE). - - -## Acknowledgements - -Originally written by [Steven Frank](https://github.com/panicsteve/w2wiki) and others, with modifications by -- [44uk](https://github.com/44uk/w2wiki) -- [knee-cola](https://github.com/knee-cola/w2wiki) -- [namvan](https://github.com/namvan/w2wiki) -- [nickodell](https://github.com/nickodell/w2wiki) -- [pilem](https://github.com/pilem/w2) - -W2 wiki uses [PHP Markdown](https://github.com/michelf/php-markdown) by Michel Fortin for rendering Markdown to HTML. - -The [Markdown syntax](https://github.com/codeling/w2wiki/blob/master/pages/MarkdownSyntax.md) description is taken from [daringfireball.net](https://daringfireball.net/projects/markdown/syntax). - -Maintainer of this fork is [codeling](https://github.com/codeling/w2wiki). - - -## Reporting Bugs - -Please report bugs in [the github issue tracker](https://github.com/codeling/w2wiki/issues) of this fork. - diff --git a/config.php b/config.php deleted file mode 100755 index 6e2bf81..0000000 --- a/config.php +++ /dev/null @@ -1,216 +0,0 @@ - - * Code may be re-used as long as the above copyright notice is retained. - * See README.md for full details. - * - * Written with Coda: - * - */ - -// -------------------- -// Site layout settings -// -------------------- - -// PAGES_PATH -// -// The path to the raw text documents maintained by W2 -// You should not use a trailing slash. - -define('PAGES_PATH', dirname(__FILE__). '/pages'); - -// UPLOAD_FOLDER -// -// The subfolder in PAGES_PATH that uploads get stored to -define('UPLOAD_FOLDER', 'images'); - -// PAGES_EXT -// -// The extension of the Markdown files in the PAGES_PATH -// folder which are displayed by W2 -define('PAGES_EXT', 'md'); - - -// BASE_URI -// -// The base URI for this W2 installation. You only need to change this if we guess wrong. -// You should not use a trailing slash. - -define('BASE_URI', str_replace('/index.php', '', $_SERVER['SCRIPT_NAME'])); - -// SELF -// -// The path component of the URL to the main script, such as: /w2/index.php - -define('SELF', $_SERVER['SCRIPT_NAME']); - -// VIEW -// -// Needed only if your web server spawns PHP as a CGI instead of an internal module. -// For example: define('VIEW', '?action=view&page='); - -define('VIEW', ''); - -// DEFAULT_PAGE -// -// The name of the page to show as the "Home" page. -// Value is a string, the title of a page (case-sensitive!) - -define('DEFAULT_PAGE', 'Home'); - -// CSS_FILE -// -// The CSS file to load to style the wiki, relative to BASE_URI - -define('CSS_FILE', 'index.css'); - -// SIDEBAR_FILE -// -// The name of the page to be shown as sidebar (leave empty to disable sidebar feature) - -define ('SIDEBAR_PAGE', '_sidebar'); - -// PAGE_TITLE -// -// A title prepended to the title head tag of all pages of the wiki - -define ('PAGE_TITLE', 'Wiki: '); - -// -------------------- -// File upload settings -// -------------------- - -// DISABLE_UPLOADS -// -// Globally enable/disable file uploads - -define('DISABLE_UPLOADS', false); - -// VALID_UPLOAD_TYPES -// -// Acceptable file types for file uploads. This is a good idea for security. -// Value is a comma-separated string of MIME types. - -define('VALID_UPLOAD_TYPES', 'image/jpeg,image/pjpeg,image/png,image/gif,application/pdf'); - -// VALID_UPLOAD_EXTS -// -// Acceptable filename extensions for file uploads -// Value is a comma-separated string of filename extensions (case-sensitive!) - -define('VALID_UPLOAD_EXTS', 'jpg,jpeg,png,gif,pdf'); - -// ------------------ -// Interface settings -// ------------------ - -// TITLE_DATE -// -// The format to use when displaying page modification times. -// See the manual for the PHP 'date()' function for the specification: -// http://php.net/manual/en/function.date.php -// Note that these settings are overridden by the -// date_format/date_format_no_time in the used locale! - -define('TITLE_DATE', 'j-M-Y g:i A'); -define('TITLE_DATE_NO_TIME', 'j-M-Y'); - -// EDIT_ROWS -// -// Default size of the text editing area in text rows. - -define('EDIT_ROWS', 18); - -// AUTOLINK_PAGE_TITLES -// -// Automatically converts any page titles appearing in text into links -// to the named page. This might degrade performance if you have many -// thousands of pages. - -define('AUTOLINK_PAGE_TITLES', false); - - -// ----------------------------- -// Security and session settings -// ----------------------------- - -// REQUIRE_PASSWORD -// -// Is a password required to access this wiki? - -define('REQUIRE_PASSWORD', false); - -// W2_PASSWORD -// -// The password for the wiki, if REQUIRE_PASSWORD is true -// Replace 'secret' with your password to set your password. - -define('W2_PASSWORD', 'secret'); - -// W2_PASSWORD_HASH -// -// Alternate (more secure) password storage. -// To use a hashed password, Comment out the W2_PASSWORD definition above and uncomment -// this one, using the result of sha1('your_password') as the value. -// -// In Mac OS X, you can do this from the Terminal: -// echo -n 'your_password' | openssl sha1 -// -// define('W2_PASSWORD_HASH', 'e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4'); - -define('W2_PASSWORD_HASH', ''); - -// allowedIPs -// -// A whitelist of IP addresses that are allowed access to the wiki. -// If empty, all IPs are allowed. - -$allowedIPs = array(); - -// W2_SESSION_LIFETIME -// -// How long before a login session expires? Default is 30 days - -define('W2_SESSION_LIFETIME', 60 * 60 * 24 * 30); - -// W2_SESSION_NAME -// -// Name for session (used in the cookie) - -define('W2_SESSION_NAME', 'W2'); - - -// ----------------------------- -// Git Integration -// ----------------------------- - -// GIT_COMMIT_ENABLED -// -// Enable/Disable committing changes in page folder to local git repository - -define('GIT_COMMIT_ENABLED', false); - -// GIT_PUSH_ENABLED -// -// Enable/Disable pushing changes in page folder to a remote git repository - -define('GIT_PUSH_ENABLED', false); - - -// ----------------------------- -// Locale and encoding settings -// ----------------------------- - -// W2_CHARSET -// -// Value for meta charset. - -define('W2_CHARSET', 'UTF-8'); - -// W2_LOCALE -// -// Name for locale. - -define('W2_LOCALE', 'en'); diff --git a/icons/close.svg b/icons/close.svg deleted file mode 100755 index 4d8b37e..0000000 --- a/icons/close.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/icons/delete-dark.svg b/icons/delete-dark.svg deleted file mode 100755 index 9c33315..0000000 --- a/icons/delete-dark.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/delete.svg b/icons/delete.svg deleted file mode 100755 index 9c33315..0000000 --- a/icons/delete.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/edit-dark.svg b/icons/edit-dark.svg deleted file mode 100755 index 255b07d..0000000 --- a/icons/edit-dark.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/edit.svg b/icons/edit.svg deleted file mode 100755 index 611d77a..0000000 --- a/icons/edit.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/format-text-bold.svg b/icons/format-text-bold.svg deleted file mode 100755 index 1b2b8e4..0000000 --- a/icons/format-text-bold.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/format-text-code.svg b/icons/format-text-code.svg deleted file mode 100755 index ae5e15e..0000000 --- a/icons/format-text-code.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/format-text-italic.svg b/icons/format-text-italic.svg deleted file mode 100755 index d051ff2..0000000 --- a/icons/format-text-italic.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/icons/home.svg b/icons/home.svg deleted file mode 100755 index 27d5580..0000000 --- a/icons/home.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/internet.png b/icons/internet.png deleted file mode 100755 index 56991f28f295ec828288839fbab55fa994828c8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 886 zcmV-+1Bv{JP)_6rCNvy8lgy~Ep3^0>g$_n=l%G8 zzb;-&gm{ya+?$--oO5rE@JPM$+qILGuIQt_qTSo&>FgiNS$%e@blW07xQ_eH>|0OH z{Fg5~%^MdklxhRHsr~)okO)MvaPCSsm7-?yW&w@DiZUYVw8Zwkxwi+~4;Gxfc(G^X z2|L%nE9wRawj9p>xQqLK27?2luu7$LQRF-A)WN~k*UpWO`Yu4VY_3##wz^{jvx_;- zPwpm46etBESP`&*q=J>T&u=wz-vYKJk zQD79-C?t_|)&kZ6o%Yq$4@nW7sngPxCyTw{hm^B0|2cROUq?0O&%iA+jmh8AnfT| zV9&q`^?G5+>3;cx8jkmzmuYjLb{&JpSc4T!SD{H?wT?w-1_gBDf(1V)F~8W)dOdeW zsg1@2VPtfqh>U*VZwL8OgTv2WW9;Z<(4=;ZgT!dZ_b1f+XNP`K!P=QHaJhAJAF)aP z7xQ$h_zOd=u^6PcKxnc@1S7iipj47C|(XJct17r5iIr}l*p zrE#Z@d~yDGS9Rsne9<4yc$?XkTf@oXjRSWu(N9Kqetqw&+Cy>v7oC=71Z3T`dH?_b M07*qoM6N<$f@im=oB#j- diff --git a/icons/link-dark.svg b/icons/link-dark.svg deleted file mode 100755 index 36db492..0000000 --- a/icons/link-dark.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/icons/link.svg b/icons/link.svg deleted file mode 100755 index 9381210..0000000 --- a/icons/link.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/icons/list.svg b/icons/list.svg deleted file mode 100755 index 02605c1..0000000 --- a/icons/list.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/new.svg b/icons/new.svg deleted file mode 100755 index 2f81e2f..0000000 --- a/icons/new.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/icons/rename-dark.svg b/icons/rename-dark.svg deleted file mode 100755 index 9d31cc1..0000000 --- a/icons/rename-dark.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/icons/rename.svg b/icons/rename.svg deleted file mode 100755 index e8570f9..0000000 --- a/icons/rename.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/icons/upload.svg b/icons/upload.svg deleted file mode 100755 index c6ec427..0000000 --- a/icons/upload.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/icons/w2-icon.png b/icons/w2-icon.png deleted file mode 100755 index 9df16f66023bb0297701e1bb2ba8a55a50529a2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1744 zcmaJ?c~BEq9L@+-4Yyovn876!MJ3rJB!Q%W97#B8s0J`8f+fdB0wf!fMFNVAqPC!@ zK-8i*fYc&#RSTtv7iB1lAlE1(cogLn5yi#yV2z{ge^eAVJVU#R6!Vj2`qwu5V>$0#Dj#A)TA4b zHwwkeA_RzlyMZZ&w+EUawIK#R(7sh@fpUg%5tR;VK@GNqq2p8kfXX z210SN;4~E!o)#7%PD>CoB>45dfVYN;3dkWu2x#Pq3N=&XgP+r7qI<(JhzI5%NP-Xk zeNY1KMj#MYK>&?NB8W+J5P;n) zGI=b{2Vbb=gO5WHB@+ZwQc{R19zA&b*cgpY6uFo%e(>$Qj1kG zB_e|rfI(3xf|C&+JR0fy6y(YUS%vyTnb3lP8le&-6G?`Y=7C)9|3l^S1+*IBK_BD& zPhoXLsuBWukQz=_iP6SMT@0?2%s>?+L||0}3@6T4abp~e!0I?y2?U1I0IpChQyAcqi4?3O3p;Ad?GK&*HCUaPUEDkM@9Z2`5c+GQJ zusB%`DUf-tcmfb`?6-SFeoKqPK+=!t#&M^tDAbWH*RET1{zL%bVfhe ztn^AW=~C1cKE3|((mwVk+YNgwnoW!BEVeh?xBo(vHv_aMv8{c7r@f$`zcE3HAI^HP zCZ>05bxY9n&`vvNYKxu8z-qq|hW6Hoi?@?yx;&Fd_z7P){zB7+JMyFb5eNQsSJ~-5 zPn;`1QGV9Fn?Kvi_vKqMWB6V1yGI-f6DDTX256Gx!(n5Lq7HtSuaiqlkVcm?rt))+ z550oRZSCt$ip%8Hh;WfWo+npz`9%-n@{GS`kZXl75|X&d`tA1{rch7 zw%(}tFH6h4mOeE{hNBKwVXMZf^LXk=Rpe@|;?z6k&=&W+b-Sh2M{##LW{+JL$>iG6 z?G2UWZ;nPYX42eUk{U<29@I( zBzw4#WJ9=nJKpYo_KM7?CW>{IgX!~4)VtTF?^!2ZnL3d1bp@$iQK}eBeda8|{uOFt zRm?37kBG3EefJ0(lPY*?C2g2;(l4!7C7R+k*SwkidzZ<|;2d2a_N3*-7Qb|C=)H@^ z`f8`(oQq}$p2aRJyijR|owg~ubi%DW?wD-#)SBbk5pA%(tp0Si)V<96F>*3N6eh3T zx0zRQsWW#^=_K9pwq$f->uWn}1T@ - * - * Code may be re-used as long as the above copyright notice is retained. - * See README.txt for full details. - * - * Written with Coda: - * - * colors icons: - * 240,240,240 - * dark: 15, 15, 15 - */ - -* { - font-family: Monospace; - font-size: 11px; - margin: 0; - padding: 0; -} - -body { - background-color: #363636; -} - -blockquote { - background-color: #0f070f; - margin: 4px 4px 12px 20px; - padding: 4px 10px 4px 10px; -} - -form { - display: inline; -} - -li { - line-height: 1.5em; -} - -h1 { - font-size: 2em; - font-weight: bold; - margin-bottom: 4px; - /*margin-top: .6em;*/ -} - -h2 { - font-size: 1.2em; - font-weight: bold; - margin-bottom: 4px; - margin-top: .5em; -} - -h3 { - font-size: 1.2em; - font-weight: bold; -} -h3, h4, h5, h6 { - margin-top: .4em; - margin-bottom: 4px; -} - -hr { - border-top: 1px solid #363636; - border-bottom: 0; - border-left: 0; - border-right: 0; - margin-top: 12px; - margin-bottom: 12px; -} - -ul, -ol { - margin-top: .5em; - margin-left: 1em; - padding-left: 1em; - list-style-position: outside; -} - -ul li, ol li { - padding-left: .5em; -} - -li > ul, li > ol -{ - margin-top: 0; -} - -p { - margin-top: 1.5em; - margin-bottom: 1.5em; -} - -pre { - font-family: Monospace; - margin-left: 0; - margin-bottom: .5em; - margin-top: .5em; - - /* stroke each browser so that they wrap lines in the pre tag */ - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - - background: #212121; - border: 1px dotted gray; - padding: .2em .2em .2em .4em; -} - -code { - font-family: Monospace; - background: #212121; - color: #bbbbbb; - padding: .1em .1em .1em .2em; -} - -table { - border-collapse: collapse; - padding: .2em; - max-width: 99%; - background-color: #212121; - color: #dddddd; -} - th { - text-align: left; - } - td, th { - padding: .1em 1em .1em .1em; - word-break: break-all; - background: #212121; - } - thead { - border-bottom: 1px solid black; - font-weight: bold; - } - thead td a { - text-decoration:none; - } - thead td span.sortBy:after { - content: "\25BC"; - } - tr:nth-child(even) { - background: #e4e4e4; - } - tr:nth-child(odd) { - background: #eeeeee; - } -.pageActions { - padding-left: 8px; - padding-right: 8px; -} - -textarea { - font-family: Monospace; - width: 75%; - background-color: #212121; - color: #f0eee4; -} - @media (max-width: 600px), (orientation: portrait) { - textarea { - width: 99%; - } - } - -input[type="text"], -textarea { - padding: 2px; -} - -input { - font-family: Monospace; -} - -input#gitmsg -{ - width: 60%; -} - -.main { - padding: .3em .3em .3em 1em; - background-color: #212121; - color: #f0eee4; -} - -.main a { - color: #89bfff; - text-decoration: none; - transition: 0.1s; -} - -.main a:hover { - color: #ccccff; - text-decoration: underline; -} - -/* the globe */ -.main a[href^="http"]::after { - /*content: url('/icons/internet.png');*/ -} - -.main a.literalMatch { - font-weight: bold; - color: #6666ff; -} - -.main a.noexist { - color: #f34000 !important; -} - -.login { - margin: 40px auto; - max-width: 650px; - line-height: 1.4; -} - -.note { - background-color: #212121; - padding: 4px; - margin: .5em 0 .5em 0; - color: #6666ff; - border: solid 1px #6666ff; - width: 75%; -} - @media (max-width: 600px), (orientation: portrait) { - .note { - width: 99%; - } - } - -.titlebar { - background-color: #262626; - color: #89bfff; - padding: 2px; -} - -.titlebar span.title { - font-size: 10px; - font-weight: bold; - margin: 5px; -} - -.titledate { - font-size: 0.90em; - color: #777777; - margin-left: 1em; - margin-right: 1em; -} - -.toolbar { - background-color: #363636; - position: sticky; - top: 0; - font-size: 2px; -} - -.toolbar > a, .titlebar > a { - font-size: 0.90em; - margin-right: 1em; - color: #eeeeee; - text-decoration: none; - font-weight: normal; -} - -.toolbar > a:hover, .titlebar > a:hover { - text-decoration: underline; -} - -.sidebar { - float: right; -} -.sidebar, .linkshere { - margin-right: 5px; - margin-top: 5px; - padding: 4px; - border: solid 1px #666644; -} -.sidebar ul { - margin-top: 0; - margin-left: 4px; -} -.linkshere { - width: 50%; - margin-left: 5px; -} - @media (max-width: 600px), (orientation: portrait) { - .sidebar, .linkshere { - margin-left: 5px; - float: none; - width: auto; - } - } - -input.search { -/* font-size: 0.95em;*/ - color: #212121; - width: 5em; - padding: .1em; -} - -input.search:focus { - width: 15em; -} - -input.pagename { - width: 20em; -} - -/* buttons (non-colors) */ -input[type="button"], -input[type="submit"] { - border:none; - border-radius: 3px; - padding: .5em 1em; - cursor: pointer; - margin-right: .5em; -} -#maxsizelabel { - margin-right: 1em; -} - -/* buttons (such as for the edit page) */ -input[type="submit"] { - background-color: #f0eee4; - color: black; -} -input[type="button"] { - background-color: #363636; - color: white; -} - -input[type="submit"]:hover { - background-color: #f0eee4; - color: black; -} -input[type="button"]:hover { - background-color: #363636; - color: white; -} - -img { - max-width: 50%; - height: auto; -} - -#drawer { - display: inline-block; - position: absolute; - width: 300px; - background-color: rgb(240, 240, 240); - opacity: 0.5; - border: 1px solid black; - border-radius: 5px; - padding: 0; - cursor: move; -} -#drawer h5 { - border-bottom: 1px solid black; - padding: 4px; -} -#drawer div { - padding: 4px; -} -#drawer:hover { - opacity: 1.0; -} -.inactive { - display: none !important; -} -img.icon { - width: 1.5em; - vertical-align: middle; -} -a > img.icon:hover, a > span.icongroup:hover { - outline: 1px outset white; -} -a > img.icon:active, a > span.icongroup:active { - outline: 1px inset white; -} -.rightaligned -{ - float: right; -} - -input.search { - border-color: #363636; - border-width: 0px; - background-color: #363636; - color: #f0eee4; - width: 165px -} - -.sidebar { - color: #aaaaaa; - border-color: #aaaaaa; - background-color: #262626; -} - -.sidebar a { - color: #19bfff; - text-decoration: none; - transition: 0.1s; -} - -.sidebar a:hover { - color: #bbbbff; - text-decoration: underline; -} diff --git a/index.css.2 b/index.css.2 deleted file mode 100755 index c9de0d3..0000000 --- a/index.css.2 +++ /dev/null @@ -1,362 +0,0 @@ -/* - * W2 - * - * Copyright (C) 2007-2011 Steven Frank - * - * Code may be re-used as long as the above copyright notice is retained. - * See README.txt for full details. - * - * Written with Coda: - * - * colors icons: - * 240,240,240 - * dark: 15, 15, 15 - */ - -* { - font-family: Monospace; - margin: 0; - padding: 0; - font-size: 11px; -} - -body { - background-color: #eeeeee; -} - -blockquote { - background-color: #0f070f; - margin: 4px 4px 12px 20px; - padding: 4px 10px 4px 10px; -} - -form { - display: inline; -} - -li { - line-height: 1.5em; -} - -h1 { - font-size: 2em; - font-weight: bold; - margin-bottom: 4px; - margin-top: .6em; -} - -h2 { - font-size: 1.6em; - font-weight: bold; - margin-bottom: 4px; - margin-top: .5em; -} - -h3 { - font-size: 1.2em; - font-weight: bold; -} -h3, h4, h5, h6 { - margin-top: .4em; - margin-bottom: 4px; -} - -hr { - border-top: 1px solid #222222; - border-bottom: 0; - border-left: 0; - border-right: 0; - margin-top: 12px; - margin-bottom: 12px; -} - -ul, -ol { - margin-top: .5em; - margin-left: 1em; - padding-left: 1em; - list-style-position: outside; -} - -ul li, ol li { - padding-left: .5em; -} - -li > ul, li > ol -{ - margin-top: 0; -} - -p { - margin-top: .5em; -} - -pre { - font-family: Monospace; - margin-left: 0; - margin-bottom: .5em; - margin-top: .5em; - - /* stroke each browser so that they wrap lines in the pre tag */ - white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ - word-wrap: break-word; /* Internet Explorer 5.5+ */ - - background: #ffc; - border: 1px dotted gray; - padding: .2em .2em .2em .4em; -} - -code { - font-family: Monospace; - background: #ffc; - padding: .1em .1em 0 .2em; -} - -table { - border-collapse: collapse; - padding: .2em; - max-width: 99%; - background-color: #000000; - color: #ffffff; -} - th { - text-align: left; - } - td, th { - padding: .1em 1em .1em .1em; - word-break: break-all; - } - thead { - border-bottom: 1px solid black; - font-weight: bold; - } - thead td a { - text-decoration:none; - } - thead td span.sortBy:after { - content: "\25BC"; - } - tr:nth-child(even) { - background: #e4e4e4; - } - tr:nth-child(odd) { - background: #eeeeee; - } -.pageActions { - padding-left: 8px; - padding-right: 8px; -} - -textarea { - font-family: Monospace; - width: 75%; - background-color: #000011; - color: #ffffff; -} - @media (max-width: 600px), (orientation: portrait) { - textarea { - width: 99%; - } - } - -input[type="text"], -textarea { - padding: 2px; -} - -input#gitmsg -{ - width: 60%; -} - -.main { - padding: .3em .3em .3em 1em; - background-color: #000000; - color: #ffffff; -} - -.main a[href^="http"]::after { - content: url('/icons/internet.png'); -} - -.main a.literalMatch { - font-weight: bold; - color: #00f; -} - -.main a.noexist { - color: #b00 !important; -} - -.login { - margin: 40px auto; - max-width: 650px; - line-height: 1.4; -} - -.note { - background-color: #000011; - padding: 4px; - margin: .5em 0 .5em 0; - color: #9999bb; - border: solid 1px #9999bb; - width: 75%; -} - @media (max-width: 600px), (orientation: portrait) { - .note { - width: 99%; - } - } - -.titlebar { - background-color: #111111; - color: #ffffff; -} - -.titlebar span.title { - font-size: 10px; - font-weight: bold; -} - -.titledate { - font-size: 0.90em; - color: #777777; - margin-left: 1em; - margin-right: 1em; -} - -.toolbar { - background-color: #222222; - position: sticky; - top: 0; - font-size: 8px; -} - -.toolbar > a, .titlebar > a { - font-size: 0.90em; - margin-right: 1em; - color: #eeeeee; - text-decoration: none; - font-weight: normal; -} - -.toolbar > a:hover, .titlebar > a:hover { - text-decoration: underline; -} - -.sidebar { - float: right; -} -.sidebar, .linkshere { - margin-right: 5px; - margin-top: 5px; - padding: 4px; - border: solid 1px #666644; -} -.sidebar ul { - margin-top: 0; - margin-left: 4px; -} -.linkshere { - width: 50%; - margin-left: 5px; -} - @media (max-width: 600px), (orientation: portrait) { - .sidebar, .linkshere { - margin-left: 5px; - float: none; - width: auto; - } - } - -input.search { -/* font-size: 0.95em;*/ - color: #000000; - width: 5em; - padding: .1em; -} - -input.search:focus { - width: 15em; -} - -input.pagename { - width: 20em; -} - -input[type="button"], -input[type="submit"] { - border:none; - border-radius: 3px; - padding: .5em 1em; - cursor: pointer; - margin-right: .5em; -} -#maxsizelabel { - margin-right: 1em; -} - -input[type="submit"] { - background-color: rgb(30, 101, 201); - color: white; -} -input[type="button"] { - background-color: rgb(220, 220, 220); -} - -input[type="submit"]:hover { - background-color: rgb(69, 135, 226); -} -input[type="button"]:hover { - background-color: rgb(200, 200, 200); -} - -img { - max-width: 100%; - height: auto; -} - -#drawer { - display: inline-block; - position: absolute; - width: 300px; - background-color: rgb(240, 240, 240); - opacity: 0.5; - border: 1px solid black; - border-radius: 5px; - padding: 0; - cursor: move; -} -#drawer h5 { - border-bottom: 1px solid black; - padding: 4px; -} -#drawer div { - padding: 4px; -} -#drawer:hover { - opacity: 1.0; -} -.inactive { - display: none !important; -} -img.icon { - width: 1.5em; - vertical-align: middle; -} -a > img.icon:hover, a > span.icongroup:hover { - outline: 1px outset white; -} -a > img.icon:active, a > span.icongroup:active { - outline: 1px inset white; -} -a.missing-link { - color: #ba0000; -} -.rightaligned -{ - float: right; -} diff --git a/index.html b/index.html new file mode 100644 index 0000000..22a5939 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + +Wiki + + + + + + + + + + diff --git a/index.php b/index.php deleted file mode 100755 index 7596e5b..0000000 --- a/index.php +++ /dev/null @@ -1,944 +0,0 @@ - - * - * Code may be re-used as long as the above copyright notice is retained. - * See README.txt for full details. - * - * Written with Coda: - * - */ - -// Install PSR-4-compatible class autoloader -spl_autoload_register(function($class){ - require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php'; -}); - -// Get Markdown class -use md\MarkdownExtra; - - -// User configurable options: -require_once "config.php"; - -// Load configured localization: -require_once 'locales/' . W2_LOCALE . '.php'; - -/** - * Get translated word - * - * String $label Key for locale word - * String $alt_word Alternative word - * return String - */ -function __( $label, $alt_word = null ) -{ - global $w2_word_set; - if( empty($w2_word_set[$label]) ) - { - return is_null($alt_word) ? $label : $alt_word; - } - return htmlspecialchars($w2_word_set[$label], ENT_QUOTES); -} - -if ( REQUIRE_PASSWORD ) -{ - ini_set('session.gc_maxlifetime', W2_SESSION_LIFETIME); - session_set_cookie_params(W2_SESSION_LIFETIME); -} -session_name(W2_SESSION_NAME); -session_start(); - - -if ( count($allowedIPs) > 0 ) -{ - $ip = $_SERVER['REMOTE_ADDR']; - $accepted = false; - - foreach ( $allowedIPs as $allowed ) - { - if ( strncmp($allowed, $ip, strlen($allowed)) == 0 ) - { - $accepted = true; - break; - } - } - - if ( !$accepted ) - { - print "Access from IP address $ip is not allowed"; - exit; - } -} - -function printHeader($title, $action, $bodyclass="") -{ - print "\n"; - print "\n"; - print " \n"; - print " \n"; - print " \n"; - print " \n"; - print " \n"; - print " ".PAGE_TITLE."$title\n"; - print " \n"; - print " \n"; -} - -function printFooter() -{ - print " \n"; - print ""; -} - -function printDrawer() -{ - print "
\n". - " \"".__('Close')."\"\n". - "
".__('Markdown Syntax Helper')."
\n". - "
\n". - "# ".__('Header')." 1
". - "## ".__('Header')." 2
". - "### ".__('Header')." 3
". - "#### ".__('Header')." 4
". - "##### ".__('Header')." 5
". - "###### ".__('Header')." 6
". - "
". - "*".__('Emphasize')."* - ".__('Emphasize')."
". - "_".__('Emphasize')."* - ".__('Emphasize')."
". - "**".__('Bold')."** - ".__('Bold')."
". - "__".__('Bold')."__ - ".__('Bold')."
". - "
". - "[[Link to page]]
". - "<http://example.com/>
". - "[link text](http://url)

". - "{{image.jpg}}
". - "![Alt text](/images/image.jpg)
". - "![Alt text](/images/image.jpg \"Optional title\")
". - "
". - "- Unordered list
". - "+ Unordered list
". - "* Unordered list
". - "1. Ordered list
". - "
". - "> Blockquote
".//
Blockquotes
\n". - "```Code```
". //
Code
\n\n". - "`inline-code`

". - "*** Horizontal rule
". - "--- Horizontal rule
\n". - "
\n". - "
\n". - " \n". - " \n". - " \"".__('Formatting\n". - " \"".__('Formatting\n". - " \"".__('Formatting\n". - " \n". - " \n"; -} - -if ( REQUIRE_PASSWORD && !isset($_SESSION['password']) ) -{ - if ( !defined('W2_PASSWORD_HASH') || W2_PASSWORD_HASH == '' ) - define('W2_PASSWORD_HASH', sha1(W2_PASSWORD)); - - if ( (isset($_POST['p'])) && (sha1($_POST['p']) == W2_PASSWORD_HASH) ) - $_SESSION['password'] = W2_PASSWORD_HASH; - else - { - printHeader( __('Log In'), '', "login"); - print "

" . __('Log In') . "

\n"; - print "
\n"; - print " ".__('Password') . ": \n"; - print " \n"; - print "
\n"; - printFooter(); - exit; - } -} - -// Support functions - -function descLengthSort($val_1, $val_2) -{ - $firstVal = strlen($val_1); - $secondVal = strlen($val_2); - return ( $firstVal > $secondVal ) ? - -1 : ( ( $firstVal < $secondVal ) ? 1 : 0); -} - -function getAllPageNames($path = "") -{ - $filenames = array(); - $dir = opendir(PAGES_PATH . "/$path" ); - while ( $filename = readdir($dir) ) - { - if ( $filename[0] == "." ) - { - continue; - } - if ( is_dir( PAGES_PATH . "/$path/$filename" ) ) - { - array_push($filenames, ...getAllPageNames( "$path/$filename" ) ); - continue; - } - if ( preg_match("/".PAGES_EXT."$/", $filename) != 1) - { - continue; - } - $filename = substr($filename, 0, -(strlen(PAGES_EXT)+1) ); - $filenames[] = substr("$path/$filename", 1); - } - closedir($dir); - return $filenames; -} - -function fileNameForPage($page) -{ - return PAGES_PATH . "/$page." . PAGES_EXT; -} - -function imageLinkText($imgName) -{ - return "![".__("Image Description")."](/".UPLOAD_FOLDER."/$imgName)"; -} - -function sanitizeFilename($inFileName) -{ - return str_replace(array('~', '..', '\\', ':', '|', '&'), '-', $inFileName); -} - -function pageURL($page) -{ - return SELF . VIEW . "/".str_replace("%2F", "/", str_replace("%23", "#", urlencode(sanitizeFilename($page)))); -} - -function pageLink($page, $title, $attributes="") -{ - return "$title"; - /* wip - $link_page = $match[1]; - $link_filename = PAGES_PATH . "/$link_page.txt"; - $link_page_exists = file_exists($link_filename); - if ($link_page_exists) - return "$title"; - else - //return "" . htmlentities($link_page) . ""; - return "$title"; - */ -} - -function redirectWithMessage($page, $msg) -{ - $_SESSION["msg"] = $msg; - header("HTTP/1.1 303 See Other"); - header("Location: " . pageURL($page) ); - exit; -} - -function checkedExecute(&$msg, $cmd) -{ - $returnValue = 0; - $output = ''; - exec($cmd, $output, $returnValue); - if ($returnValue != 0) - { - $msg .= "
Error executing command ".$cmd." (return value: ".$returnValue."): ".implode(" ", $output); - } - return ($returnValue == 0); -} - -function gitChangeHandler($commitmsg, &$msg) -{ - if (!GIT_COMMIT_ENABLED) - { - return; - } - if (checkedExecute($msg, "cd ".PAGES_PATH." && git add -A && git commit -m ".escapeshellarg($commitmsg))) - { - if (!GIT_PUSH_ENABLED) - { - return; - } - checkedExecute($msg, "cd ".PAGES_PATH." && git push"); - } -} - -function toHTMLID($noid) -{ // in HTML5, only spaces aren't allowed - return str_replace(" ", "-", $noid); -} - -function toHTML($inText) -{ - $parser = new MarkdownExtra; - $parser->no_markup = true; - $outHTML = $parser->transform($inText); - if ( AUTOLINK_PAGE_TITLES ) - { - $pagenames = getAllPageNames(); - uasort($pagenames, "descLengthSort"); - foreach ( $pagenames as $pageName ) - { - // match pageName, but only if it isn't inside another word or inside braces (as in "[$pageName]"). - $outHTML = preg_replace("/(? 1) ? $linkTitleSplit[1] : $linkedPage; - $pagePart = explode('#', $linkedPage)[0]; // split away an eventual anchor part - $linkedFilename = fileNameForPage(sanitizeFilename($pagePart)); - $exists = file_exists($linkedFilename); - $outHTML = str_replace("[[$fullLinkText]]", - pageLink($linkedPage, $linkText, ($exists? "" : " class=\"noexist\"")), $outHTML); - } - $outHTML = preg_replace("/\{\{(.*?)\}\}/", "\"\\1\"", $outHTML); - - // add an anchor in all title tags (h1/2/3/4): - preg_match_all( - "/(.*?)<\/h\\1>/", - $outHTML, - $matches, - PREG_PATTERN_ORDER - ); - for ($i = 0; $i < count($matches[0]); $i++) - { - $prefix = ""; - $caption = $matches[2][$i]; - $suffix = substr_replace($prefix, "/", 1, 0); - $outHTML = str_replace("$prefix$caption$suffix", - "$prefix$caption$suffix", $outHTML); - } - return $outHTML; -} - -function destroy_session() -{ - if ( isset($_COOKIE[session_name()]) ) - { - setcookie(session_name(), '', time() - 42000, '/'); - } - session_destroy(); - unset($_SESSION["password"]); - unset($_SESSION); -} - -function getPageActions($page, $action, $imgSuffix) -{ - $pageActions = array('edit', 'delete', 'rename'); - $pageActionNames = array(__('Edit'), __('Delete'), __('Rename')); - $result = ''; - for ($i = 0; $i < count($pageActions); $i++ ) - { - if ($action != $pageActions[$i]) - { - $result .= " \"".$pageActionNames[$i]."\"\n"; - } - } - $result .= " \"".__('Show\n"; - return $result; -} - -// Main code - -$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view'; -$newPage = ""; -$text = ""; -$html = ""; -if ($action === 'view' || $action === 'edit' || $action === 'save' || $action === 'rename' || $action === 'delete') -{ - // Look for page name following the script name in the URL, like this: - // http://stevenf.com/w2demo/index.php/Markdown%20Syntax - // - // Otherwise, get page name from 'page' request variable. - - $page = preg_match('@^/@', @$_SERVER["PATH_INFO"]) ? - urldecode(substr($_SERVER["PATH_INFO"], 1)) : urldecode(@$_REQUEST['page']); - $page = sanitizeFilename($page); - if ( $page == "" ) - { - $page = DEFAULT_PAGE; - } - $filename = fileNameForPage($page); -} -if ($action === 'view' || $action === 'edit') -{ - if ( file_exists($filename) ) - { - $text = file_get_contents($filename); - } - else - { - $newPage = $page; - $action = 'new'; - } -} -$oldgitmsg = ""; -$triedSave = false; -if ( $action == 'save' ) -{ - $msg = ''; - $newText = $_REQUEST['newText']; - $isNew = $_REQUEST['isNew']; - if ($isNew) - { - $page = str_replace(array('|','#'), '', $page); - $filename = fileNameForPage($page); - } - if ($isNew && file_exists($filename)) - { - $msg .= "Error creating page '$page' - it already exists! Please choose a different name, or edit the existing page (this discards current text!)!\n"; - $action = 'new'; - $text = $newText; - $newPage = $page; - if (GIT_COMMIT_ENABLED) - { - $oldgitmsg = $_REQUEST['gitmsg']; - } - $triedSave = true; - } - else - { - $errLevel = error_reporting(0); - if ( !file_exists( dirname($filename) ) ) { - mkdir(dirname($filename), 0755, true); - } - $success = file_put_contents($filename, $newText); - error_reporting($errLevel); - if ( $success === FALSE) - { - $msg .= "Error saving changes! Make sure your web server has write access to " . PAGES_PATH . "\n"; - $action = ($isNew ? 'new' : 'edit'); - $text = $newText; - $newPage = $page; - if (GIT_COMMIT_ENABLED) - { - $oldgitmsg = $_REQUEST['gitmsg']; - } - $triedSave = true; - } - else - { - $msg .= ($isNew ? __('Created'): __('Saved')); - $usermsg = $_REQUEST['gitmsg']; - $commitmsg = $page . ($usermsg !== '' ? (": ".$usermsg) : ($isNew ? " created" : " changed")); - gitChangeHandler($commitmsg, $msg); - } - } - redirectWithMessage($page, $msg); -} - -if ( $action === 'edit' || $action === 'new' ) -{ - $formAction = SELF . (($action === 'edit') ? "/$page" : ""); - $html .= "
\n"; - - if ( $action === 'edit' ) - { - $html .= "\n"; - } - else - { - if ($newPage != "" && !$triedSave) - { - $html .= "
". __('Creating new page since no page with given title exists!') ; - // check if similar page exists... - $pageNames = getAllPageNames(); - foreach($pageNames as $pageName) - { - if (levenshtein(strtoupper($newPage), strtoupper($pageName)) < sqrt(min(strlen($newPage), strlen($pageName))) ) - { - $html .= "
Note: Found similar page ".pageLink($pageName, $pageName).". Maybe you meant to edit this instead?"; - } - } - $html .= "
\n"; - } - $html .= "

" . __('Title') . ":

\n"; - - } - - $html .= "

\n"; - if (GIT_COMMIT_ENABLED) - { - $html .= "

Message:

\n"; - } - - $html .= "

\n"; - $html .= "\n"; - $html .= ''."\n"; - $html .= ''."\n"; - $html .= "

\n"; -} -else if ( $action === 'logout' ) -{ - destroy_session(); - header("Location: " . SELF); - exit; -} -else if ( $action === 'upload' ) -{ - if ( DISABLE_UPLOADS ) - { - $html .= '

' . __('Image uploading has been disabled on this installation.') . '

'; - } - else - { - $html .= "

\n". - "". - "\n". - ''. - ''. - ''. - ''. - ''."\n". - ''."\n"; - "

\n"; - } - // list files in UPLOAD_FOLDER - $path = PAGES_PATH . "/". UPLOAD_FOLDER . "/*"; - $imgNames = glob($path); - natcasesort($imgNames); - $html .= "

".__('Total').": ".count($imgNames)." ".__('images')."

"; - $html .= ""; - $html .= "". -/* - "". - "". - */ "". - ""; - $date_format = __('date_format', TITLE_DATE); - foreach ($imgNames as $imgName) - { - $html .= "". - "". - "". - "". - "". - "\n"; - } - $html .= "
".(($sortBy!='name')?("Name"):"Name")."".(($sortBy!='recent')?("Modified"):"Modified")."".__("Name")."".__("Usage")."".__("Modified")."".__("Action")."
".basename($imgName)."
".imageLinkText(basename($imgName))."
".date($date_format, filemtime($imgName))."".__('Delete')."
\n"; -} -else if ( $action === 'uploaded' ) -{ - if ( DISABLE_UPLOADS ) - { - die('Invalid access. Uploads are disabled in the configuration.'); - } - $dstName = sanitizeFilename($_FILES['userfile']['name']); - $dstName = str_replace(" ", "_", $dstName); // image display currently doesn't like spaces! - $fileType = $_FILES['userfile']['type']; - preg_match('/\.([^.]+)$/', $dstName, $matches); - $fileExt = isset($matches[1]) ? $matches[1] : null; - $imgExts = array('jpg','jpeg','png','gif'); - $msg = ''; - if (in_array($fileType, explode(',', VALID_UPLOAD_TYPES)) && - in_array($fileExt, explode(',', VALID_UPLOAD_EXTS))) - { - $path = PAGES_PATH . "/". UPLOAD_FOLDER . "/$dstName"; - $resize = isset($_POST['resize']) && $_POST['resize'] === 'true'; - $doResize = $resize && in_array($fileExt, $imgExts); - if ($doResize) - { - $exif = exif_read_data($_FILES['userfile']['tmp_name']); - $size = getimagesize($_FILES['userfile']['tmp_name']); - $maxsize = intval($_POST['maxsize']); - $doResize = ($size[0] > $maxsize || $size[1] > $maxsize); - if ($doResize) - { - $msg .= "trying to resize"; - $finalPath = $path; - $path = substr($path, 0, strlen($path)-strlen($fileExt)-1) . "-tmp-resize." . $fileExt; - } - } - $errLevel = error_reporting(0); - if ( move_uploaded_file($_FILES['userfile']['tmp_name'], $path) === true ) - { - $msg = "File '$dstName' uploaded! "; - if ($doResize) - { - $newSize = array(0, 0); - $idx0 = ($size[0] > $size[1]) ? 0 : 1; - $idx1 = ($idx0 == 0) ? 1 : 0; - $newSize[$idx0] = $maxsize; - $newSize[$idx1] = (int)round($size[$idx1] * $maxsize / $size[$idx0]); - $src = imagecreatefromstring(file_get_contents($path)); - $dst = imagecreatetruecolor($newSize[0], $newSize[1]); - if (!imagecopyresampled($dst, $src, 0, 0, 0, 0, $newSize[0], $newSize[1], $size[0], $size[1])) - { - $msg .= "Resizing file failed!"; - } - imagedestroy( $src ); - if(!empty($exif['Orientation'])) - { - switch($exif['Orientation']) - { - case 8: - $msg .= "Image rotated by +90°. "; - $rot = imagerotate($dst,90,0); - break; - case 3: - $msg .= "Image rotated by 180°. "; - $rot = imagerotate($dst,180,0); - break; - case 6: - $msg .= "Image rotated by -90°. "; - $rot = imagerotate($dst,-90,0); - break; - default: - $msg .= "Unknown EXIF orientation specification: ".$exif['Orientation']."!"; - break; - } - if ($rot === false) - { - $msg .= "Rotation failed!"; - } - else - { - imagedestroy( $dst ); - $dst = $rot; - } - } - if ($fileExt === 'png') - { - imagepng($dst, $finalPath); - } - else if ($fileExt === 'jpg' || $fileExt === 'jpeg') - { - imagejpeg($dst, $finalPath); - } - else if ($fileExt === 'gif') - { - imagegif($dst, $finalPath); - } - unlink($path); - imagedestroy( $dst ); - } - gitChangeHandler($msg, $msg); - $msg .= " ($size[0]x$size[1]".(($doResize)?", resized to $newSize[0]x$newSize[1]":"").") successfully! Use
".imageLinkText($dstName)."
to refer to it!"; - } - else - { - $error_code = $_FILES['userfile']['error']; - if ( $error_code === 0 ) { - // Likely a permissions issue - $msg .= __('Upload error') .": Can't write to ".$path."

\n". - "Check that your permissions are set correctly."; - } else { - // Give generic error message - $msg .= __('Upload error').", error #".$error_code."

\n". - "Please see here for more information.

\n". - "If you see this message, please file a bug to improve w2wiki"; - } - } - error_reporting($errLevel); - } - else - { - $msg .= __('Upload error: invalid file type'); - } - redirectWithMessage(DEFAULT_PAGE, $msg); -} -else if ( $action === 'rename' || $action === 'delete' || $action === 'imgDelete') -{ - if ($action === 'imgDelete') - { - $page = sanitizeFilename(urldecode($_REQUEST['imgName'])); - } - $actionName = ($action === 'delete' || $action === 'imgDelete')?__('Delete'):__('Rename'); - $html .= "
"; - $html .= "

".$actionName." $page ". - (($action==='rename')? (__('to')." ") : "?") . "

"; - $html .= "

"; - $html .= "\n"; - $html .= ""; - $html .= ""; - $html .= "

"; -} -else if ( $action === 'renamed' || $action === 'deleted') -{ - // TODO: prevent relative filenames from being injected - $oldPageName = sanitizeFilename($_POST['oldPageName']); - $newPageName = ($action === 'deleted') ? "": sanitizeFilename($_POST['newPageName']); - $msg = ''; - if ($action === 'deleted') - { - $success = unlink(fileNameForPage($oldPageName)); - } - else - { - $success = rename(fileNameForPage($oldPageName), fileNameForPage($newPageName)); - } - if ($success) - { - $message = ($action === 'deleted') ? "Removed $oldPageName." : - "Renamed $oldPageName to $newPageName."; - $msg .= $message; - // Change links in all pages to point to new page - $pagenames = getAllPageNames(); - $changedPages = array(); - foreach ($pagenames as $replacePage) - { - $content = file_get_contents(fileNameForPage($replacePage)); - $count = 0; - $regexSaveOldPageName = str_replace("/", "\\/", $oldPageName); - $newContent = preg_replace("/\[\[$regexSaveOldPageName([|#].*\]\]|\]\])/", - (($action === 'deleted') ? "" : "[[$newPageName\\1"), - $content, -1, $count); - if ($count > 0) // if something changed - { - $changedPages[] = $replacePage." ($count ".__('matches').")"; - file_put_contents(fileNameForPage($replacePage), $newContent); - } - } - if (count($changedPages) > 0) - { - $msg .= "
\n".__('Updated links in the following pages:')."\n
  • "; - $msg .= implode("
  • ", $changedPages); - $msg .= "
"; - } - gitChangeHandler($message, $msg); - $page = $newPageName; - } - else - { - $msg .= ($action === 'deleted') ? __('Error deleting file'): __('Error renaming file'); - $page = $oldPageName; - } - if ($action === 'deleted' && $success) - { - $page = DEFAULT_PAGE; - } - redirectWithMessage($page, $msg); -} -else if ( $action === 'imgDeleted') -{ - // TODO: prevent relative filenames from being injected - $oldPageName = sanitizeFilename($_REQUEST['oldPageName']); - $imgPath = PAGES_PATH . "/". UPLOAD_FOLDER . "/". $oldPageName; - $success = unlink($imgPath); - if ($success) - { - $msg = __('Image deleted'); - gitChangeHandler($msg, $msg); - $msg .= " (".$imgPath.")"; - } - else - { - $msg = __('Error deleting image'); - $msg .= " (".$imgPath.")"; - } - redirectWithMessage(DEFAULT_PAGE, $msg); -} -else if ( $action === 'all' ) -{ - $pageNames = getAllPageNames(); - $filelist = array(); - $sortBy = isset($_REQUEST['sortBy']) ? $_REQUEST['sortBy'] : 'name'; - if (!in_array($sortBy, array('name', 'recent'))) - { - $sortBy = 'name'; - } - if ($sortBy === 'name') - { - natcasesort($pageNames); - foreach($pageNames as $page) - { - $filelist[$page] = filemtime(fileNameForPage($page)); - } - } - else - { - foreach($pageNames as $page) - { - $filelist[$page] = filemtime(fileNameForPage($page)); - } - arsort($filelist, SORT_NUMERIC); - } - $html .= "

".__('Total').": ".count($pageNames)." ".__("pages")."

"; - $html .= ""; - $html .= "". - "". - "". - "". - ""; - $date_format = __('date_format', TITLE_DATE); - - foreach ($filelist as $pageName => $pageDate) - { - $html .= "". - "". - "". - //"". /* dark mode */ - "". /* light mode */ - "\n"; - } - $html .= "
".(($sortBy!='name')?("Name"):"".__('Name')."")."".(($sortBy!='recent')?("".__('Modified').""):"".__('Modified')."")."".__('Action')."
".pageLink($pageName, $pageName)."".date( $date_format, $pageDate)."".getPageActions($pageName, $action,"-dark")."".getPageActions($pageName, $action, "")."
\n"; - } - else if ( $action === 'search' ) - { - $matches = 0; - $q = $_REQUEST['q']; - $html .= "

Search: $q

\n"; - - if ( trim($q) != "" ) - { - $html .= "
    \n"; - $pagenames = getAllPageNames(); - $found = FALSE; - $matchingPages = array(); - foreach ($pagenames as $searchPage) - { - if ($searchPage === $q) - { - $found = TRUE; - } - if (preg_match("/{$q}/i", $searchPage)) - { - array_unshift($matchingPages, $searchPage); - ++$matches; - } - else - { - $text = file_get_contents(fileNameForPage($searchPage)); - if ( preg_match("/{$q}/i", $text) ) - { - $matchingPages[] = $searchPage; - ++$matches; - } - } - } - foreach ($matchingPages as $page) - { - $link = pageLink($page, $page, ($page === $q)? " class=\"literalMatch\"": ""); - $html .= "
  • $link
  • \n"; - } - if (!$found) - { - $html .= "
  • ".pageLink($q, __('Create page')." '$q'", " class=\"noexist\"")."
  • "; - } - $html .= "
\n"; - } - $html .= "

$matches ".__('matches')."

\n"; - } - else - { - $html .= empty($text) ? '' : toHTML($text); - } - - $datetime = ''; - - if ( ($action === 'all')) - { - $title = __("All"); - } - else if ( $action === 'upload' ) - { - $title = __("Upload"); - } - else if ( $action === 'new' ) - { - $title = __("New"); - } - else if ( $action === 'search' ) - { - $title = __("Search"); - } - else if ($filename != '') - { - $title = (($action === 'edit')? (__('Edit').": "):"") . $page; - $date_format = __('date_format', TITLE_DATE); - if ( $date_format ) - { - $datetime = "" . date($date_format, @filemtime($filename)) . ""; - } - } - else - { - $title = __($action); - } - - // Disable caching on the client (the iPhone is pretty agressive about this - // and it can cause problems with the editing function) - - header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past - printHeader($title, $action); - print "
$title$datetime"; - if ($action === 'view' || $action === 'rename' || $action === 'delete' || $action === 'edit') - { - print(getPageActions($page, $action, "")); - } - print "
\n"; - print "
\n"; - print " \"".\n"; -print " \"".\n"; -print " \"".__('New')."\"\n"; -if ( !DISABLE_UPLOADS ) -{ - print " \"".__('Upload')."\"\n"; -} -if ( REQUIRE_PASSWORD ) -{ - print " ". __('Log out') . ""; -} -print "
\n"; -print " \n
\n"; -if ($action === 'edit') -{ - printDrawer(); -} -print "
\n"; -if (SIDEBAR_PAGE != '') -{ - print "
\n\n"; - $sidebarFile = fileNameForPage(SIDEBAR_PAGE); - if (file_exists($sidebarFile)) - { - $text = file_get_contents($sidebarFile); - } - else - { - $text = __('Sidebar file could not be found')." ($sidebarFile)"; - } - print toHTML($text); - print "
\n"; -} -if ($action === 'view' && $_GET['linkshere']) -{ - print "
".__('What links here:')."
    "; - $pagenames = getAllPageNames(); - foreach($pagenames as $searchPage) - { - $text = file_get_contents(fileNameForPage($searchPage)); - $regexSavePage = str_replace("/", "\\/", $page); - if ( preg_match("/\[\[$regexSavePage/i", $text) ) - { - $link = pageLink($searchPage, $searchPage, ""); - print("
  • $link
  • \n"); - } - } - print "
"; -} -print "
\n\n"; -if(isset($_SESSION['msg']) && $_SESSION['msg'] != '') -{ - print "
".$_SESSION['msg']."
"; - unset($_SESSION['msg']); -} -print "$html\n"; -print "
\n"; -printFooter(); diff --git a/locales/de.php b/locales/de.php deleted file mode 100755 index 1ef8db1..0000000 --- a/locales/de.php +++ /dev/null @@ -1,65 +0,0 @@ - 'Start', - 'New' => 'Neu', - 'Edit' => 'Bearbeiten', - 'Delete' => 'Löschen', - 'Rename' => 'Umbenennen', - 'Created' => 'Angelegt', - 'Upload' => 'Hochladen', - 'All' => 'Alle', - 'Recent' => 'Zuletzt', - 'Exit' => 'Ausloggen', - 'Search' => 'Suchen', - 'Formatting help' => 'Formatierungshilfe', - 'Bold' => 'Fett', - 'Emphasize' => 'Kursiv', - 'Header' => 'Überschrift', - 'Save' => 'Speichern', - 'Cancel' => 'Abbrechen', - 'Saved' => 'Gespeichert', - 'Log In' => 'Einloggen', - 'Log Out' => 'Ausloggen', - 'Password' => 'Passwort', - 'Title' => 'Titel', - 'Image Description' => 'Bildbeschreibung', - 'Name' => 'Name', - 'Usage' => 'Verwendung', - 'Modified' => 'Verändert', - 'Action' => 'Aktion', - 'Total' => 'Gesamt', - 'images' => 'Bilder', - 'matches' => 'Übereinstimmung(en)', - 'pages' => 'Seite(n)', - 'Create page' => 'Seite anlegen', - 'to' => 'in', - 'Shrink if larger than ' => 'Verkleinern wenn größer als ', - 'Pixels' => 'Pixel', - 'What links here:' => 'Seiten die hierher linken:', - 'Close' => 'Schließen', - // Messages - 'Upload error' => 'Fehler beim Hochladen', - 'Upload error: invalid file type' => 'Fehler beim Hochladen: Dieser Dateityp ist nicht zugelassen, bitte wende Dich an deinen Administrator!', - 'Image uploading has been disabled on this installation.' => 'Hochladen ist nicht erlaubt, bitte wende Dich an deinen Administrator!', - 'Creating new page since no page with given title exists!' => 'Es wird eine neue Seite angelegt, weil noch keine Seite mit dem angegebenen Titel existiert!', - 'Updated links in the following pages:' => 'Es wurden Links in den folgenden Seiten aktualisiert:', - 'Error deleting file' => 'Fehler beim Löschen der Datei', - 'Error renaming file' => 'Fehler beim Umbenennen der Datei', - 'Sidebar file could not be found' => 'Seitenleisten-Datei nicht gefunden', - 'Name of new page (restrictions in tip)' => 'Seitenname (Einschränkungen im Tip)', - "Character restrictions: '#' and '|' have a special meaning in page links, they will therefore be removed; also, characters '~', '/', '\\', ':', '|', '&' might cause trouble in filenames and are therefore replaced by '-'." => "Buchstaben-Beschränkungen: '#' und '|' haben eine spezielle Bedeutung in Links, sie werden deshalb entfernt. Weiters können die Zeichen '~', '/', '\\', ':', '|', '&' Probleme in Dateinamen verursachen, und werden deshalb durch einen Bindestrich '-' ersetzt.", - 'Image deleted' => 'Bild gelöscht', - 'Error deleting image' => 'Fehler beim Löschen des Bildes', - // Override TITLE_DATE and TITLE_DATE_NO_TIME if set. - 'date_format' => 'd.m.Y H:i', - 'date_format_no_time' => 'd.m.Y', -); diff --git a/locales/en.php b/locales/en.php deleted file mode 100755 index c609d05..0000000 --- a/locales/en.php +++ /dev/null @@ -1,32 +0,0 @@ - 'Home', - 'New' => 'New', - 'Edit' => 'Edit', - 'Upload' => 'Upload', - 'All' => 'All', - 'Recent' => 'Recent', - 'Exit' => 'Exit', - 'Search' => 'Search', - 'Save' => 'Save', - 'Cancel' => 'Cancel', - 'Saved' => 'Saved', - 'Log In' => 'Log In', - 'Title' => 'Title', - // Messages - 'Upload error' => 'Upload error', - 'Upload error: invalid file type' => 'Upload error: invalid file type', - 'Image uploading has been disabled on this installation.' => 'Image uploading has been disabled on this installation.', - // Override TITLE_DATE and TITLE_DATE_NO_TIME if set. - 'date_format' => 'Y-m-d H:i:s', - 'date_format_no_time' => 'Y-m-d', -); diff --git a/locales/ja.php b/locales/ja.php deleted file mode 100755 index 26ca03a..0000000 --- a/locales/ja.php +++ /dev/null @@ -1,32 +0,0 @@ - 'ホーム', - 'New' => '新規', - 'Edit' => '編集', - 'Upload' => 'アップロード', - 'All' => '全て', - 'Recent' => '最近', - 'Exit' => 'ログアウト', - 'Search' => '検索', - 'Save' => '保存', - 'Cancel' => 'キャンセル', - 'Saved' => '保存しました', - 'Log In' => 'ログイン', - 'Title' => 'ページタイトル', - // Messages - 'Upload error' => 'アップロードエラー', - 'Upload error: invalid file type' => 'アップロードエラー:不正なファイル形式です', - 'Image uploading has been disabled on this installation.' => '画像アップロードは許可されていません。', - // Override TITLE_DATE and TITLE_DATE_NO_TIME if set. - 'date_format' => 'Y-m-d H:i:s', - 'date_format_no_time' => 'Y-m-d', -); diff --git a/locales/sample.php b/locales/sample.php deleted file mode 100755 index c609d05..0000000 --- a/locales/sample.php +++ /dev/null @@ -1,32 +0,0 @@ - 'Home', - 'New' => 'New', - 'Edit' => 'Edit', - 'Upload' => 'Upload', - 'All' => 'All', - 'Recent' => 'Recent', - 'Exit' => 'Exit', - 'Search' => 'Search', - 'Save' => 'Save', - 'Cancel' => 'Cancel', - 'Saved' => 'Saved', - 'Log In' => 'Log In', - 'Title' => 'Title', - // Messages - 'Upload error' => 'Upload error', - 'Upload error: invalid file type' => 'Upload error: invalid file type', - 'Image uploading has been disabled on this installation.' => 'Image uploading has been disabled on this installation.', - // Override TITLE_DATE and TITLE_DATE_NO_TIME if set. - 'date_format' => 'Y-m-d H:i:s', - 'date_format_no_time' => 'Y-m-d', -); diff --git a/md/Markdown.inc.php b/md/Markdown.inc.php deleted file mode 100755 index e2bd380..0000000 --- a/md/Markdown.inc.php +++ /dev/null @@ -1,10 +0,0 @@ - - * @copyright 2004-2019 Michel Fortin - * @copyright (Original Markdown) 2004-2006 John Gruber - */ - -namespace md; - -/** - * Markdown Parser Class - */ -class Markdown implements MarkdownInterface { - /** - * Define the package version - * @var string - */ - const MARKDOWNLIB_VERSION = "1.9.0"; - - /** - * Simple function interface - Initialize the parser and return the result - * of its transform method. This will work fine for derived classes too. - * - * @api - * - * @param string $text - * @return string - */ - public static function defaultTransform($text) { - // Take parser class on which this function was called. - $parser_class = \get_called_class(); - - // Try to take parser from the static parser list - static $parser_list; - $parser =& $parser_list[$parser_class]; - - // Create the parser it not already set - if (!$parser) { - $parser = new $parser_class; - } - - // Transform text using parser. - return $parser->transform($text); - } - - /** - * Configuration variables - */ - - /** - * Change to ">" for HTML output. - * @var string - */ - public $empty_element_suffix = " />"; - - /** - * The width of indentation of the output markup - * @var int - */ - public $tab_width = 4; - - /** - * Change to `true` to disallow markup or entities. - * @var boolean - */ - public $no_markup = false; - public $no_entities = false; - - - /** - * Change to `true` to enable line breaks on \n without two trailling spaces - * @var boolean - */ - public $hard_wrap = false; - - /** - * Predefined URLs and titles for reference links and images. - * @var array - */ - public $predef_urls = array(); - public $predef_titles = array(); - - /** - * Optional filter function for URLs - * @var callable|null - */ - public $url_filter_func = null; - - /** - * Optional header id="" generation callback function. - * @var callable|null - */ - public $header_id_func = null; - - /** - * Optional function for converting code block content to HTML - * @var callable|null - */ - public $code_block_content_func = null; - - /** - * Optional function for converting code span content to HTML. - * @var callable|null - */ - public $code_span_content_func = null; - - /** - * Class attribute to toggle "enhanced ordered list" behaviour - * setting this to true will allow ordered lists to start from the index - * number that is defined first. - * - * For example: - * 2. List item two - * 3. List item three - * - * Becomes: - *
    - *
  1. List item two
  2. - *
  3. List item three
  4. - *
- * - * @var bool - */ - public $enhanced_ordered_list = false; - - /** - * Parser implementation - */ - - /** - * Regex to match balanced [brackets]. - * Needed to insert a maximum bracked depth while converting to PHP. - * @var int - */ - protected $nested_brackets_depth = 6; - protected $nested_brackets_re; - - protected $nested_url_parenthesis_depth = 4; - protected $nested_url_parenthesis_re; - - /** - * Table of hash values for escaped characters: - * @var string - */ - protected $escape_chars = '\`*_{}[]()>#+-.!'; - protected $escape_chars_re; - - /** - * Constructor function. Initialize appropriate member variables. - * @return void - */ - public function __construct() { - $this->_initDetab(); - $this->prepareItalicsAndBold(); - - $this->nested_brackets_re = - str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). - str_repeat('\])*', $this->nested_brackets_depth); - - $this->nested_url_parenthesis_re = - str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). - str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); - - $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; - - // Sort document, block, and span gamut in ascendent priority order. - asort($this->document_gamut); - asort($this->block_gamut); - asort($this->span_gamut); - } - - - /** - * Internal hashes used during transformation. - * @var array - */ - protected $urls = array(); - protected $titles = array(); - protected $html_hashes = array(); - - /** - * Status flag to avoid invalid nesting. - * @var boolean - */ - protected $in_anchor = false; - - /** - * Status flag to avoid invalid nesting. - * @var boolean - */ - protected $in_emphasis_processing = false; - - /** - * Called before the transformation process starts to setup parser states. - * @return void - */ - protected function setup() { - // Clear global hashes. - $this->urls = $this->predef_urls; - $this->titles = $this->predef_titles; - $this->html_hashes = array(); - $this->in_anchor = false; - $this->in_emphasis_processing = false; - } - - /** - * Called after the transformation process to clear any variable which may - * be taking up memory unnecessarly. - * @return void - */ - protected function teardown() { - $this->urls = array(); - $this->titles = array(); - $this->html_hashes = array(); - } - - /** - * Main function. Performs some preprocessing on the input text and pass - * it through the document gamut. - * - * @api - * - * @param string $text - * @return string - */ - public function transform($text) { - $this->setup(); - - # Remove UTF-8 BOM and marker character in input, if present. - $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); - - # Standardize line endings: - # DOS to Unix and Mac to Unix - $text = preg_replace('{\r\n?}', "\n", $text); - - # Make sure $text ends with a couple of newlines: - $text .= "\n\n"; - - # Convert all tabs to spaces. - $text = $this->detab($text); - - # Turn block-level HTML blocks into hash entries - $text = $this->hashHTMLBlocks($text); - - # Strip any lines consisting only of spaces and tabs. - # This makes subsequent regexen easier to write, because we can - # match consecutive blank lines with /\n+/ instead of something - # contorted like /[ ]*\n+/ . - $text = preg_replace('/^[ ]+$/m', '', $text); - - # Run document gamut methods. - foreach ($this->document_gamut as $method => $priority) { - $text = $this->$method($text); - } - - $this->teardown(); - - return $text . "\n"; - } - - /** - * Define the document gamut - * @var array - */ - protected $document_gamut = array( - // Strip link definitions, store in hashes. - "stripLinkDefinitions" => 20, - "runBasicBlockGamut" => 30, - ); - - /** - * Strips link definitions from text, stores the URLs and titles in - * hash references - * @param string $text - * @return string - */ - protected function stripLinkDefinitions($text) { - - $less_than_tab = $this->tab_width - 1; - - // Link defs are in the form: ^[id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (?: - <(.+?)> # url = $2 - | - (\S+?) # url = $3 - ) - [ ]* - \n? # maybe one newline - [ ]* - (?: - (?<=\s) # lookbehind for whitespace - ["(] - (.*?) # title = $4 - [")] - [ ]* - )? # title is optional - (?:\n+|\Z) - }xm', - array($this, '_stripLinkDefinitions_callback'), - $text - ); - return $text; - } - - /** - * The callback to strip link definitions - * @param array $matches - * @return string - */ - protected function _stripLinkDefinitions_callback($matches) { - $link_id = strtolower($matches[1]); - $url = $matches[2] == '' ? $matches[3] : $matches[2]; - $this->urls[$link_id] = $url; - $this->titles[$link_id] =& $matches[4]; - return ''; // String that will replace the block - } - - /** - * Hashify HTML blocks - * @param string $text - * @return string - */ - protected function hashHTMLBlocks($text) { - if ($this->no_markup) { - return $text; - } - - $less_than_tab = $this->tab_width - 1; - - /** - * Hashify HTML blocks: - * - * We only want to do this for block-level HTML tags, such as headers, - * lists, and tables. That's because we still want to wrap

s around - * "paragraphs" that are wrapped in non-block-level tags, such as - * anchors, phrase emphasis, and spans. The list of tags we're looking - * for is hard-coded: - * - * * List "a" is made of tags which can be both inline or block-level. - * These will be treated block-level when the start tag is alone on - * its line, otherwise they're not matched here and will be taken as - * inline later. - * * List "b" is made of tags which are always block-level; - */ - $block_tags_a_re = 'ins|del'; - $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. - 'script|noscript|style|form|fieldset|iframe|math|svg|'. - 'article|section|nav|aside|hgroup|header|footer|'. - 'figure|details|summary'; - - // Regular expression for the content of a block tag. - $nested_tags_level = 4; - $attr = ' - (?> # optional tag attributes - \s # starts with whitespace - (?> - [^>"/]+ # text outside quotes - | - /+(?!>) # slash not followed by ">" - | - "[^"]*" # text inside double quotes (tolerate ">") - | - \'[^\']*\' # text inside single quotes (tolerate ">") - )* - )? - '; - $content = - str_repeat(' - (?> - [^<]+ # content without tag - | - <\2 # nested opening tag - '.$attr.' # attributes - (?> - /> - | - >', $nested_tags_level). // end of opening tag - '.*?'. // last level nested tag content - str_repeat(' - # closing nested tag - ) - | - <(?!/\2\s*> # other tags with a different name - ) - )*', - $nested_tags_level); - $content2 = str_replace('\2', '\3', $content); - - /** - * First, look for nested blocks, e.g.: - *

- *
- * tags for inner block must be indented. - *
- *
- * - * The outermost tags must start at the left margin for this to match, - * and the inner nested divs must be indented. - * We need to do this before the next, more liberal match, because the - * next match will start at the first `
` and stop at the - * first `
`. - */ - $text = preg_replace_callback('{(?> - (?> - (?<=\n) # Starting on its own line - | # or - \A\n? # the at beginning of the doc - ) - ( # save in $1 - - # Match from `\n` to `\n`, handling nested tags - # in between. - - [ ]{0,'.$less_than_tab.'} - <('.$block_tags_b_re.')# start tag = $2 - '.$attr.'> # attributes followed by > and \n - '.$content.' # content, support nesting - # the matching end tag - [ ]* # trailing spaces/tabs - (?=\n+|\Z) # followed by a newline or end of document - - | # Special version for tags of group a. - - [ ]{0,'.$less_than_tab.'} - <('.$block_tags_a_re.')# start tag = $3 - '.$attr.'>[ ]*\n # attributes followed by > - '.$content2.' # content, support nesting - # the matching end tag - [ ]* # trailing spaces/tabs - (?=\n+|\Z) # followed by a newline or end of document - - | # Special case just for
. It was easier to make a special - # case than to make the other regex more complicated. - - [ ]{0,'.$less_than_tab.'} - <(hr) # start tag = $2 - '.$attr.' # attributes - /?> # the matching end tag - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - | # Special case for standalone HTML comments: - - [ ]{0,'.$less_than_tab.'} - (?s: - - ) - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - | # PHP and ASP-style processor instructions ( - ) - [ ]* - (?=\n{2,}|\Z) # followed by a blank line or end of document - - ) - )}Sxmi', - array($this, '_hashHTMLBlocks_callback'), - $text - ); - - return $text; - } - - /** - * The callback for hashing HTML blocks - * @param string $matches - * @return string - */ - protected function _hashHTMLBlocks_callback($matches) { - $text = $matches[1]; - $key = $this->hashBlock($text); - return "\n\n$key\n\n"; - } - - /** - * Called whenever a tag must be hashed when a function insert an atomic - * element in the text stream. Passing $text to through this function gives - * a unique text-token which will be reverted back when calling unhash. - * - * The $boundary argument specify what character should be used to surround - * the token. By convension, "B" is used for block elements that needs not - * to be wrapped into paragraph tags at the end, ":" is used for elements - * that are word separators and "X" is used in the general case. - * - * @param string $text - * @param string $boundary - * @return string - */ - protected function hashPart($text, $boundary = 'X') { - // Swap back any tag hash found in $text so we do not have to `unhash` - // multiple times at the end. - $text = $this->unhash($text); - - // Then hash the block. - static $i = 0; - $key = "$boundary\x1A" . ++$i . $boundary; - $this->html_hashes[$key] = $text; - return $key; // String that will replace the tag. - } - - /** - * Shortcut function for hashPart with block-level boundaries. - * @param string $text - * @return string - */ - protected function hashBlock($text) { - return $this->hashPart($text, 'B'); - } - - /** - * Define the block gamut - these are all the transformations that form - * block-level tags like paragraphs, headers, and list items. - * @var array - */ - protected $block_gamut = array( - "doHeaders" => 10, - "doHorizontalRules" => 20, - "doLists" => 40, - "doCodeBlocks" => 50, - "doBlockQuotes" => 60, - ); - - /** - * Run block gamut tranformations. - * - * We need to escape raw HTML in Markdown source before doing anything - * else. This need to be done for each block, and not only at the - * begining in the Markdown function since hashed blocks can be part of - * list items and could have been indented. Indented blocks would have - * been seen as a code block in a previous pass of hashHTMLBlocks. - * - * @param string $text - * @return string - */ - protected function runBlockGamut($text) { - $text = $this->hashHTMLBlocks($text); - return $this->runBasicBlockGamut($text); - } - - /** - * Run block gamut tranformations, without hashing HTML blocks. This is - * useful when HTML blocks are known to be already hashed, like in the first - * whole-document pass. - * - * @param string $text - * @return string - */ - protected function runBasicBlockGamut($text) { - - foreach ($this->block_gamut as $method => $priority) { - $text = $this->$method($text); - } - - // Finally form paragraph and restore hashed blocks. - $text = $this->formParagraphs($text); - - return $text; - } - - /** - * Convert horizontal rules - * @param string $text - * @return string - */ - protected function doHorizontalRules($text) { - return preg_replace( - '{ - ^[ ]{0,3} # Leading space - ([-*_]) # $1: First marker - (?> # Repeated marker group - [ ]{0,2} # Zero, one, or two spaces. - \1 # Marker character - ){2,} # Group repeated at least twice - [ ]* # Tailing spaces - $ # End of line. - }mx', - "\n".$this->hashBlock("empty_element_suffix")."\n", - $text - ); - } - - /** - * These are all the transformations that occur *within* block-level - * tags like paragraphs, headers, and list items. - * @var array - */ - protected $span_gamut = array( - // Process character escapes, code spans, and inline HTML - // in one shot. - "parseSpan" => -30, - // Process anchor and image tags. Images must come first, - // because ![foo][f] looks like an anchor. - "doImages" => 10, - "doAnchors" => 20, - // Make links out of things like `` - // Must come after doAnchors, because you can use < and > - // delimiters in inline links like [this](). - "doAutoLinks" => 30, - "encodeAmpsAndAngles" => 40, - "doItalicsAndBold" => 50, - "doHardBreaks" => 60, - ); - - /** - * Run span gamut transformations - * @param string $text - * @return string - */ - protected function runSpanGamut($text) { - foreach ($this->span_gamut as $method => $priority) { - $text = $this->$method($text); - } - - return $text; - } - - /** - * Do hard breaks - * @param string $text - * @return string - */ - protected function doHardBreaks($text) { - if ($this->hard_wrap) { - return preg_replace_callback('/ *\n/', - array($this, '_doHardBreaks_callback'), $text); - } else { - return preg_replace_callback('/ {2,}\n/', - array($this, '_doHardBreaks_callback'), $text); - } - } - - /** - * Trigger part hashing for the hard break (callback method) - * @param array $matches - * @return string - */ - protected function _doHardBreaks_callback($matches) { - return $this->hashPart("empty_element_suffix\n"); - } - - /** - * Turn Markdown link shortcuts into XHTML tags. - * @param string $text - * @return string - */ - protected function doAnchors($text) { - if ($this->in_anchor) { - return $text; - } - $this->in_anchor = true; - - // First, handle reference-style links: [link text] [id] - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - // Next, inline-style links: [link text](url "optional title") - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ('.$this->nested_brackets_re.') # link text = $2 - \] - \( # literal paren - [ \n]* - (?: - <(.+?)> # href = $3 - | - ('.$this->nested_url_parenthesis_re.') # href = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # Title = $7 - \6 # matching quote - [ \n]* # ignore any spaces/tabs between closing quote and ) - )? # title is optional - \) - ) - }xs', - array($this, '_doAnchors_inline_callback'), $text); - - // Last, handle reference-style shortcuts: [link text] - // These must come last in case you've also got [link text][1] - // or [link text](/foo) - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ([^\[\]]+) # link text = $2; can\'t contain [ or ] - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - $this->in_anchor = false; - return $text; - } - - /** - * Callback method to parse referenced anchors - * @param string $matches - * @return string - */ - protected function _doAnchors_reference_callback($matches) { - $whole_match = $matches[1]; - $link_text = $matches[2]; - $link_id =& $matches[3]; - - if ($link_id == "") { - // for shortcut links like [this][] or [this]. - $link_id = $link_text; - } - - // lower-case and turn embedded newlines into spaces - $link_id = strtolower($link_id); - $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); - - if (isset($this->urls[$link_id])) { - $url = $this->urls[$link_id]; - $url = $this->encodeURLAttribute($url); - - $result = "titles[$link_id] ) ) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - $result = $this->hashPart($result); - } else { - $result = $whole_match; - } - return $result; - } - - /** - * Callback method to parse inline anchors - * @param string $matches - * @return string - */ - protected function _doAnchors_inline_callback($matches) { - $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] === '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - - // If the URL was of the form it got caught by the HTML - // tag parser and hashed. Need to reverse the process before using - // the URL. - $unhashed = $this->unhash($url); - if ($unhashed !== $url) - $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); - - $url = $this->encodeURLAttribute($url); - - $result = "encodeAttribute($title); - $result .= " title=\"$title\""; - } - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - - return $this->hashPart($result); - } - - /** - * Turn Markdown image shortcuts into tags. - * @param string $text - * @return string - */ - protected function doImages($text) { - // First, handle reference-style labeled images: ![alt text][id] - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - - ) - }xs', - array($this, '_doImages_reference_callback'), $text); - - // Next, handle inline images: ![alt text](url "optional title") - // Don't forget: encode * and _ - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - ('.$this->nested_brackets_re.') # alt text = $2 - \] - \s? # One optional whitespace character - \( # literal paren - [ \n]* - (?: - <(\S*)> # src url = $3 - | - ('.$this->nested_url_parenthesis_re.') # src url = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # title = $7 - \6 # matching quote - [ \n]* - )? # title is optional - \) - ) - }xs', - array($this, '_doImages_inline_callback'), $text); - - return $text; - } - - /** - * Callback to parse references image tags - * @param array $matches - * @return string - */ - protected function _doImages_reference_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $link_id = strtolower($matches[3]); - - if ($link_id == "") { - $link_id = strtolower($alt_text); // for shortcut links like ![this][]. - } - - $alt_text = $this->encodeAttribute($alt_text); - if (isset($this->urls[$link_id])) { - $url = $this->encodeURLAttribute($this->urls[$link_id]); - $result = "\"$alt_text\"";titles[$link_id])) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - $result .= $this->empty_element_suffix; - $result = $this->hashPart($result); - } else { - // If there's no such link ID, leave intact: - $result = $whole_match; - } - - return $result; - } - - /** - * Callback to parse inline image tags - * @param array $matches - * @return string - */ - protected function _doImages_inline_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $url = $matches[3] == '' ? $matches[4] : $matches[3]; - $title =& $matches[7]; - - $alt_text = $this->encodeAttribute($alt_text); - $url = $this->encodeURLAttribute($url); - $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; // $title already quoted - } - $result .= $this->empty_element_suffix; - - return $this->hashPart($result); - } - - /** - * Parse Markdown heading elements to HTML - * @param string $text - * @return string - */ - protected function doHeaders($text) { - /** - * Setext-style headers: - * Header 1 - * ======== - * - * Header 2 - * -------- - */ - $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', - array($this, '_doHeaders_callback_setext'), $text); - - /** - * atx-style headers: - * # Header 1 - * ## Header 2 - * ## Header 2 with closing hashes ## - * ... - * ###### Header 6 - */ - $text = preg_replace_callback('{ - ^(\#{1,6}) # $1 = string of #\'s - [ ]* - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #\'s (not counted) - \n+ - }xm', - array($this, '_doHeaders_callback_atx'), $text); - - return $text; - } - - /** - * Setext header parsing callback - * @param array $matches - * @return string - */ - protected function _doHeaders_callback_setext($matches) { - // Terrible hack to check we haven't found an empty list item. - if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { - return $matches[0]; - } - - $level = $matches[2][0] == '=' ? 1 : 2; - - // ID attribute generation - $idAtt = $this->_generateIdFromHeaderValue($matches[1]); - - $block = "".$this->runSpanGamut($matches[1]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - /** - * ATX header parsing callback - * @param array $matches - * @return string - */ - protected function _doHeaders_callback_atx($matches) { - // ID attribute generation - $idAtt = $this->_generateIdFromHeaderValue($matches[2]); - - $level = strlen($matches[1]); - $block = "".$this->runSpanGamut($matches[2]).""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - /** - * If a header_id_func property is set, we can use it to automatically - * generate an id attribute. - * - * This method returns a string in the form id="foo", or an empty string - * otherwise. - * @param string $headerValue - * @return string - */ - protected function _generateIdFromHeaderValue($headerValue) { - if (!is_callable($this->header_id_func)) { - return ""; - } - - $idValue = call_user_func($this->header_id_func, $headerValue); - if (!$idValue) { - return ""; - } - - return ' id="' . $this->encodeAttribute($idValue) . '"'; - } - - /** - * Form HTML ordered (numbered) and unordered (bulleted) lists. - * @param string $text - * @return string - */ - protected function doLists($text) { - $less_than_tab = $this->tab_width - 1; - - // Re-usable patterns to match list item bullets and number markers: - $marker_ul_re = '[*+-]'; - $marker_ol_re = '\d+[\.]'; - - $markers_relist = array( - $marker_ul_re => $marker_ol_re, - $marker_ol_re => $marker_ul_re, - ); - - foreach ($markers_relist as $marker_re => $other_marker_re) { - // Re-usable pattern to match any entirel ul or ol list: - $whole_list_re = ' - ( # $1 = whole list - ( # $2 - ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces - ('.$marker_re.') # $4 = first list item marker - [ ]+ - ) - (?s:.+?) - ( # $5 - \z - | - \n{2,} - (?=\S) - (?! # Negative lookahead for another list item marker - [ ]* - '.$marker_re.'[ ]+ - ) - | - (?= # Lookahead for another kind of list - \n - \3 # Must have the same indentation - '.$other_marker_re.'[ ]+ - ) - ) - ) - '; // mx - - // We use a different prefix before nested lists than top-level lists. - //See extended comment in _ProcessListItems(). - - if ($this->list_level) { - $text = preg_replace_callback('{ - ^ - '.$whole_list_re.' - }mx', - array($this, '_doLists_callback'), $text); - } else { - $text = preg_replace_callback('{ - (?:(?<=\n)\n|\A\n?) # Must eat the newline - '.$whole_list_re.' - }mx', - array($this, '_doLists_callback'), $text); - } - } - - return $text; - } - - /** - * List parsing callback - * @param array $matches - * @return string - */ - protected function _doLists_callback($matches) { - // Re-usable patterns to match list item bullets and number markers: - $marker_ul_re = '[*+-]'; - $marker_ol_re = '\d+[\.]'; - $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; - $marker_ol_start_re = '[0-9]+'; - - $list = $matches[1]; - $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol"; - - $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); - - $list .= "\n"; - $result = $this->processListItems($list, $marker_any_re); - - $ol_start = 1; - if ($this->enhanced_ordered_list) { - // Get the start number for ordered list. - if ($list_type == 'ol') { - $ol_start_array = array(); - $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array); - if ($ol_start_check){ - $ol_start = $ol_start_array[0]; - } - } - } - - if ($ol_start > 1 && $list_type == 'ol'){ - $result = $this->hashBlock("<$list_type start=\"$ol_start\">\n" . $result . ""); - } else { - $result = $this->hashBlock("<$list_type>\n" . $result . ""); - } - return "\n". $result ."\n\n"; - } - - /** - * Nesting tracker for list levels - * @var integer - */ - protected $list_level = 0; - - /** - * Process the contents of a single ordered or unordered list, splitting it - * into individual list items. - * @param string $list_str - * @param string $marker_any_re - * @return string - */ - protected function processListItems($list_str, $marker_any_re) { - /** - * The $this->list_level global keeps track of when we're inside a list. - * Each time we enter a list, we increment it; when we leave a list, - * we decrement. If it's zero, we're not in a list anymore. - * - * We do this because when we're not inside a list, we want to treat - * something like this: - * - * I recommend upgrading to version - * 8. Oops, now this line is treated - * as a sub-list. - * - * As a single paragraph, despite the fact that the second line starts - * with a digit-period-space sequence. - * - * Whereas when we're inside a list (or sub-list), that line will be - * treated as the start of a sub-list. What a kludge, huh? This is - * an aspect of Markdown's syntax that's hard to parse perfectly - * without resorting to mind-reading. Perhaps the solution is to - * change the syntax rules such that sub-lists must start with a - * starting cardinal number; e.g. "1." or "a.". - */ - $this->list_level++; - - // Trim trailing blank lines: - $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - - $list_str = preg_replace_callback('{ - (\n)? # leading line = $1 - (^[ ]*) # leading whitespace = $2 - ('.$marker_any_re.' # list marker and space = $3 - (?:[ ]+|(?=\n)) # space only required if item is not empty - ) - ((?s:.*?)) # list item text = $4 - (?:(\n+(?=\n))|\n) # tailing blank line = $5 - (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) - }xm', - array($this, '_processListItems_callback'), $list_str); - - $this->list_level--; - return $list_str; - } - - /** - * List item parsing callback - * @param array $matches - * @return string - */ - protected function _processListItems_callback($matches) { - $item = $matches[4]; - $leading_line =& $matches[1]; - $leading_space =& $matches[2]; - $marker_space = $matches[3]; - $tailing_blank_line =& $matches[5]; - - if ($leading_line || $tailing_blank_line || - preg_match('/\n{2,}/', $item)) - { - // Replace marker with the appropriate whitespace indentation - $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; - $item = $this->runBlockGamut($this->outdent($item)."\n"); - } else { - // Recursion for sub-lists: - $item = $this->doLists($this->outdent($item)); - $item = $this->formParagraphs($item, false); - } - - return "
  • " . $item . "
  • \n"; - } - - /** - * Process Markdown `
    ` blocks.
    -	 * @param  string $text
    -	 * @return string
    -	 */
    -	protected function doCodeBlocks($text) {
    -		$text = preg_replace_callback('{
    -				(?:\n\n|\A\n?)
    -				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    -				  (?>
    -					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
    -					.*\n+
    -				  )+
    -				)
    -				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
    -			}xm',
    -			array($this, '_doCodeBlocks_callback'), $text);
    -
    -		return $text;
    -	}
    -
    -	/**
    -	 * Code block parsing callback
    -	 * @param  array $matches
    -	 * @return string
    -	 */
    -	protected function _doCodeBlocks_callback($matches) {
    -		$codeblock = $matches[1];
    -
    -		$codeblock = $this->outdent($codeblock);
    -		if (is_callable($this->code_block_content_func)) {
    -			$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
    -		} else {
    -			$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    -		}
    -
    -		# trim leading newlines and trailing newlines
    -		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
    -
    -		$codeblock = "
    $codeblock\n
    "; - return "\n\n" . $this->hashBlock($codeblock) . "\n\n"; - } - - /** - * Create a code span markup for $code. Called from handleSpanToken. - * @param string $code - * @return string - */ - protected function makeCodeSpan($code) { - if (is_callable($this->code_span_content_func)) { - $code = call_user_func($this->code_span_content_func, $code); - } else { - $code = htmlspecialchars(trim($code), ENT_NOQUOTES); - } - return $this->hashPart("$code"); - } - - /** - * Define the emphasis operators with their regex matches - * @var array - */ - protected $em_relist = array( - '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(?em_relist as $em => $em_re) { - foreach ($this->strong_relist as $strong => $strong_re) { - // Construct list of allowed token expressions. - $token_relist = array(); - if (isset($this->em_strong_relist["$em$strong"])) { - $token_relist[] = $this->em_strong_relist["$em$strong"]; - } - $token_relist[] = $em_re; - $token_relist[] = $strong_re; - - // Construct master expression from list. - $token_re = '{(' . implode('|', $token_relist) . ')}'; - $this->em_strong_prepared_relist["$em$strong"] = $token_re; - } - } - } - - /** - * Convert Markdown italics (emphasis) and bold (strong) to HTML - * @param string $text - * @return string - */ - protected function doItalicsAndBold($text) { - if ($this->in_emphasis_processing) { - return $text; // avoid reentrency - } - $this->in_emphasis_processing = true; - - $token_stack = array(''); - $text_stack = array(''); - $em = ''; - $strong = ''; - $tree_char_em = false; - - while (1) { - // Get prepared regular expression for seraching emphasis tokens - // in current context. - $token_re = $this->em_strong_prepared_relist["$em$strong"]; - - // Each loop iteration search for the next emphasis token. - // Each token is then passed to handleSpanToken. - $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - $text_stack[0] .= $parts[0]; - $token =& $parts[1]; - $text =& $parts[2]; - - if (empty($token)) { - // Reached end of text span: empty stack without emitting. - // any more emphasis. - while ($token_stack[0]) { - $text_stack[1] .= array_shift($token_stack); - $text_stack[0] .= array_shift($text_stack); - } - break; - } - - $token_len = strlen($token); - if ($tree_char_em) { - // Reached closing marker while inside a three-char emphasis. - if ($token_len == 3) { - // Three-char closing marker, close em and strong. - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $em = ''; - $strong = ''; - } else { - // Other closing marker: close one em or strong and - // change current token state to match the other - $token_stack[0] = str_repeat($token[0], 3-$token_len); - $tag = $token_len == 2 ? "strong" : "em"; - $span = $text_stack[0]; - $span = $this->runSpanGamut($span); - $span = "<$tag>$span"; - $text_stack[0] = $this->hashPart($span); - $$tag = ''; // $$tag stands for $em or $strong - } - $tree_char_em = false; - } else if ($token_len == 3) { - if ($em) { - // Reached closing marker for both em and strong. - // Closing strong marker: - for ($i = 0; $i < 2; ++$i) { - $shifted_token = array_shift($token_stack); - $tag = strlen($shifted_token) == 2 ? "strong" : "em"; - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "<$tag>$span"; - $text_stack[0] .= $this->hashPart($span); - $$tag = ''; // $$tag stands for $em or $strong - } - } else { - // Reached opening three-char emphasis marker. Push on token - // stack; will be handled by the special condition above. - $em = $token[0]; - $strong = "$em$em"; - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $tree_char_em = true; - } - } else if ($token_len == 2) { - if ($strong) { - // Unwind any dangling emphasis marker: - if (strlen($token_stack[0]) == 1) { - $text_stack[1] .= array_shift($token_stack); - $text_stack[0] .= array_shift($text_stack); - $em = ''; - } - // Closing strong marker: - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $strong = ''; - } else { - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $strong = $token; - } - } else { - // Here $token_len == 1 - if ($em) { - if (strlen($token_stack[0]) == 1) { - // Closing emphasis marker: - array_shift($token_stack); - $span = array_shift($text_stack); - $span = $this->runSpanGamut($span); - $span = "$span"; - $text_stack[0] .= $this->hashPart($span); - $em = ''; - } else { - $text_stack[0] .= $token; - } - } else { - array_unshift($token_stack, $token); - array_unshift($text_stack, ''); - $em = $token; - } - } - } - $this->in_emphasis_processing = false; - return $text_stack[0]; - } - - /** - * Parse Markdown blockquotes to HTML - * @param string $text - * @return string - */ - protected function doBlockQuotes($text) { - $text = preg_replace_callback('/ - ( # Wrap whole match in $1 - (?> - ^[ ]*>[ ]? # ">" at the start of a line - .+\n # rest of the first line - (.+\n)* # subsequent consecutive lines - \n* # blanks - )+ - ) - /xm', - array($this, '_doBlockQuotes_callback'), $text); - - return $text; - } - - /** - * Blockquote parsing callback - * @param array $matches - * @return string - */ - protected function _doBlockQuotes_callback($matches) { - $bq = $matches[1]; - // trim one level of quoting - trim whitespace-only lines - $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); - $bq = $this->runBlockGamut($bq); // recurse - - $bq = preg_replace('/^/m', " ", $bq); - // These leading spaces cause problem with
     content,
    -		// so we need to fix that:
    -		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', - array($this, '_doBlockQuotes_callback2'), $bq); - - return "\n" . $this->hashBlock("
    \n$bq\n
    ") . "\n\n"; - } - - /** - * Blockquote parsing callback - * @param array $matches - * @return string - */ - protected function _doBlockQuotes_callback2($matches) { - $pre = $matches[1]; - $pre = preg_replace('/^ /m', '', $pre); - return $pre; - } - - /** - * Parse paragraphs - * - * @param string $text String to process in paragraphs - * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

    tags - * @return string - */ - protected function formParagraphs($text, $wrap_in_p = true) { - // Strip leading and trailing lines: - $text = preg_replace('/\A\n+|\n+\z/', '', $text); - - $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - - // Wrap

    tags and unhashify HTML blocks - foreach ($grafs as $key => $value) { - if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { - // Is a paragraph. - $value = $this->runSpanGamut($value); - if ($wrap_in_p) { - $value = preg_replace('/^([ ]*)/', "

    ", $value); - $value .= "

    "; - } - $grafs[$key] = $this->unhash($value); - } else { - // Is a block. - // Modify elements of @grafs in-place... - $graf = $value; - $block = $this->html_hashes[$graf]; - $graf = $block; -// if (preg_match('{ -// \A -// ( # $1 =
    tag -//
    ]* -// \b -// markdown\s*=\s* ([\'"]) # $2 = attr quote char -// 1 -// \2 -// [^>]* -// > -// ) -// ( # $3 = contents -// .* -// ) -// (
    ) # $4 = closing tag -// \z -// }xs', $block, $matches)) -// { -// list(, $div_open, , $div_content, $div_close) = $matches; -// -// // We can't call Markdown(), because that resets the hash; -// // that initialization code should be pulled into its own sub, though. -// $div_content = $this->hashHTMLBlocks($div_content); -// -// // Run document gamut methods on the content. -// foreach ($this->document_gamut as $method => $priority) { -// $div_content = $this->$method($div_content); -// } -// -// $div_open = preg_replace( -// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); -// -// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; -// } - $grafs[$key] = $graf; - } - } - - return implode("\n\n", $grafs); - } - - /** - * Encode text for a double-quoted HTML attribute. This function - * is *not* suitable for attributes enclosed in single quotes. - * @param string $text - * @return string - */ - protected function encodeAttribute($text) { - $text = $this->encodeAmpsAndAngles($text); - $text = str_replace('"', '"', $text); - return $text; - } - - /** - * Encode text for a double-quoted HTML attribute containing a URL, - * applying the URL filter if set. Also generates the textual - * representation for the URL (removing mailto: or tel:) storing it in $text. - * This function is *not* suitable for attributes enclosed in single quotes. - * - * @param string $url - * @param string $text Passed by reference - * @return string URL - */ - protected function encodeURLAttribute($url, &$text = null) { - if (is_callable($this->url_filter_func)) { - $url = call_user_func($this->url_filter_func, $url); - } - - if (preg_match('{^mailto:}i', $url)) { - $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7); - } else if (preg_match('{^tel:}i', $url)) { - $url = $this->encodeAttribute($url); - $text = substr($url, 4); - } else { - $url = $this->encodeAttribute($url); - $text = $url; - } - - return $url; - } - - /** - * Smart processing for ampersands and angle brackets that need to - * be encoded. Valid character entities are left alone unless the - * no-entities mode is set. - * @param string $text - * @return string - */ - protected function encodeAmpsAndAngles($text) { - if ($this->no_entities) { - $text = str_replace('&', '&', $text); - } else { - // Ampersand-encoding based entirely on Nat Irons's Amputator - // MT plugin: - $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', - '&', $text); - } - // Encode remaining <'s - $text = str_replace('<', '<', $text); - - return $text; - } - - /** - * Parse Markdown automatic links to anchor HTML tags - * @param string $text - * @return string - */ - protected function doAutoLinks($text) { - $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i', - array($this, '_doAutoLinks_url_callback'), $text); - - // Email addresses: - $text = preg_replace_callback('{ - < - (?:mailto:)? - ( - (?: - [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+ - | - ".*?" - ) - \@ - (?: - [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ - | - \[[\d.a-fA-F:]+\] # IPv4 & IPv6 - ) - ) - > - }xi', - array($this, '_doAutoLinks_email_callback'), $text); - - return $text; - } - - /** - * Parse URL callback - * @param array $matches - * @return string - */ - protected function _doAutoLinks_url_callback($matches) { - $url = $this->encodeURLAttribute($matches[1], $text); - $link = "$text"; - return $this->hashPart($link); - } - - /** - * Parse email address callback - * @param array $matches - * @return string - */ - protected function _doAutoLinks_email_callback($matches) { - $addr = $matches[1]; - $url = $this->encodeURLAttribute("mailto:$addr", $text); - $link = "$text"; - return $this->hashPart($link); - } - - /** - * Input: some text to obfuscate, e.g. "mailto:foo@example.com" - * - * Output: the same text but with most characters encoded as either a - * decimal or hex entity, in the hopes of foiling most address - * harvesting spam bots. E.g.: - * - * mailto:foo - * @example.co - * m - * - * Note: the additional output $tail is assigned the same value as the - * ouput, minus the number of characters specified by $head_length. - * - * Based by a filter by Matthew Wickline, posted to BBEdit-Talk. - * With some optimizations by Milian Wolff. Forced encoding of HTML - * attribute special characters by Allan Odgaard. - * - * @param string $text - * @param string $tail Passed by reference - * @param integer $head_length - * @return string - */ - protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) { - if ($text == "") { - return $tail = ""; - } - - $chars = preg_split('/(? $char) { - $ord = ord($char); - // Ignore non-ascii chars. - if ($ord < 128) { - $r = ($seed * (1 + $key)) % 100; // Pseudo-random function. - // roughly 10% raw, 45% hex, 45% dec - // '@' *must* be encoded. I insist. - // '"' and '>' have to be encoded inside the attribute - if ($r > 90 && strpos('@"&>', $char) === false) { - /* do nothing */ - } else if ($r < 45) { - $chars[$key] = '&#x'.dechex($ord).';'; - } else { - $chars[$key] = '&#'.$ord.';'; - } - } - } - - $text = implode('', $chars); - $tail = $head_length ? implode('', array_slice($chars, $head_length)) : $text; - - return $text; - } - - /** - * Take the string $str and parse it into tokens, hashing embeded HTML, - * escaped characters and handling code spans. - * @param string $str - * @return string - */ - protected function parseSpan($str) { - $output = ''; - - $span_re = '{ - ( - \\\\'.$this->escape_chars_re.' - | - (?no_markup ? '' : ' - | - # comment - | - <\?.*?\?> | <%.*?%> # processing instruction - | - <[!$]?[-a-zA-Z0-9:_]+ # regular tags - (?> - \s - (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* - )? - > - | - <[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag - | - # closing tag - ').' - ) - }xs'; - - while (1) { - // Each loop iteration seach for either the next tag, the next - // openning code span marker, or the next escaped character. - // Each token is then passed to handleSpanToken. - $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); - - // Create token from text preceding tag. - if ($parts[0] != "") { - $output .= $parts[0]; - } - - // Check if we reach the end. - if (isset($parts[1])) { - $output .= $this->handleSpanToken($parts[1], $parts[2]); - $str = $parts[2]; - } else { - break; - } - } - - return $output; - } - - /** - * Handle $token provided by parseSpan by determining its nature and - * returning the corresponding value that should replace it. - * @param string $token - * @param string $str Passed by reference - * @return string - */ - protected function handleSpanToken($token, &$str) { - switch ($token[0]) { - case "\\": - return $this->hashPart("&#". ord($token[1]). ";"); - case "`": - // Search for end marker in remaining text. - if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', - $str, $matches)) - { - $str = $matches[2]; - $codespan = $this->makeCodeSpan($matches[1]); - return $this->hashPart($codespan); - } - return $token; // Return as text since no ending marker found. - default: - return $this->hashPart($token); - } - } - - /** - * Remove one level of line-leading tabs or spaces - * @param string $text - * @return string - */ - protected function outdent($text) { - return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text); - } - - - /** - * String length function for detab. `_initDetab` will create a function to - * handle UTF-8 if the default function does not exist. - * @var string - */ - protected $utf8_strlen = 'mb_strlen'; - - /** - * Replace tabs with the appropriate amount of spaces. - * - * For each line we separate the line in blocks delemited by tab characters. - * Then we reconstruct every line by adding the appropriate number of space - * between each blocks. - * - * @param string $text - * @return string - */ - protected function detab($text) { - $text = preg_replace_callback('/^.*\t.*$/m', - array($this, '_detab_callback'), $text); - - return $text; - } - - /** - * Replace tabs callback - * @param string $matches - * @return string - */ - protected function _detab_callback($matches) { - $line = $matches[0]; - $strlen = $this->utf8_strlen; // strlen function for UTF-8. - - // Split in blocks. - $blocks = explode("\t", $line); - // Add each blocks to the line. - $line = $blocks[0]; - unset($blocks[0]); // Do not add first block twice. - foreach ($blocks as $block) { - // Calculate amount of space, insert spaces, insert block. - $amount = $this->tab_width - - $strlen($line, 'UTF-8') % $this->tab_width; - $line .= str_repeat(" ", $amount) . $block; - } - return $line; - } - - /** - * Check for the availability of the function in the `utf8_strlen` property - * (initially `mb_strlen`). If the function is not available, create a - * function that will loosely count the number of UTF-8 characters with a - * regular expression. - * @return void - */ - protected function _initDetab() { - - if (function_exists($this->utf8_strlen)) { - return; - } - - $this->utf8_strlen = function($text) { - return preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m); - }; - } - - /** - * Swap back in all the tags hashed by _HashHTMLBlocks. - * @param string $text - * @return string - */ - protected function unhash($text) { - return preg_replace_callback('/(.)\x1A[0-9]+\1/', - array($this, '_unhash_callback'), $text); - } - - /** - * Unhashing callback - * @param array $matches - * @return string - */ - protected function _unhash_callback($matches) { - return $this->html_hashes[$matches[0]]; - } -} diff --git a/md/MarkdownExtra.inc.php b/md/MarkdownExtra.inc.php deleted file mode 100755 index d09bd7a..0000000 --- a/md/MarkdownExtra.inc.php +++ /dev/null @@ -1,11 +0,0 @@ - - * @copyright 2004-2019 Michel Fortin - * @copyright (Original Markdown) 2004-2006 John Gruber - */ - -namespace md; - -/** - * Markdown Extra Parser Class - */ -class MarkdownExtra extends \md\Markdown { - /** - * Configuration variables - */ - - /** - * Prefix for footnote ids. - * @var string - */ - public $fn_id_prefix = ""; - - /** - * Optional title attribute for footnote links. - * @var string - */ - public $fn_link_title = ""; - - /** - * Optional class attribute for footnote links and backlinks. - * @var string - */ - public $fn_link_class = "footnote-ref"; - public $fn_backlink_class = "footnote-backref"; - - /** - * Content to be displayed within footnote backlinks. The default is '↩'; - * the U+FE0E on the end is a Unicode variant selector used to prevent iOS - * from displaying the arrow character as an emoji. - * Optionally use '^^' and '%%' to refer to the footnote number and - * reference number respectively. {@see parseFootnotePlaceholders()} - * @var string - */ - public $fn_backlink_html = '↩︎'; - - /** - * Optional title and aria-label attributes for footnote backlinks for - * added accessibility (to ensure backlink uniqueness). - * Use '^^' and '%%' to refer to the footnote number and reference number - * respectively. {@see parseFootnotePlaceholders()} - * @var string - */ - public $fn_backlink_title = ""; - public $fn_backlink_label = ""; - - /** - * Class name for table cell alignment (%% replaced left/center/right) - * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' - * If empty, the align attribute is used instead of a class name. - * @var string - */ - public $table_align_class_tmpl = ''; - - /** - * Optional class prefix for fenced code block. - * @var string - */ - public $code_class_prefix = ""; - - /** - * Class attribute for code blocks goes on the `code` tag; - * setting this to true will put attributes on the `pre` tag instead. - * @var boolean - */ - public $code_attr_on_pre = false; - - /** - * Predefined abbreviations. - * @var array - */ - public $predef_abbr = array(); - - /** - * Only convert atx-style headers if there's a space between the header and # - * @var boolean - */ - public $hashtag_protection = false; - - /** - * Determines whether footnotes should be appended to the end of the document. - * If true, footnote html can be retrieved from $this->footnotes_assembled. - * @var boolean - */ - public $omit_footnotes = false; - - - /** - * After parsing, the HTML for the list of footnotes appears here. - * This is available only if $omit_footnotes == true. - * - * Note: when placing the content of `footnotes_assembled` on the page, - * consider adding the attribute `role="doc-endnotes"` to the `div` or - * `section` that will enclose the list of footnotes so they are - * reachable to accessibility tools the same way they would be with the - * default HTML output. - * @var null|string - */ - public $footnotes_assembled = null; - - /** - * Parser implementation - */ - - /** - * Constructor function. Initialize the parser object. - * @return void - */ - public function __construct() { - // Add extra escapable characters before parent constructor - // initialize the table. - $this->escape_chars .= ':|'; - - // Insert extra document, block, and span transformations. - // Parent constructor will do the sorting. - $this->document_gamut += array( - "doFencedCodeBlocks" => 5, - "stripFootnotes" => 15, - "stripAbbreviations" => 25, - "appendFootnotes" => 50, - ); - $this->block_gamut += array( - "doFencedCodeBlocks" => 5, - "doTables" => 15, - "doDefLists" => 45, - ); - $this->span_gamut += array( - "doFootnotes" => 5, - "doAbbreviations" => 70, - ); - - $this->enhanced_ordered_list = true; - parent::__construct(); - } - - - /** - * Extra variables used during extra transformations. - * @var array - */ - protected $footnotes = array(); - protected $footnotes_ordered = array(); - protected $footnotes_ref_count = array(); - protected $footnotes_numbers = array(); - protected $abbr_desciptions = array(); - /** @var string */ - protected $abbr_word_re = ''; - - /** - * Give the current footnote number. - * @var integer - */ - protected $footnote_counter = 1; - - /** - * Ref attribute for links - * @var array - */ - protected $ref_attr = array(); - - /** - * Setting up Extra-specific variables. - */ - protected function setup() { - parent::setup(); - - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - $this->footnote_counter = 1; - $this->footnotes_assembled = null; - - foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { - if ($this->abbr_word_re) - $this->abbr_word_re .= '|'; - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - } - } - - /** - * Clearing Extra-specific variables. - */ - protected function teardown() { - $this->footnotes = array(); - $this->footnotes_ordered = array(); - $this->footnotes_ref_count = array(); - $this->footnotes_numbers = array(); - $this->abbr_desciptions = array(); - $this->abbr_word_re = ''; - - if ( ! $this->omit_footnotes ) - $this->footnotes_assembled = null; - - parent::teardown(); - } - - - /** - * Extra attribute parser - */ - - /** - * Expression to use to catch attributes (includes the braces) - * @var string - */ - protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; - - /** - * Expression to use when parsing in a context when no capture is desired - * @var string - */ - protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; - - /** - * Parse attributes caught by the $this->id_class_attr_catch_re expression - * and return the HTML-formatted list of attributes. - * - * Currently supported attributes are .class and #id. - * - * In addition, this method also supports supplying a default Id value, - * which will be used to populate the id attribute in case it was not - * overridden. - * @param string $tag_name - * @param string $attr - * @param mixed $defaultIdValue - * @param array $classes - * @return string - */ - protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) { - if (empty($attr) && !$defaultIdValue && empty($classes)) { - return ""; - } - - // Split on components - preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); - $elements = $matches[0]; - - // Handle classes and IDs (only first ID taken into account) - $attributes = array(); - $id = false; - foreach ($elements as $element) { - if ($element[0] === '.') { - $classes[] = substr($element, 1); - } else if ($element[0] === '#') { - if ($id === false) $id = substr($element, 1); - } else if (strpos($element, '=') > 0) { - $parts = explode('=', $element, 2); - $attributes[] = $parts[0] . '="' . $parts[1] . '"'; - } - } - - if ($id === false || $id === '') { - $id = $defaultIdValue; - } - - // Compose attributes as string - $attr_str = ""; - if (!empty($id)) { - $attr_str .= ' id="'.$this->encodeAttribute($id) .'"'; - } - if (!empty($classes)) { - $attr_str .= ' class="'. implode(" ", $classes) . '"'; - } - if (!$this->no_markup && !empty($attributes)) { - $attr_str .= ' '.implode(" ", $attributes); - } - return $attr_str; - } - - /** - * Strips link definitions from text, stores the URLs and titles in - * hash references. - * @param string $text - * @return string - */ - protected function stripLinkDefinitions($text) { - $less_than_tab = $this->tab_width - 1; - - // Link defs are in the form: ^[id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (?: - <(.+?)> # url = $2 - | - (\S+?) # url = $3 - ) - [ ]* - \n? # maybe one newline - [ ]* - (?: - (?<=\s) # lookbehind for whitespace - ["(] - (.*?) # title = $4 - [")] - [ ]* - )? # title is optional - (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr - (?:\n+|\Z) - }xm', - array($this, '_stripLinkDefinitions_callback'), - $text); - return $text; - } - - /** - * Strip link definition callback - * @param array $matches - * @return string - */ - protected function _stripLinkDefinitions_callback($matches) { - $link_id = strtolower($matches[1]); - $url = $matches[2] == '' ? $matches[3] : $matches[2]; - $this->urls[$link_id] = $url; - $this->titles[$link_id] =& $matches[4]; - $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); - return ''; // String that will replace the block - } - - - /** - * HTML block parser - */ - - /** - * Tags that are always treated as block tags - * @var string - */ - protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure|details|summary'; - - /** - * Tags treated as block tags only if the opening tag is alone on its line - * @var string - */ - protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; - - /** - * Tags where markdown="1" default to span mode: - * @var string - */ - protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; - - /** - * Tags which must not have their contents modified, no matter where - * they appear - * @var string - */ - protected $clean_tags_re = 'script|style|math|svg'; - - /** - * Tags that do not need to be closed. - * @var string - */ - protected $auto_close_tags_re = 'hr|img|param|source|track'; - - /** - * Hashify HTML Blocks and "clean tags". - * - * We only want to do this for block-level HTML tags, such as headers, - * lists, and tables. That's because we still want to wrap

    s around - * "paragraphs" that are wrapped in non-block-level tags, such as anchors, - * phrase emphasis, and spans. The list of tags we're looking for is - * hard-coded. - * - * This works by calling _HashHTMLBlocks_InMarkdown, which then calls - * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" - * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back - * _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. - * These two functions are calling each other. It's recursive! - * @param string $text - * @return string - */ - protected function hashHTMLBlocks($text) { - if ($this->no_markup) { - return $text; - } - - // Call the HTML-in-Markdown hasher. - list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); - - return $text; - } - - /** - * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. - * - * * $indent is the number of space to be ignored when checking for code - * blocks. This is important because if we don't take the indent into - * account, something like this (which looks right) won't work as expected: - * - *

    - *
    - * Hello World. <-- Is this a Markdown code block or text? - *
    <-- Is this a Markdown code block or a real tag? - *
    - * - * If you don't like this, just don't indent the tag on which - * you apply the markdown="1" attribute. - * - * * If $enclosing_tag_re is not empty, stops at the first unmatched closing - * tag with that name. Nested tags supported. - * - * * If $span is true, text inside must treated as span. So any double - * newline will be replaced by a single newline so that it does not create - * paragraphs. - * - * Returns an array of that form: ( processed text , remaining text ) - * - * @param string $text - * @param integer $indent - * @param string $enclosing_tag_re - * @param boolean $span - * @return array - */ - protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, - $enclosing_tag_re = '', $span = false) - { - - if ($text === '') return array('', ''); - - // Regex to check for the presense of newlines around a block tag. - $newline_before_re = '/(?:^\n?|\n\n)*$/'; - $newline_after_re = - '{ - ^ # Start of text following the tag. - (?>[ ]*)? # Optional comment. - [ ]*\n # Must be followed by newline. - }xs'; - - // Regex to match any tag. - $block_tag_re = - '{ - ( # $2: Capture whole tag. - # Tag name. - ' . $this->block_tags_re . ' | - ' . $this->context_block_tags_re . ' | - ' . $this->clean_tags_re . ' | - (?!\s)'.$enclosing_tag_re . ' - ) - (?: - (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. - (?> - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - ' . ( !$span ? ' # If not in span. - | - # Indented code block - (?: ^[ ]*\n | ^ | \n[ ]*\n ) - [ ]{' . ($indent + 4) . '}[^\n]* \n - (?> - (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n - )* - | - # Fenced code block marker - (?<= ^ | \n ) - [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,}) - [ ]* - (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name - [ ]* - (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes - [ ]* - (?= \n ) - ' : '' ) . ' # End (if not is span). - | - # Code span marker - # Note, this regex needs to go after backtick fenced - # code blocks but it should also be kept outside of the - # "if not in span" condition adding backticks to the parser - `+ - ) - }xs'; - - - $depth = 0; // Current depth inside the tag tree. - $parsed = ""; // Parsed text that will be returned. - - // Loop through every tag until we find the closing tag of the parent - // or loop until reaching the end of text if no parent tag specified. - do { - // Split the text using the first $tag_match pattern found. - // Text before pattern will be first in the array, text after - // pattern will be at the end, and between will be any catches made - // by the pattern. - $parts = preg_split($block_tag_re, $text, 2, - PREG_SPLIT_DELIM_CAPTURE); - - // If in Markdown span mode, add a empty-string span-level hash - // after each newline to prevent triggering any block element. - if ($span) { - $void = $this->hashPart("", ':'); - $newline = "\n$void"; - $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; - } - - $parsed .= $parts[0]; // Text before current tag. - - // If end of $text has been reached. Stop loop. - if (count($parts) < 3) { - $text = ""; - break; - } - - $tag = $parts[1]; // Tag to handle. - $text = $parts[2]; // Remaining text after current tag. - - // Check for: Fenced code block marker. - // Note: need to recheck the whole tag to disambiguate backtick - // fences from code spans - if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) { - // Fenced code block marker: find matching end marker. - $fence_indent = strlen($capture[1]); // use captured indent in re - $fence_re = $capture[2]; // use captured fence in re - if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text, - $matches)) - { - // End marker found: pass text unchanged until marker. - $parsed .= $tag . $matches[0]; - $text = substr($text, strlen($matches[0])); - } - else { - // No end marker: just skip it. - $parsed .= $tag; - } - } - // Check for: Indented code block. - else if ($tag[0] === "\n" || $tag[0] === " ") { - // Indented code block: pass it unchanged, will be handled - // later. - $parsed .= $tag; - } - // Check for: Code span marker - // Note: need to check this after backtick fenced code blocks - else if ($tag[0] === "`") { - // Find corresponding end marker. - $tag_re = preg_quote($tag); - if (preg_match('{^(?>.+?|\n(?!\n))*?(?block_tags_re . ')\b}', $tag) || - ( preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) && - preg_match($newline_before_re, $parsed) && - preg_match($newline_after_re, $text) ) - ) - { - // Need to parse tag and following text using the HTML parser. - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); - - // Make sure it stays outside of any paragraph by adding newlines. - $parsed .= "\n\n$block_text\n\n"; - } - // Check for: Clean tag (like script, math) - // HTML Comments, processing instructions. - else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) || - $tag[1] === '!' || $tag[1] === '?') - { - // Need to parse tag and following text using the HTML parser. - // (don't check for markdown attribute) - list($block_text, $text) = - $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); - - $parsed .= $block_text; - } - // Check for: Tag with same name as enclosing tag. - else if ($enclosing_tag_re !== '' && - // Same name as enclosing tag. - preg_match('{^= 0); - - return array($parsed, $text); - } - - /** - * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. - * - * * Calls $hash_method to convert any blocks. - * * Stops when the first opening tag closes. - * * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. - * (it is not inside clean tags) - * - * Returns an array of that form: ( processed text , remaining text ) - * @param string $text - * @param string $hash_method - * @param bool $md_attr Handle `markdown="1"` attribute - * @return array - */ - protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { - if ($text === '') return array('', ''); - - // Regex to match `markdown` attribute inside of a tag. - $markdown_attr_re = ' - { - \s* # Eat whitespace before the `markdown` attribute - markdown - \s*=\s* - (?> - (["\']) # $1: quote delimiter - (.*?) # $2: attribute value - \1 # matching delimiter - | - ([^\s>]*) # $3: unquoted attribute value - ) - () # $4: make $3 always defined (avoid warnings) - }xs'; - - // Regex to match any tag. - $tag_re = '{ - ( # $2: Capture whole tag. - - ".*?" | # Double quotes (can contain `>`) - \'.*?\' | # Single quotes (can contain `>`) - .+? # Anything but quotes and `>`. - )*? - )? - > # End of tag. - | - # HTML Comment - | - <\?.*?\?> | <%.*?%> # Processing instruction - | - # CData Block - ) - }xs'; - - $original_text = $text; // Save original text in case of faliure. - - $depth = 0; // Current depth inside the tag tree. - $block_text = ""; // Temporary text holder for current text. - $parsed = ""; // Parsed text that will be returned. - $base_tag_name_re = ''; - - // Get the name of the starting tag. - // (This pattern makes $base_tag_name_re safe without quoting.) - if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) - $base_tag_name_re = $matches[1]; - - // Loop through every tag until we find the corresponding closing tag. - do { - // Split the text using the first $tag_match pattern found. - // Text before pattern will be first in the array, text after - // pattern will be at the end, and between will be any catches made - // by the pattern. - $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - - if (count($parts) < 3) { - // End of $text reached with unbalenced tag(s). - // In that case, we return original text unchanged and pass the - // first character as filtered to prevent an infinite loop in the - // parent function. - return array($original_text[0], substr($original_text, 1)); - } - - $block_text .= $parts[0]; // Text before current tag. - $tag = $parts[1]; // Tag to handle. - $text = $parts[2]; // Remaining text after current tag. - - // Check for: Auto-close tag (like
    ) - // Comments and Processing Instructions. - if (preg_match('{^auto_close_tags_re . ')\b}', $tag) || - $tag[1] === '!' || $tag[1] === '?') - { - // Just add the tag to the block as if it was text. - $block_text .= $tag; - } - else { - // Increase/decrease nested tag count. Only do so if - // the tag's name match base tag's. - if (preg_match('{^contain_span_tags_re . ')\b}', $tag)); - - // Calculate indent before tag. - if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { - $strlen = $this->utf8_strlen; - $indent = $strlen($matches[1], 'UTF-8'); - } else { - $indent = 0; - } - - // End preceding block with this tag. - $block_text .= $tag; - $parsed .= $this->$hash_method($block_text); - - // Get enclosing tag name for the ParseMarkdown function. - // (This pattern makes $tag_name_re safe without quoting.) - preg_match('/^<([\w:$]*)\b/', $tag, $matches); - $tag_name_re = $matches[1]; - - // Parse the content using the HTML-in-Markdown parser. - list ($block_text, $text) - = $this->_hashHTMLBlocks_inMarkdown($text, $indent, - $tag_name_re, $span_mode); - - // Outdent markdown text. - if ($indent > 0) { - $block_text = preg_replace("/^[ ]{1,$indent}/m", "", - $block_text); - } - - // Append tag content to parsed text. - if (!$span_mode) { - $parsed .= "\n\n$block_text\n\n"; - } else { - $parsed .= (string) $block_text; - } - - // Start over with a new block. - $block_text = ""; - } - else $block_text .= $tag; - } - - } while ($depth > 0); - - // Hash last block text that wasn't processed inside the loop. - $parsed .= $this->$hash_method($block_text); - - return array($parsed, $text); - } - - /** - * Called whenever a tag must be hashed when a function inserts a "clean" tag - * in $text, it passes through this function and is automaticaly escaped, - * blocking invalid nested overlap. - * @param string $text - * @return string - */ - protected function hashClean($text) { - return $this->hashPart($text, 'C'); - } - - /** - * Turn Markdown link shortcuts into XHTML tags. - * @param string $text - * @return string - */ - protected function doAnchors($text) { - if ($this->in_anchor) { - return $text; - } - $this->in_anchor = true; - - // First, handle reference-style links: [link text] [id] - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - (' . $this->nested_brackets_re . ') # link text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - // Next, inline-style links: [link text](url "optional title") - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - (' . $this->nested_brackets_re . ') # link text = $2 - \] - \( # literal paren - [ \n]* - (?: - <(.+?)> # href = $3 - | - (' . $this->nested_url_parenthesis_re . ') # href = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # Title = $7 - \6 # matching quote - [ \n]* # ignore any spaces/tabs between closing quote and ) - )? # title is optional - \) - (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doAnchors_inline_callback'), $text); - - // Last, handle reference-style shortcuts: [link text] - // These must come last in case you've also got [link text][1] - // or [link text](/foo) - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - \[ - ([^\[\]]+) # link text = $2; can\'t contain [ or ] - \] - ) - }xs', - array($this, '_doAnchors_reference_callback'), $text); - - $this->in_anchor = false; - return $text; - } - - /** - * Callback for reference anchors - * @param array $matches - * @return string - */ - protected function _doAnchors_reference_callback($matches) { - $whole_match = $matches[1]; - $link_text = $matches[2]; - $link_id =& $matches[3]; - - if ($link_id == "") { - // for shortcut links like [this][] or [this]. - $link_id = $link_text; - } - - // lower-case and turn embedded newlines into spaces - $link_id = strtolower($link_id); - $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); - - if (isset($this->urls[$link_id])) { - $url = $this->urls[$link_id]; - $url = $this->encodeURLAttribute($url); - - $result = "titles[$link_id] ) ) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) - $result .= $this->ref_attr[$link_id]; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - $result = $this->hashPart($result); - } - else { - $result = $whole_match; - } - return $result; - } - - /** - * Callback for inline anchors - * @param array $matches - * @return string - */ - protected function _doAnchors_inline_callback($matches) { - $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] === '' ? $matches[4] : $matches[3]; - $title_quote =& $matches[6]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); - - // if the URL was of the form it got caught by the HTML - // tag parser and hashed. Need to reverse the process before using the URL. - $unhashed = $this->unhash($url); - if ($unhashed !== $url) - $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); - - $url = $this->encodeURLAttribute($url); - - $result = "encodeAttribute($title); - $result .= " title=\"$title\""; - } - $result .= $attr; - - $link_text = $this->runSpanGamut($link_text); - $result .= ">$link_text"; - - return $this->hashPart($result); - } - - /** - * Turn Markdown image shortcuts into tags. - * @param string $text - * @return string - */ - protected function doImages($text) { - // First, handle reference-style labeled images: ![alt text][id] - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - (' . $this->nested_brackets_re . ') # alt text = $2 - \] - - [ ]? # one optional space - (?:\n[ ]*)? # one optional newline followed by spaces - - \[ - (.*?) # id = $3 - \] - - ) - }xs', - array($this, '_doImages_reference_callback'), $text); - - // Next, handle inline images: ![alt text](url "optional title") - // Don't forget: encode * and _ - $text = preg_replace_callback('{ - ( # wrap whole match in $1 - !\[ - (' . $this->nested_brackets_re . ') # alt text = $2 - \] - \s? # One optional whitespace character - \( # literal paren - [ \n]* - (?: - <(\S*)> # src url = $3 - | - (' . $this->nested_url_parenthesis_re . ') # src url = $4 - ) - [ \n]* - ( # $5 - ([\'"]) # quote char = $6 - (.*?) # title = $7 - \6 # matching quote - [ \n]* - )? # title is optional - \) - (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes - ) - }xs', - array($this, '_doImages_inline_callback'), $text); - - return $text; - } - - /** - * Callback for referenced images - * @param array $matches - * @return string - */ - protected function _doImages_reference_callback($matches) { - $whole_match = $matches[1]; - $alt_text = $matches[2]; - $link_id = strtolower($matches[3]); - - if ($link_id === "") { - $link_id = strtolower($alt_text); // for shortcut links like ![this][]. - } - - $alt_text = $this->encodeAttribute($alt_text); - if (isset($this->urls[$link_id])) { - $url = $this->encodeURLAttribute($this->urls[$link_id]); - $result = "\"$alt_text\"";titles[$link_id])) { - $title = $this->titles[$link_id]; - $title = $this->encodeAttribute($title); - $result .= " title=\"$title\""; - } - if (isset($this->ref_attr[$link_id])) { - $result .= $this->ref_attr[$link_id]; - } - $result .= $this->empty_element_suffix; - $result = $this->hashPart($result); - } - else { - // If there's no such link ID, leave intact: - $result = $whole_match; - } - - return $result; - } - - /** - * Callback for inline images - * @param array $matches - * @return string - */ - protected function _doImages_inline_callback($matches) { - $alt_text = $matches[2]; - $url = $matches[3] === '' ? $matches[4] : $matches[3]; - $title_quote =& $matches[6]; - $title =& $matches[7]; - $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); - - $alt_text = $this->encodeAttribute($alt_text); - $url = $this->encodeURLAttribute($url); - $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; // $title already quoted - } - $result .= $attr; - $result .= $this->empty_element_suffix; - - return $this->hashPart($result); - } - - /** - * Process markdown headers. Redefined to add ID and class attribute support. - * @param string $text - * @return string - */ - protected function doHeaders($text) { - // Setext-style headers: - // Header 1 {#header1} - // ======== - // - // Header 2 {#header2 .class1 .class2} - // -------- - // - $text = preg_replace_callback( - '{ - (^.+?) # $1: Header text - (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes - [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer - }mx', - array($this, '_doHeaders_callback_setext'), $text); - - // atx-style headers: - // # Header 1 {#header1} - // ## Header 2 {#header2} - // ## Header 2 with closing hashes ## {#header3.class1.class2} - // ... - // ###### Header 6 {.class2} - // - $text = preg_replace_callback('{ - ^(\#{1,6}) # $1 = string of #\'s - [ ]'.($this->hashtag_protection ? '+' : '*').' - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #\'s (not counted) - (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes - [ ]* - \n+ - }xm', - array($this, '_doHeaders_callback_atx'), $text); - - return $text; - } - - /** - * Callback for setext headers - * @param array $matches - * @return string - */ - protected function _doHeaders_callback_setext($matches) { - if ($matches[3] === '-' && preg_match('{^- }', $matches[1])) { - return $matches[0]; - } - - $level = $matches[3][0] === '=' ? 1 : 2; - - $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null; - - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId); - $block = "" . $this->runSpanGamut($matches[1]) . ""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - /** - * Callback for atx headers - * @param array $matches - * @return string - */ - protected function _doHeaders_callback_atx($matches) { - $level = strlen($matches[1]); - - $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null; - $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId); - $block = "" . $this->runSpanGamut($matches[2]) . ""; - return "\n" . $this->hashBlock($block) . "\n\n"; - } - - /** - * Form HTML tables. - * @param string $text - * @return string - */ - protected function doTables($text) { - $less_than_tab = $this->tab_width - 1; - // Find tables with leading pipe. - // - // | Header 1 | Header 2 - // | -------- | -------- - // | Cell 1 | Cell 2 - // | Cell 3 | Cell 4 - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,' . $less_than_tab . '} # Allowed whitespace. - [|] # Optional leading pipe (present) - (.+) \n # $1: Header row (at least one pipe) - - [ ]{0,' . $less_than_tab . '} # Allowed whitespace. - [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - [ ]* # Allowed whitespace. - [|] .* \n # Row content. - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_doTable_leadingPipe_callback'), $text); - - // Find tables without leading pipe. - // - // Header 1 | Header 2 - // -------- | -------- - // Cell 1 | Cell 2 - // Cell 3 | Cell 4 - $text = preg_replace_callback(' - { - ^ # Start of a line - [ ]{0,' . $less_than_tab . '} # Allowed whitespace. - (\S.*[|].*) \n # $1: Header row (at least one pipe) - - [ ]{0,' . $less_than_tab . '} # Allowed whitespace. - ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline - - ( # $3: Cells - (?> - .* [|] .* \n # Row content - )* - ) - (?=\n|\Z) # Stop at final double newline. - }xm', - array($this, '_DoTable_callback'), $text); - - return $text; - } - - /** - * Callback for removing the leading pipe for each row - * @param array $matches - * @return string - */ - protected function _doTable_leadingPipe_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - $content = preg_replace('/^ *[|]/m', '', $content); - - return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); - } - - /** - * Make the align attribute in a table - * @param string $alignname - * @return string - */ - protected function _doTable_makeAlignAttr($alignname) { - if (empty($this->table_align_class_tmpl)) { - return " align=\"$alignname\""; - } - - $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); - return " class=\"$classname\""; - } - - /** - * Calback for processing tables - * @param array $matches - * @return string - */ - protected function _doTable_callback($matches) { - $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - - // Remove any tailing pipes for each line. - $head = preg_replace('/[|] *$/m', '', $head); - $underline = preg_replace('/[|] *$/m', '', $underline); - $content = preg_replace('/[|] *$/m', '', $content); - - // Reading alignement from header underline. - $separators = preg_split('/ *[|] */', $underline); - foreach ($separators as $n => $s) { - if (preg_match('/^ *-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('right'); - else if (preg_match('/^ *:-+: *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('center'); - else if (preg_match('/^ *:-+ *$/', $s)) - $attr[$n] = $this->_doTable_makeAlignAttr('left'); - else - $attr[$n] = ''; - } - - // Parsing span elements, including code spans, character escapes, - // and inline HTML tags, so that pipes inside those gets ignored. - $head = $this->parseSpan($head); - $headers = preg_split('/ *[|] */', $head); - $col_count = count($headers); - $attr = array_pad($attr, $col_count, ''); - - // Write column headers. - $text = "\n"; - $text .= "\n"; - $text .= "\n"; - foreach ($headers as $n => $header) { - $text .= " " . $this->runSpanGamut(trim($header)) . "\n"; - } - $text .= "\n"; - $text .= "\n"; - - // Split content by row. - $rows = explode("\n", trim($content, "\n")); - - $text .= "\n"; - foreach ($rows as $row) { - // Parsing span elements, including code spans, character escapes, - // and inline HTML tags, so that pipes inside those gets ignored. - $row = $this->parseSpan($row); - - // Split row by cell. - $row_cells = preg_split('/ *[|] */', $row, $col_count); - $row_cells = array_pad($row_cells, $col_count, ''); - - $text .= "\n"; - foreach ($row_cells as $n => $cell) { - $text .= " " . $this->runSpanGamut(trim($cell)) . "\n"; - } - $text .= "\n"; - } - $text .= "\n"; - $text .= "
    "; - - return $this->hashBlock($text) . "\n"; - } - - /** - * Form HTML definition lists. - * @param string $text - * @return string - */ - protected function doDefLists($text) { - $less_than_tab = $this->tab_width - 1; - - // Re-usable pattern to match any entire dl list: - $whole_list_re = '(?> - ( # $1 = whole list - ( # $2 - [ ]{0,' . $less_than_tab . '} - ((?>.*\S.*\n)+) # $3 = defined term - \n? - [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition - ) - (?s:.+?) - ( # $4 - \z - | - \n{2,} - (?=\S) - (?! # Negative lookahead for another term - [ ]{0,' . $less_than_tab . '} - (?: \S.*\n )+? # defined term - \n? - [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition - ) - (?! # Negative lookahead for another definition - [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition - ) - ) - ) - )'; // mx - - $text = preg_replace_callback('{ - (?>\A\n?|(?<=\n\n)) - ' . $whole_list_re . ' - }mx', - array($this, '_doDefLists_callback'), $text); - - return $text; - } - - /** - * Callback for processing definition lists - * @param array $matches - * @return string - */ - protected function _doDefLists_callback($matches) { - // Re-usable patterns to match list item bullets and number markers: - $list = $matches[1]; - - // Turn double returns into triple returns, so that we can make a - // paragraph for the last item in a list, if necessary: - $result = trim($this->processDefListItems($list)); - $result = "
    \n" . $result . "\n
    "; - return $this->hashBlock($result) . "\n\n"; - } - - /** - * Process the contents of a single definition list, splitting it - * into individual term and definition list items. - * @param string $list_str - * @return string - */ - protected function processDefListItems($list_str) { - - $less_than_tab = $this->tab_width - 1; - - // Trim trailing blank lines: - $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - - // Process definition terms. - $list_str = preg_replace_callback('{ - (?>\A\n?|\n\n+) # leading line - ( # definition terms = $1 - [ ]{0,' . $less_than_tab . '} # leading whitespace - (?!\:[ ]|[ ]) # negative lookahead for a definition - # mark (colon) or more whitespace. - (?> \S.* \n)+? # actual term (not whitespace). - ) - (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed - # with a definition mark. - }xm', - array($this, '_processDefListItems_callback_dt'), $list_str); - - // Process actual definitions. - $list_str = preg_replace_callback('{ - \n(\n+)? # leading line = $1 - ( # marker space = $2 - [ ]{0,' . $less_than_tab . '} # whitespace before colon - \:[ ]+ # definition mark (colon) - ) - ((?s:.+?)) # definition text = $3 - (?= \n+ # stop at next definition mark, - (?: # next term or end of text - [ ]{0,' . $less_than_tab . '} \:[ ] | -
    | \z - ) - ) - }xm', - array($this, '_processDefListItems_callback_dd'), $list_str); - - return $list_str; - } - - /** - * Callback for
    elements in definition lists - * @param array $matches - * @return string - */ - protected function _processDefListItems_callback_dt($matches) { - $terms = explode("\n", trim($matches[1])); - $text = ''; - foreach ($terms as $term) { - $term = $this->runSpanGamut(trim($term)); - $text .= "\n
    " . $term . "
    "; - } - return $text . "\n"; - } - - /** - * Callback for
    elements in definition lists - * @param array $matches - * @return string - */ - protected function _processDefListItems_callback_dd($matches) { - $leading_line = $matches[1]; - $marker_space = $matches[2]; - $def = $matches[3]; - - if ($leading_line || preg_match('/\n{2,}/', $def)) { - // Replace marker with the appropriate whitespace indentation - $def = str_repeat(' ', strlen($marker_space)) . $def; - $def = $this->runBlockGamut($this->outdent($def . "\n\n")); - $def = "\n". $def ."\n"; - } - else { - $def = rtrim($def); - $def = $this->runSpanGamut($this->outdent($def)); - } - - return "\n
    " . $def . "
    \n"; - } - - /** - * Adding the fenced code block syntax to regular Markdown: - * - * ~~~ - * Code block - * ~~~ - * - * @param string $text - * @return string - */ - protected function doFencedCodeBlocks($text) { - - $text = preg_replace_callback('{ - (?:\n|\A) - # 1: Opening marker - ( - (?:~{3,}|`{3,}) # 3 or more tildes/backticks. - ) - [ ]* - (?: - \.?([-_:a-zA-Z0-9]+) # 2: standalone class name - )? - [ ]* - (?: - ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes - )? - [ ]* \n # Whitespace and newline following marker. - - # 4: Content - ( - (?> - (?!\1 [ ]* \n) # Not a closing marker. - .*\n+ - )+ - ) - - # Closing marker. - \1 [ ]* (?= \n ) - }xm', - array($this, '_doFencedCodeBlocks_callback'), $text); - - return $text; - } - - /** - * Callback to process fenced code blocks - * @param array $matches - * @return string - */ - protected function _doFencedCodeBlocks_callback($matches) { - $classname =& $matches[2]; - $attrs =& $matches[3]; - $codeblock = $matches[4]; - - if ($this->code_block_content_func) { - $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname); - } else { - $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); - } - - $codeblock = preg_replace_callback('/^\n+/', - array($this, '_doFencedCodeBlocks_newlines'), $codeblock); - - $classes = array(); - if ($classname !== "") { - if ($classname[0] === '.') { - $classname = substr($classname, 1); - } - $classes[] = $this->code_class_prefix . $classname; - } - $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes); - $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; - $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; - $codeblock = "$codeblock
    "; - - return "\n\n".$this->hashBlock($codeblock)."\n\n"; - } - - /** - * Replace new lines in fenced code blocks - * @param array $matches - * @return string - */ - protected function _doFencedCodeBlocks_newlines($matches) { - return str_repeat("empty_element_suffix", - strlen($matches[0])); - } - - /** - * Redefining emphasis markers so that emphasis by underscore does not - * work in the middle of a word. - * @var array - */ - protected $em_relist = array( - '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags - * @return string HTML output - */ - protected function formParagraphs($text, $wrap_in_p = true) { - // Strip leading and trailing lines: - $text = preg_replace('/\A\n+|\n+\z/', '', $text); - - $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - - // Wrap

    tags and unhashify HTML blocks - foreach ($grafs as $key => $value) { - $value = trim($this->runSpanGamut($value)); - - // Check if this should be enclosed in a paragraph. - // Clean tag hashes & block tag hashes are left alone. - $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); - - if ($is_p) { - $value = "

    $value

    "; - } - $grafs[$key] = $value; - } - - // Join grafs in one text, then unhash HTML tags. - $text = implode("\n\n", $grafs); - - // Finish by removing any tag hashes still present in $text. - $text = $this->unhash($text); - - return $text; - } - - - /** - * Footnotes - Strips link definitions from text, stores the URLs and - * titles in hash references. - * @param string $text - * @return string - */ - protected function stripFootnotes($text) { - $less_than_tab = $this->tab_width - 1; - - // Link defs are in the form: [^id]: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?: # note_id = $1 - [ ]* - \n? # maybe *one* newline - ( # text = $2 (no blank lines allowed) - (?: - .+ # actual text - | - \n # newlines but - (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. - (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed - # by non-indented content - )* - ) - }xm', - array($this, '_stripFootnotes_callback'), - $text); - return $text; - } - - /** - * Callback for stripping footnotes - * @param array $matches - * @return string - */ - protected function _stripFootnotes_callback($matches) { - $note_id = $this->fn_id_prefix . $matches[1]; - $this->footnotes[$note_id] = $this->outdent($matches[2]); - return ''; // String that will replace the block - } - - /** - * Replace footnote references in $text [^id] with a special text-token - * which will be replaced by the actual footnote marker in appendFootnotes. - * @param string $text - * @return string - */ - protected function doFootnotes($text) { - if (!$this->in_anchor) { - $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); - } - return $text; - } - - /** - * Append footnote list to text - * @param string $text - * @return string - */ - protected function appendFootnotes($text) { - $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $text); - - if ( ! empty( $this->footnotes_ordered ) ) { - $this->_doFootnotes(); - if ( ! $this->omit_footnotes ) { - $text .= "\n\n"; - $text .= "
    \n"; - $text .= "empty_element_suffix . "\n"; - $text .= $this->footnotes_assembled; - $text .= "
    "; - } - } - return $text; - } - - - /** - * Generates the HTML for footnotes. Called by appendFootnotes, even if - * footnotes are not being appended. - * @return void - */ - protected function _doFootnotes() { - $attr = array(); - if ($this->fn_backlink_class !== "") { - $class = $this->fn_backlink_class; - $class = $this->encodeAttribute($class); - $attr['class'] = " class=\"$class\""; - } - $attr['role'] = " role=\"doc-backlink\""; - $num = 0; - - $text = "
      \n\n"; - while (!empty($this->footnotes_ordered)) { - $footnote = reset($this->footnotes_ordered); - $note_id = key($this->footnotes_ordered); - unset($this->footnotes_ordered[$note_id]); - $ref_count = $this->footnotes_ref_count[$note_id]; - unset($this->footnotes_ref_count[$note_id]); - unset($this->footnotes[$note_id]); - - $footnote .= "\n"; // Need to append newline before parsing. - $footnote = $this->runBlockGamut("$footnote\n"); - $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $footnote); - - $num++; - $note_id = $this->encodeAttribute($note_id); - - // Prepare backlink, multiple backlinks if multiple references - // Do not create empty backlinks if the html is blank - $backlink = ""; - if (!empty($this->fn_backlink_html)) { - for ($ref_num = 1; $ref_num <= $ref_count; ++$ref_num) { - if (!empty($this->fn_backlink_title)) { - $attr['title'] = ' title="' . $this->encodeAttribute($this->fn_backlink_title) . '"'; - } - if (!empty($this->fn_backlink_label)) { - $attr['label'] = ' aria-label="' . $this->encodeAttribute($this->fn_backlink_label) . '"'; - } - $parsed_attr = $this->parseFootnotePlaceholders( - implode('', $attr), - $num, - $ref_num - ); - $backlink_text = $this->parseFootnotePlaceholders( - $this->fn_backlink_html, - $num, - $ref_num - ); - $ref_count_mark = $ref_num > 1 ? $ref_num : ''; - $backlink .= " $backlink_text"; - } - $backlink = trim($backlink); - } - - // Add backlink to last paragraph; create new paragraph if needed. - if (!empty($backlink)) { - if (preg_match('{

      $}', $footnote)) { - $footnote = substr($footnote, 0, -4) . " $backlink

      "; - } else { - $footnote .= "\n\n

      $backlink

      "; - } - } - - $text .= "
    1. \n"; - $text .= $footnote . "\n"; - $text .= "
    2. \n\n"; - } - $text .= "
    \n"; - - $this->footnotes_assembled = $text; - } - - /** - * Callback for appending footnotes - * @param array $matches - * @return string - */ - protected function _appendFootnotes_callback($matches) { - $node_id = $this->fn_id_prefix . $matches[1]; - - // Create footnote marker only if it has a corresponding footnote *and* - // the footnote hasn't been used by another marker. - if (isset($this->footnotes[$node_id])) { - $num =& $this->footnotes_numbers[$node_id]; - if (!isset($num)) { - // Transfer footnote content to the ordered list and give it its - // number - $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; - $this->footnotes_ref_count[$node_id] = 1; - $num = $this->footnote_counter++; - $ref_count_mark = ''; - } else { - $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; - } - - $attr = ""; - if ($this->fn_link_class !== "") { - $class = $this->fn_link_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_link_title !== "") { - $title = $this->fn_link_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; - } - $attr .= " role=\"doc-noteref\""; - - $attr = str_replace("%%", $num, $attr); - $node_id = $this->encodeAttribute($node_id); - - return - "". - "$num". - ""; - } - - return "[^" . $matches[1] . "]"; - } - - /** - * Build footnote label by evaluating any placeholders. - * - ^^ footnote number - * - %% footnote reference number (Nth reference to footnote number) - * @param string $label - * @param int $footnote_number - * @param int $reference_number - * @return string - */ - protected function parseFootnotePlaceholders($label, $footnote_number, $reference_number) { - return str_replace( - array('^^', '%%'), - array($footnote_number, $reference_number), - $label - ); - } - - - /** - * Abbreviations - strips abbreviations from text, stores titles in hash - * references. - * @param string $text - * @return string - */ - protected function stripAbbreviations($text) { - $less_than_tab = $this->tab_width - 1; - - // Link defs are in the form: [id]*: url "optional title" - $text = preg_replace_callback('{ - ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?: # abbr_id = $1 - (.*) # text = $2 (no blank lines allowed) - }xm', - array($this, '_stripAbbreviations_callback'), - $text); - return $text; - } - - /** - * Callback for stripping abbreviations - * @param array $matches - * @return string - */ - protected function _stripAbbreviations_callback($matches) { - $abbr_word = $matches[1]; - $abbr_desc = $matches[2]; - if ($this->abbr_word_re) { - $this->abbr_word_re .= '|'; - } - $this->abbr_word_re .= preg_quote($abbr_word); - $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - return ''; // String that will replace the block - } - - /** - * Find defined abbreviations in text and wrap them in elements. - * @param string $text - * @return string - */ - protected function doAbbreviations($text) { - if ($this->abbr_word_re) { - // cannot use the /x modifier because abbr_word_re may - // contain significant spaces: - $text = preg_replace_callback('{' . - '(?abbr_word_re . ')' . - '(?![\w\x1A])' . - '}', - array($this, '_doAbbreviations_callback'), $text); - } - return $text; - } - - /** - * Callback for processing abbreviations - * @param array $matches - * @return string - */ - protected function _doAbbreviations_callback($matches) { - $abbr = $matches[0]; - if (isset($this->abbr_desciptions[$abbr])) { - $desc = $this->abbr_desciptions[$abbr]; - if (empty($desc)) { - return $this->hashPart("$abbr"); - } - $desc = $this->encodeAttribute($desc); - return $this->hashPart("$abbr"); - } - return $matches[0]; - } -} diff --git a/md/MarkdownInterface.inc.php b/md/MarkdownInterface.inc.php deleted file mode 100755 index c4e9ac7..0000000 --- a/md/MarkdownInterface.inc.php +++ /dev/null @@ -1,9 +0,0 @@ - - * @copyright 2004-2019 Michel Fortin - * @copyright (Original Markdown) 2004-2006 John Gruber - */ - -namespace md; - -/** - * Markdown Parser Interface - */ -interface MarkdownInterface { - /** - * Initialize the parser and return the result of its transform method. - * This will work fine for derived classes too. - * - * @api - * - * @param string $text - * @return string - */ - public static function defaultTransform($text); - - /** - * Main function. Performs some preprocessing on the input text - * and pass it through the document gamut. - * - * @api - * - * @param string $text - * @return string - */ - public function transform($text); -} diff --git a/pages/Getting Started.md b/pages/Getting Started.md deleted file mode 100755 index 05b74d1..0000000 --- a/pages/Getting Started.md +++ /dev/null @@ -1,183 +0,0 @@ -Getting Started ---------------- - -[speedwm](https://speedie.gq/projects/speedwm.php) is a window manager forked -from [dwm](https://dwm.suckless.org) (also known as dynamic window manager). -It manages the user's open windows and tiles them according to a set layout. -This is what makes it dynamic, unlike windows managers like i3 which you may -be used to. - -### This is an X11 window manager, you need to use X. - -Yes, this is an X11 window manager. I do not like Wayland and it's -philosophies, and I will not -support it for multiple reasons. See for my reasoning -behind this. Hate me all you want for it! - -If it isn't clear, `xorg-server` as well as `xinit` or `sx` is pretty much -expected. You can also use display managers like `sddm` or `lightdm` although -it should be mentioned that `ly` is **known** to have issues with dwm and -therefore also -speedwm. Do note that setting up X11 is out of the scope of this wiki, and you -need to figure out how to do that yourself. - -### Supported operating systems - -This is not some arbitrary requirement. While it may run if it's not listed -here, I will not be providing support due to having a lack of experience with -said operating system. The main operating systems that **do not** support -speedwm are macOS and Microsoft Windows. UNIX like operating systems are the -most likely to run it. - -- Nearly all GNU/Linux distributions - - NixOS and GNU Guix may require separate instructions. I will not provide - support for these, use the existing documentation to set it up. -- FreeBSD, OpenBSD, NetBSD - - There are likely more BSDs that can run speedwm, but I cannot support all - of them. Try it and see if it works. - -### Installation on Gentoo GNU/Linux - -Gentoo has slightly different instructions for setting up speedwm. While you -can follow along with the generic installation instructions, I have a Gentoo -overlay with packages for all speedwm versions. - -To get started, add [my -overlay](https://codeberg.org/speedie/speedie-overlay). Then simply `emerge -x11-wm/speedwm x11-wm/libspeedwm x11-wm/speedwm-extras`. Optionally, you may -`emerge x11-misc/spde` instead, which is a metapackage for a lot of stuff -including fonts, and general programs that work well for me. - -If you want to install speedwm using Git, do this by adding the following -lines: - -`=x11-wm/speedwm-9999 **` - -`=x11-wm/libspeedwm-9999 **` - -`=x11-wm/speedwm-extras-9999 **` - -to `/etc/portage/package.accept_keywords` and then emerging the packages as -per the instructions above. - -### Installation on generic GNU/Linux distributions - -Installing speedwm on most GNU/Linux distributions is very simple. First, -determine if you want to install it using Git (the absolute latest version) or -using a stable tarball. - -As of 26/01/2023, 1.8 is the latest tarball release -which is not very stable. For this reason, it is recommended that you `git -clone` the repository. If you do not have `git`, install it using your -distribution's package manager. If you're (still) going to be using a 'stable' -tarball, you do not need to install `git`. - -While the list of dependencies will vary depending on the speedwm version -you're going to install (see docs/dependencies.md for your specific version), -below is a list for the latest release, 1.8 and soon to be 1.9. - -- libXft -- libXinerama - - Used for multi-monitor support. It can be disabled if you do not need it - by commenting the XINERAMA libraries in `toggle.mk`. -- imlib2 - - Used for tag previews and window icons. It can be disabled if you do not - need it. To do this, comment out `IMLIB2LIBS` in `toggle.mk` and set - `USEIMLIB2`, `USEWINICON` and `USETAGPREVIEW` to `0` in `toggle.h`. -- pango -- yajl - - Used for IPC support. It can be disabled if you do not need it. To do - this, comment out `YAJLINC` and `YAJLLIBS` in `toggle.mk` and set `USEIPC` - to `0` in `toggle.h`. -- tcc - - This is a compiler. It is used because it is much faster than `clang` or - `gcc` (although at the expense of debugging and compatibility). You can - swap it out by passing `CC=cc` to the `make` command later when we compile - speedwm. - -#### Installation using `git` - -This assumes you have `git` installed. - -`cd` into a location where your normal user (not root) has permission to both -read and write. Do not clone the speedwm repository in `~/.config` as speedwm -will write configuration files to that location. - -Note: Cloning the repository to `~/.config` is fine -if the speedwm source code directory is **not** `speedwm` but speedwm -will use the `~/.config/speedwm` directory to store configuration files (not -source code). - -From here on, we're going to assume you are in the location `~/Documents`! Run -`git clone https://codeberg.org/speedie/speedwm.git speedwm` to clone the -repository into a directory named `speedwm`. Provided the repository hasn't -moved and you have a working internet connection, you should have received a -copy of the speedwm source code. - -You can now `cd speedwm` into it so we can actually install it. If you need to -make changes to `toggle.h`, `toggle.mk`, `host.mk` or any other C source code, -now is the time to do it. - -Now, it's time to compile it! Provided you have all dependencies installed, -this should be very, very easy and quick. Run `make clean install` as root to install -speedwm. The binary will be in `/usr/bin/speedwm`. If you need to use a -different compiler (tcc in Arch repositories has a few issues), you can run -`make CC=cc clean install` to use the system default compiler. Alternatively -use `gcc` instead of `cc` or whatever you want. - -After installation, it is *highly* recommended that you move your source code -directory to a safe place. speedwm is a source based window manager and -**most** (but not all) changes you make to it are going to be done by -recompiling the window manager. This is, of course done with the same `make -clean install` command you used earlier. - -I recommend you do this by forking the speedwm repository, and putting it on a -Git repository somewhere. That way, you can always clone your specific -version. - -Warning: If you lose your source code, you will be -**unable** to make any further changes to speedwm. - -Now follow along with 'Using speedwm'. - -#### Installation using a tarball - -Installation using a tarball works pretty much the same. Visit [the releases -page](https://codeberg.org/speedie/speedwm/releases) and get the latest - (or an old if you want) tarball. Avoid the 'Source Code (ZIP)' and 'Source - Code (TAR.GZ)' options, get the 'speedwm-.tar.gz' file. - -`cd` into a location where your normal user (not root) has permission to both -read and write. Make sure `~/.config/speedwm` is not used by anything. - -Now we need to unpack the tarball and get our source code. To do this, you can -use the `tar` command. I will spare you the time reading the man page and the -command to unpack the tarball is `tar -xpvf -/path/to/the/speedwm/tarball.tar.gz`. The `-x` argument here means extract. -`-p` means preserve permissions. The `-v` means verbose, we want to see -what's going on. `-f` means file, we want to specify a file to unpack. - -After unpacking it, there should be one directory; `speedwm-`. Let's -`cd speedwm-` into it. Now it's time to compile speedwm! - -Provided you have all dependencies installed, this should be very, very easy -and quick. Run `make clean install` as root to install speedwm. The binary -will be in `/usr/bin/speedwm`. If you need to use a different compiler (tcc in -Arch repostories has a few issues), you can run `make CC=cc clean install` to -use the system default compiler. Alternatively use `gcc` instead of `cc` or -whatever you want. - -After installation, it is *highly* recommended that you move your source code -directory to a safe place. speedwm is a source based window manager and -**most** (but not all) changes you make to it are going to be done by -recompiling the window manager. This is, of course done with the same `make -clean install` command you used earlier. - -I recommend you do this by putting the source code on a -Git or subversion repository somewhere. That way, you can always clone your specific -version. - -Warning: If you lose your source code, you will be -**unable** to make any further changes to speedwm. - -Now follow along with 'Using speedwm'. diff --git a/pages/Home.md b/pages/Home.md deleted file mode 100755 index 44f8aa2..0000000 --- a/pages/Home.md +++ /dev/null @@ -1,4 +0,0 @@ -Welcome to the speedie.site wiki! ---------------------------------- - -Welcome to the speedie.site wiki! This is a wiki that anyone may edit. It is mostly related to speedie.site projects such as fontctrl, spmenu and others, although [speedwm](https://speedwm.speedie.site) has its own wiki. \ No newline at end of file diff --git a/pages/[spmenu] Code documentation.md b/pages/[spmenu] Code documentation.md deleted file mode 100755 index ebeafd4..0000000 --- a/pages/[spmenu] Code documentation.md +++ /dev/null @@ -1,173 +0,0 @@ -# Code documentation - -NOTE: This article was taken from [the spmenu repository](https://git.speedie.site/spmenu/plain/code.pdf). This article therefore be outdated or vice versa. I highly recommend you check out the repository first though. - -Some of spmenu's code documented. If you want to hack on the project, this -should be useful. Note that these may be renamed in the future to make the -codebase easier to understand and make changes to. Also note that this is -**definitely not** a complete list. - -## Position and width/height variables - -- `bh` - - Menu height divided by lines gets you `bh`. The name comes from dwm's `bh` - meaning 'bar height'. This is the height of each item in the list. -- `mh` - - Menu height (or height of the window) - - Use `drw_resize()` and `XResizeWindow()` to adjust this. -- `mw` - - Menu width (or width of the window) - - Use `drw_resize()` and `XResizeWindow()` to adjust this. - - `2 * borderwidth` is removed from `mw` (2* because we have two sides) - - `2 * sp` is removed from `mw` (2* because we have two sides) -- `x` - - X position, functions like `drw_text` use this. - - If you set this in bar drawing functions, you must apply the same - to `buttonpress()`, otherwise clicks will be offset. -- `y` - - Y position, functions like `drw_text` use this. - - If you set this in bar drawing functions, you must apply the same - to `buttonpress()`, otherwise clicks will be offset. -- `ev->x` - - X position where you clicked. This is used in the `buttonpress()` function - to check where you clicked. -- `ev->y` - - Y position where you clicked. This is used in the `buttonpress()` function - to check where you clicked. -- `w` - - Width of something, this is passed to `drw_text()` for example, but you may - override this. -- `plw` - - This is the width of the powerline arrow. It must be added on in - the `buttonpress()` and draw functions. -- `vp` - - Vertical padding, this is initially added on in the `create_window()` function. -- `sp` - - Horizontal padding, this is initially added on in the `create_window()` function. -- `promptw` - - Width of the prompt text, this is going to be the same as `TEXTW(prompt)`. -- `inputw` - - Width of the input text. -- `fh` - - Font height. Used to calculate the height of the cursor. See `drawcaret()`. -- `menuposition` - - Integer the user is meant to configure. If it's set to `0`, spmenu will be - put on the bottom of the screen. If it's set to `1` it will be put on the - top of the screen. If it's `2` it will be put in the center of the screen. -- `wa.width` - - Window width, `wa` is `XWindowAttributes`. -- `wa.height` - - Window height, `wa` is `XWindowAttributes`. -- `imageheight` - - Image height, This is **not** the height of the image, it is the height - that the image will be scaled to fit. -- `imagewidth` - - Image width, This is **not** the width of the image, it is the width - that the image will be scaled to fit. -- `imagegaps` - - Image gaps, this is extra space added around the image. -- `imageh` - - Usually the same as `imageheight`. This is what `imageheight` is initially - set to. -- `imagew` - - Usually the same as `imagewidth`. This is what `imagewidth` is initially - set to. -- `imageg` - - Usually the same as `imagegaps`. This is what `imagegaps` is initially set to. -- `longestedge` - - As the name implies, it is the longest (highest value) of `imageheight` and `imagewidth`. -- `numberWidth` - - Integer set in some functions, it is simply `TEXTW(numbers)` if the match - count isn't hidden. -- `modeWidth` - - Integer set in some functions, it is simply `TEXTW(modetext)` if the mode - indicator isn't hidden. -- `larrowWidth` - - Integer set in some functions, it is simply `TEXTW(leftarrow)` if the left - arrow isn't hidden. -- `rarrowWidth` - - Integer set in some functions, it is simply `TEXTW(rightarrow)` if the right - arrow isn't hidden. -- `powerlinewidth` - - Integer set in some functions, it is simply `plw / 2` if powerlines are enabled. -- `curpos` - - Cursor/caret position. When text is added to the input, the width of that text - is added to this. - -## Drawable abstraction functions - -Most of these are in `libs/sl/draw.c` and `libs/sl/draw.h`. - -- `drw_create(Display *dpy, int screen, Window win, unsigned int w, -unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);` - - This function creates a drawable from `Display *dpy`, `Drw`. Think of - it as a canvas. -- `drw_resize(Drw *drw, unsigned int w, unsigned int h)` - - This function resizes the drawable to the dimensions passed as - arguments (`w`, `h`). -- `drw_free(Drw *drw);` - - This function will free the drawable from memory. It is *usually* called in - cleanup functions like `cleanup()` so most of the time you don't need to use this. - -## Font abstraction functions - -Most of these are in `libs/sl/draw.c` and `libs/sl/draw.h`. -NOTE: These will differ slightly depending on if Pango is enabled or not. - -- `drw_font_create(Drw* drw, char *font[], size_t fontcount);` - - This function will return a font libXft can use. -- `drw_font_free(Fnt *set);` - - This function will free the font from memory. -- `drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup);` - - This function returns the smallest value out of the passed argument `n` - and the length of the text drawn. The text is not actually drawn though. -- `drw_font_getwidth(Drw *drw, const char *text, Bool markup);` - - This function returns the width of drawn text. The text is not actually - drawn though. -- `drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned - int *w, unsigned int *h, Bool markup);` - - This function returns the length of the text with the used font. - -## Colorscheme abstraction functions - -- `drw_clr_create(Drw *drw, Clr *dest, char *clrname, unsigned int alpha);` - - This function allocates space for a color. -- `drw_scm_create(Drw *drw, char *clrnames[], unsigned int alphas[], -size_t clrcount);` - - This function returns a color scheme from an array of colors and alpha. - -## Cursor abstraction functions - -- `drw_cur_create(Drw *drw, int shape);` - - This function creates and returns a cursor. -- `drw_cur_free(Drw *drw, Cur *cursor);` - - This function will free the cursor from memory. - -## Drawable context functions - -- `drw_setscheme(Drw *drw, Clr *scm);` - - Sets the color scheme to `*scm` created by `drw_scm_create()` - -## Drawing functions - -- `drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled -, int invert);` - - Draws a simple rectangle. Used in other functions to create more useful - shapes, such as a cursor. -- `drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned -int lpad, const char *text, int invert, Bool markup);` - - Draws text on the drawable using the font created. `const char *text` - contains the text itself. - -## Map functions - -- `drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);` - - Maps the drawable. (makes it visible) - -## Removed functions - -Various functions that have been removed for some reason. - -- `drw_setfont(Drw *drw, Fnt *set);` - - Sets the font. - - NOTE: Applies only if Pango is disabled. diff --git a/pages/[spmenu] How to use the buildconf.md b/pages/[spmenu] How to use the buildconf.md deleted file mode 100755 index 38fbee6..0000000 --- a/pages/[spmenu] How to use the buildconf.md +++ /dev/null @@ -1,9 +0,0 @@ -# [spmenu] How to use the buildconf - -This wiki article describes how to use the buildconf. It's really simple, and there's not much to say. - -If you cloned spmenu from the [git repository](https://git.speedie.gq/spmenu), you should already have a default buildconf. This same config is used to build the Arch/Gentoo packages. - -# Toggle image support - -If you want to enable/disable image support (and as such, the `imlib2` dependency), you may set `imlib2=true` or `imlib2=false` in the buildconf. \ No newline at end of file diff --git a/pages/_sidebar.md b/pages/_sidebar.md deleted file mode 100755 index 61e946c..0000000 --- a/pages/_sidebar.md +++ /dev/null @@ -1,5 +0,0 @@ -Useful articles: - -- [[Home]] -- [[[spmenu] Code documentation]] -- [[[spmenu] How to use the buildconf]] diff --git a/run.sh b/run.sh deleted file mode 100755 index d0c9661..0000000 --- a/run.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# -# crontab this to run every X minutes -# 5 * * * * /usr/bin/run.sh - -die() { printf "%s\n" "$*"; exit 1; } - -WIKINAME="wiki" -POST_DIR="$1" -[ -z "$1" ] && POST_DIR="/var/www/page/$WIKINAME/pages" - -[ -e "$POST_DIR" ] || die "You must specify a VALID path. Edit $0." - -cd "$POST_DIR" || die "Does not exist." - -pwd - -[ -e "/tmp/markdown-log" ] && mv /tmp/markdown-log /tmp/markdown-log-2 -find ./*md > /tmp/markdown-log - -[ -e "/tmp/markdown-log-2" ] || exit 0 - -[ -z "$(diff -up /tmp/markdown-log /tmp/markdown-log-2)" ] && exit 0 - -git add ./*.md -git commit -am "Add articles" - -printf "%s - Added articles" "$(date)" > /tmp/markdown-crontab-log - -exit 0 diff --git a/tests/travis-ci-apache.conf b/tests/travis-ci-apache.conf deleted file mode 100755 index 3eedbe6..0000000 --- a/tests/travis-ci-apache.conf +++ /dev/null @@ -1,21 +0,0 @@ - - DocumentRoot %TRAVIS_BUILD_DIR% - - - Options FollowSymLinks MultiViews ExecCGI - AllowOverride All - Require all granted - - - # Wire up Apache to use Travis CI's php-fpm. - - AddHandler php5-fcgi .php - Action php5-fcgi /php5-fcgi - Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi - FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization - - - Require all granted - - -