Run jekyll as part of the matrix-doc build
- this saves us having to run it manually on the web server.pull/977/head
parent
299b60970b
commit
9d2a93ad7b
@ -1,10 +1,10 @@
|
|||||||
scripts/gen
|
/scripts/gen
|
||||||
scripts/continuserv/continuserv
|
/scripts/continuserv/continuserv
|
||||||
scripts/speculator/speculator
|
/scripts/speculator/speculator
|
||||||
/scripts/swagger
|
/scripts/swagger
|
||||||
templating/out
|
/templating/out
|
||||||
*.pyc
|
*.pyc
|
||||||
*.swp
|
*.swp
|
||||||
supporting-docs/_site
|
/api/node_modules
|
||||||
supporting-docs/.sass-cache
|
/site.tar.gz
|
||||||
api/node_modules
|
/_site
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
# Site settings
|
||||||
|
title: Matrix
|
||||||
|
email: webmaster@matrix.org
|
||||||
|
description: > # this means to ignore newlines until "baseurl:"
|
||||||
|
Matrix.org documentation
|
||||||
|
baseurl: "/docs" # the subpath of your site, e.g. /blog/
|
||||||
|
url: "http://matrix.org" # the base hostname & protocol for your site
|
||||||
|
twitter_username: matrixdotorg
|
||||||
|
github_username: matrix-org
|
||||||
|
|
||||||
|
exclude:
|
||||||
|
- "*.png"
|
||||||
|
- "*.jpg"
|
||||||
|
- "*.gif"
|
||||||
|
|
||||||
|
# Build settings
|
||||||
|
markdown: kramdown
|
||||||
|
|
||||||
|
#defaults:
|
||||||
|
permalink: /:categories/:title.html # can use this when/if we use jekyll for all docs
|
||||||
|
#permalink: /:title.html
|
@ -0,0 +1,7 @@
|
|||||||
|
<script type='text/javascript' src='//matrix.org/blog/wp-content/themes/Divi-child/js/waypoints.min.js?ver=2.2'></script>
|
||||||
|
<script type='text/javascript' src='//matrix.org/docs/css/custom.js'></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div id="footer"><div id="footerContent">© 2014-2017 Matrix.org | Hosted by <a href="https://upcloud.com/matrix">UpCloud</a></div></div>
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<script type='text/javascript' src='//matrix.org/blog/wp-includes/js/jquery/jquery.js?ver=1.11.3'></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/site.css">
|
||||||
|
<link rel="stylesheet" href="/docs/css/main.css">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/docs/css/site_overrides.css">
|
||||||
|
<link rel="stylesheet" href="/docs/css/basic.css">
|
||||||
|
<link rel="stylesheet" href="/docs/css/nature.css">
|
||||||
|
|
||||||
|
<link rel='stylesheet' id='divi-fonts-css' href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,800italic,400,300,700,800&subset=latin,latin-ext' type='text/css' media='all'>
|
||||||
|
<link rel='stylesheet' id='divi-style-css' href='//matrix.org/blog/wp-content/themes/Divi-child/style.css?ver=2.2' type='text/css' media='all'>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
|
ga('create', 'UA-54779209-1', 'auto');
|
||||||
|
ga('send', 'pageview');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
<header id="main-header" class="et_nav_text_color_dark" style="top: 0px;">
|
||||||
|
<div class="container clearfix" >
|
||||||
|
<a href="https://matrix.org/blog/">
|
||||||
|
<img src="//matrix.org/blog/wp-content/uploads/2015/01/logo1.png" alt="Matrix.org" id="logo" />
|
||||||
|
</a>
|
||||||
|
<div id="et-top-navigation">
|
||||||
|
<nav id="top-menu-nav">
|
||||||
|
<ul id="top-menu" class="nav"><li id="menu-item-17" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-17"><a href="http://matrix.org/">Home</a></li>
|
||||||
|
<li id="menu-item-794" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-794"><a href="/docs/projects/try-matrix-now.html">Try Matrix Now!</a></li>
|
||||||
|
<li id="menu-item-348" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-348"><a href="/docs/guides/">Guides</a></li>
|
||||||
|
<li id="menu-item-349" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-349"><a href="/docs/spec">Spec</a></li>
|
||||||
|
<li id="menu-item-350" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-350"><a href="/docs/api/client-server">Client-Server APIs</a></li>
|
||||||
|
<li id="menu-item-351" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-351"><a href="/code">Code</a></li>
|
||||||
|
<li id="menu-item-347" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-347"><a href="/docs/guides/faq.html">FAQ</a></li>
|
||||||
|
<li id="menu-item-353" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-353"><a href="/blog">Blog</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<div id="et_top_search">
|
||||||
|
<span id="et_search_icon"></span>
|
||||||
|
<form role="search" method="get" class="et-search-form et-hidden" action="https://matrix.org/blog/">
|
||||||
|
<input type="search" class="et-search-field" placeholder="Search …" value="" name="s" title="Search for:" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="et_mobile_nav_menu">
|
||||||
|
<a href="#" class="mobile_nav closed">
|
||||||
|
<span class="select_page">Select Page</span>
|
||||||
|
<span class="mobile_menu_bar"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div> <!-- #et-top-navigation -->
|
||||||
|
</div> <!-- .container -->
|
||||||
|
</header> <!-- #main-header -->
|
@ -0,0 +1,4 @@
|
|||||||
|
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %} | Matrix.org</title>
|
||||||
|
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}">
|
||||||
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-US" class="js">
|
||||||
|
<head>
|
||||||
|
{% include title.html %}
|
||||||
|
{% include head.html %}
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body class="blog et_fixed_nav et_cover_background et_right_sidebar">
|
||||||
|
<div id="page-wrapper">
|
||||||
|
<div class="page-content" id="page-container">
|
||||||
|
{% include nav.html %}
|
||||||
|
<div id="main-content">
|
||||||
|
|
||||||
|
<div class="wrapper" id="wrapper">
|
||||||
|
<div class="document_foo" id="document">
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="push"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include footer.html %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
<div class="post">
|
||||||
|
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title">{{ page.title }}</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<article class="post-content">
|
||||||
|
{{ content }}
|
||||||
|
</article>
|
||||||
|
|
||||||
|
</div>
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
|
||||||
|
{{ content }}
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
<style>
|
||||||
|
img[alt="screenshot"] {
|
||||||
|
max-width: 800px;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.font18 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project {
|
||||||
|
|
||||||
|
vertical-align: text-top;
|
||||||
|
width: 170px;
|
||||||
|
padding-right: 5px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bigproject {
|
||||||
|
vertical-align: text-top;
|
||||||
|
width: 300px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featured_screenshot {
|
||||||
|
max-height: 200px;
|
||||||
|
width: auto;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc {
|
||||||
|
display: table;
|
||||||
|
padding-top: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
list-style: disc inside;
|
||||||
|
list-style-type: disc inside;
|
||||||
|
color: #2EA3F2;
|
||||||
|
padding-left: 16px;
|
||||||
|
width: 400px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
{{ content }}
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
*.pyc
|
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2011 Greg Thornton, http://xdissent.com
|
||||||
|
|
||||||
|
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.
|
@ -0,0 +1,97 @@
|
|||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
This plugin adds `ReStructuredText`_ support to `Jekyll`_ and `Octopress`_.
|
||||||
|
It renders ReST in posts and pages, and provides a custom directive to
|
||||||
|
support Octopress-compatible syntax highlighting.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
* Jekyll *or* Octopress >= 2.0
|
||||||
|
* Docutils
|
||||||
|
* Pygments
|
||||||
|
* `RbST`_
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
1. Install Docutils and Pygments.
|
||||||
|
|
||||||
|
The most convenient way is to use virtualenv_burrito:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ curl -s https://raw.github.com/brainsik/virtualenv-burrito/master/virtualenv-burrito.sh | bash
|
||||||
|
$ source /Users/xdissent/.venvburrito/startup.sh
|
||||||
|
$ mkvirtualenv jekyll-rst
|
||||||
|
$ pip install docutils pygments
|
||||||
|
|
||||||
|
2. Install RbST.
|
||||||
|
|
||||||
|
If you use `bundler`_ with Octopress, add ``gem 'RbST'`` to
|
||||||
|
your ``Gemfile`` in the ``development`` group, then run
|
||||||
|
``bundle install``. Otherwise, ``gem install RbST``.
|
||||||
|
|
||||||
|
3. Install the plugin.
|
||||||
|
|
||||||
|
For Jekyll:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ cd <jekyll-project-path>
|
||||||
|
$ git submodule add https://github.com/xdissent/jekyll-rst.git _plugins/jekyll-rst
|
||||||
|
|
||||||
|
For Octopress:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ cd <octopress-project-path>
|
||||||
|
$ git submodule add https://github.com/xdissent/jekyll-rst.git plugins/jekyll-rst
|
||||||
|
|
||||||
|
4. Start blogging in ReStructuredText. Any file with the ``.rst`` extension
|
||||||
|
will be parsed as ReST and rendered into HTML.
|
||||||
|
|
||||||
|
.. note:: Be sure to activate the ``jekyll-rst`` virtualenv before generating
|
||||||
|
the site by issuing a ``workon jekyll-rst``. I suggest you follow `Harry
|
||||||
|
Marr's advice`_ and create a ``.venv`` file that will automatically
|
||||||
|
activate the ``jekyll-rst`` virtualenv when you ``cd`` into your project.
|
||||||
|
|
||||||
|
Source Code Highlighting
|
||||||
|
========================
|
||||||
|
|
||||||
|
A ``code-block`` ReST directive is registered and aliased as ``sourcecode``.
|
||||||
|
It adds syntax highlighting to code blocks in your documents::
|
||||||
|
|
||||||
|
.. code-block:: ruby
|
||||||
|
|
||||||
|
# Output "I love ReST"
|
||||||
|
say = "I love ReST"
|
||||||
|
puts say
|
||||||
|
|
||||||
|
Optional arguments exist to supply a caption, link, and link title::
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
:caption: Read Hacker News on a budget
|
||||||
|
:url: http://news.ycombinator.com
|
||||||
|
:title: Hacker News
|
||||||
|
|
||||||
|
$ curl http://news.ycombinator.com | less
|
||||||
|
|
||||||
|
Octopress already includes style sheets for syntax highlighting, but you'll
|
||||||
|
need to generate one yourself if using Jekyll::
|
||||||
|
|
||||||
|
$ pygmentize -S default -f html > css/pygments.css
|
||||||
|
|
||||||
|
Octopress Tips
|
||||||
|
==============
|
||||||
|
|
||||||
|
* Use ``.. more`` in your ReST documents to indicate where Octopress's
|
||||||
|
``excerpt`` tag should split your content for summary views.
|
||||||
|
|
||||||
|
.. _ReStructuredText: http://docutils.sourceforge.net/rst.html
|
||||||
|
.. _Jekyll: http://jekyllrb.com/
|
||||||
|
.. _Octopress: http://octopress.com/
|
||||||
|
.. _RbST: http://rubygems.org/gems/RbST
|
||||||
|
.. _bundler: http://gembundler.com/
|
||||||
|
.. _Harry Marr's advice: http://hmarr.com/2010/jan/19/making-virtualenv-play-nice-with-git/
|
@ -0,0 +1,30 @@
|
|||||||
|
require 'rbst'
|
||||||
|
|
||||||
|
module Jekyll
|
||||||
|
class RestConverter < Converter
|
||||||
|
safe true
|
||||||
|
|
||||||
|
priority :low
|
||||||
|
|
||||||
|
def matches(ext)
|
||||||
|
ext =~ /rst/i
|
||||||
|
end
|
||||||
|
|
||||||
|
def output_ext(ext)
|
||||||
|
".html"
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert(content)
|
||||||
|
RbST.executables = {:html => "#{File.expand_path(File.dirname(__FILE__))}/rst2html.py"}
|
||||||
|
RbST.new(content).to_html(:part => :fragment, :initial_header_level => 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Filters
|
||||||
|
def restify(input)
|
||||||
|
site = @context.registers[:site]
|
||||||
|
converter = site.getConverterImpl(Jekyll::RestConverter)
|
||||||
|
converter.convert(input)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,97 @@
|
|||||||
|
# Define a new directive `code-block` (aliased as `sourcecode`) that uses the
|
||||||
|
# `pygments` source highlighter to render code in color.
|
||||||
|
#
|
||||||
|
# Incorporates code from the `Pygments`_ documentation for `Using Pygments in
|
||||||
|
# ReST documents`_ and `Octopress`_.
|
||||||
|
#
|
||||||
|
# .. _Pygments: http://pygments.org/
|
||||||
|
# .. _Using Pygments in ReST documents: http://pygments.org/docs/rstdirective/
|
||||||
|
# .. _Octopress: http://octopress.org/
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import md5
|
||||||
|
import __main__
|
||||||
|
|
||||||
|
# Absolute path to pygments cache dir
|
||||||
|
PYGMENTS_CACHE_DIR = os.path.abspath(os.path.join(os.path.dirname(__main__.__file__), '../../.pygments-cache'))
|
||||||
|
|
||||||
|
# Ensure cache dir exists
|
||||||
|
if not os.path.exists(PYGMENTS_CACHE_DIR):
|
||||||
|
os.makedirs(PYGMENTS_CACHE_DIR)
|
||||||
|
|
||||||
|
from pygments.formatters import HtmlFormatter
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers.rst import directives, Directive
|
||||||
|
|
||||||
|
from pygments import highlight
|
||||||
|
from pygments.lexers import get_lexer_by_name, TextLexer
|
||||||
|
|
||||||
|
class Pygments(Directive):
|
||||||
|
""" Source code syntax hightlighting.
|
||||||
|
"""
|
||||||
|
required_arguments = 1
|
||||||
|
optional_arguments = 0
|
||||||
|
final_argument_whitespace = True
|
||||||
|
string_opts = ['title', 'url', 'caption']
|
||||||
|
option_spec = dict([(key, directives.unchanged) for key in string_opts])
|
||||||
|
has_content = True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.assert_has_content()
|
||||||
|
try:
|
||||||
|
lexer_name = self.arguments[0]
|
||||||
|
lexer = get_lexer_by_name(lexer_name)
|
||||||
|
except ValueError:
|
||||||
|
# no lexer found - use the text one instead of an exception
|
||||||
|
lexer_name = 'text'
|
||||||
|
lexer = TextLexer()
|
||||||
|
formatter = HtmlFormatter()
|
||||||
|
|
||||||
|
# Construct cache filename
|
||||||
|
cache_file = None
|
||||||
|
content_text = u'\n'.join(self.content)
|
||||||
|
cache_file_name = '%s-%s.html' % (lexer_name, md5.new(content_text).hexdigest())
|
||||||
|
cached_path = os.path.join(PYGMENTS_CACHE_DIR, cache_file_name)
|
||||||
|
|
||||||
|
# Look for cached version, otherwise parse
|
||||||
|
if os.path.exists(cached_path):
|
||||||
|
cache_file = open(cached_path, 'r')
|
||||||
|
parsed = cache_file.read()
|
||||||
|
else:
|
||||||
|
parsed = highlight(content_text, lexer, formatter)
|
||||||
|
|
||||||
|
# Strip pre tag and everything outside it
|
||||||
|
pres = re.compile("<pre>(.+)<\/pre>", re.S)
|
||||||
|
stripped = pres.search(parsed).group(1)
|
||||||
|
|
||||||
|
# Create tabular code with line numbers
|
||||||
|
table = '<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers">'
|
||||||
|
lined = ''
|
||||||
|
for idx, line in enumerate(stripped.splitlines(True)):
|
||||||
|
table += '<span class="line-number">%d</span>\n' % (idx + 1)
|
||||||
|
lined += '<span class="line">%s</span>' % line
|
||||||
|
table += '</pre></td><td class="code"><pre><code class="%s">%s</code></pre></td></tr></table></div>' % (lexer_name, lined)
|
||||||
|
|
||||||
|
# Add wrapper with optional caption and link
|
||||||
|
code = '<figure class="code">'
|
||||||
|
if self.options:
|
||||||
|
caption = ('<span>%s</span>' % self.options['caption']) if 'caption' in self.options else ''
|
||||||
|
title = self.options['title'] if 'title' in self.options else 'link'
|
||||||
|
link = ('<a href="%s">%s</a>' % (self.options['url'], title)) if 'url' in self.options else ''
|
||||||
|
|
||||||
|
if caption or link:
|
||||||
|
code += '<figcaption>%s %s</figcaption>' % (caption, link)
|
||||||
|
code += '%s</figure>' % table
|
||||||
|
|
||||||
|
# Write cache
|
||||||
|
if cache_file is None:
|
||||||
|
cache_file = open(cached_path, 'w')
|
||||||
|
cache_file.write(parsed)
|
||||||
|
cache_file.close()
|
||||||
|
|
||||||
|
return [nodes.raw('', code, format='html')]
|
||||||
|
|
||||||
|
directives.register_directive('code-block', Pygments)
|
||||||
|
directives.register_directive('sourcecode', Pygments)
|
@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# :Author: David Goodger, the Pygments team, Guenter Milde
|
||||||
|
# :Date: $Date: $
|
||||||
|
# :Copyright: This module has been placed in the public domain.
|
||||||
|
|
||||||
|
# This is a merge of the `Docutils`_ `rst2html` front end with an extension
|
||||||
|
# suggestion taken from the `Pygments`_ documentation, reworked specifically
|
||||||
|
# for `Octopress`_.
|
||||||
|
#
|
||||||
|
# .. _Pygments: http://pygments.org/
|
||||||
|
# .. _Docutils: http://docutils.sourceforge.net/
|
||||||
|
# .. _Octopress: http://octopress.org/
|
||||||
|
|
||||||
|
"""
|
||||||
|
A front end to docutils, producing HTML with syntax colouring using pygments
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
import locale
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
from transform import transform
|
||||||
|
from docutils.writers.html4css1 import Writer
|
||||||
|
from docutils.core import default_description
|
||||||
|
from directives import Pygments
|
||||||
|
|
||||||
|
description = ('Generates (X)HTML documents from standalone reStructuredText '
|
||||||
|
'sources. Uses `pygments` to colorize the content of'
|
||||||
|
'"code-block" directives. Needs an adapted stylesheet'
|
||||||
|
+ default_description)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
return transform(writer=Writer(), part='html_body')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# rav 2016/10/18: encode the output as UTF-8, otherwise python will grumble
|
||||||
|
# when writing to a pipe, because it doesn't know how to encode unicode
|
||||||
|
# strings.
|
||||||
|
print(main().encode('utf-8'))
|
@ -0,0 +1,42 @@
|
|||||||
|
import sys
|
||||||
|
from docutils.core import publish_parts
|
||||||
|
from optparse import OptionParser
|
||||||
|
from docutils.frontend import OptionParser as DocutilsOptionParser
|
||||||
|
from docutils.parsers.rst import Parser
|
||||||
|
|
||||||
|
def transform(writer=None, part=None):
|
||||||
|
p = OptionParser(add_help_option=False)
|
||||||
|
|
||||||
|
# Collect all the command line options
|
||||||
|
docutils_parser = DocutilsOptionParser(components=(writer, Parser()))
|
||||||
|
for group in docutils_parser.option_groups:
|
||||||
|
p.add_option_group(group.title, None).add_options(group.option_list)
|
||||||
|
|
||||||
|
p.add_option('--part', default=part)
|
||||||
|
|
||||||
|
opts, args = p.parse_args()
|
||||||
|
|
||||||
|
settings = dict({
|
||||||
|
'file_insertion_enabled': False,
|
||||||
|
'raw_enabled': False,
|
||||||
|
'doctitle_xform': False,
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(args) == 1:
|
||||||
|
try:
|
||||||
|
content = open(args[0], 'r').read()
|
||||||
|
except IOError:
|
||||||
|
content = args[0]
|
||||||
|
else:
|
||||||
|
content = sys.stdin.read()
|
||||||
|
|
||||||
|
parts = publish_parts(
|
||||||
|
source=content,
|
||||||
|
writer=writer,
|
||||||
|
settings_overrides=settings
|
||||||
|
)
|
||||||
|
if 'html_body' in parts:
|
||||||
|
return parts['html_body']
|
||||||
|
if opts.part in parts:
|
||||||
|
return parts[opts.part]
|
||||||
|
return ''
|
@ -0,0 +1,40 @@
|
|||||||
|
# _plugins/post_images.rb
|
||||||
|
module Jekyll
|
||||||
|
POST_IMAGES_DIR = '_posts/projects/images'
|
||||||
|
DEST_IMAGES_DIR = 'projects/images'
|
||||||
|
|
||||||
|
class PostImageFile < StaticFile
|
||||||
|
def destination(dest)
|
||||||
|
name_bits = @name.split('-', 4)
|
||||||
|
date_dir = ''
|
||||||
|
date_dir += "#{name_bits.shift}/" if name_bits.first.to_i > 0
|
||||||
|
date_dir += "#{name_bits.shift}/" if name_bits.first.to_i > 0
|
||||||
|
date_dir += "#{name_bits.shift}/" if name_bits.first.to_i > 0
|
||||||
|
File.join(dest, date_dir + DEST_IMAGES_DIR, name_bits.join('-'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class PostImagesGenerator < Generator
|
||||||
|
def generate(site)
|
||||||
|
# Check for the images directory inside the posts directory.
|
||||||
|
return unless File.exists?(POST_IMAGES_DIR)
|
||||||
|
|
||||||
|
post_images = []
|
||||||
|
|
||||||
|
# Process each image.
|
||||||
|
Dir.foreach(POST_IMAGES_DIR) do |entry|
|
||||||
|
if entry != '.' && entry != '..'
|
||||||
|
site.static_files << PostImageFile.new(site, site.source, POST_IMAGES_DIR, entry)
|
||||||
|
post_images << entry.gsub(File.extname(entry), '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Remove images considered to be "actual" posts from the posts array.
|
||||||
|
site.posts.each do |post|
|
||||||
|
if post_images.include?(post.id[1..-1].gsub('/', '-'))
|
||||||
|
site.posts.delete(post)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,51 @@
|
|||||||
|
module Jekyll
|
||||||
|
class ProjectVersionTag < Liquid::Tag
|
||||||
|
NO_GIT_MESSAGE = 'Oops, are you sure this is a git project?'
|
||||||
|
UNABLE_TO_PARSE_MESSAGE = 'Sorry, could not read project version at the moment'
|
||||||
|
|
||||||
|
def render(context)
|
||||||
|
if git_repo?
|
||||||
|
current_version.chomp
|
||||||
|
else
|
||||||
|
NO_GIT_MESSAGE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_version
|
||||||
|
@_current_version ||= begin
|
||||||
|
# attempt to find the latest tag, falling back to last commit
|
||||||
|
version = git_describe || parse_head
|
||||||
|
|
||||||
|
version || UNABLE_TO_PARSE_MESSAGE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def git_describe
|
||||||
|
tagged_version = %x{ git describe --tags --always }
|
||||||
|
|
||||||
|
if command_succeeded?
|
||||||
|
tagged_version
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_head
|
||||||
|
head_commitish = %x{ git rev-parse --short HEAD }
|
||||||
|
|
||||||
|
if command_succeeded?
|
||||||
|
head_commitish
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def command_succeeded?
|
||||||
|
!$?.nil? && $?.success?
|
||||||
|
end
|
||||||
|
|
||||||
|
def git_repo?
|
||||||
|
system('git rev-parse')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Liquid::Template.register_tag('project_version', Jekyll::ProjectVersionTag)
|
@ -0,0 +1 @@
|
|||||||
|
../supporting-docs
|
@ -0,0 +1,204 @@
|
|||||||
|
/**
|
||||||
|
* Reset some basic elements
|
||||||
|
*/
|
||||||
|
body, h1, h2, h3, h4, h5, h6,
|
||||||
|
p, blockquote, pre, hr,
|
||||||
|
dl, dd, ol, ul, figure {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic styling
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
font-family: $base-font-family;
|
||||||
|
font-size: $base-font-size;
|
||||||
|
line-height: $base-line-height;
|
||||||
|
font-weight: 300;
|
||||||
|
color: $text-color;
|
||||||
|
background-color: $background-color;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set `margin-bottom` to maintain vertical rhythm
|
||||||
|
*/
|
||||||
|
h1, h2, h3, h4, h5, h6,
|
||||||
|
p, blockquote, pre,
|
||||||
|
ul, ol, dl, figure,
|
||||||
|
%vertical-rhythm {
|
||||||
|
margin-bottom: $spacing-unit / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Images
|
||||||
|
*/
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figures
|
||||||
|
*/
|
||||||
|
figure > img {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
font-size: $small-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists
|
||||||
|
*/
|
||||||
|
ul, ol {
|
||||||
|
margin-left: $spacing-unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
> ul,
|
||||||
|
> ol {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Headings
|
||||||
|
*/
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links
|
||||||
|
*/
|
||||||
|
a {
|
||||||
|
color: $brand-color;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:visited {
|
||||||
|
color: darken($brand-color, 15%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $text-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blockquotes
|
||||||
|
*/
|
||||||
|
blockquote {
|
||||||
|
color: $grey-color;
|
||||||
|
border-left: 4px solid $grey-color-light;
|
||||||
|
padding-left: $spacing-unit / 2;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
font-style: italic;
|
||||||
|
|
||||||
|
> :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code formatting
|
||||||
|
*/
|
||||||
|
pre,
|
||||||
|
code {
|
||||||
|
font-size: 15px;
|
||||||
|
border: 1px solid $grey-color-light;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #eef;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 8px 12px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
|
> code {
|
||||||
|
border: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper
|
||||||
|
*/
|
||||||
|
.wrapper {
|
||||||
|
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||||
|
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
padding-right: $spacing-unit;
|
||||||
|
padding-left: $spacing-unit;
|
||||||
|
@extend %clearfix;
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
|
||||||
|
max-width: calc(#{$content-width} - (#{$spacing-unit}));
|
||||||
|
padding-right: $spacing-unit / 2;
|
||||||
|
padding-left: $spacing-unit / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clearfix
|
||||||
|
*/
|
||||||
|
%clearfix {
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icons
|
||||||
|
*/
|
||||||
|
.icon {
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: $grey-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,236 @@
|
|||||||
|
/**
|
||||||
|
* Site header
|
||||||
|
*/
|
||||||
|
.site-header {
|
||||||
|
border-top: 5px solid $grey-color-dark;
|
||||||
|
border-bottom: 1px solid $grey-color-light;
|
||||||
|
min-height: 56px;
|
||||||
|
|
||||||
|
// Positioning context for the mobile navigation icon
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-title {
|
||||||
|
font-size: 26px;
|
||||||
|
line-height: 56px;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:visited {
|
||||||
|
color: $grey-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-nav {
|
||||||
|
float: right;
|
||||||
|
line-height: 56px;
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link {
|
||||||
|
color: $text-color;
|
||||||
|
line-height: $base-line-height;
|
||||||
|
|
||||||
|
// Gaps between nav items, but not on the first one
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-query($on-palm) {
|
||||||
|
position: absolute;
|
||||||
|
top: 9px;
|
||||||
|
right: 30px;
|
||||||
|
background-color: $background-color;
|
||||||
|
border: 1px solid $grey-color-light;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
display: block;
|
||||||
|
float: right;
|
||||||
|
width: 36px;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 0;
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
width: 18px;
|
||||||
|
height: 15px;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: $grey-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trigger {
|
||||||
|
clear: both;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .trigger {
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-link {
|
||||||
|
display: block;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Site footer
|
||||||
|
*/
|
||||||
|
.site-footer {
|
||||||
|
border-top: 1px solid $grey-color-light;
|
||||||
|
padding: $spacing-unit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-heading {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: $spacing-unit / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-list,
|
||||||
|
.social-media-list {
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col-wrapper {
|
||||||
|
font-size: 15px;
|
||||||
|
color: $grey-color;
|
||||||
|
margin-left: -$spacing-unit / 2;
|
||||||
|
@extend %clearfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col {
|
||||||
|
float: left;
|
||||||
|
margin-bottom: $spacing-unit / 2;
|
||||||
|
padding-left: $spacing-unit / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col-1 {
|
||||||
|
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(35% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col-2 {
|
||||||
|
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(20% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col-3 {
|
||||||
|
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(45% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
.footer-col-1,
|
||||||
|
.footer-col-2 {
|
||||||
|
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(50% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-col-3 {
|
||||||
|
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(100% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-query($on-palm) {
|
||||||
|
.footer-col {
|
||||||
|
float: none;
|
||||||
|
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||||
|
width: calc(100% - (#{$spacing-unit} / 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page content
|
||||||
|
*/
|
||||||
|
.page-content {
|
||||||
|
padding: $spacing-unit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-heading {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list {
|
||||||
|
margin-left: 0;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
margin-bottom: $spacing-unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-meta {
|
||||||
|
font-size: $small-font-size;
|
||||||
|
color: $grey-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-link {
|
||||||
|
display: block;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts
|
||||||
|
*/
|
||||||
|
.post-header {
|
||||||
|
margin-bottom: $spacing-unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
font-size: 42px;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-content {
|
||||||
|
margin-bottom: $spacing-unit;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 32px;
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 26px;
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
|
@include media-query($on-laptop) {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Syntax highlighting styles
|
||||||
|
*/
|
||||||
|
.highlight {
|
||||||
|
background: #fff;
|
||||||
|
@extend %vertical-rhythm;
|
||||||
|
|
||||||
|
.c { color: #998; font-style: italic } // Comment
|
||||||
|
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||||
|
.k { font-weight: bold } // Keyword
|
||||||
|
.o { font-weight: bold } // Operator
|
||||||
|
.cm { color: #998; font-style: italic } // Comment.Multiline
|
||||||
|
.cp { color: #999; font-weight: bold } // Comment.Preproc
|
||||||
|
.c1 { color: #998; font-style: italic } // Comment.Single
|
||||||
|
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
|
||||||
|
.gd { color: #000; background-color: #fdd } // Generic.Deleted
|
||||||
|
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
|
||||||
|
.ge { font-style: italic } // Generic.Emph
|
||||||
|
.gr { color: #a00 } // Generic.Error
|
||||||
|
.gh { color: #999 } // Generic.Heading
|
||||||
|
.gi { color: #000; background-color: #dfd } // Generic.Inserted
|
||||||
|
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
|
||||||
|
.go { color: #888 } // Generic.Output
|
||||||
|
.gp { color: #555 } // Generic.Prompt
|
||||||
|
.gs { font-weight: bold } // Generic.Strong
|
||||||
|
.gu { color: #aaa } // Generic.Subheading
|
||||||
|
.gt { color: #a00 } // Generic.Traceback
|
||||||
|
.kc { font-weight: bold } // Keyword.Constant
|
||||||
|
.kd { font-weight: bold } // Keyword.Declaration
|
||||||
|
.kp { font-weight: bold } // Keyword.Pseudo
|
||||||
|
.kr { font-weight: bold } // Keyword.Reserved
|
||||||
|
.kt { color: #458; font-weight: bold } // Keyword.Type
|
||||||
|
.m { color: #099 } // Literal.Number
|
||||||
|
.s { color: #d14 } // Literal.String
|
||||||
|
.na { color: #008080 } // Name.Attribute
|
||||||
|
.nb { color: #0086B3 } // Name.Builtin
|
||||||
|
.nc { color: #458; font-weight: bold } // Name.Class
|
||||||
|
.no { color: #008080 } // Name.Constant
|
||||||
|
.ni { color: #800080 } // Name.Entity
|
||||||
|
.ne { color: #900; font-weight: bold } // Name.Exception
|
||||||
|
.nf { color: #900; font-weight: bold } // Name.Function
|
||||||
|
.nn { color: #555 } // Name.Namespace
|
||||||
|
.nt { color: #000080 } // Name.Tag
|
||||||
|
.nv { color: #008080 } // Name.Variable
|
||||||
|
.ow { font-weight: bold } // Operator.Word
|
||||||
|
.w { color: #bbb } // Text.Whitespace
|
||||||
|
.mf { color: #099 } // Literal.Number.Float
|
||||||
|
.mh { color: #099 } // Literal.Number.Hex
|
||||||
|
.mi { color: #099 } // Literal.Number.Integer
|
||||||
|
.mo { color: #099 } // Literal.Number.Oct
|
||||||
|
.sb { color: #d14 } // Literal.String.Backtick
|
||||||
|
.sc { color: #d14 } // Literal.String.Char
|
||||||
|
.sd { color: #d14 } // Literal.String.Doc
|
||||||
|
.s2 { color: #d14 } // Literal.String.Double
|
||||||
|
.se { color: #d14 } // Literal.String.Escape
|
||||||
|
.sh { color: #d14 } // Literal.String.Heredoc
|
||||||
|
.si { color: #d14 } // Literal.String.Interpol
|
||||||
|
.sx { color: #d14 } // Literal.String.Other
|
||||||
|
.sr { color: #009926 } // Literal.String.Regex
|
||||||
|
.s1 { color: #d14 } // Literal.String.Single
|
||||||
|
.ss { color: #990073 } // Literal.String.Symbol
|
||||||
|
.bp { color: #999 } // Name.Builtin.Pseudo
|
||||||
|
.vc { color: #008080 } // Name.Variable.Class
|
||||||
|
.vg { color: #008080 } // Name.Variable.Global
|
||||||
|
.vi { color: #008080 } // Name.Variable.Instance
|
||||||
|
.il { color: #099 } // Literal.Number.Integer.Long
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: About
|
||||||
|
permalink: /about/
|
||||||
|
---
|
||||||
|
|
||||||
|
This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](http://jekyllrb.com/)
|
||||||
|
|
||||||
|
You can find the source code for the Jekyll new theme at: [github.com/jglovier/jekyll-new](https://github.com/jglovier/jekyll-new)
|
||||||
|
|
||||||
|
You can find the source code for Jekyll at [github.com/jekyll/jekyll](https://github.com/jekyll/jekyll)
|
@ -0,0 +1,129 @@
|
|||||||
|
Application Services
|
||||||
|
====================
|
||||||
|
|
||||||
|
This file contains examples of some application service
|
||||||
|
|
||||||
|
IRC Bridge
|
||||||
|
----------
|
||||||
|
Pre-conditions:
|
||||||
|
- Server admin stores the AS token "T_a" on the home server.
|
||||||
|
- Home server has a token "T_h".
|
||||||
|
- Home server has the domain "hsdomain.com"
|
||||||
|
|
||||||
|
1. Application service registration
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
AS -> HS: Registers itself with the home server
|
||||||
|
POST /register
|
||||||
|
{
|
||||||
|
url: "https://someapp.com/matrix",
|
||||||
|
as_token: "T_a",
|
||||||
|
namespaces: {
|
||||||
|
users: [
|
||||||
|
{
|
||||||
|
"exclusive": true,
|
||||||
|
"regex": "@irc\.freenode\.net/.*"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
aliases: [
|
||||||
|
{
|
||||||
|
"exclusive": true,
|
||||||
|
"regex": "#irc\.freenode\.net/.*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Returns 200 OK:
|
||||||
|
{
|
||||||
|
hs_token: "T_h"
|
||||||
|
}
|
||||||
|
|
||||||
|
2. IRC user "Bob" says "hello?" on "#matrix" at timestamp 1421416883133:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
- AS stores message as potential scrollback.
|
||||||
|
- Nothing happens as no Matrix users are in the room.
|
||||||
|
|
||||||
|
3. Matrix user "@alice:hsdomain.com" wants to join "#matrix":
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
User -> HS: Request to join "#irc.freenode.net/#matrix:hsdomain.com"
|
||||||
|
|
||||||
|
HS -> AS: Room Query "#irc.freenode.net/#matrix:hsdomain.com"
|
||||||
|
GET /rooms/%23irc.freenode.net%2F%23matrix%3Ahsdomain.com?access_token=T_h
|
||||||
|
[Starts blocking]
|
||||||
|
AS -> HS: Creates room. Gets room ID "!aasaasasa:hsdomain.com".
|
||||||
|
AS -> HS: Sets room name to "#matrix".
|
||||||
|
AS -> HS: Sends message as ""@irc.freenode.net/Bob:hsdomain.com"
|
||||||
|
PUT /rooms/%21aasaasasa%3Ahsdomain.com/send/m.room.message
|
||||||
|
?access_token=T_a
|
||||||
|
&user_id=%40irc.freenode.net%2FBob%3Ahsdomain.com
|
||||||
|
&ts=1421416883133
|
||||||
|
{
|
||||||
|
body: "hello?"
|
||||||
|
msgtype: "m.text"
|
||||||
|
}
|
||||||
|
HS -> AS: User Query "@irc.freenode.net/Bob:hsdomain.com"
|
||||||
|
GET /users/%40irc.freenode.net%2FBob%3Ahsdomain.com?access_token=T_h
|
||||||
|
[Starts blocking]
|
||||||
|
AS -> HS: Creates user using CS API extension.
|
||||||
|
POST /register?access_token=T_a
|
||||||
|
{
|
||||||
|
type: "m.login.application_service",
|
||||||
|
user: "irc.freenode.net/Bob"
|
||||||
|
}
|
||||||
|
AS -> HS: Set user display name to "Bob".
|
||||||
|
[Finishes blocking]
|
||||||
|
[Finished blocking]
|
||||||
|
|
||||||
|
- HS sends room information back to client.
|
||||||
|
|
||||||
|
4. @alice:hsdomain.com says "hi!" in this room:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
User -> HS: Send message "hi!" in room !aasaasasa:hsdomain.com
|
||||||
|
|
||||||
|
- HS sends message.
|
||||||
|
- HS sees the room ID is in the AS namespace and pushes it to the AS.
|
||||||
|
|
||||||
|
HS -> AS: Push event
|
||||||
|
PUT /transactions/1?access_token=T_h
|
||||||
|
{
|
||||||
|
events: [
|
||||||
|
{
|
||||||
|
content: {
|
||||||
|
body: "hi!",
|
||||||
|
msgtype: "m.text"
|
||||||
|
},
|
||||||
|
origin_server_ts: <generated by hs>,
|
||||||
|
user_id: "@alice:hsdomain.com",
|
||||||
|
room_id: "!aasaasasa:hsdomain.com",
|
||||||
|
type: "m.room.message"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
- AS passes this through to IRC.
|
||||||
|
|
||||||
|
|
||||||
|
5. IRC user "Bob" says "what's up?" on "#matrix" at timestamp 1421418084816:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
IRC -> AS: "what's up?"
|
||||||
|
AS -> HS: Send message via CS API extension
|
||||||
|
PUT /rooms/%21aasaasasa%3Ahsdomain.com/send/m.room.message
|
||||||
|
?access_token=T_a
|
||||||
|
&user_id=%40irc.freenode.net%2FBob%3Ahsdomain.com
|
||||||
|
&ts=1421418084816
|
||||||
|
{
|
||||||
|
body: "what's up?"
|
||||||
|
msgtype: "m.text"
|
||||||
|
}
|
||||||
|
|
||||||
|
- HS modifies the user_id and origin_server_ts on the event and sends it.
|
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
layout: null
|
||||||
|
---
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>{{ site.title | xml_escape }}</title>
|
||||||
|
<description>{{ site.description | xml_escape }}</description>
|
||||||
|
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||||
|
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
|
||||||
|
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||||
|
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||||
|
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||||
|
{% for post in site.posts limit:10 %}
|
||||||
|
<item>
|
||||||
|
<title>{{ post.title | xml_escape }}</title>
|
||||||
|
<description>{{ post.content | xml_escape }}</description>
|
||||||
|
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
|
||||||
|
<link>{{ post.url | prepend: site.baseurl | prepend: site.url }}</link>
|
||||||
|
<guid isPermaLink="true">{{ post.url | prepend: site.baseurl | prepend: site.url }}</guid>
|
||||||
|
{% for tag in post.tags %}
|
||||||
|
<category>{{ tag | xml_escape }}</category>
|
||||||
|
{% endfor %}
|
||||||
|
{% for cat in post.categories %}
|
||||||
|
<category>{{ cat | xml_escape }}</category>
|
||||||
|
{% endfor %}
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</channel>
|
||||||
|
</rss>
|
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
categories: guides
|
||||||
|
---
|
||||||
|
<div class="home">
|
||||||
|
|
||||||
|
<h1>Guides</h1>
|
||||||
|
|
||||||
|
<p>Here is a collection of guides that might help you get involved with Matrix.</p>
|
||||||
|
<p>First, there is the <a href="./getting_involved.html" title="Getting Involved">Getting Involved</a> guide, which explains various ways of getting started with Matrix.</p>
|
||||||
|
<p>The <a href="/docs/howtos/client-server.html" title="Client-Server API">Client-Server API</a> guide explains in detail how to use the CS API, which is useful if you want to write a client (or modify an existing one) - or if you're just interested in how it works "under the hood".</p>
|
||||||
|
<p>The <a href="./application_services.html" title="Application services">Application services</a> guide introduces and explains Application services, and what they can be used for.
|
||||||
|
<p>Finally there is the <a href="./faq.html" title="FAQ">FAQ</a>, which tries to answer all your questions relating to Matrix!</p>
|
||||||
|
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# adds anchors before any <h1/h2/h3/h4/h5> tags with an id="..." - this is used
|
||||||
|
# for things like the FAQ where we want to have anchored links to every
|
||||||
|
# question (and this way you don't have to manually maintain it in the source
|
||||||
|
# doc).
|
||||||
|
|
||||||
|
from sys import argv
|
||||||
|
import re
|
||||||
|
|
||||||
|
script, filename = argv
|
||||||
|
|
||||||
|
textfile = open(filename, "r")
|
||||||
|
regex = r'(<h\d id="(.*?)">)'
|
||||||
|
regex2 = r'(<div class="section" id="(.*?)">)'
|
||||||
|
|
||||||
|
replacement = r'<p><a class="anchor" id="\2"></a></p>\n\1'
|
||||||
|
|
||||||
|
# check for <hX id="..." (used in the FAQ) and add anchors - and then check
|
||||||
|
# for <div class="section" id="..." and add anchors (used in the spec)
|
||||||
|
for line in textfile:
|
||||||
|
line = re.sub(regex, replacement, line.rstrip())
|
||||||
|
print(re.sub(regex2, replacement, line.rstrip()))
|
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# this script runs 'jekyll' to turn the 'supporting-docs' into HTML.
|
||||||
|
#
|
||||||
|
# jekyll requires the `docutils` and `pygments` python packages, so install
|
||||||
|
# them or run from a virtualenv which includes them.
|
||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# tell jekyll to parse things as utf-8
|
||||||
|
export LANG="en_GB.UTF-8"
|
||||||
|
|
||||||
|
cd `dirname $0`/..
|
||||||
|
|
||||||
|
mkdir -p _site
|
||||||
|
jekyll build -s jekyll
|
||||||
|
./scripts/add_anchors.py _site/guides/faq.html >tmp && mv tmp _site/guides/faq.html
|
||||||
|
./scripts/add_anchors.py _site/projects/try-matrix-now.html >tmp && mv tmp _site/projects/try-matrix-now.html
|
||||||
|
|
Loading…
Reference in New Issue