diff --git a/.github/workflows/linkchecker.yaml b/.github/workflows/linkchecker.yaml
new file mode 100644
index 0000000..777932f
--- /dev/null
+++ b/.github/workflows/linkchecker.yaml
@@ -0,0 +1,103 @@
+name: Check for broken links
+
+on:
+ workflow_dispatch:
+ schedule:
+ # Run every weekend
+ - cron: '0 2 * * 6'
+
+jobs:
+ url:
+ runs-on: ubuntu-latest
+ outputs:
+ url: ${{ steps.get-url.outputs.url }}
+ steps:
+ - name: Get URL
+ id: get-url
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ set -ex
+ url=$(gh api --jq .html_url repos/${{ github.repository }}/pages)
+ echo "::set-output name=url::$url"
+
+ # internal and external links
+ linkchecker:
+ needs: url
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.x'
+ - name: Install linkchecker
+ run: |
+ pip3 install git+https://github.com/linkchecker/linkchecker.git
+
+ - id: attempt1
+ continue-on-error: true
+ name: Run linkchecker
+ run: |
+ linkchecker --check-extern --ignore-url='sony\.com' ${{ needs.url.outputs.url }}
+
+ - name: Sleep
+ if: steps.attempt1.outcome == 'failure'
+ run: sleep 30
+ - id: attempt2
+ if: steps.attempt1.outcome == 'failure'
+ continue-on-error: true
+ name: Run linkchecker
+ run: |
+ linkchecker --check-extern --ignore-url='sony\.com' ${{ needs.url.outputs.url }}
+
+ - name: Sleep
+ if: steps.attempt2.outcome == 'failure'
+ run: sleep 30
+ - id: attempt3
+ if: steps.attempt2.outcome == 'failure'
+ continue-on-error: true
+ name: Run linkchecker
+ run: |
+ linkchecker --check-extern --ignore-url='sony\.com' ${{ needs.url.outputs.url }}
+
+ - name: Fail
+ if: steps.attempt1.outcome == 'failure' && steps.attempt2.outcome == 'failure' && steps.attempt3.outcome == 'failure'
+ run: false
+
+ # internal links and anchors
+ linkcheck:
+ needs: url
+ runs-on: ubuntu-latest
+ steps:
+ - id: attempt1
+ continue-on-error: true
+ name: Run linkcheck
+ uses: filiph/linkcheck@v2.0.15+1
+ with:
+ arguments: ${{ needs.url.outputs.url }}
+
+ - name: Sleep
+ if: steps.attempt1.outcome == 'failure'
+ run: sleep 30
+ - id: attempt2
+ if: steps.attempt1.outcome == 'failure'
+ continue-on-error: true
+ name: Run linkcheck
+ uses: filiph/linkcheck@v2.0.15+1
+ with:
+ arguments: ${{ needs.url.outputs.url }}
+
+ - name: Sleep
+ if: steps.attempt2.outcome == 'failure'
+ run: sleep 30
+ - id: attempt3
+ if: steps.attempt2.outcome == 'failure'
+ continue-on-error: true
+ name: Run linkcheck
+ uses: filiph/linkcheck@v2.0.15+1
+ with:
+ arguments: ${{ needs.url.outputs.url }}
+
+ - name: Fail
+ if: steps.attempt1.outcome == 'failure' && steps.attempt2.outcome == 'failure' && steps.attempt3.outcome == 'failure'
+ run: false
diff --git a/Gemfile b/Gemfile
index 258340e..0c8671c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,15 +1,3 @@
source "https://rubygems.org"
-gem "minima", "~> 2.5"
gem "github-pages", group: :jekyll_plugins
-
-group :jekyll_plugins do
- gem "jekyll-default-layout"
-end
-
-platforms :mingw, :x64_mingw, :mswin, :jruby do
- gem "tzinfo", "~> 1.2"
- gem "tzinfo-data"
-end
-
-gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..006f832
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+export BUNDLE_PATH ?= $(CURDIR)/.bundle/gems
+
+.PHONY: build
+build: .bundle/.done
+ bundle exec jekyll build
+
+.PHONY: serve
+serve: .bundle/.done
+ bundle exec jekyll serve --livereload
+
+.bundle/.done: Gemfile
+ bundle install
+ touch $@
+
+.PHONY: clean
+clean:
+ $(RM) -r Gemfile.lock .bundle _site
diff --git a/README.md b/README.md
index 9a20949..9f0dfcc 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,40 @@
# xmonad-web: the website for the xmonad window manager
+
The website for [xmonad.org](https://xmonad.org).
## Requirements
+
The website is built with [Jekyll](https://jekyllrb.com/). Check their website
to get started.
The tl;dr is the following:
-1. Install some form of `ruby` (and possibly `ruby-devel`) on your
- system.
-
-2. Install `bundler` and `jekyll` with
+1. Install `ruby`, `ruby-dev(el)` and `bundler` on your system. Depending on
+ your distribution, `bundler` might not be packaged and may need to be
+ installed manually via `gem`:
- ``` shell
- $ gem install --user bundler jekyll
+ ```console
+ $ gem install --user bundler
```
Make sure to add the necessary directories to your `$PATH`!
-3. Install the required gems locally; you must be in the `xmonad-web`
- directory for this:
+2. Build the website with
- ``` shell
- $ bundle config set --local path '.bundle/xmonad-gems'
- $ bundle install
+ ```console
+ $ make
```
-4. Build the website with
+ This uses `bundler` to get all the necessary Jekyll extensions to
+ replicate a GitHub Pages setup locally. The result will be in `./_site`.
- ``` shell
- $ bundle exec jekyll serve
+3. For an interactive editing session with live reloads in your browser, use
+
+ ```console
+ $ make serve
```
- This should create a browsable copy of the website—and your changes
+ This serves a browsable local copy of the website—and your changes
thereof—on `http://127.0.0.1:4000`.
## Application Structures
@@ -49,6 +51,7 @@ the `_data/videos.yml`
The `_site` directory is a place for the Jekyll output.
## Contributing
+
Contributions to the content as well as to the looks of the website are welcome!
Please don't check the `_site` folder, as *it will be overwritten while
deploying the website*. Check our [contributing
diff --git a/_config.yml b/_config.yml
index e84e6a2..e3984f1 100644
--- a/_config.yml
+++ b/_config.yml
@@ -1,4 +1,11 @@
-baseurl: ""
url: "https://xmonad.org"
-plugins:
- - jekyll-default-layout
+
+theme: null
+
+exclude:
+ - CNAME
+ - Gemfile
+ - Gemfile.lock
+ - LICENSE
+ - Makefile
+ - README.md
diff --git a/community.md b/community.md
index 1ac5849..1d9c5e7 100644
--- a/community.md
+++ b/community.md
@@ -36,20 +36,20 @@ the xmonad developer team:
-* Spencer Janssen
-* [Don Stewart](http://donsbot.wordpress.com/)
-* [Adam Vogt](http://www.eng.uwaterloo.ca/~aavogt/)
-* [Brent Yorgey](http://byorgey.wordpress.com/)
+* [Spencer Janssen](https://github.com/spencerjanssen)
+* [Don Stewart](https://donsbot.wordpress.com/)
+* [Adam Vogt](https://www.eng.uwaterloo.ca/~aavogt/)
+* [Brent Yorgey](https://byorgey.wordpress.com/)
* [Daniel Wagner](http://www.dmwit.com/)
-* [David Roundy](http://physics.oregonstate.edu/~roundyd/people.php)
-* Daniel Schoepe
-* [Eric Mertens](http://github.com/glguy)
-* [Nicolas Pouillard](http://nicolaspouillard.fr/)
-* [Roman Cheplyaka](http://ro-che.info/)
-* Gwern Branwen
-* Lukas Mai
-* [Braden Shepherdson](http://braincrater.wordpress.com/)
-* [Devin Mullins](http://twifkak.com/)
+* [David Roundy](https://sites.science.oregonstate.edu/~roundyd/people.html)
+* [Daniel Schoepe](https://github.com/dschoepe)
+* [Eric Mertens](https://github.com/glguy)
+* [Nicolas Pouillard](https://nicolaspouillard.fr/)
+* [Roman Cheplyaka](https://ro-che.info/)
+* [Gwern Branwen](https://www.gwern.net/)
+* [Lukas Mai](https://github.com/mauke)
+* [Braden Shepherdson](https://braincrater.wordpress.com/)
+* [Devin Mullins](https://twifkak.com/)
diff --git a/css/default.css b/css/default.css
deleted file mode 100644
index acd66a4..0000000
--- a/css/default.css
+++ /dev/null
@@ -1,48 +0,0 @@
-body {
- color: black;
- font-size: 16px;
- margin: 0px auto 0px auto;
- width: 600px;
-}
-header {
- border-bottom: 2px solid black;
- margin-bottom: 30px;
- padding: 12px 0px 12px 0px;
-}
-nav {
- text-align: right;
-}
-nav a {
- color: black;
- font-size: 18px;
- font-weight: bold;
- margin-left: 12px;
- text-decoration: none;
- text-transform: uppercase;
-}
-footer {
- border-top: solid 2px black;
- color: #555;
- font-size: 12px;
- margin-top: 30px;
- padding: 12px 0px 12px 0px;
- text-align: right;
-}
-h1 {
- font-size: 24px;
-}
-h2 {
- font-size: 20px;
-}
-article .header {
- color: #555;
- font-size: 14px;
- font-style: italic;
-}
-.logo a {
- color: black;
- float: left;
- font-size: 18px;
- font-weight: bold;
- text-decoration: none;
-}
diff --git a/css/font-raleway.css b/css/font-raleway.css
index 41dd1f4..33e1dd8 100644
--- a/css/font-raleway.css
+++ b/css/font-raleway.css
@@ -1,6 +1,8 @@
+---
+---
@font-face {
font-family: "Raleway";
font-style: normal;
font-weight: 400;
- src: local("Raleway"), local("Raleway-Regular"), url(/assets/fonts/Raleway.ttf) format("truetype");
+ src: local("Raleway"), local("Raleway-Regular"), url({{ "/fonts/Raleway.ttf" | relative_url }}) format("truetype");
}
diff --git a/css/main.css b/css/main.css
index a7d624e..956851d 100644
--- a/css/main.css
+++ b/css/main.css
@@ -1,3 +1,7 @@
+---
+---
+@import "{{ "/css/font-raleway.css" | relative_url }}";
+
background {
background-color: yellow;
}
diff --git a/documentation.md b/documentation.md
index ac92944..3d880e6 100644
--- a/documentation.md
+++ b/documentation.md
@@ -35,7 +35,7 @@ title: Documentation
## In your environment
-[Installing from tarball](intro.html) - [Gnome](https://wiki.haskell.org/Xmonad/Using_xmonad_in_Gnome) - [KDE](https://wiki.haskell.org/Xmonad/Using_xmonad_in_KDE) - [XFCE](https://wiki.haskell.org/Xmonad/Using_xmonad_in_XFCE) - [Arch Linux](https://wiki.archlinux.org/index.php/XMonad) - [OS X](https://wiki.haskell.org/Xmonad/Using_xmonad_on_Apple_OSX) - [OLPC](https://wiki.haskell.org/Xmonad/Using_xmonad_on_OLPC_XO)
+[Installing xmonad](install-instructions.md) - [Gnome](https://wiki.haskell.org/Xmonad/Using_xmonad_in_Gnome) - [KDE](https://wiki.haskell.org/Xmonad/Using_xmonad_in_KDE) - [XFCE](https://wiki.haskell.org/Xmonad/Using_xmonad_in_XFCE) - [Arch Linux](https://wiki.archlinux.org/index.php/XMonad) - [OS X](https://wiki.haskell.org/Xmonad/Using_xmonad_on_Apple_OSX) - [OLPC](https://wiki.haskell.org/Xmonad/Using_xmonad_on_OLPC_XO)
diff --git a/download.md b/download.md
index 5784e70..f592183 100644
--- a/download.md
+++ b/download.md
@@ -71,6 +71,6 @@ cabal install https://github.com/xmonad/xmonad-contrib/archive/master.tar.gz
Here are some tools we've found work well with xmonad:
* [dmenu](https://tools.suckless.org/dmenu/), a program launcher
-* [dzen](https://gotmor.googlepages.com/dzen), an extensible status bar
-* [xmobar](https://hackage.haskell.org/package/xmobar), an extensible status bar
-* [rxvt-unicode](https://software.schmorp.de/pkg/rxvt-unicode.html), a better terminal
+* [dzen](https://robm.github.io/dzen/), an extensible status bar
+* [xmobar](https://github.com/jaor/xmobar), an extensible status bar
+* [rxvt-unicode](http://software.schmorp.de/pkg/rxvt-unicode.html), a better terminal
diff --git a/install-instructions.md b/install-instructions.md
index 62581a5..6fac802 100644
--- a/install-instructions.md
+++ b/install-instructions.md
@@ -34,7 +34,7 @@ Since you're building an X application, you'll need the C X11 library headers. O
$ apt-get install libx11-dev
```
-Typically you need the C libraries: `libXinerama` `libXext` `libX11`.
+Typically you need the C libraries: `libx11` `libxext` `libxinerama` `libxrandr` `libxscreensaver`.
Further, since xmonad is build with XFT support by default, you will also need the `libxft` C headers:
@@ -64,7 +64,7 @@ If this doesn't help, try asking on the IRC channel, `#xmonad@irc.libera.chat` (
Extra programs that make life with xmonad more exciting: dmenu and dzen. dmenu provides a simple popup menu for launching programs, dzen provides customisable status bars. You can get them here:
-* [dzen](http://gotmor.googlepages.com/dzen)
+* [dzen](https://robm.github.io/dzen/)
* [dmenu](https://tools.suckless.org/dmenu/)
@@ -79,6 +79,6 @@ exec xmonad
as the last line of your file, commenting out any previous window manager. Now, when you log in to X, xmonad will start, (by default in tall tiling mode, with no status bar), and you'll be presented with an empty screen:
-[]({{site.url}}/images/overview/large/empty.png)
+[]({{ "/images/overview/large/empty.png" | relative_url }})
From here, and assuming you can find the **mod1** modifier key (usually 'alt'), you can launch clients and access the rest of the window manager's features. Refer to the [manual page](./manpage.html), or the [cheatsheet](./images/cheat/xmbindings.png)
diff --git a/tour.md b/tour.md
index 6c415ab..55308cf 100644
--- a/tour.md
+++ b/tour.md
@@ -26,7 +26,7 @@ If you're already familiar with the basics and want to learn how to configure xm
-[]({{site.url}}/images/screen-dons-tall-status.png)
+[]({{ "/images/screen-dons-tall-status.png" | relative_url }})
@@ -46,39 +46,39 @@ We'll assume you've been able to build xmonad from hackage (or from your package
Note the use of xpmroot to set a background image.
-* [How to build xmonad by hand](intro.html#comp)
+* [How to build xmonad by hand](install-instructions.md)
* [How to use a display manager with xmonad](https://wiki.haskell.org/Xmonad/Frequently_asked_questions#How_can_I_use_xmonad_with_a_display_manager.3F_.28xdm.2C_kdm.2C_gdm.29)
#### Opening clients
When you start xmonad, without launching clients, you'll be presented with an empty screen:
-[]({{site.url}}/images/tour/large/empty.png)
+[]({{ "/images/tour/large/empty.png" | relative_url }})
Let's start some clients, to fill the screen. xmonad uses the mod1 key (alt) by default, and we can start by launching a terminal with **mod-shift-return**. The new terminal will fill the screen (and we'll use a bit of image processing to contrast the terminals a bit for the tutorial):
-[]({{site.url}}/images/tour/large/one.png)
+[]({{ "/images/tour/large/one.png" | relative_url }})
Let's open up another terminal **mod-shift-return**:
-[]({{site.url}}/images/tour/large/two.png)
+[]({{ "/images/tour/large/two.png" | relative_url }})
The window manager has now tiled the screen such that both windows fit, without overlaps, filling the plane. Note that the new window was inserted to the left of the previous window. What happens if we insert another client? **mod-shift-return**.
-[]({{site.url}}/images/tour/large/three.png)
+[]({{ "/images/tour/large/three.png" | relative_url }})
-xmonad uses a simple tiling algorithm to tile the windows to fill the screen without gaps, while ensuring space is managed in a reasonable way. xmonad, by default, divides the screen into two panes. All windows are then partitioned into these two panes. The ratio each pane takes up on the screen is configurable, as are the number of clients in each pane. By convention, one pane is denoted as the 'master' pane, and is used to place the largest window. Other tiling algorithms are possible, (for example, fullscreen mode, or floating windows), and in these the concept of a `pane' has no real meaning.
+xmonad uses a simple tiling algorithm to tile the windows to fill the screen without gaps, while ensuring space is managed in a reasonable way. xmonad, by default, divides the screen into two panes. All windows are then partitioned into these two panes. The ratio each pane takes up on the screen is configurable, as are the number of clients in each pane. By convention, one pane is denoted as the 'master' pane, and is used to place the largest window. Other tiling algorithms are possible, (for example, fullscreen mode, or floating windows), and in these the concept of a 'pane' has no real meaning.
#### Layout modes
We can try out the other layouts now, with **mod-space**, which cycles through the available tiling algorithms:
-[]({{site.url}}/images/tour/large/mirror.png)
+[]({{ "/images/tour/large/mirror.png" | relative_url }})
The next mode up is the 'wide' mode, a 90-degree rotation of the initial tiling. This is useful for smaller screens. If we hit **mod-space** again, we end up in fullscreen mode, where the currently focused window is maximisd, and the only visible window:
-[]({{site.url}}/images/tour/large/full.png)
+[]({{ "/images/tour/large/full.png" | relative_url }})
Other tiling algorithms may be written directly in configuration files.
@@ -88,15 +88,15 @@ Other tiling algorithms may be written directly in configuration files.
Let's return now to the original 'tall' tiling, **mod-space**. We can move focus around with the mouse, or with mod-j and mod-k (which moves the window focus up or down) (coloured red here for emphasis):
-[]({{site.url}}/images/tour/large/focus.png)
+[]({{ "/images/tour/large/focus.png" | relative_url }})
We can also increase, or decrease, the number of windows stored in the master pane, with mod-comma and mod-period:
-[]({{site.url}}/images/tour/large/inc1.png)
+[]({{ "/images/tour/large/inc1.png" | relative_url }})
and again **mod-comma**:
-[]({{site.url}}/images/tour/large/inc2.png)
+[]({{ "/images/tour/large/inc2.png" | relative_url }})
Use **mod-period** a few times to decrement the master pane count back to 1, to return to the default tiling.
@@ -104,15 +104,15 @@ Use **mod-period** a few times to decrement the master pane count back to 1, to
Now, let's open up another client, we'll launch glxgears:
-[]({{site.url}}/images/tour/large/glxgears.png)
+[]({{ "/images/tour/large/glxgears.png" | relative_url }})
We can shuffle the window ordering in three ways: **mod-return**, **mod-shift-j** and **mod-shift-k**. First, let's try **mod-return**, which swaps the focused window with the window in the master pane:
-[]({{site.url}}/images/tour/large/glxgears2.png)
+[]({{ "/images/tour/large/glxgears2.png" | relative_url }})
**mod-shift-j** (and its inverse, **mod-shift-k**), swap the currently focused window with its neighbour above or below. This allows us to 'bubblesort' the window ordering, to achieve a desired ordering of windows. Applying **mod-shift-j** twice:
-[]({{site.url}}/images/tour/large/glxgears.png)
+[]({{ "/images/tour/large/glxgears.png" | relative_url }})
and we're back where we started.
@@ -120,11 +120,11 @@ and we're back where we started.
We can resize the ratio between the master and subordinate areas with **mod-h** and **mod-l**. Hitting **mod-h** a few times:
-[]({{site.url}}/images/tour/large/inc.png)
+[]({{ "/images/tour/large/inc.png" | relative_url }})
Now, let's cycle to wide mode, and shrink (**mod-space**, then **mod-l**):
-[]({{site.url}}/images/tour/large/dec.png)
+[]({{ "/images/tour/large/dec.png" | relative_url }})
We can return to tall mode by cycling through the tiling modes some more.
@@ -136,7 +136,7 @@ xmonad supports floating windows. Certain windows (such as transien
When a window is closed naturally, or using **mod-shift-c** to kill it, focus is moved to the next window down in the workspace list. Let's kill glxgears. Focus should move to the xterm below it:
-[]({{site.url}}/images/tour/large/kill.png)
+[]({{ "/images/tour/large/kill.png" | relative_url }})
To fully quit xmonad, use **mod-shift-q** to exit X (don't do that now!).
@@ -144,33 +144,33 @@ To fully quit xmonad, use **mod-shift-q** to exit X (don't do that now!).
Assuming you have installed 'dmenu', you can launch programs from the status bar, by typing a few characters of the program's name. Use **mod-p** to launch dmenu, and then type 'fir' to find firefox:
-[]({{site.url}}/images/tour/large/dmenu.png)
+[]({{ "/images/tour/large/dmenu.png" | relative_url }})
After firefox launches, it is inserted above the focused window:
-[]({{site.url}}/images/tour/large/launched.png)
+[]({{ "/images/tour/large/launched.png" | relative_url }})
Now, let's close a terminal, use **mod-space** to enter wide mode, and **mod-return** to move firefox into the master window:
-[]({{site.url}}/images/tour/large/wide.png)
+[]({{ "/images/tour/large/wide.png" | relative_url }})
#### Using other workspaces
xmonad has by default 9 virtual workspaces. Each physical screen is a portal onto one of these workspaces. The relationship between physical screens and virtual workspaces is described by the following image, which shows a conceptual model of xmonad, with 2 physical screens acting as portals onto 5 virtual workspaces.
-
+
You can switch between workspaces using **mod-1** to **mod-9**. Switching to workspace 4 **mod-4** we find it empty:
-[]({{site.url}}/images/tour/large/empty.png)
+[]({{ "/images/tour/large/empty.png" | relative_url }})
Let's open xclock here, using dmenu:
-[]({{site.url}}/images/tour/large/xclock.png)
+[]({{ "/images/tour/large/xclock.png" | relative_url }})
We can now move firefox from workspace 1 this new workspace 4, by first switching back to workspace 1, **mod-1**, then using **mod-shift-4** on firefox's window, to toss it over to #4\. This removes firefox from workspace 1, passing focus there to the next window in the list, and view workspace 4, after , looks like:
-[]({{site.url}}/images/tour/large/ws4-1.png)
+[]({{ "/images/tour/large/ws4-1.png" | relative_url }})
Workspace 4 is using tall tiling, and workspace 1 is still in wide mode. xmonad allows you to run different tiling modes on each workspace. And that is the core set of window manager operations covered:
@@ -188,6 +188,6 @@ Workspace 4 is using tall tiling, and workspace 1 is still in wide mode. xmonad
Please consult the [man page](manpage.html) for more details. With just these basics it should be possible to get started productively using xmonad as your tiling window manager. With custom configuration in Haskell, you can try out all sorts of interesting tiling or key binding ideas quite cheaply, as well as producing nice eye candy.
-[]({{site.url}}/images/screen-ejt-spiral-dzen.png)
+[]({{ "/images/screen-ejt-spiral-dzen.png" | relative_url }})
Throw away the mouse, and get productive in X!