Remove the speedwm wiki and instead redirect to the git repository

This commit is contained in:
speedie 2023-06-12 01:53:21 +02:00
parent 7e2b0dcf72
commit 767980a057
50 changed files with 14 additions and 6938 deletions

21
LICENSE
View file

@ -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.

View file

@ -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.

View file

@ -1,216 +0,0 @@
<?php if (!defined('W2APP')){ die('No direct access.'); }
/*
* W2
*
* Copyright (C) 2007-2009 Steven Frank <http://stevenf.com/>
* Code may be re-used as long as the above copyright notice is retained.
* See README.md for full details.
*
* Written with Coda: <http://panic.com/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');

View file

@ -1,12 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#232629;
}
.ColorScheme-NegativeText {
color:#da4453;
}</style>
</defs>
<path class="ColorScheme-Text" d="m2 2v12h12v-12h-12m1 2h10v9h-10v-9" fill="#0f0f0f"/>
<path class="ColorScheme-NegativeText" d="m6.2 6l-.707.707 1.793 1.793-1.793 1.793.707.707 1.793-1.793 1.793 1.793.707-.707-1.793-1.793 1.793-1.793-.707-.707-1.793 1.793" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 556 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-NegativeText {
color:#da4453;
}</style>
</defs>
<path class="ColorScheme-NegativeText" d="m5 2v2h1v-1h4v1h1v-2h-5zm-3 3v1h2v8h8v-8h2v-1zm3 1h6v7h-6z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 342 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-NegativeText {
color:#da4453;
}</style>
</defs>
<path class="ColorScheme-NegativeText" d="m5 2v2h1v-1h4v1h1v-2h-5zm-3 3v1h2v8h8v-8h2v-1zm3 1h6v7h-6z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 342 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m10.4 2-8.398 8.398v3.602h3.602l8.398-8.398-3.602-3.602zm-2.049 3.49 2.16 2.16-3.174 3.176v-0.6758l-1.014 0.02148h-1.035v-1.035-0.5859l1.441-1.439 1.621-1.621zm-4.076 4.074v1.621h1.035 0.9922l0.02148 0.6523-1.08 1.082h-1.441l-0.7207-0.7207v-1.441l1.193-1.193z" fill="#0f0f0f"/>
</svg>

Before

Width:  |  Height:  |  Size: 522 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m10.4 2-8.398 8.398v3.602h3.602l8.398-8.398-3.602-3.602zm-2.049 3.49 2.16 2.16-3.174 3.176v-0.6758l-1.014 0.02148h-1.035v-1.035-0.5859l1.441-1.439 1.621-1.621zm-4.076 4.074v1.621h1.035 0.9922l0.02148 0.6523-1.08 1.082h-1.441l-0.7207-0.7207v-1.441l1.193-1.193z" fill="#f0f0f0"/>
</svg>

Before

Width:  |  Height:  |  Size: 522 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m2.375 2c-0.1285 0-0.2515 0.01355-0.375 0.03125v0.9688c0.5523 0 1 0.4477 1 1v8c0 0.5523-0.4477 1-1 1v0.9688c0.1235 0.018 0.2465 0.03125 0.375 0.03125h7.875c2.078 0 3.75-1.672 3.75-3.75 0-1.654-1.082-3.03-2.562-3.531 0.6331-0.4784 1.062-1.236 1.062-2.094 0-1.454-1.171-2.625-2.625-2.625h-7.5zm3.625 1h3c0.5523 0 1 0.8954 1 2s-0.4477 2-1 2h-3v-4zm0 5h3c0.05347 0 0.1038 0.0261 0.1562 0.03125 1.03 0.1012 1.844 1.155 1.844 2.469 0 1.381-0.8954 2.5-2 2.5h-3v-5z" fill="#f0f0f0"/>
</svg>

Before

Width:  |  Height:  |  Size: 720 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m9.09 2-3.146 11.74 0.9668 0.2598 3.146-11.74-0.9668-0.2598zm-3.805 2-2.961 3.145-0.3242 0.3477 0.3242 0.3457 2.943 3.162 0.7148-0.6953-2.621-2.812 2.639-2.797-0.7148-0.6953zm5.43 0-0.7148 0.6953 2.639 2.797-2.621 2.812 0.7148 0.6953 2.943-3.162 0.3242-0.3457-0.3242-0.3477-2.961-3.145z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 554 B

View file

@ -1,13 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 5 2 L 5 3 L 6 3 L 9 3 L 4.71875 13 L 2 13 L 2 14 L 4.28125 14 L 6.28125 14 L 10 14 L 11 14 L 11 13 L 10 13 L 7 13 L 11.28125 3 L 14 3 L 14 2 L 11.71875 2 L 9.71875 2 L 6 2 L 5 2 z "
class="ColorScheme-Text"
/>
</svg>

Before

Width:  |  Height:  |  Size: 533 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m8 2-0.707 0.6992 0.003906 0.003906-5.297 5.295v0.001953 1h1.008v4h-0.007812v1h10v-1-4h1v-1-0.001953l-1.143-1.143-0.7012 0.7012 0.4434 0.4434h-0.5996v5h-3v-3h-2v3h-3v-4-1h-0.5996l4.598-4.596 0.001953 0.001953 0.001953-0.001953 1.441 1.439 0.7012-0.7012-1.441-1.439 0.003906-0.003906-0.707-0.6992zm3 1v3h1.008v-3h-1.008z" fill="#f0f0f0"/>
</svg>

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 886 B

View file

@ -1,10 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<g transform="translate(-3 -1033)">
<path class="ColorScheme-Text" transform="translate(0 1030)" d="m4 7c-0.554 0-1 0.446-1 1v6c0 0.554 0.446 1 1 1h5c0.554 0 1-0.446 1-1v-1h2v1c0 0.554 0.446 1 1 1h5c0.554 0 1-0.446 1-1v-6c0-0.554-0.446-1-1-1h-5c-0.554 0-1 0.446-1 1v1h-2v-1c0-0.554-0.446-1-1-1zm0 1h5v1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1v1h-5zm9 0h5v6h-5v-1c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1zm-4 2h4v2h-4z" fill="#0f0f0f"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 659 B

View file

@ -1,10 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<g transform="translate(-3 -1033)">
<path class="ColorScheme-Text" transform="translate(0 1030)" d="m4 7c-0.554 0-1 0.446-1 1v6c0 0.554 0.446 1 1 1h5c0.554 0 1-0.446 1-1v-1h2v1c0 0.554 0.446 1 1 1h5c0.554 0 1-0.446 1-1v-6c0-0.554-0.446-1-1-1h-5c-0.554 0-1 0.446-1 1v1h-2v-1c0-0.554-0.446-1-1-1zm0 1h3 2v1c-0.554 0-1 0.446-1 1v2c0 0.554 0.446 1 1 1v1h-2-3zm9 0h3 2v6h-2-3v-1c0.554 0 1-0.446 1-1v-2c0-0.554-0.446-1-1-1zm-4 2h4v2h-4z" fill="#f0f0f0"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 667 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m2 2v12h12v-12zm1 1h10v10h-10zm1 1v1h8v-1zm0 3v1h8v-1zm0 3v1h8v-1z" fill="#f0f0f0"/>
</svg>

Before

Width:  |  Height:  |  Size: 329 B

View file

@ -1,13 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#eff0f1;
}
</style>
</defs>
<path style="fill:currentColor;fill-opacity:1;stroke:none"
d="M 3 2 L 3 14 L 8 14 L 8 13 L 4 13 L 4 3 L 9 3 L 9 6 L 12 6 L 12 9 L 13 9 L 13 6 L 13 5 L 10 2 L 9 2 L 3 2 z M 10 9 L 10 11 L 8 11 L 8 12 L 10 12 L 10 14 L 11 14 L 11 12 L 13 12 L 13 11 L 11 11 L 11 9 L 10 9 z "
class="ColorScheme-Text"
/>
</svg>

Before

Width:  |  Height:  |  Size: 559 B

View file

@ -1,17 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<g fill="none" stroke="#0f0f0f">
<path d="m4.5 5v6" stroke-width="1px"/>
<g stroke-width="1px">
<path d="m3 4.5h3"/>
<path d="m3 11.5h3"/>
<path d="m8 11.5h2"/>
<path d="m11 11.5h2"/>
</g>
<rect x="1.5" y="2.5" width="13" height="11" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 519 B

View file

@ -1,17 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<g fill="none" stroke="#f0f0f0">
<path d="m4.5 5v6" stroke-width="1px"/>
<g stroke-width="1px">
<path d="m3 4.5h3"/>
<path d="m3 11.5h3"/>
<path d="m8 11.5h2"/>
<path d="m11 11.5h2"/>
</g>
<rect x="1.5" y="2.5" width="13" height="11" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 519 B

View file

@ -1,8 +0,0 @@
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<defs>
<style id="current-color-scheme" type="text/css">.ColorScheme-Text {
color:#eff0f1;
}</style>
</defs>
<path class="ColorScheme-Text" d="m2 2v11.28 0.7188h12v-1-1-1-1-3h-1v2l-2-2-3.344 3.344-1.344-1.344h-0.03125l-3.281 3.281v-9.281h6v-1h-7zm9 5h1v-3.086l2 2v-1.414l-2.5-2.5-2.5 2.5v1.414l2-2v3.086zm-5-3c-1.105 0-2 0.8954-2 2s0.8954 2 2 2 2-0.8954 2-2-0.8954-2-2-2z" fill="#f0f0f0"/>
</svg>

Before

Width:  |  Height:  |  Size: 491 B

4
images/.gitignore vendored
View file

@ -1,4 +0,0 @@
# Ignore everything
*
# except this file
!.gitignore

410
index.css
View file

@ -1,410 +0,0 @@
/*
* W2
*
* Copyright (C) 2007-2011 Steven Frank <http://stevenf.com/>
*
* Code may be re-used as long as the above copyright notice is retained.
* See README.txt for full details.
*
* Written with Coda: <http://panic.com/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;
}

14
index.html Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>speedwm</title>
<meta charset="UTF-8">
<meta name="description" content="speedie's fork of suckless.org's dwm">
<meta name="author" content="speedie">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<meta http-equiv="refresh" content="0;https://git.speedie.site/speedie/speedwm" />
</body>
</html>

938
index.php
View file

@ -1,938 +0,0 @@
<?php
define('W2APP', true);
/*
* W2
*
* Copyright (C) 2007-2011 Steven Frank <http://stevenf.com/>
*
* Code may be re-used as long as the above copyright notice is retained.
* See README.txt for full details.
*
* Written with Coda: <http://panic.com/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 "<html><body>Access from IP address $ip is not allowed</body></html>";
exit;
}
}
function printHeader($title, $action, $bodyclass="")
{
print "<!doctype html>\n";
print "<html lang=\"" . W2_LOCALE . "\">\n";
print " <head>\n";
print " <meta charset=\"" . W2_CHARSET . "\">\n";
print " <link rel=\"icon\" href=\"/icons/fav.png\"/>\n";
print " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n";
print " <link type=\"text/css\" rel=\"stylesheet\" href=\"" . BASE_URI . "/" . CSS_FILE ."\" />\n";
print " <title>".PAGE_TITLE."$title</title>\n";
print " </head>\n";
print " <body".($bodyclass != "" ? " class=\"$bodyclass\"":"").">\n";
}
function printFooter()
{
print " </body>\n";
print "</html>";
}
function printDrawer()
{
print " <div id=\"drawer\" class=\"inactive\">\n".
" <a href=\"\" onclick=\"toggleDrawer(); return false;\"><img src=\"/icons/close.svg\" alt=\"".__('Close')."\" title=\"".__('Close')."\" class=\"icon rightaligned\"/></a>\n".
" <div>\n".
"# ".__('Header')." 1<br/>".
"## ".__('Header')." 2<br/>".
"### ".__('Header')." 3<br/>".
"#### ".__('Header')." 4<br/>".
"##### ".__('Header')." 5<br/>".
"###### ".__('Header')." 6<br/>".
"<br/>".
"*".__('Emphasize')."* - <em>".__('Emphasize')."</em><br/>".
"_".__('Emphasize')."* - <em>".__('Emphasize')."</em><br/>".
"**".__('Bold')."** - <strong>".__('Bold')."</strong><br/>".
"__".__('Bold')."__ - <strong>".__('Bold')."</strong><br/>".
"<br/>".
"[[Link to page]]<br/>".
"&lt;http://example.com/&gt;<br/>".
"[link text](http://url)<br/><br/>".
"{{image.jpg}}<br/>".
"![Alt text](/images/image.jpg)<br/>".
"![Alt text](/images/image.jpg \"Optional title\")<br/>".
"<br/>".
"- Unordered list<br/>".
"+ Unordered list<br/>".
"* Unordered list<br/>".
"1. Ordered list<br/>".
"<br/>".
"> Blockquote<br/>".// <blockquote>Blockquotes</blockquote>\n".
"```Code```<br/>". //<pre>Code</pre>\n\n".
"`inline-code`<br/><br/>".
"*** Horizontal rule<br/>".
"--- Horizontal rule<br/>\n".
" </div>\n".
" </div>\n".
" <a id=\"drawer-control\" href=\"\" onclick=\"toggleDrawer(); return false;\">\n".
" </a>\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 " <h1>" . __('Log In') . "</h1>\n";
print " <form method=\"post\">\n";
print " ".__('Password') . ": <input type=\"password\" name=\"p\">\n";
print " <input type=\"submit\" value=\"" . __('Log In') . "\">\n";
print " </form>\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 "<a href=\"" . pageURL($page) ."\"$attributes>$title</a>";
/* wip
$link_page = $match[1];
$link_filename = PAGES_PATH . "/$link_page.txt";
$link_page_exists = file_exists($link_filename);
if ($link_page_exists)
return "<a href=\"" . pageURL($page) ."\"$attributes>$title</a>";
else
//return "<a href=\"" . SELF . VIEW . "/" . htmlentities($link_page) . "\" class=\"missing-link\">" . htmlentities($link_page) . "</a>";
return "<a href=\"" . pageURL($page) ."\" class=\"missing-link\" . $attributes>$title</a>";
*/
}
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 .= "<br/>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("/(?<![\[a-zA-Z])$pageName(?![\]a-zA-Z])/i", "[[$pageName]]", $outHTML);
}
}
preg_match_all(
"/\[\[(.*?)\]\]/",
$outHTML,
$matches,
PREG_PATTERN_ORDER
);
for ($i = 0; $i < count($matches[0]); $i++)
{
$fullLinkText = $matches[1][$i];
$linkTitleSplit = explode('|', $fullLinkText);
$linkedPage = $linkTitleSplit[0]; // split away an eventual link text
$linkText = (count($linkTitleSplit) > 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("/\{\{(.*?)\}\}/", "<img src=\"" . BASE_URI . "/images/\\1\" alt=\"\\1\" />", $outHTML);
// add an anchor in all title tags (h1/2/3/4):
preg_match_all(
"/<h([1-4])>(.*?)<\/h\\1>/",
$outHTML,
$matches,
PREG_PATTERN_ORDER
);
for ($i = 0; $i < count($matches[0]); $i++)
{
$prefix = "<h".$matches[1][$i].">";
$caption = $matches[2][$i];
$suffix = substr_replace($prefix, "/", 1, 0);
$outHTML = str_replace("$prefix$caption$suffix",
"$prefix<a id=\"".toHTMLID($caption)."\">$caption</a>$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 .= " <a href=\"".SELF."?action=".$pageActions[$i].
"&amp;page=".urlencode($page)."\"><img src=\"/icons/".$pageActions[$i].$imgSuffix.".svg\" alt=\"".$pageActionNames[$i]."\" title=\"".$pageActionNames[$i]."\" class=\"icon\"></a>\n";
}
}
$result .= " <a href=\"" . SELF . "?action=view&page=$page&linkshere=true\"><img src=\"/icons/link".$imgSuffix.".svg\" alt=\"".__('Show links here')."\" title=\"".__('Show links here')."\" class=\"icon\"/></a>\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 <a href=\"?action=edit&amp;page=".urlencode($page)."\">edit</a> the existing page (this discards current text!)!</div>\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 .= "<form id=\"edit\" method=\"post\" action=\"$formAction\">\n";
if ( $action === 'edit' )
{
$html .= "<input type=\"hidden\" name=\"page\" value=\"$page\" />\n";
}
else
{
if ($newPage != "" && !$triedSave)
{
$html .= "<div class=\"note\">". __('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 .= "<br/><strong>Note:</strong> Found similar page ".pageLink($pageName, $pageName).". Maybe you meant to edit this instead?";
}
}
$html .= "</div>\n";
}
$html .= "<p>" . __('Title') . ": <input id=\"title\" title=\"".__("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 '-'.")."\" type=\"text\" name=\"page\" value=\"$newPage\" class=\"pagename\" placeholder=\"".__('Name of new page (restrictions in tip)')."\"/></p>\n";
}
$html .= "<p><textarea id=\"text\" name=\"newText\" rows=\"" . EDIT_ROWS . "\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\">$text</textarea></p>\n";
if (GIT_COMMIT_ENABLED)
{
$html .= "<p>Message: <input type=\"text\" id=\"gitmsg\" name=\"gitmsg\" value=\"$oldgitmsg\" /></p>\n";
}
$html .= "<p><input type=\"hidden\" name=\"action\" value=\"save\" />\n";
$html .= "<input type=\"hidden\" name=\"isNew\" value=\"".(($action==='new')?"true":"")."\" />\n";
$html .= '<input id="save" type="submit" value="'. __('Save') .'" />'."\n";
$html .= '<input id="cancel" type="button" onclick="history.go(-1);" value="'. __('Cancel') .'" />'."\n";
$html .= "</p></form>\n";
}
else if ( $action === 'logout' )
{
destroy_session();
header("Location: " . SELF);
exit;
}
else if ( $action === 'upload' )
{
if ( DISABLE_UPLOADS )
{
$html .= '<p>' . __('Image uploading has been disabled on this installation.') . '</p>';
}
else
{
$html .= "<form id=\"upload\" method=\"post\" action=\"" . SELF . "\" enctype=\"multipart/form-data\"><p>\n".
"<input type=\"hidden\" name=\"action\" value=\"uploaded\" />".
"<input id=\"file\" type=\"file\" name=\"userfile\" />\n".
'<input id="resize" type="checkbox" checked="checked" name="resize" value="true">'.
'<label for="resize">'.__('Shrink if larger than ').'</label>'.
'<input id="maxsize" type="number" name="maxsize" min="20" max="8192" value="1200">'.
'<label for="maxsize" id="maxsizelabel">'.__('Pixels').'</label>'.
'<input id="upload" type="submit" value="' . __('Upload') . '" />'."\n".
'<input id="cancel" type="button" onclick="history.go(-1);" value="'. __('Cancel') .'" />'."\n";
"</p></form>\n";
}
// list files in UPLOAD_FOLDER
$path = PAGES_PATH . "/". UPLOAD_FOLDER . "/*";
$imgNames = glob($path);
natcasesort($imgNames);
$html .= "<p>".__('Total').": ".count($imgNames)." ".__('images')."</p>";
$html .= "<table><thead>";
$html .= "<tr>".
/*
"<td>".(($sortBy!='name')?("<a href=\"".SELF."?action=all&sortBy=name\">Name</a>"):"<span class=\"sortBy\">Name</span>")."</td>".
"<td>".(($sortBy!='recent')?("<a href=\"".SELF."?action=all&sortBy=recent\">Modified</a>"):"<span class=\"sortBy\">Modified</span>")."</td>".
*/ "<td>".__("Name")."</td><td>".__("Usage")."</td><td>".__("Modified")."</td><td>".__("Action")."</td>".
"</tr></thead><tbody>";
$date_format = __('date_format', TITLE_DATE);
foreach ($imgNames as $imgName)
{
$html .= "<tr>".
"<td>".basename($imgName)."</td>".
"<td><pre>".imageLinkText(basename($imgName))."</pre></td>".
"<td><nobr>".date($date_format, filemtime($imgName))."</nobr></td>".
"<td><a href=\"".SELF."?action=imgDelete"."&amp;imgName=".urlencode(basename($imgName))."\">".__('Delete')."</a></td>".
"</tr>\n";
}
$html .= "</tbody></table>\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 <pre>".imageLinkText($dstName)."</pre> 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."<br/><br/>\n".
"Check that your permissions are set correctly.";
} else {
// Give generic error message
$msg .= __('Upload error').", error #".$error_code."<br/><br/>\n".
"Please see <a href=\"https://www.php.net/manual/en/features.file-upload.errors.php\">here</a> for more information.<br/><br/>\n".
"If you see this message, please <a href=\"https://github.com/codeling/w2wiki/issues\">file a bug to improve w2wiki</a>";
}
}
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 .= "<form id=\"$action\" method=\"post\" action=\"" . SELF . "\">";
$html .= "<p>".$actionName." $page ".
(($action==='rename')? (__('to')." <input id=\"newPageName\" type=\"text\" name=\"newPageName\" value=\"" . htmlspecialchars($page) . "\" class=\"pagename\" />") : "?") . "</p>";
$html .= "<p><input id=\"$action\" type=\"submit\" value=\"$actionName\">";
$html .= "<input id=\"cancel\" type=\"button\" onclick=\"history.go(-1);\" value=\"Cancel\" />\n";
$html .= "<input type=\"hidden\" name=\"action\" value=\"${action}d\" />";
$html .= "<input type=\"hidden\" name=\"oldPageName\" value=\"" . htmlspecialchars($page) . "\" />";
$html .= "</p></form>";
}
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 .= "<br/>\n".__('Updated links in the following pages:')."\n<ul><li>";
$msg .= implode("</li><li>", $changedPages);
$msg .= "</li></ul>";
}
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 .= "<p>".__('Total').": ".count($pageNames)." ".__("pages")."</p>";
$html .= "<table><thead>";
$html .= "<tr>".
"<td>".(($sortBy!='name')?("<a href=\"".SELF."?action=all&sortBy=name\">Name</a>"):"<span class=\"sortBy\">".__('Name')."</span>")."</td>".
"<td>".(($sortBy!='recent')?("<a href=\"".SELF."?action=all&sortBy=recent\">".__('Modified')."</a>"):"<span class=\"sortBy\">".__('Modified')."</span>")."</td>".
"<td>".__('Action')."</td>".
"</tr></thead><tbody>";
$date_format = __('date_format', TITLE_DATE);
foreach ($filelist as $pageName => $pageDate)
{
$html .= "<tr>".
"<td>".pageLink($pageName, $pageName)."</td>".
"<td valign=\"top\"><nobr>".date( $date_format, $pageDate)."</nobr></td>".
//"<td class=\"pageActions\">".getPageActions($pageName, $action,"-dark")."</td>". /* dark mode */
"<td class=\"pageActions\">".getPageActions($pageName, $action, "")."</td>". /* light mode */
"</tr>\n";
}
$html .= "</tbody></table>\n";
}
else if ( $action === 'search' )
{
$matches = 0;
$q = $_REQUEST['q'];
$html .= " <h1>Search: $q</h1>\n";
if ( trim($q) != "" )
{
$html .= " <ul>\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 .= " <li>$link</li>\n";
}
if (!$found)
{
$html .= " <li>".pageLink($q, __('Create page')." '$q'", " class=\"noexist\"")."</li>";
}
$html .= " </ul>\n";
}
$html .= " <p>$matches ".__('matches')."</p>\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 = "<span class=\"titledate\">" . date($date_format, @filemtime($filename)) . "</span>";
}
}
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 " <div class=\"titlebar\"><span class=\"title\">$title</span>$datetime";
if ($action === 'view' || $action === 'rename' || $action === 'delete' || $action === 'edit')
{
print(getPageActions($page, $action, ""));
}
print " </div>\n";
print " <div class=\"toolbar\">\n";
print " <a href=\"" . SELF . "\"><img src=\"/icons/home.svg\" alt=\"". __(DEFAULT_PAGE) . "\" title=\"". __(DEFAULT_PAGE) . "\" class=\"icon\"></a>\n";
print " <a href=\"" . SELF . "?action=all\"><img src=\"/icons/list.svg\" alt=\"". __('All') . "\" title=\"". __('All') . "\" class=\"icon\"></a>\n";
print " <a href=\"" . SELF . "?action=new\"><img src=\"/icons/new.svg\" alt=\"".__('New')."\" title=\"".__('New')."\" class=\"icon\"></a>\n";
if ( !DISABLE_UPLOADS )
{
print " <a href=\"" . SELF . VIEW . "?action=upload\"><img src=\"/icons/upload.svg\" alt=\"".__('Upload')."\" title=\"".__('Upload')."\" class=\"icon\"/></a>\n";
}
if ( REQUIRE_PASSWORD )
{
print " <a href=\"" . SELF . "?action=logout\">". __('Log out') . "</a>";
}
print " <form method=\"post\" action=\"" . SELF . "?action=search\">\n";
print " <input class=\"search\" placeholder=\"". __('Search') ."\" size=\"20\" id=\"search\" type=\"text\" name=\"q\" />\n </form>\n";
if ($action === 'edit')
{
printDrawer();
}
print " </div>\n";
if (SIDEBAR_PAGE != '')
{
print " <div class=\"sidebar\">\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 " </div>\n";
}
if ($action === 'view' && $_GET['linkshere'])
{
print "<div class=\"linkshere\">".__('What links here:')."<ul>";
$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(" <li>$link</li>\n");
}
}
print "</ul></div>";
}
print " <div class=\"main\">\n\n";
if(isset($_SESSION['msg']) && $_SESSION['msg'] != '')
{
print " <div class=\"note\">".$_SESSION['msg']."</div>";
unset($_SESSION['msg']);
}
print "$html\n";
print " </div>\n";
printFooter();

View file

@ -1,65 +0,0 @@
<?php if (!defined('W2APP')){ die('No direct access.'); }
/**
* Locale set
*
* Do not change variable name $w2_word_set.
* Rewrite values in your locale and rename this file to locale code.
* Set "LOCALE" to your locale in config.php.
*/
$w2_word_set = array(
// Buttons / Labels
'Home' => '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',
);

View file

@ -1,32 +0,0 @@
<?php if (!defined('W2APP')){ die('No direct access.'); }
/**
* Locale set
*
* Do not change variable name $w2_word_set.
* Rewrite values in your locale and rename this file to locale code.
* Set "LOCALE" to your locale in config.php.
*/
$w2_word_set = array(
// Buttons / Labels
'Home' => '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',
);

View file

@ -1,32 +0,0 @@
<?php if (!defined('W2APP')){ die('No direct access.'); }
/**
* Locale set
*
* Do not change variable name $w2_word_set.
* Rewrite values in your locale and rename this file to locale code.
* Set "LOCALE" to your locale in config.php.
*/
$w2_word_set = array(
// Buttons / Labels
'Home' => 'ホーム',
'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',
);

View file

@ -1,32 +0,0 @@
<?php if (!defined('W2APP')){ die('No direct access.'); }
/**
* Locale set
*
* Do not change variable name $w2_word_set.
* Rewrite values in your locale and rename this file to locale code.
* Set "LOCALE" to your locale in config.php.
*/
$w2_word_set = array(
// Buttons / Labels
'Home' => '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',
);

