Commit cb44370e authored by Kenton Varda's avatar Kenton Varda

Started on docs.

parent ced6a707
......@@ -4,6 +4,7 @@
# Eclipse-generated stuff.
.cproject
.project
.pydevproject
.settings
.dist-buildwrapper
/c++/gen/
......@@ -20,3 +21,6 @@
/c++/tmp/
/c++/bin/
# Jekyll-generated site
/doc/_site
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<meta name="description" content="Capnproto : Cap'n Proto serialization/RPC system" />
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
<title>Capnproto</title>
</head>
<body>
<!-- HEADER -->
<div id="header_wrap" class="outer">
<header class="inner">
<a id="forkme_banner" href="https://github.com/kentonv/capnproto">View on GitHub</a>
<h1 id="project_title">Capnproto</h1>
<h2 id="project_tagline">Cap'n Proto serialization/RPC system</h2>
<section id="downloads">
<a class="zip_download_link" href="https://github.com/kentonv/capnproto/zipball/master">Download this project as a .zip file</a>
<a class="tar_download_link" href="https://github.com/kentonv/capnproto/tarball/master">Download this project as a tar.gz file</a>
</section>
</header>
</div>
<!-- MAIN CONTENT -->
<div id="main_content_wrap" class="outer">
<section id="menu">
<ul>
<li><a href="index.html">Introduction</a></li>
<li><a href="install.html">Installation</a></li>
<li><a href="language.html">Defining Types</a></li>
<li><a href="encoding.html">Encoding</a></li>
<li><a href="rpc.html">RPC Protocol</a></li>
<li><a href="cxx.html">C++ Runtime</a></li>
<li><a href="otherlang.html">Other Languages</a></li>
</ul>
</section>
<section id="main_content" class="inner">
{{ content }}
</section>
</div>
<!-- FOOTER -->
<div id="footer_wrap" class="outer">
<footer class="inner">
<p class="copyright">Capnproto maintained by <a href="https://github.com/kentonv">kentonv</a></p>
<p>Published with <a href="http://pages.github.com">GitHub Pages</a></p>
</footer>
</div>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-39711112-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
</body>
</html>
#! /usr/bin/env python
from pygments.lexer import RegexLexer
from pygments.token import *
class CapnpLexer(RegexLexer):
name = "Cap'n Proto lexer"
aliases = ['capnp']
filenames = ['*.capnp']
tokens = {
'root': [
(r'#.*?$', Comment.Single),
(r'@[0-9]*', Name.Decorator),
(r'=[^;]*', Literal),
(r':[^;=]*', Name.Class),
(r'@[0-9]*', Token.Annotation),
(r'(struct|enum|interface|union|import|using|const|option|in|of|on|as|with|from)\b',
Token.Keyword),
(r'[a-zA-Z0-9_.]+', Token.Name),
(r'[^#@=:a-zA-Z0-9_]+', Text),
]
}
if __name__ == "__main__":
from setuptools import setup, find_packages
setup(name = "CapnpPygmentsLexer",
version = "0.1",
packages = find_packages(),
py_modules = [ 'capnp_lexer' ],
entry_points = {'pygments.lexers': 'capnp = capnp_lexer:CapnpLexer'})
---
layout: page
---
# Introduction
<img src='images/infinity-times-faster.png' style='width:334px; height:306px; float: right;'>
Cap'n Proto is an insanely fast data interchange format and capability-based RPC system. Think
JSON, except binary. Or think [Protocol Buffers](http://protobuf.googlecode.com), except faster.
In fact, in benchmarks, Cap'n Proto is INFINITY TIMES faster than Protocol Buffers.
This benchmark is, of course, silly. It is only measuring the time to encode and decode a message
in memory. Cap'n Proto gets a perfect score because _there is no encoding/decoding step_. The Cap'n
Proto encoding is appropriate both as a data interchange format and an in-memory representation, so
once your structure is built, you can simply write the bytes straight out to disk!
**_But doesn't that mean the encoding is platform-specific?_**
NO! The encoding is defined byte-for-byte independently of any platform. However, it is designed to
be efficiently manipulated on common modern CPUs. Data is arranged like a compiler would arrange a
struct -- with fixed widths, fixed offsets, and proper alignment. Variable-sized elements are
embedded as pointers. Pointers are offset-based rather than absolute so that messages are
position-independent. Integers use little-endian byte order because most CPUs are little-endian,
and even big-endian CPUs usually have instructions for reading little-endian data.
**_Doesn't that back backwards-compatibility hard?_**
Not at all! New fields are always added to the end of a struct (or replace padding space), so
existing field positions are unchanged. The recipient simply needs to do a bounds check when
reading each field. Fields are numbered in the order in which they were added, so Cap'n Proto
always knows how to arrange them for backwards-compatibility.
**_Won't fixed-width integers, unset optional fields, and padding waste space on the wire?_**
Yes. However, since all these extra bytes are zeros, when bandwidth matters, we can apply an
extremely fast compression scheme to remove them. Cap'n Proto calls this "packing"; the message,
it achieves similar (better, even) message sizes to protobuf encoding, and it's still faster.
When bandwidth really matters, you should apply general-purpose compression, like
[zlib](http://www.zlib.net/) or [Snappy](https://code.google.com/p/snappy/), regardless of your
encoding format.
**_Are there other advantages?_**
Glad you asked!
* **Incremental reads:** It is easy to start processing a Cap'n Proto message before you have
received all of it since outer objects appear entirely before inner objects (as opposed to most
encodings, where outer objects encompass inner objects).
* **Random access:** You can read just one field of a message without parsing the whole thing.
* **mmap:** Read a large Cap'n Proto file by memory-mapping it. The OS won't even read in the
parts that you don't access.
* **Inter-language communication:** Calling C++ code from, say, Java or Python tends to be painful
or slow. With Cap'n Proto, the two languages can easily operate on the same in-memory data
structure.
* **Inter-process communication:** Multiple processes running on the same machine can share a
Cap'n Proto message via shared memory. No need to pipe data through the kernel. Calling another
process can be just as fast and easy as calling another thread.
* **Arena allocation:** Manipulating Protobuf objects tends to be bogged down by memory
allocation, unless you are very careful about object reuse. Cap'n Proto objects are always
allocated in an "arena"; or "region"; style, which is faster and promotes cache locality.
* **Tiny generated code:** Protobuf generates dedicated parsing and serialization code for every
message type, and this code tends to be enormous. Cap'n Proto generated code is smaller by an
order of magnitude or more.
* **Tiny runtime library:** Due to the simplicity of the Cap'n Proto format, the runtime library
can be much smaller.
**_Why do you pick on Protocol Buffers so much?_**
Because it's easy to pick on myself. :) I, Kenton Varda, was the primary author of Protocol Buffers version 2, which is the version that Google released open source. Cap'n Proto is the result of years of experience working on Protobufs, listening to user feedback, and thinking about how things could be done better.
I am no longer employed by Google. Cap'n Proto is not affiliated with Google or any other company.
**_Tell me about the RPC system._**
_As of this writing, the RPC system is not yet implemented._
Cap'n Proto defines a [capability-based](http://en.wikipedia.org/wiki/Capability-based_security) RPC protocol. In such a system, any message passed over the wire can itself contain references to callable objects. Passing such a reference over the wire implies granting the recipient permission to call the referenced object -- until a reference is sent, the recipient has no way of addressing it in order to form a request to it, or even knowing that it exists.
Such a system makes it very easy to define stateful, secure object-oriented protocols.
# Cap'n Proto is EXPERIMENTAL
As of this writing, Cap'n Proto is in the very early stages of development. It is still missing many essential features:
* **Security:** There are almost certainly a few exploitable security bugs in the Cap'n Proto code. You should not use Cap'n Proto on untrusted data until a proper security review has been completed.
* **Stability:** The Cap'n Proto format is still changing. Any data written today probably won't be understood by future versions. Additionally, the programming interface is still evolving, so code written today probably won't work with future versions.
* **Performance:** While already beating the pants off other systems, Cap'n Proto has not yet undergone serious profiling and optimization.
* **RPC:** The RPC protocol has not yet been specified, much less implemented.
* **Support for languages other than C++:** Hasn't been started yet.
Would you like to contribute? Join the [discussion group](https://groups.google.com/group/capnproto) and let us know!
console.log('This would be the main JS file.');
---
layout: page
---
# Defining Types
Like Protocol Buffers and Thrift (but unlike JSON or MessagePack), Cap'n Proto messages are
strongly-typed and not self-describing. You must define your message structure in a special
language, then invoke the Cap'n Proto compiler (`capnpc`) to generate source code to manipulate
that message type in your desired language.
For example:
{% highlight capnp %}
struct Person {
name @0 :Text;
birthdate @3 :Date;
email @1 :Text;
phones @2 :List(PhoneNumber);
struct PhoneNumber {
number @0 :Text;
type @1 :Type;
enum Type {
mobile @0;
home @1;
work @2;
}
}
}
struct Date {
year @0 :Int16;
month @1 :UInt8;
day @2 :UInt8;
}
{% endhighlight %}
Some notes:
* Types come after names. This makes sense because the name is usually the thing you are looking
for when you read the code, so it should be up front where it is easiest to see, not hidden later
on the line. Sorry, C got it wrong.
* The `@N` annotations show how the protocol evolved over time, so that the system can make sure
to maintain compatibility with older versions. Fields (and enum values, and interface methods)
must be numbered consecutively starting from zero in the order in which they were added. In this
example, it looks like the `birthdate` field was added to the `Person` structure recently -- its
number is higher than the `email` and `phones` fields. Unlike Protobufs, you cannot skip numbers
when defining fields -- but there was never any reason to do so anyway.
## Language Reference
### Comments
Comments are indicated by hash signs and extend to the end of the line;
{% highlight capnp %}
# This is a comment.
{% endhighlight %}
Comments meant as documentation should appear _after_ the declaration, either on the same line, or
on a subsequent line. Doc comments for aggregate definitions should appear on the line after the
opening brace.
{% highlight capnp %}
struct Date {
# A standard Gregorian calendar date.
year @0 :Int16;
# The year. Must include the century.
# Negative value indicates BC.
month @1 :UInt8; # Month number, 1-12.
day @2 :UInt8; # Day number, 1-30.
}
{% endhighlight %}
Placing the comment _after_ the declaration rather than before makes the code more readable,
especially when doc comments grow long. You almost always need to see the declaration before you
can start reading the comment.
### Built-in Types
The following types are automatically defined:
* **Void:** `Void`
* **Boolean:** `Bool`
* **Integers:** `Int8`, `Int16`, `Int32`, `Int64`
* **Unsigned integers:** `UInt8`, `UInt16`, `UInt32`, `UInt64`
* **Floating-point:** `Float32`, `Float64`
* **Blobs:** `Text`, `Data`
* **Lists:** `List(T)`
Notes:
* The `Void` type has exactly one possible value, and thus can be encoded in zero bytes. It is
rarely used, but can be useful as a union member.
* `Text` is always UTF-8 encoded and NUL-terminated.
* `Data` is a completely arbitrary sequence of bytes.
* `List` is a parameterized type, where the parameter is the element type. For example,
`List(Int32)`, `List(Person)`, and `List(List(Text))` are all valid.
### Structs
A struct has a set of named, typed fields, numbered consecutively starting from zero.
{% highlight capnp %}
struct Person {
name @0 :Text;
email @1 :Text;
}
{% endhighlight %}
Fields can have default values:
{% highlight capnp %}
foo @0 :Int32 = 123;
bar @1 :Text = "blah";
baz @2 :List(Bool) = [ true, false, false, true ];
qux @3 :Person = (name = "Bob", email = "bob@example.com");
corge @4 :Void = void;
{% endhighlight %}
### Unions
A union is two or more fields of a struct which are stored in the same location. Only one of
these fields can be set at a time, and a separate tag is maintained to track which one is
currently set. Unlike in C, unions are not types, they are simply properties of fields, therefore
union declarations do not look like types.
{% highlight capnp %}
struct Person {
# ...
union employment @4;
unemployed @5 in employment :Void;
employer @6 in employment :Company;
school @7 in employment :School;
selfEmployed @8 in employment :Void;
}
{% endhighlight %}
Notes:
* Unions are numbered in the same number space as other fields. Remember that the purpose of the
numbers is to indicate the evolution order of the struct. The system needs to know when the union
was declared relative to the fields in it. Also note that at most one element of the union is
allowed to have a number less than the union's number, as unionizing two or more existing fields
would change their layout.
* Notice that we used the "useless" `Void` type here. We don't have any extra information to store
for the `unemployed` or `selfEmployed` cases, but we still want the union to have tags for them.
### Enums
An enum is a type with a small finite set of symbolic values.
{% highlight capnp %}
enum Rfc3092Variable {
foo @0;
bar @1;
baz @2;
qux @3;
# ...
}
{% endhighlight %}
Like fields, enum values must be numbered sequentially starting from zero. In languages where
enums have numeric values, these numbers will be used, but in general Cap'n Proto enums should not
be considered numeric.
### Interfaces
An interface has a collection of methods, each of which takes some parameters and returns a
result. Like struct fields, methods are numbered.
{% highlight capnp %}
interface Directory {
list @0 () :List(FileInfo);
create @1 (name :Text) :FileInfo;
open @2 (name :Text) :FileInfo;
delete @3 (name :Text) :Void;
link @4 (name :Text, file :File) :Void;
}
struct FileInfo {
name @0 :Text;
size @1 :UInt64;
file @2 :File; # A pointer to a File.
}
interface File {
read @0 (startAt :UInt64, amount :UInt64) :Data;
write @1 (startAt :UInt64, data :Data) :Void;
truncate @2 (size :UInt64) :Void;
}
{% endhighlight %}
Notice something interesting here: `FileInfo` is a struct, but it contains a `File`, which is an
interface. Structs (and primitive types) are passed by value, but interfaces are passed by
reference. So when `Directory.open` is called remotely, the content of a `FileInfo` (including
values for `name` and `size`) is transmitted back, but for the `file` field, only the address of
some remote `File` object is sent.
When an address of an object is transmitted, the RPC system automatically manages making sure that
the recipient gets permission to call the addressed object -- because if the recipient wasn't
meant to have access, the sender shouldn't have sent the reference in the first place. This makes
it very easy to develop secure protocols with Cap'n Proto -- you almost don't need to think about
access control at all. This feature is what makes Cap'n Proto a "capability-based" RPC system -- a
reference to an object inherently represents a "capability" to access it.
### Constants
You can define constants in Cap'n Proto. Constants can have any value.
{% highlight capnp %}
const pi :Float32 = 3.14159;
const bob :Person = (name = "Bob", email = "bob@example.com");
{% endhighlight %}
### Nesting, Scope, and Aliases
You can nest constant, alias, and type definitions inside structs and interfaces (but not enums).
This has no effect on any definition involved except to define the scope of its name. So in Java
terms, inner classes are always "static". To name a nested type from another scope, separate the
path with `.`s.
{% highlight capnp %}
struct Foo {
struct Bar {
#...
}
bar@0 :Bar;
}
struct Baz {
bar@0 :Foo.Bar;
}
{% endhighlight %}
If typing long scopes becomes cumbersome, you can use `using` to declare an alias.
{% highlight capnp %}
struct Qux {
using Foo.Bar;
bar@0 :Bar;
}
struct Corge {
using T = Foo.Bar;
bar@0 :T;
}
{% endhighlight %}
### Imports
An `import` expression names the scope of some other file:
{% highlight capnp %}
struct Foo {
# Use type "Baz" defined in bar.capnp.
baz@0 :import "bar.capnp".Baz;
}
{% endhighlight %}
Of course, typically it's more readable to define an alias:
{% highlight capnp %}
using Bar = import "bar.capnp";
struct Foo {
# Use type "Baz" defined in bar.capnp.
baz@0 :Bar.Baz;
}
{% endhighlight %}
Or even:
{% highlight capnp %}
using import "bar.capnp".Baz;
struct Foo {
baz @0 :Baz;
}
{% endhighlight %}
## Running the Compiler
Simply run:
capnpc person.capnp
This will create `person.capnp.h` and `person.capnp.c++` in the same directory as `person.capnp`.
_TODO: This will become more complicated later as we add support for more languages and such._
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f0f3f3; }
.highlight .c { color: #808080; font-style: italic } /* Comment */
.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */
.highlight .k { color: #000099; font-weight: bold } /* Keyword */
.highlight .o { color: #555555 } /* Operator */
.highlight .cm { color: #808080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #009999 } /* Comment.Preproc */
.highlight .c1 { color: #808080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */
.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */
.highlight .go { color: #AAAAAA } /* Generic.Output */
.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #99CC66 } /* Generic.Traceback */
.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #006699 } /* Keyword.Pseudo */
.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #FF6600 } /* Literal.Number */
.highlight .s { color: #CC3300 } /* Literal.String */
.highlight .na { color: #330099 } /* Name.Attribute */
.highlight .nb { color: #336666 } /* Name.Builtin */
.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */
.highlight .no { color: #336600 } /* Name.Constant */
.highlight .nd { color: #9999FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #CC00FF } /* Name.Function */
.highlight .nl { color: #9999FF } /* Name.Label */
.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #003333 } /* Name.Variable */
.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #FF6600 } /* Literal.Number.Float */
.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */
.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */
.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */
.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */
.highlight .sc { color: #CC3300 } /* Literal.String.Char */
.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #CC3300 } /* Literal.String.Double */
.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */
.highlight .si { color: #AA0000 } /* Literal.String.Interpol */
.highlight .sx { color: #CC3300 } /* Literal.String.Other */
.highlight .sr { color: #33AAAA } /* Literal.String.Regex */
.highlight .s1 { color: #CC3300 } /* Literal.String.Single */
.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */
.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #003333 } /* Name.Variable.Class */
.highlight .vg { color: #003333 } /* Name.Variable.Global */
.highlight .vi { color: #003333 } /* Name.Variable.Instance */
.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */
.type-csharp .highlight .k { color: #0000FF }
.type-csharp .highlight .kt { color: #0000FF }
.type-csharp .highlight .nf { color: #000000; font-weight: normal }
.type-csharp .highlight .nc { color: #2B91AF }
.type-csharp .highlight .nn { color: #000000 }
.type-csharp .highlight .s { color: #A31515 }
.type-csharp .highlight .sc { color: #A31515 }
.highlight .capnp .nd { color: #0099FF; font-weight: normal; } /* @N */
.highlight .capnp .l { color: #003399; } /* = value */
.highlight .capnp .nc { color: #009900; font-weight: normal; } /* :Type */
/*******************************************************************************
Slate Theme for GitHub Pages
by Jason Costello, @jsncostello
*******************************************************************************/
@import url(pygment_trac.css);
/*******************************************************************************
MeyerWeb Reset
*******************************************************************************/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
ol, ul {
list-style: none;
}
blockquote, q {
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a:focus {
outline: none;
}
/*******************************************************************************
Theme Styles
*******************************************************************************/
body {
box-sizing: border-box;
color:#373737;
background: #212121;
font-size: 16px;
font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6 {
margin: 10px 0;
font-weight: 700;
color:#222222;
font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
letter-spacing: -1px;
}
h1 {
font-size: 36px;
font-weight: 700;
}
h2 {
padding-bottom: 10px;
font-size: 32px;
background: url('../images/bg_hr.png') repeat-x bottom;
}
h3 {
font-size: 24px;
}
h4 {
font-size: 21px;
}
h5 {
font-size: 18px;
}
h6 {
font-size: 16px;
}
p {
margin: 10px 0 15px 0;
}
footer p {
color: #f2f2f2;
}
a {
text-decoration: none;
color: #007edf;
text-shadow: none;
transition: color 0.5s ease;
transition: text-shadow 0.5s ease;
-webkit-transition: color 0.5s ease;
-webkit-transition: text-shadow 0.5s ease;
-moz-transition: color 0.5s ease;
-moz-transition: text-shadow 0.5s ease;
-o-transition: color 0.5s ease;
-o-transition: text-shadow 0.5s ease;
-ms-transition: color 0.5s ease;
-ms-transition: text-shadow 0.5s ease;
}
#main_content a:hover {
color: #0069ba;
text-shadow: #0090ff 0px 0px 2px;
}
footer a:hover {
color: #43adff;
text-shadow: #0090ff 0px 0px 2px;
}
em {
font-style: italic;
}
strong {
font-weight: bold;
}
img {
position: relative;
margin: 0 auto;
max-width: 739px;
padding: 5px;
margin: 10px 0 10px 0;
border: 1px solid #ebebeb;
box-shadow: 0 0 5px #ebebeb;
-webkit-box-shadow: 0 0 5px #ebebeb;
-moz-box-shadow: 0 0 5px #ebebeb;
-o-box-shadow: 0 0 5px #ebebeb;
-ms-box-shadow: 0 0 5px #ebebeb;
}
pre, code {
width: 100%;
color: #222;
background-color: #fff;
font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
font-size: 14px;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
pre {
width: 100%;
padding: 10px;
box-shadow: 0 0 10px rgba(0,0,0,.1);
overflow: auto;
}
code {
padding: 3px;
margin: 0 3px;
box-shadow: 0 0 10px rgba(0,0,0,.1);
}
pre code {
display: block;
box-shadow: none;
}
blockquote {
color: #666;
margin-bottom: 20px;
padding: 0 0 0 20px;
border-left: 3px solid #bbb;
}
ul, ol, dl {
margin-bottom: 15px
}
ul li {
list-style: inside;
padding-left: 20px;
}
ol li {
list-style: decimal inside;
padding-left: 20px;
}
dl dt {
font-weight: bold;
}
dl dd {
padding-left: 20px;
font-style: italic;
}
dl p {
padding-left: 20px;
font-style: italic;
}
hr {
height: 1px;
margin-bottom: 5px;
border: none;
background: url('../images/bg_hr.png') repeat-x center;
}
table {
border: 1px solid #373737;
margin-bottom: 20px;
text-align: left;
}
th {
font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
padding: 10px;
background: #373737;
color: #fff;
}
td {
padding: 10px;
border: 1px solid #373737;
}
form {
background: #f2f2f2;
padding: 20px;
}
img {
width: 100%;
max-width: 100%;
background-color: white;
}
/*******************************************************************************
Full-Width Styles
*******************************************************************************/
.outer {
width: 100%;
}
.inner {
position: relative;
max-width: 640px;
padding: 20px 10px;
margin: 0 auto;
}
#forkme_banner {
display: block;
position: absolute;
top:0;
right: 10px;
z-index: 10;
padding: 10px 50px 10px 10px;
color: #fff;
background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
font-weight: 700;
box-shadow: 0 0 10px rgba(0,0,0,.5);
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
#header_wrap {
background: #212121;
background: -moz-linear-gradient(top, #373737, #212121);
background: -webkit-linear-gradient(top, #373737, #212121);
background: -ms-linear-gradient(top, #373737, #212121);
background: -o-linear-gradient(top, #373737, #212121);
background: linear-gradient(top, #373737, #212121);
}
#header_wrap .inner {
padding: 50px 10px 30px 10px;
}
#project_title {
margin: 0;
color: #fff;
font-size: 42px;
font-weight: 700;
text-shadow: #111 0px 0px 10px;
}
#project_tagline {
color: #fff;
font-size: 24px;
font-weight: 300;
background: none;
text-shadow: #111 0px 0px 10px;
}
#downloads {
position: absolute;
width: 210px;
z-index: 10;
bottom: -40px;
right: 0;
height: 70px;
background: url('../images/icon_download.png') no-repeat 0% 90%;
}
.zip_download_link {
display: block;
float: right;
width: 90px;
height:70px;
text-indent: -5000px;
overflow: hidden;
background: url(../images/sprite_download.png) no-repeat bottom left;
}
.tar_download_link {
display: block;
float: right;
width: 90px;
height:70px;
text-indent: -5000px;
overflow: hidden;
background: url(../images/sprite_download.png) no-repeat bottom right;
margin-left: 10px;
}
.zip_download_link:hover {
background: url(../images/sprite_download.png) no-repeat top left;
}
.tar_download_link:hover {
background: url(../images/sprite_download.png) no-repeat top right;
}
#main_content_wrap {
background: #f2f2f2;
border-top: 1px solid #111;
border-bottom: 1px solid #111;
}
#main_content {
padding-top: 40px;
}
#footer_wrap {
background: #212121;
}
/*******************************************************************************
Small Device Styles
*******************************************************************************/
@media screen and (max-width: 480px) {
body {
font-size:14px;
}
#downloads {
display: none;
}
.inner {
min-width: 320px;
max-width: 480px;
}
#project_title {
font-size: 32px;
}
h1 {
font-size: 28px;
}
h2 {
font-size: 24px;
}
h3 {
font-size: 21px;
}
h4 {
font-size: 18px;
}
h5 {
font-size: 14px;
}
h6 {
font-size: 12px;
}
code, pre {
min-width: 320px;
max-width: 480px;
font-size: 11px;
}
}
/*******************************************************************************
Sidbar style borrowed from cldoc by jessevdk, because I thought it looked good.
*******************************************************************************/
div.maruku_toc {
position: absolute;
left: 0;
}
#menu {
float: left;
}
#menu ul {
padding: 0;
margin: 0;
margin-top: 30px;
}
#menu li {
margin: 0;
padding: 10px 15px 10px 15px;
list-style-type: none;
background-color: #212121;
}
#menu li:first-child {
border-radius: 0px 10px 0px 0px;
}
#menu li:last-child {
border-radius: 0px 0px 10px 0px;
}
#menu a {
color: #aaa;
}
#menu li.selected {
background-color: #2a2a2a;
}
#menu li.selected a {
color: #fff;
}
#menu a:hover {
color: #eee;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment