Swift Playground
Create and modify Xcode Swift Playgrounds from Ruby. Includes both a Ruby API and a CLI.
Contents
- Installation
- CLI Usage
- Creating an empty playground
- Generate a playground from markdown
- Ruby Usage
- Constructing a basic playground
- Generating a playground from markdown
- Sections
- Markdown Format
- Default Stylesheet
- Credits
Installation
Install via RubyGems:
$ gem install swift-playground
CLI Usage
Creating an empty playground
The playground created is the same as as Xcode would via "File > New > Playground…":
$ swift-playground new [options] example.playground
This command supports these options (see swift-playground help new
):
-
--platform=[ios|osx]
The target platform for the generated playground (default: ios).
-
--[no-]reset
Allow the playground to be reset to it's original state via "Editor > Reset Playground" in Xcode (default: enabled).
-
--open
Open the playground in Xcode once it has been created.
Generate a playground from markdown
$ swift-playground generate [options] example.md
This command supports the following options (see swift-playground help generate
) in addition to the options supported by the new
command that are detailed above:
-
--stylesheet=<file>
CSS stylesheet for the HTML documentation sections of the playground. SASS/SCSS syntax is supported. This will be included after the default stylesheet. (default: none).
-
--javascript=<file>
Open the playground in Xcode once it has been created.
-
--[no-]emoji
Convert emoji aliases (e.g.
:+1:
) into emoji characters (default: enabled). -
--[no-]highlighting
Detect non-swift code blocks and add syntax highlighting. Only has an effect if 'github-linguist' and 'pygments.rb' gems are installed. (default: enabled).
-
--highlighting-style=<style>
The name of a pygments (http://pygments.org/) style to apply to syntax highlighted code blocks. Set to 'custom' if providing your own pygments-compatible stylesheet. Ignored if
--no-highlighting
is set. (default: default).
Ruby Usage
WARNING: This is still under development and the API may change before 1.0 is released.
Constructing a basic playground
require 'swift/playground'
playground = Swift::Playground.new
documentation = Swift::Playground::DocumentationSection.new <<-HTML
<h1>Welcome to the Playground!</h1>
<p>
This is an <em>awesome</em> example playground!
</p>
HTML
code = Swift::Playground::CodeSection.new <<-SWIFT
// Write swiftly!
import UIKit
var str = "This string has contents."
SWIFT
playground.sections << documentation
playground.sections << code
playground.save('~/example.playground')
Generating a playground from markdown
require 'swift/playground/generator'
playground = Swift::Playground::Generator.generate(markdown_file)
Sections
There are two section types you can use to construct a playground in Ruby:
DocumentationSection
These contain HTML that is rendered within the playground. You can construct a DocumentationSection
with either an IO object or a string representing the contents of the HTML file:
# All of the following are valid values for content:
content = Pathname.new('/path/to/file.html')
content = File.open('/path/to/file.html')
content = <<-HTML
<h1>An example HTML fragment</h1>
<p>
Note this is a fragment, it does not have a root 'html' or 'body' tag.
</p>
HTML
# Creating the section:
section = Swift::Playground::DocumentationSection.new(content)
# Adding the section to a playground:
playground.sections << section
# or perhaps:
playground.sections.insert(0, section)
The content you provide must be an HTML fragment - if a <html>
, <head>
or <body>
tag is present an exception will be raised.
CodeSection
These contain the executable swift code, and each playground must contain at least one of these sections. Constructing these sections is the same as DocumentationSection
- you can use either an IO object or a string representing the contents of the swift file:
# All of the following are valid values for content:
content = Pathname.new('/path/to/file.swift')
content = File.open('/path/to/file.swift')
content = <<-SWIFT
// Write swiftly!
import UIKit
var str = "This string has contents."
SWIFT
# Creating the section:
section = Swift::Playground::CodeSection.new(content)
# Set the 'style' of the section. Apple only document 'setup' at the
# moment and this is all that is supported.
#
# 'setup' will wrap the section in a "Setup" label that can be toggled
# (and initially appears minimized):
section.style = 'setup'
# Adding the section to a playground:
playground.sections << section
# or perhaps:
playground.sections.insert(0, section)
Markdown Format
Generating a playground from Markdown supports the Github Flavoured Markdown syntax.
Default Stylesheet
Each documentation section is generated with a default stylesheet loaded before any custom stylesheet. This stylesheet aims to provide an improved baseline over what is already there from the webkit renderer's agent stylesheets.
It does so in some specific ways:
- The default font size is adjusted so that at
1rem
the default Xcode font "Menlo" will render at exactly the same size as it would in the swift code sections of the playground. This is true even if the user has changed the editor font size. - A "gutter" (
body > .gutter
) is added that renders a line where the editor gutter appears in Xcode when line numbers are disabled. When Line numbers are visible it will appear centered with the line numbers. - The main body of the section (
body > section
) has a left and right padding that aligns the text with the left hand margin of swift code sections. - Sets the default font of
<code>
and<pre>
elements to "Menlo" which matches with the current default Xcode font.
Warning: These features rely on aspects of the Xcode interface the could change in future versions: the width of the editor gutter and the default size of the font inside of HTML documentation sections. There are no guarantees that these will stay the same between Xcode versions.
Be particularly cautious with adding color to the gutter, those colors may clash with the real gutter in the swift code sections - depending on the Theme being used by the user.
Credits
Initial development by Mark Haylock. Development sponsored by Resolve Digital.
This work was originally inspired by the work of Jason Sandmeyer (created Playground using Node.js) and Sam Soffes (created Playground using Ruby) - thank you to you both!
Thank you to Amanda Wagener for some pair programming assistance at Rails Camp NZ 5.