View file

@ -1,10 +0,0 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the Markdown parser.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';

File diff suppressed because it is too large Load diff

View file

@ -1,11 +0,0 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the MarkdownExtra parser.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';
require_once dirname(__FILE__) . '/Markdown.php';
require_once dirname(__FILE__) . '/MarkdownExtra.php';

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
<?php
// Use this file if you cannot use class autoloading. It will include all the
// files needed for the MarkdownInterface interface.
//
// Take a look at the PSR-0-compatible class autoloading implementation
// in the Readme.php file if you want a simple autoloader setup.
require_once dirname(__FILE__) . '/MarkdownInterface.php';

View file

@ -1,38 +0,0 @@
<?php
/**
* Markdown - A text-to-HTML conversion tool for web writers
*
* @package php-markdown
* @author Michel Fortin <michel.fortin@michelf.com>
* @copyright 2004-2019 Michel Fortin <https://michelf.com/projects/php-markdown/>
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
*/
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);
}

View file

@ -1,22 +0,0 @@
Centered status bar
===================
Thanks to [[Configuring the bar]] and the `es` modules, we can position the status text in the center similar to the [splitstatus](https://dwm.suckless.org/patches/splitstatus) patch.
To do this, start off by copying `bar.h` to `bar.rl.h`. This is optional, but I highly recommend it. Now, you'll want to add a module like this.
`{ -1, 0, bar_align_center, width_status_es, draw_status_es, click_status_es, 0, "extra status" },`
We're using `bar_align_center` because we want it in the center, that's the point here. We're using `es` modules because we want to have status text in both the center and the usual right. In the default configuration, you'll (probably) want to remove the title module, or move it to the other bar to get the aesthetic you want. Now that you have the modules configured, compile this using `make clean install`.
To use the `es` modules, you simply add `;` somewhere in the status text. Any text after will be considered extrastatus text. For example `speedwm -s "Hello;World"` will draw Hello as regular status text and World as extra status text in the center of the bar.
### Usage in the status bar
The above is all cool and all, but if we want to use it with the built in status bar, we need to integrate it into the modules. There are many different ways this could be done, but we're going to do it the easiest here. In this example, we're going to put the time in the center and the rest will be in the normal status bar.
Copy `status.h` to `status.rl.h` and `vim status.rl.h`. Now we can remove the `module_time` module, because a duplicate is unnecessary. Let's add a module to the array like this.
`{ ";", "module_time --print", 1, 1 },`
Of course, the `;` here switches to the centered status. Now we can run `make clean install` and restart `speedwm_status`. You should see your expected changes and the time should be in the center now.

View file

@ -1,130 +0,0 @@
Client rules
============
The `Rule` array allows you to specify rules for X11 clients based on factors such as WM_CLASS and WM_NAME. In the English language, that means you can specify how clients are tiled based on the class, instance or title of said client.
To get this information, you can use the X11 utility `xprop` to get information about a client. If you want to see in detail how the rule system works, refer to function `applyrules` and the `Rule` struct in `speedwm.c`.
### Rule structure (user-friendly)
1. Class
Type: `const char *`
2. Instance
Type: `const char *`
3. Title
Type: `const char *`
4. Tags
Type: `unsigned int`
5. isfloating
Type: `int`
6. ispermanent
Type: `int`
7. isterminal
Type: `int`
8. noswallow
Type: `int`
9. Monitor
Type: `int`
10. unmanaged
Type: `int`
11. ignoretransient
Type: `int`
12. floatx
Type: `int`
13. floaty
Type: `int`
14. floatw
Type: `int`
15. floath
Type: `int`
16. scratchkey
Type: `const char`
### Rule structure (internally)
`typedef struct {`
`const char *class;`
`const char *instance;`
`const char *title;`
`unsigned int tags;`
`int isfloating;`
`int ispermanent;`
`int isterminal;`
`int noswallow;`
`int monitor;`
`int unmanaged;`
`int ignoretransient;`
`int floatx, floaty, floatw, floath;`
`const char scratchkey;`
`} Rule;`
### Class
Every X11 client has a class. Even the window manager, speedwm in this case which has the class `speedwm` has a class. speedwm is **not** responsible for setting a client's class, clients using X11 libraries should set this themselves. speedwm just retrieves this information when a client is mapped.
As mentioned previously, you can get the class for a client by running the command-line utility `xprop` on any client. Running `xprop` on speedwm's bar for example will return:
`
[anon@arch ~]$ xprop
WM_CLASS(STRING) = "speedwm", "speedwm"
`
Running it and clicking on the root window however will return information such as the different tags and their glyphs, supported atoms, loaded xrdb resources and information such as the focused client which is not relevant here.
Now, some clients may have multiple classes, `st` for example has both `st` and `St`. Note the class of the program you want to use. Let's say, we want to set a rule for Chromium. Running `xprop | grep CLASS` returns the following information.
`
[anon@arch ~]$ xprop | grep CLASS
WM_CLASS(STRING) = "chromium", "Chromium"
`
This means our class here is `chromium`. That would also be the value of `const char *class` or simply the class. This means if the class matches what we specified (ie. `chromium`), and provided the instance and title also matches an existing client, we set the other values to what is specified.
### Instance
This allows us to specify which instance of the class

View file

@ -1,178 +0,0 @@
Configuring the bar
===================
As of 1.8, speedwm has a module system. It is based on the [barmodules](https://github.com/bakkeby/patches/blob/master/dwm/dwm-barmodules-6.2.diff) patch for dwm and allows extensive control over the way the speedwm bar functions. This control has its own header, `bar.h`.
`bar.h` contains a somewhat detailed list of all possible options here, but more importantly it contains a `barrules` array. This array similar to the `rules` array allows extensive control over where each bar module is placed and how it functions. In theory, this means you could put 22 instances of the same, boring tags on one bar, although why would one do that?
Each module can be aligned to any part of the bar (See 'Alignment' for possible values). If, let's say multiple modules both align to the right next to the center split (middle), the first module takes priority.
### BarRule structure (user-friendly)
1. Monitor
Type: `int`
2. Bar
Type: `int`
3. Alignment
Type: `int`
4. Width function
Type: `int (*widthfunc)`
5. Draw function
Type: `int (*drawfunc)`
6. Click function
Type: `int (*clickfunc)`
7. Value
Type: `int`
8. Name
Type: `char *`
### BarRule structure (internally)
`typedef struct {`
`int monitor;`
`int bar;`
`int alignment;`
`int (*widthfunc)(Bar *bar, BarWidthArg *a);`
`int (*drawfunc)(Bar *bar, BarDrawArg *a);`
`int (*clickfunc)(Bar *bar, Arg *arg, BarClickArg *a);`
`int val;`
`char *name;`
`int x, w;`
`} BarRule;`
### Module list
Below is a list of all modules bundled with speedwm. The source code for these modules are all in `bar/` and declared in `bar/items.c` and `bar/items.h`. If you want to add more, you can just declare them in the same way and add them to the `barrules` array if you want to use them.
- ltsymbol: Standard, basic layout icon.
- tags: Basic tags, without powerlines.
- tags_pwl: Tags with powerlines.
- systray: Basic X11 system tray.
- status_basic: Basic status bar.
- status_basic_es: Basic status bar.
- status: Clickable status bar with color support through status2d.
- status_es: Clickable status bar with color support through status2d (Extra status).
- status_pwl: Non-clickable status bar with powerlines. It supports colors by cycling through colorschemes.
- status_pwl_es: Non-clickable status bar with powerlines. It supports colors by cycling through colorschemes (Extra status).
- title: Title, shows all windows, including hidden windows.
- title_basic: Basic title, shows focused window.
### Monitor
The monitor value allows you to specify which monitor the module should be placed on. In addition to this, you can also choose to only draw the module on the focused monitor.
-1: Show the module on all monitors.
0: Show on the main monitor (monitor 0).
1: Show on monitor #1 (This can be any monitor you want).
### Bar
This value allows you to specify which bar the module is placed on. speedwm supports two (0 and 1) bars. 0 is the main bar, which is by default placed at the top. 1 is the second bar which is only visible if modules actively use it. If the main bar is placed on the top, the second bar is placed on the bottom and vice versa.
0: Place the module on the main bar
1: Place the module on the extra bar
### Alignment
This value allows you to specify an alignment for the module in question. As previously mentioned, the first module takes priority if multiple modules have the same alignment.
The 'center split' refers to the middle of the bar, and that's where any free space/remainder of the screen ends up for other modules to use if desired.
- bar_align_left: Force the module to be placed on the left side of the bar if possible.
- bar_align_right: Force the module to be placed on the right side of the bar if possible.
- bar_align_center: Force the module to be placed in the center of the bar if possible.
- bar_align_left_left: Force the module to be placed on the left side of the bar next to the center split.
- bar_align_left_right: Force the module to be placed on the right side of the bar next to the center split.
- bar_align_left_center: Force the module to be placed on the center in the middle of the remaining space left of the center split on the left..
- bar_align_right_left: Force the module to be placed on the left side of the bar next to the center split.
- bar_align_right_right: Force the module to be placed on the right side of the bar next to the center split.
- bar_align_right_center: Force the module to be placed on the center in the middle of the remaining space left of the center split on the right.
- bar_align_none: No specific alignment. This will give the module the remaining space.
### Width
'Width' refers to the function to call which returns the width of a module. The syntax below applies to all default modules.
Syntax: width_<module>
Example: width_tags_pwl
### Draw
'Draw' refers to the function to call which draws the module on the bar. The syntax below applies to all default modules.
Syntax: draw_<module>
Example: draw_tags_pwl
### Click
'Click' refers to the function to call which checks if you clicked on said module. The syntax below applies to all default modules.
Syntax: click_<module>
Example: click_tags_pwl
### Value
**NOTE: Support for this was added in version 1.9 of speedwm, and speedwm 1.8 does not have it. Any modules using it will be incompatible with speedwm 1.8. I highly recommend upgrading to 1.9 for this (and many more) reason.**
'Value' here is simply an integer (a number) which the different functions can access and read to (possibly) determine different functionality. Most modules don't use it, in fact speedwm 1.9 doesn't even come with any modules that use this, however in an effort to make writing modules easy, it is included in the base build.
It should be noted that passing `0` here does not *disable* it, but sets it to `0`. For most modules, it doesn't matter what you pass but it is recommended that you simply pass `0`.
Syntax: <int>
Example: 12
### Module name
The module name really doesn't mean anything at all, it is just useful for debugging.
### Example module
With all that said, you should now be able to add a module. In case you weren't able to follow along, here is an example of how you can add powerline tags on the focused monitor.
1. `{ 'A',`
2. `0,`
3. `bar_align_left,`
4. `width_tags_pwl,`
5. `draw_tags_pwl,`
6. `click_tags_pwl,`
7. `0,`
8. `"my cool powerline tags" },`
Combined into one line: `{ 'A', 0, bar_align_left, width-tags_pwl, draw_tags_pwl, click_tags_pwl, 0, "my cool powerline tags" },`
Let's break down the above.
1. 'A' here refers to the focused monitor, indicating that we want to place it on the focused monitor.
2. 0 here means we want to place it on the primary bar.
3. bar_align_left indicates we want to align it to the left part of the bar, you know, where tags usually are.
4. width_tags_pwl is the function we call to get the width.
5. draw_tags_pwl is the function we call to draw the bar.
6. click_tags_pwl is the function we call to check if we clicked on that module.
7. 0 here is the value we allow the function to access. The value doesn't matter for most modules but 0 is used here.
8. A label for our module, it's only useful for debugging.
Feel free to copy the above to `bar.h` if you want to experiment with it.

View file

@ -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 [[Wayland support]] 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-<version>.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-<version>`. Let's
`cd speedwm-<version>` 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'.

View file

@ -1,27 +0,0 @@
Welcome to the speedwm wiki!
----------------------------
![image](https://codeberg.org/speedie/speedwm/raw/branch/master/docs/preview.png)
[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.
Just like dwm, speedwm also tries to be minimal but also brings functionality
and aesthetics to the table without patching or other work. It is a good
middle ground between creating your own dwm build from scratch and bloated
window managers like awesome which are not primarily configured by editing source code.
Tiling window managers (unlike floating window managers that you may be used to) tile windows based on a set layout making them easy to get productive on. They also encourage the user to use their keyboard instead of the mouse so that the user doesn't have to move his hands much but there are also mouse binds and more can be added by the user if desired.
You have reached the wiki for speedwm, the main source of information
regarding the project. Any information too detailed or complex to be part of the speedwm
release is placed here. Because it's a wiki, anyone may submit changes to the
wiki. The wiki is also free/libre (as in freedom) software and you can have a
copy. See [this git repository](https://codeberg.org/speedie/speedwm-wiki) for
more information.
Not sure where to begin with speedwm? See [[Getting Started]] for a nice way
to get into it!

View file

@ -1,167 +0,0 @@
Keybinds
========
Like the `BarRules` array mentioned, there is a `Key keys` array in `keybinds.h` which contains all keybinds speedwm will recognize. While this isn't the only way to add keybinds in speedwm, it does not require any additional software to be installed.
### Key structure (user-friendly)
1. Event
Type: `int`
2. Modifier
Type: `unsigned int`
3. Chain key
Type: `KeySym`
4. Key
Type: `KeySym`
5. Function
Type: `void (*func)`
6. Function arguments
Type: `const Arg`
### Key structure (internally)
`typedef struct {`
`int type;`
`unsigned int mod;`
`KeySym chain;`
`KeySym keysym;`
`void (*func)(const Arg *);`
`const Arg arg;`
`} Key;`
### Event
The event value allow you to specify when a keybind is executed. Internally this is known as `int type` and it specifies when the function is executed.
- KeyPress: Activate immediately on key press.
- KeyRelease: Activate immediately on key release.
### Modifier
There are a lot of different modifiers, this list is only going to list the ones declared in speedwm. You can, of course declare more if necessary although it should be noted that doing so is out of the scope of this documentation. We will be focusing on the defined modifiers which are defined in `speedwm.c` like this:
`/* Modifiers */`
`#define CONTROL ControlMask`
`#define SHIFT ShiftMask`
`#define ALT Mod1Mask`
`#define ALTR Mod3Mask`
`#define SUPER Mod4Mask`
`#define SUPERR Mod5Mask`
Below is a list of defined modifiers:
- CONTROL Left Control (Ctrl) key.
- SHIFT Left Shift key.
- ALT Left Alt key.
- SUPER Left Super (Windows) key.
- SUPERR Right Super (Windows) key.
In keybinds.h, MODIFIER1 and MODIFIER2 are also defined. MODIFIER1 is defined in order to make modifying keybinds easier. MODIFIER1 is by default defined as SUPER or Mod4Mask. For instance, if you want to use MODIFIER1 as your modifier, `MODIFIER1` would be the right value here.
Do note that you can may use multiple modifiers. Do this by adding two or more modifiers separated by a pipe (MODIFIER1|SHIFT)
### Chain key
This value *is* mandatory, but it does not have to be used. speedwm has supported chained keybinds since 0.4. Chained keybinds allow more keybinds as like the name implies, the user has to press multiple keys to activate it. You can think of it as in Vim where there's different modes.
The first key that needs to be pressed to activate a chain needs to be the key specified here. In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. If, let's say we want to use simply the letter `a` as the key to start a chain, the value here would be `XK_a`.
If we want a normal key, one that is **not** chained, we can accomplish that by simply setting the Chain key to `-1`. You can see this in the `keypress()` function in `speedwm.c`. This line of code is responsible for this behavior.
`if (keysym == keys[i].keysym && keys[i].chain == -1`
### Key
The next value, similar to the Chain key also needs to be a keysym. If the key is a chained key, this is the second key that needs to be pressed. If it isn't a chained key, this is the key that needs to be pressed while the Modifier is pressed.
In order to see a list of possible keys, see `/usr/include/X11/keysymdef.h`. Note that this path may differ depending on your operating system.
There are a lot more keys technically defined, see `/usr/include/X11/XF86keysym.h` for a list of media keys.
### Function
Many functions expect `const Arg *arg` to be passed to them. However this value does require any function argument to be specified because it simply passes the next value to the function and calls it.
There is no list of functions, but `speedwm.c` has a lot of declared functions which you may use in keybinds provided the function expects `const Arg *arg`.
### Function arguments
This is the actual argument passed to the function we're calling when the keybind is activated. Explaining this well would be fairly simple, but instead of doing so I recommend you read the `typedef union Arg` in `speedwm.c`. It looks like this:
`typedef union {`
`long i;`
`unsigned long ui;`
`float f;`
`const void *v;`
`} Arg;`
In short, Arg is a list of different types, which may be used to set different things in the argument.
Passing a float (such as mfact) through would mean I should override `.f`, passing an integer (such as barposition) through would mean I should override `.i`. There's also `.v` for `void` and `.ui` for tags. This is not used unless you want to mess with tag keybinds.
When you don't care about the value given to the function, you may simply enter a `0`.
### Example keybind
With all that said, you probably get the idea of how it works. But you still don't know how to put all this knowledge together.
1. `{ KeyPress,`
2. `MODIFIER1|SHIFT,`
3. `-1,`
4. `XK_w,`
5. `spawn,`
6. `cmd( "firefox" ) },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, -1, XK_w, spawn, cmd( "firefox" ) },`
Let's break down the above.
1. This is our type. If it's `KeyPress`, it will be activated when the keybind is pressed. If it is `KeyRelease` it will be activated when the keybind is released.
2. This is our modifier. `MODIFIER1` is defined in `keybinds.h`. We're adding SHIFT to it, (defined in `speedwm.c`) which means we have to press BOTH `MODIFIER1` and `SHIFT` at the same time to activate this keybind.
3. This is our **chain** key. `-1` here indicates that we do not want it to be chained. We want a regular keybind. See the example below for an example *with* a chained keybind instead.
4. This is our regular key. `XK_w` is defined in `/usr/include/X11/keysymdef.h` on most operating systems and it means we have to press `w` on our keyboard along with the modifier to activate this keybind.
5. This is our function. We call this, passing the next value (`const Arg *arg`) to it.
6. This is our function argument. Do note that in this case `cmd()` is a macro and it is defined in `speedwm.c`. This macro will pass the contents of the macro to a shell it will spawn.
Feel free to copy the above to `keybinds.h` if you want to experiment with it.
### Example chained keybind
1. `{ KeyPress,`
2. `MODIFIER1|SHIFT,`
3. `XK_a,`
4. `XK_w,`
5. `togglebar,`
6. `{0} },`
Combined into one line: `{ KeyPress, MODIFIER1|SHIFT, XK_a, XK_w, togglebar, {0} },`
Let's break down the above.
1. This is our type. If it's `KeyPress`, it will be activated when the keybind is pressed. If it is `KeyRelease` it will be activated when the keybind is released.
2. This is our modifier. `MODIFIER1` is defined in `keybinds.h`. We're adding SHIFT to it, (defined in `speedwm.c`) which means we have to press BOTH `MODIFIER1` and `SHIFT` at the same time to activate this keybind.
3. This is our **chain** key. `XK_a` here is the key we have to press along with our modifier to activate this keybind. `XK_a` is defined in `/usr/include/X11/keysymdef.h` on most operating systems.
4. This is our regular key. `XK_w` is defined in `/usr/include/X11/keysymdef.h` on most operating systems and it means we have to press `w` on our keyboard to activate this keybind. Note that we do **not** need to press the modifier here, because it is a chained keybind.
5. This is our function. We call this, passing the next value (`const Arg *arg`) to it.
6. This is our function argument. We simply pass `0` here because we don't need to pass anything to the function, because the function does not care.
Feel free to copy the above to `keybinds.h` if you want to experiment with it.
This should give you a brief idea of how keybinds work in speedwm. Most of this carries over to `dwm` as well, although it does not have some of this stuff. It should be noted that as I mentioned previously, you don't HAVE to use this system. You can use external programs to handle keybinds, and `libspeedwm` to perform actions in speedwm. sxkbd is one popular program for this purpose and window managers like `bspwm` use it. However such a solution is out of the scope of this documentation!

View file

@ -1,14 +0,0 @@
Managing changes
----------------
speedwm's Makefile has a nice feature which allows you to compile one header into the binary while keeping the original unmodified.
If I want to make a change to, let's say `bar.h` in my personal build I just `cp bar.h bar.rl.h`, make changes to `bar.rl.h` and recompile. `bar.h` will be intact, but my changes from bar.rl.h will be applied in the compiled binary.
This feature is currently available for:
- bar.h
- options.h
- keybinds.h
- mouse.h
- status.h

View file

@ -1,167 +0,0 @@
Restoring the dwm bar
=====================
This wiki article describes how to restore the default dwm look to the bar. This should look nearly identical if not exactly the same as dwm-6.4, and can be done in like 2 minutes.
### Restoring the dwm modules
To do this, you must first restore the original modules dwm uses. To do this, you can edit `bar.h`. However, what I recommend you do is copy `bar.h` to `bar.rl.h`. The `rl` headers will be compiled into the binary without replacing the original files and so is nice if you want a configuration without pushing it to the Git repository. Of course, this is optional.
In `bar.rl.h`, you'll want to remove any modules not present in default dwm such as all the powerline modules and systray. You can choose to keep things like the systray if you want, but this article is about being as close to regular dwm as possible.
If you want, you can copy my `barrules` array below:
`{ -1, 0, bar_align_left, width_tags, draw_tags, click_tags, 0, "tags" },`
`{ -1, 0, bar_align_left, width_ltsymbol, draw_ltsymbol, click_ltsymbol, 0, "layout" },`
`{ -1, 0, bar_align_right, width_status_basic, draw_status_basic, click_status_basic, 0, "status" },`
`{ -1, 0, bar_align_none, width_title_basic, draw_title_basic, click_title_basic, 0, "title" },`
As you can see, you'll want to set some of the modules to the `basic` variant. With that done, go ahead and recompile speedwm using `make clean install`.
Then follow along with 'Restoring settings'.
### Restoring settings
Now that we have the old modules, we'll want to restore the colors, fonts, and other things to the dwm settings. This includes disabling gaps, padding, and any other features dwm does not have.
To do this, edit `~/.config/speedwm/speedwmrc`. You *can* add all the .Xresources values yourself, or you can just copy my list of values below into your own config. I should note though that you may not achieve perfect results if your config already has other options. For best results, start with a blank `speedwmrc`.
`speedwm.fonts.font: monospace 10`
`speedwm.gaps.enable: 0`
`speedwm.color.hiddentitle: 0`
`speedwm.color.selectedtitle: 1`
`speedwm.color.layout: 0`
`speedwm.client.map: 0`
`speedwm.client.hide.border: 0`
`speedwm.client.hide.unselected.border: 0`
`speedwm.tiling.resizehints: 1`
`speedwm.bar.alpha: 0`
`speedwm.bar.position: 1`
`speedwm.bar.height: 4`
`speedwm.bar.paddingih: 0`
`speedwm.bar.paddingiv: 0`
`speedwm.bar.paddingoh: 0`
`speedwm.bar.paddingov: 0`
`speedwm.bar.hide.emptytags: 0`
`speedwm.bar.hide.floating: 0`
`speedwm.bar.hide.layout: 0`
`speedwm.bar.hide.status: 0`
`speedwm.bar.hide.title: 0`
`speedwm.bar.hide.clientindicator: 0`
`speedwm.bar.titleposition: 0`
`speedwm.bar.hide.systray: 1`
`speedwm.bar.hide.sticky: 1`
`speedwm.bar.hide.icon: 1`
`speedwm.border.size: 1`
`speedwm.text.layout1: []=`
`speedwm.text.layout2: ><>`
`speedwm.text.layout3: [M]`
`speedwm.text.tag1.empty: 1`
`speedwm.text.tag2.empty: 2`
`speedwm.text.tag3.empty: 3`
`speedwm.text.tag4.empty: 4`
`speedwm.text.tag5.empty: 5`
`speedwm.text.tag6.empty: 6`
`speedwm.text.tag7.empty: 7`
`speedwm.text.tag8.empty: 8`
`speedwm.text.tag9.empty: 9`
`speedwm.text.tag1.used: 1`
`speedwm.text.tag2.used: 2`
`speedwm.text.tag3.used: 3`
`speedwm.text.tag4.used: 4`
`speedwm.text.tag5.used: 5`
`speedwm.text.tag6.used: 6`
`speedwm.text.tag7.used: 7`
`speedwm.text.tag8.used: 8`
`speedwm.text.tag9.used: 9`
`speedwm.col.tag1: #005577`
`speedwm.col.tag2: #005577`
`speedwm.col.tag3: #005577`
`speedwm.col.tag4: #005577`
`speedwm.col.tag5: #005577`
`speedwm.col.tag6: #005577`
`speedwm.col.tag7: #005577`
`speedwm.col.tag8: #005577`
`speedwm.col.tag9: #005577`
`speedwm.col.titlenorm: #222222`
`speedwm.col.titlesel: #005577`
`speedwm.col.titlehid: #222222`
`speedwm.col.windowbordernorm: #444444`
`speedwm.col.windowbordersel: #005577`
`speedwm.col.textnorm: #bbbbbb`
`speedwm.col.textsel: #eeeeee`
`speedwm.status.defaultstatus: dwm-6.4`
Append this to your `speedwmrc` and then simply restart using `libspeedwm --perform core_wm_restart`.
**NOTE: If you're using .Xresources, you'll likely notice that colors are not being overridden. You can stop overriding colors, or you can disable .Xresources support in toggle.h, but do note that doing this means you'll have to edit `options.h` with the values above.**
### Done
After doing the above, you should have a configuration that looks more or less identical to dwm 6.4. If you want to take it a step further, you can disable things like tag previews, window icons and task switcher through `toggle.h` if resources is your concern.

View file

@ -1,90 +0,0 @@
Rounded corners
---------------
speedwm versions before 1.9 had built in rounded corner support done using standard X11 libraries. This worked relatively well, but only for clients, not the bar. In 1.9 however, this was removed. The removal was done because if you like rounded corners, chances are you already have a compositor like `picom` installed on your system anyway.
`picom` does rounded corners for any program, and that includes the speedwm bar, and it does it better than speedwm did, so it made no sense to keep it around in speedwm causing possible future bugs.
### Rounded corners using `picom`
To enable rounded corners in speedwm, install picom.
For Gentoo: `emerge --ask picom`
For Arch: `pacman -S picom`
Once `picom` is installed, you can add `picom &` to `~/.config/speedwm/autostart.sh` which will allow it to automatically run on speedwm startup. Alternatively, add it to another file which is autostarted, such as `~/.xinitrc`.
`picom` has a configuration file in `~/.config/picom/picom.conf`. Here you can do a bunch of cool things, but importantly you can enable rounded corners. A good start would be to add the following to the file:
`corner-radius = 10.0;`
`rounded-corners-exclude = [`
`"class_g = 'Dunst'",`
`];`
`round-borders = 10;`
`round-borders-exclude = [`
`#"class_g = 'Chromium'",`
`];`
You can adjust `round-borders` and `corner-radius` depending on how sharp you want the window borders. Similar to speedwm rules, you can exclude certain clients based on class. There are a few examples here by default. Settings should apply immediately when the file is saved which is very convenient. In case it doesn't though, restart `picom`.
### Excluding the speedwm bar
Some users may not want to round the bar, specifically if you're not using any barpadding. In that case, simply add a rule like this:
`rounded-corners-exclude = [`
`"class_g = 'speedwm'",`
`];`
to your `picom.conf` configuration file.
### speedwm configuration
It may be a good idea to disable window borders in the speedwm configuration. This isn't required of course, but window borders can look a bit out of place. Otherwise, you may want to consider increasing the size. Add `speedwm.border.size: 0` to `~/.config/speedwm/speedwmrc` to disable the window border for clients in speedwm.
It also does not make much sense to use rounded corners without padding, so I set outer horizontal and outer vertical padding to 5 like so:
`speedwm.bar.paddingoh: 5`
`speedwm.bar.paddingov: 5`
I also want a smaller bar, but instead of decreasing the font size, I choose to decrease bar height by 2 like so:
`speedwm.bar.height: -2`
Gaps are set to 10 by default, but because 10 pixels of padding is too much, I choose to decrease inner and outer gaps like this:
`speedwm.gaps.sizeih: 5`
`speedwm.gaps.sizeiv: 5`
`speedwm.gaps.sizeoh: 5`
`speedwm.gaps.sizeov: 5`
My configuration looks like this. Feel free to copy it to your own `speedwmrc`.
`speedwm.border.size: 0`
`speedwm.bar.paddingoh: 5`
`speedwm.bar.paddingov: 5`
`speedwm.bar.height: -2`
`speedwm.gaps.sizeih: 5`
`speedwm.gaps.sizeiv: 5`
`speedwm.gaps.sizeoh: 5`
`speedwm.gaps.sizeov: 5`

View file

@ -1,24 +0,0 @@
Using the wiki
==============
Lost? If you don't know where to go, you can click the icon on the top bar. The `All` button allows you to get a view of all articles that have been posted on the wiki.
There is also a search bar at the top of every page which allows you to search for any article that has been posted.
## Basic wiki features
The wiki, based on a fork of w2wiki allows you to create new articles, edit existing articles, read existing articles (that's pretty much given), [host it yourself](https://codeberg.org/speedie/speedwm-wiki), and delete articles.
Now, please note that I am giving you this power, and with great power comes great responsibility. I want everyone to be able to help with the project. However, if it gets abused by people then I will have to remove this functionality and go back to using purely Git.
So please don't ruin it for everyone. If the wiki has to be shut down due to your vandalism, we hate you forever. That said, we do make Git backups fairly often (I will not say how often to prevent vandalism), so if an article is deleted it should be possible to restore it with minor changes lost.
## The sidebar
The sidebar is a markdown page like any other and can also be edited as any other. It is supposed to be used as a list of links, but of course there is no limit to what you can do with it.
To edit it, click `All` and edit `_sidebar`. From there, you can follow regular markdown syntax.
## Testing locally
Please, please, please test locally if you're new to markdown. That way, you avoid (for example) deleting pages by accident. You can easily test an identical (minus some pages perhaps) copy of the wiki locally by installing `php` with your distro's package manager and cloning [the repo](https://codeberg.org/speedie/speedwm-wiki) somewhere. If you don't know what you're doing, just cd into it, run `php -S localhost:1337` to start PHP, open any web browser and go to `localhost:1337`. Of course, the `1337` here can be swapped out for almost any value, it's just what I happen to go with.

View file

@ -1,2 +0,0 @@
Wayland, and why it sucks.
--------------------------

View file

@ -1,24 +0,0 @@
Where do I go?
==============
Lost? If you don't know where to go, you can click the icon on the top bar. The `All` button allows you to get a view of all articles that have been posted on the wiki.
There is also a search bar at the top of every page which allows you to search for any article that has been posted.
## Basic wiki features
The wiki, based on a fork of w2wiki allows you to create new articles, edit existing articles, read existing articles (that's pretty much given), [host it yourself](https://codeberg.org/speedie/speedwm-wiki), and delete articles.
Now, please note that I am giving you this power, and with great power comes great responsibility. I want everyone to be able to help with the project. However, if it gets abused by people then I will have to remove this functionality and go back to using purely Git.
So please don't ruin it for everyone. If the wiki has to be shut down due to your vandalism, we hate you forever. That said, we do make Git backups fairly often (I will not say how often to prevent vandalism), so if an article is deleted it should be possible to restore it with minor changes lost.
## The sidebar
The sidebar is a markdown page like any other and can also be edited as any other. It is supposed to be used as a list of links, but of course there is no limit to what you can do with it.
To edit it, click `All` and edit `_sidebar`. From there, you can follow regular markdown syntax.
## Testing locally
Please, please, please test locally if you're new to markdown. That way, you avoid (for example) deleting pages by accident. You can easily test an identical (minus some pages perhaps) copy of the wiki locally by installing `php` with your distro's package manager and cloning [the repo](https://codeberg.org/speedie/speedwm-wiki) somewhere. If you don't know what you're doing, just cd into it, run `php -S localhost:1337` to start PHP, open any web browser and go to `localhost:1337`. Of course, the `1337` here can be swapped out for almost any value, it's just what I happen to go with.

View file

@ -1,12 +0,0 @@
Basics
======
- [[Home]]
- [[Where do I go?]]
- [[Getting Started]]
### Deeper
- [[Client rules]]
- [[Keybinds]]
- [[Configuring the bar]]

28
run.sh
View file

@ -1,28 +0,0 @@
#!/bin/sh
#
# crontab this to run every X minutes
# 5 * * * * /usr/bin/run.sh
die() { printf "%s\n" "$*"; exit 1; }
WIKINAME="speedwm-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."
[ -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

View file

@ -1,3 +0,0 @@
#!/bin/sh
printf "Testing locally..\nOpen 'localhost:1337' in your web browser.\n"
php -S localhost:1337

View file

@ -1,21 +0,0 @@
<VirtualHost *:80>
DocumentRoot %TRAVIS_BUILD_DIR%
<Directory "%TRAVIS_BUILD_DIR%/">
Options FollowSymLinks MultiViews ExecCGI
AllowOverride All
Require all granted
</Directory>
# Wire up Apache to use Travis CI's php-fpm.
<IfModule mod_fastcgi.c>
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
<Directory /usr/lib/cgi-bin>
Require all granted
</Directory>
</IfModule>
</VirtualHost>