diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c12edaf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+/.build
+/.swiftpm
+/*.xcodeproj
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..6992f1d
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,68 @@
+# Plot Contribution Guide
+
+Welcome to the *Plot Contribution Guide* — a document that aims to give you all the information you need to contribute to the Plot project. Thanks for your interest in contributing to this project, and hopefully this document will help make it as smooth and enjoyable as possible to do so.
+
+## Bugs, feature requests and support
+
+Plot doesn’t use GitHub issues, so all form of support — whether that’s asking a question, reporting a bug, or discussing a feature request — takes place in Pull Requests.
+
+The idea behind this workflow is to encourage more people using Plot to dive into the source code and familiarize themselves with how it works, in order to better be able to *self-service* on bugs and issues — hopefully leading to a better and smoother experience for everyone involved.
+
+### I found a bug, how do I report it?
+
+If you find a bug, for example an element or attribute that doesn’t render correctly, here’s the recommended workflow:
+
+1. Come up with the simplest code possible that reproduces the issue in isolation.
+2. Write a test case using the code that reproduces the issue. See [Plot’s existing test suite](Tests/PlotTests) for inspiration on how to get started, or [this article](https://www.swiftbysundell.com/basics/unit-testing) if you want to learn some of the basics of unit testing in Swift.
+3. Either fix the bug yourself, or simply submit your failing test as a Pull Request, and we can work on a solution together.
+
+While doing the above does require a bit of extra work for the person who found the bug, it gives us as a community a very nice starting point for fixing issues — hopefully leading to quicker fixes and a more constructive workflow.
+
+### I have an idea for a feature request
+
+First of all, that’s awesome! Your ideas on how to make Plot better and more powerful are super welcome. Here’s the recommended workflow for feature requests:
+
+1. Do some prototyping and come up with a sample implementation of your idea or feature request. Note that this doesn’t have to be a fully working, complete implementation, just something that illustrates the feature/idea and how it could be added to Plot.
+2. Submit your sample implementation as a Pull Request. Use the description field to write down why you think the feature should be added and some initial discussion points.
+3. Together we’ll discuss the feature and your sample implementation, and either accept it as-is, or use it as a starting point for a new implementation, or decide that the idea is not worth implementing as this time.
+
+### I have a question that the documentation doesn’t yet answer
+
+With Plot, the goal is to end up with state of the art documentation that answers most of the questions that both users and developers of the tool might have — and the only way to get there is through continued improvement, with your help. Here’s the recommended workflow for getting your question answered:
+
+1. Start by looking through the code. Chances are high that you’ll be able to answer your own question by reading through the implementation, the tests, and the inline code documentation.
+2. If you found out the answer to your question — then don’t stop there. Other people will probably ask themselves the same question at some point, so let’s improve the documentation! Find an appropriate place where your question could’ve been answered by clearer documentation or a better structure (for example this document, or inline in the code), and add the documentation you wish would’ve been there. If you didn’t manage to find an answer (no worries, we're all always learning), then write down your question as a comment — either in the code or in one of the Markdown documents.
+3. Submit your new documentation or your comment as a Pull Request, and we'll work on improving the documentation together.
+
+## Project structure
+
+Plot’s code is structured into two main folders — `API` and `Internal`. Any code that has a public-facing API should go into `API`, and purely internal types and functions should go into `Internal`. Note that you shouldn’t split a type up into two files, but rather find one place for it depending on if it has *any* public-facing components.
+
+For each document type, for example `HTML`, there are several key files in which APIs are defined:
+
+- The main document file, `HTML`, defines the format itself as well as all of its `Context` types.
+- The elements file, `HTMLElements`, defines all DSL APIs for constructing elements within a document.
+- The attributes file, `HTMLAttributes`, defines all DSL APIs for constructing attributes for elements of that format.
+- Finally, the components file, `HTMLComponents`, defines higher-level components that are compositions of elements and attributes.
+
+*The same structure is also used for all other document formats — `XML`, `RSS`, `PodcastFeed`, and `SiteMap`.*
+
+## Unit testing
+
+Plot has 100% unit testing coverage, and the goal is to keep it that way. All changes to Plot should be fully covered with tests, both to make sure that the new implementation works as expected, and to ensure that it keeps working as the code base is being iterated on.
+
+If you’re new to unit testing and want to learn more about it, then Swift by Sundell has [lots of articles on the topic](https://www.swiftbysundell.com/tags/unit-testing), starting with [this Basics article](https://www.swiftbysundell.com/basics/unit-testing).
+
+## Adding a new node type
+
+If you’ve encountered an element or attribute that’s missing from Plot’s DSL, then feel free to add it. Here’s how to do that:
+
+1. Start by finding the file in which your new API should be added. The above [project structure section](#project-structure) should help you identify the file that’d be the most appropriate. For example, HTML elements should be defined within `HTMLElements.swift`, and attributes within `HTMLAttributes.swift`.
+2. Either add your new API to an existing `Node` extension, or create a new one constrained to the type of `Context` that your element or attribute belongs in. For example, if it’s an attribute for an `` HTML element, then it should be defined in the `Node` extension `where Context == HTML.AnchorContext`.
+3. Write a test that verifies that your new API is working. See the above [unit testing section](#unit-testing) for more information.
+4. Submit your new API and your test as a Pull Request.
+5. Your Pull Request will be reviewed by a maintainer as soon as possible.
+
+## Conclusion
+
+Hopefully this document has given you an introduction to how Plot works, both in terms of its recommended project workflow and its structure. Feel free to submit Pull Requests to improve this document, and hope you’ll have a nice experience contributing to Plot.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c49eda8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 John Sundell
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Logo.png b/Logo.png
new file mode 100644
index 0000000..fdfc6fe
Binary files /dev/null and b/Logo.png differ
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..c3fff33
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,26 @@
+// swift-tools-version:5.1
+
+/**
+* Plot
+* Copyright (c) John Sundell 2019
+* MIT license, see LICENSE file for details
+*/
+
+import PackageDescription
+
+let package = Package(
+ name: "Plot",
+ products: [
+ .library(
+ name: "Plot",
+ targets: ["Plot"]
+ )
+ ],
+ targets: [
+ .target(name: "Plot"),
+ .testTarget(
+ name: "PlotTests",
+ dependencies: ["Plot"]
+ )
+ ]
+)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..78b675b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,398 @@
+
+ Writing HTML in Swift is pretty great! ` element, we’d get a compiler error:
+
+```swift
+let html = HTML(.body(
+ // Compiler error: Referencing static method 'href' on
+ // 'Node' requires that 'HTML.BodyContext' conform to
+ // 'HTMLLinkableContext'.
+ .p(.href("https://github.com"))
+))
+```
+
+Plot also leverages the Swift type system to verify each document’s element structure as well. For example, within HTML lists (such as ` ` tag using `.p()`.
+public struct Element World & Everyone! Hello World & Everyone!
+
My website
+ ` and `
`), it’s only valid to place `
`). You normally don’t have to interact with this type when using Plot, since you can create instances of it through its DSL.
+- [`Attribute`](Sources/Plot/API/Attribute.swift) represents an attribute attached to an element, such as the `href` of an `` element, or the `src` of an `
` element. You can either construct `Attribute` values through its initializer, or through the DSL, using the `.attribute()` command.
+- [`Document` and `DocumentFormat`](Sources/Plot/API/Document.swift) represent documents of a given format, such as `HTML`, `RSS` and `PodcastFeed`. These are the top level types that you use in order to start a document building session using Plot’s DSL.
+
+Plot makes heavy use of a technique known as *[Phantom Types](https://www.swiftbysundell.com/articles/phantom-types-in-swift)*, which is when types are used as “markers” for the compiler, to be able to enforce type safety through [generic constraints](https://www.swiftbysundell.com/articles/using-generic-type-constraints-in-swift-4). Both `DocumentFormat`, and the `Context` of a node, element or attribute, are used this way — as these types are never instantiated, but rather just there to associate their values with a given context or format.
+
+Plot also uses a very [lightweight API design](https://www.swiftbysundell.com/articles/lightweight-api-design-in-swift), minimizing external argument labels in favor of reducing the amount of syntax needed to render a document — giving its API a very “DSL-like” design.
+
+## Compatibility with standards
+
+Plot’s ultimate goal to be fully compatible with all standards that back the document formats that it supports. However, being a very young project, it will most likely need the community’s help to move it closer to that goal.
+
+The following standards are intended to be covered by Plot’s DSL:
+
+- [HTML 5.0](https://html.spec.whatwg.org)
+- [XML 1.0](https://www.w3.org/TR/REC-xml)
+- [RSS 2.0](https://validator.w3.org/feed/docs/rss2.html)
+- [Apple’s RSS extensions for podcasts](https://help.apple.com/itc/podcasts_connect/#/itcbaf351599)
+- [The Sitemaps XML format](https://www.sitemaps.org/protocol.html)
+
+If you discover an element or attribute that’s missing, please [add it](CONTRIBUTING.md#adding-a-new-node-type) and open a Pull Request with that addition.
+
+## Credits, alternatives and focus
+
+Plot was originally written by [John Sundell](https://twitter.com/johnsundell) as part of the Publish suite of static site generation tools, which is used to build and generate [Swift by Sundell](https://swiftbysundell.com). That suite also includes the Markdown parser [Ink](https://github.com/JohnSundell/Ink), as well as Publish itself (which will be open sourced soon).
+
+The idea of using Swift to generate HTML has also been explored by many other people and projects in the community, some of them similar to Plot, some of them completely different. For example [Leaf](https://github.com/vapor/leaf) by [Vapor](https://vapor.codes), [swift-html](https://github.com/pointfreeco/swift-html) by [Point-Free](https://www.pointfree.co), and the [Swift Talk backend](https://github.com/objcio/swift-talk-backend) by [objc.io](https://www.objc.io). The fact that there’s a lot of simultaneous innovation within this area is a great thing — since all of these tools (including Plot) have made different decisions around their overall API design and scope, which lets each developer pick the tool that best fits their individual taste and needs (or perhaps build yet another one?).
+
+Plot’s main focus is on Swift-based static site generation, and on supporting a wide range of formats used when building websites, including RSS and podcast feeds. It’s also tightly integrated with the upcoming Publish static site generator, and was built to enable Publish to be as fast and flexible as possible, without having to take on any third-party dependencies. It was open sourced as a separate project both from an architectural perspective, and to enable other tools to be built on top of it without having to depend on Publish.
+
+## Contributions and support
+
+Plot is developed completely in the open, and your contributions are more than welcome.
+
+Before you start using Plot in any of your projects, it’s highly recommended that you spend a few minutes familiarizing yourself with its documentation and internal implementation, so that you’ll be ready to tackle any issues or edge cases that you might encounter.
+
+Since this is a very young project, it’s likely to have many limitations and missing features, which is something that can really only be discovered and addressed as more people start using it. While Plot is used in production to build and render all of [Swift by Sundell](https://swiftbysundell.com), it’s recommended that you first try it out for your specific use case, to make sure it supports the features that you need.
+
+This project does [not come with GitHub Issues-based support](CONTRIBUTING.md#bugs-feature-requests-and-support), and users are instead encouraged to become active participants in its continued development — by fixing any bugs that they encounter, or by improving the documentation wherever it’s found to be lacking.
+
+If you wish to make a change, [open a Pull Request](https://github.com/JohnSundell/Plot/pull/new) — even if it just contains a draft of the changes you’re planning, or a test that reproduces an issue — and we can discuss it further from there. See [Plot’s contribution guide](CONTRIBUTING.md) for more information about how to contribute to this project.
+
+Hope you’ll enjoy using Plot!
diff --git a/Sources/Plot/API/Attribute.swift b/Sources/Plot/API/Attribute.swift
new file mode 100644
index 0000000..3a3f8a5
--- /dev/null
+++ b/Sources/Plot/API/Attribute.swift
@@ -0,0 +1,73 @@
+/**
+* Plot
+* Copyright (c) John Sundell 2019
+* MIT license, see LICENSE file for details
+*/
+
+import Foundation
+
+/// A representation of an element attribute, for example an HTML element's
+/// `id` or `class`. You normally don't construct `Attribute` values manually,
+/// but rather use Plot's various DSL APIs to create them, for example by using
+/// the `id()` or `class()` modifier on an HTML element.
+public struct Attribute
`.
+ case selfClosing
+ }
+
+ /// Create a custom element with a given name and array of child nodes.
+ /// - parameter name: The name of the element to create.
+ /// - parameter nodes: The nodes (child elements + attributes) to add to the element.
+ static func named(_ name: String, nodes: [Node
World & Everyone!
]]>\ + \ + + """) + } + + func testItemHTMLDSLContent() { + let feed = RSS(.item( + .content(.h1("Title")) + )) + + assertEqualRSSFeedContent(feed, """ +