• This repository has been archived on 04/Apr/2022
  • Stars
    star
    251
  • Rank 160,955 (Top 4 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Markdown + oEmbed + Sanitize + CodeRay = the ultimate user input rendering pipeline!

Slodown

Slodown is the ultimate user input rendering pipeline.

Gem Version Build Status Status

I love Markdown. I love syntax highlighting. I love oEmbed. And last but not least, I love whitelist-based HTML sanitizing. Slodown rolls all of these into one, and then some.

Here's what Slodown does by default:

  • render extended Markdown into HTML. It uses the kramdown library, so yes, footnotes are supported!
  • add syntax highlighting to Markdown code blocks through CodeRay, Rouge, or any other highlighter supported by kramdown.
  • support super-easy rich media embeds. Just point the Markdown image syntax at, say, a Youtube video, and Slodown will fetch the complete embed code through the magic of ruby-oembed.
  • auto-link contained URLs using Rinku, which is smart enough to not auto-link URLs contained in, say, code blocks.
  • sanitize the generated HTML using the white-list based sanitize gem, with some really good default configuration.

Slodown is an extraction from sloblog.io. It is very easy to extend or modify, as it's just a plain old Ruby class you can inherit from.

General Approach

Slodown, out of the box, implements my preferred way of handling user input, which looks like this:

  • Convert all Markdown to HTML.
  • Don't strip HTML the user added themselves.
  • Auto-link contained URLs and email addresses.
  • Finally, and most importantly, run the entire HTML through a really, really good whitelist-based sanitizer.

This allows users to still add their own HTML, if required. In fact, I typically encourage users to make use of kramdown's inline attributes, leaving it up the sanitizer to make sure they don't go crazy.

If this is not what you want, you will most likely be able to bend Slodown to your will -- it's pretty flexible.

Usage

For every piece of user input that needs to be rendered, create an instance of Slodown::Formatter with the source text and use it to perform some or all transformations on it. Finally, call #to_s to get the rendered output.

Examples:

# let's create an instance to work with
formatter = Slodown::Formatter.new(text)

# just extract metadata
formatter.extract_metadata.to_s

# just render Markdown to HTML
formatter.markdown.to_s

# just auto-link contained URLs
formatter.autolink.to_s

# just sanitize HTML tags
formatter.sanitize.to_s

# you can chain multiple operations
formatter.markdown.sanitize.to_s

# this is the whole deal:
formatter.extract_metadata.markdown.autolink.sanitize.to_s

# which is the same as:
formatter.complete.to_s

If you want to customize Slodown's default behavior, simply create a new class that inherits from Slodown::Formatter and override methods like #kramdown_options, or add your own behaviors.

Syntax Highlighting

Just add CodeRay or Rouge to your project to have code blocks in your Markdown syntax-highlighted. Slodown will try to detect which library you're using, but to be sure, change your kramdown_options accordingly. For example:

class Formatter < Slodown::Formatter
  def kramdown_options
    {
      syntax_highlighter: 'coderay',
      syntax_highlighter_opts: { css: :class }
    }
  end
end

oEmbed support

oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.

Slodown extends the Markdown image syntax to support oEmbed-based embeds. Anything supported by the great oEmbed gem will work. Just supply the URL:

![youtube video](https://www.youtube.com/watch?v=oHg5SJYRHA0)

Note on IFRAMEs: Some oEmbed providers will return IFRAME-based embeds. If you want to control which hosts are allowed to have IFRAMEs on your site, override the Formatter#allowed_iframe_hosts method to return a regular expression that will be matched against the IFRAME source URL's host. Please note that this will also apply to IFRAME HTML tags added by the user directly.

Note on Twitter: Twitter's oEmbed endpoint will return a simple bit of markup that works okay out of the box, but can be expanded into a full tweet view client-side. For this to work, you'll want to add Twitter's widget.js to your application. Please refer to the Twitter documentation for full instructions.

Metadata

Slodown allows metadata, such as the creation date, to be defined in the text to be processed:

#+title: Slodown
#+created_at: 2014-03-01 13:51:12 CET
# Installation

Add this line to your application's Gemfile:

    gem 'slodown'

...

Metadata can be accessed with Slodown::Formatter#metadata:

formatter.metadata[:title] # => "Slodown"

Hints

  • If you want to add more transformations or change the behavior of the #complete method, just subclass Slodown::Formatter and go wild. :-)
  • Markdown transformations, HTML sanitizing, oEmbed handshakes and other operations are pretty expensive operations. For sake of performance (and stability), it is recommended that you cache the generated output in some manner.
  • Eat more Schnitzel. It's good for you.

TODOs

  • More/better specs. Slodown doesn't have a lot of functionality of its own, passing most of its duties over to the beautiful rendering gems it uses, but I'm sure there's still an opportunity or two for it to break, so, yeah, I should be adding some specs.
  • Better configuration for the HTML sanitizer. Right now, in order to change the sanitizing behavior, you'll need to inherit a new class from Slodown::Formatter and override its #sanitize_config method. Regarding the contents of the hash this method returns, please refer to the sanitize documentation.

Contributing

Just like with my other gems, I am trying to keep Slodown as sane (and small) as possible. If you want to contribute code, please talk to me before writing a patch or submitting a pull request! I'm serious about keeping things focused and would hate to cause unnecessary disappointment. Thank you.

If you're still set on submitting a pull request, please consider the following:

  1. Create your pull request from a feature branch.
  2. The pull request must only contain changes related to the feature.
  3. Please include specs where it makes sense.
  4. Absolutely no version bumps or similar.

Version History

0.4.0 (2017-01-13)

  • Feature: Block-level images are now rendered as a complete <figure> structure (with optional <figcaption>.)
  • Change: The Slodown sanitizer now allows <figure>, <figcaption>, <cite>, <mark>, <del> and <ins> tags by default.
  • Change: The Slodown sanitizer was stripping HTML of table tags. Tables are harmless, so they're not being stripped any longer.

0.3.0 (2016-02-22)

  • Removed the dependency on CodeRay. If you want syntax highlighting in your Markdown parsing, simply add CodeRay (or Rouge, or any other highlighter supported by kramdown) to your project.

0.2.0 (2016-02-22)

  • Slodown is now whitelisting all domains for possible iframe/embed-based media embeds by default. If you don't want this, you can override Formatter#allowed_iframe_hosts to return a regular expression that will match against the embed URL's host.
  • Bumped minimum required version of kramdown to 1.5.0 for all the nice new syntax highlighter integrations it offers (and changes required due to deprecated/changed options.)
  • Support for Twitter oEmbed (using an unfortunately deprecated API, nonetheless.)
  • Added Slodown::Formatter#kramdown_options, returning a hash of kramdown configuration options. Overload this in order to customize the formatter's behavior.

0.1.3

  • first public release

More Repositories

1

miniplex

A 👩‍💻 developer-friendly entity management system for 🕹 games and similarly demanding applications, based on 🛠 ECS architecture.
TypeScript
792
star
2

composer-suite

A suite of libraries for making game development with Three.js and React not only awesome, but so good, it would feel wrong to use anything else.
TypeScript
449
star
3

three-elements

Web Components-powered custom HTML elements for building Three.js-powered games and interactive experiences. 🎉
TypeScript
397
star
4

rbfu

Minimal Ruby version management is minimal.
Shell
118
star
5

shader-composer

80
star
6

schnitzelpress

A lean, mean blogging machine for hackers and fools.
Ruby
77
star
7

statery

Surprise-Free State Management! Designed for React with functional components, but can also be used with other frameworks (or no framework at all.)
TypeScript
71
star
8

happy

A happy little toolkit for writing web applications.
Ruby
66
star
9

pants

PANTS: Distributed Social Blogging.
Ruby
64
star
10

controlfreak

Composable Game Input.
TypeScript
57
star
11

flutterby

A flexible, Ruby-powered static site generator.
Ruby
57
star
12

timeline-composer

Compose React timelines from <Repeat>, <Delay> and <Lifetime>.
19
star
13

eventery

Super-lightweight event class implementation. 🚀
TypeScript
18
star
14

Godot-RigidBody-Auto-Scaler

Want to scale rigidbodies in Godot? Now you can. 🚀
GDScript
17
star
15

allowance

Allowance is a general-use permission management library for Ruby. It's decidedly simple, highly flexible, and has out-of-the-box support for ActiveModel-compliant classes.
Ruby
16
star
16

space-scene-sandbox

TypeScript
15
star
17

indiepants

IndiePants, aka Pants Phase 2. A clean indieweb-like implementation.
Ruby
13
star
18

hamburg-io

A hub for the Hamburg tech community.
Ruby
10
star
19

trinity

TypeScript
9
star
20

trinity-legacy

TypeScript
7
star
21

create-react-game

JavaScript
7
star
22

things

TypeScript
7
star
23

signal

TypeScript
5
star
24

react-game-starter

TypeScript
5
star
25

bigby-legacy

TypeScript
5
star
26

crankypants

A thing that does things.
Crystal
5
star
27

spacerage-one

Dumb little web-based space shootybang. (Yes, that's an actual genre.)
CoffeeScript
4
star
28

Godot-ParticlesPortal

GDScript
4
star
29

material-composer

4
star
30

three-vfx-starter

JavaScript
4
star
31

awesome-freelancing-germany

Nützliche Ressourcen für Freelancer in Deutschland.
4
star
32

supermutant

EMBRACE THE MUTATION and turn any JavaScript object into a SUPERMUTANT REACTIVE STATE CONTAINER. UUUAAAAAHHHHHHHHHHHRRRRRR
TypeScript
4
star
33

lit-shootybang

JavaScript
3
star
34

schnitzelpress-skeleton

Schnitzelpress Skeleton App. Clone/fork/download this as a base for your own Schnitzelpress powered blog.
Ruby
3
star
35

solid-trinity

TypeScript
3
star
36

spacerage.liveview

Phoenix + LiveView + three-elements = ?
Elixir
3
star
37

spacerage.6dof

Space pew pew using react-three-fiber.
TypeScript
3
star
38

fantasy-js-physics-engine

2
star
39

hmansify

Some stuff from my home directory.
Ruby
2
star
40

happy-resources

A collection of resource-focused controllers for the Happy Web Application Toolkit.
Ruby
2
star
41

ingrid

Spatial Hash Grids and not much else.
TypeScript
2
star
42

bumpy

Bumpy bumps your gem's version number.
Ruby
2
star
43

webmade.games

https://webmade.games
Astro
2
star
44

hmans_me

My blog, as seen on http://hmans.io. Powered by Flutterby.
CSS
2
star
45

randomish

TypeScript
2
star
46

render-composer

2
star
47

flutterby-website

The official website for Flutterby.
Ruby
2
star
48

indiepants-docker

Docker & Fig configuration for painless IndiePants deployment.
2
star
49

playground

A collection of experimental react-three-fiber tools and toys that aren't quite ready to be released as their own packages.
JavaScript
2
star
50

particulous

A playground for exploring patterns around CPU-based particle systems.
TypeScript
2
star
51

shadenfreude-planet

Created with CodeSandbox
TypeScript
2
star
52

bevy-mrp-macos-performance

Rust
2
star
53

panties

Command line client for #pants.
Ruby
1
star
54

happy-helpers

[Deprecated!] View helpers for your custom Rack app or framework.
Ruby
1
star
55

publicbox

Serves JSON indices of your favorite public Dropbox folders.
Ruby
1
star
56

resourcery

It's resource sorcery! Or something.
Ruby
1
star
57

imaginary

Client gem for Imaginary.
Ruby
1
star
58

happy-cli

Command line tool for the Happy web application toolkit.
Ruby
1
star
59

xml-muncher

TypeScript
1
star
60

Godot4-Node-Performance

GDScript
1
star
61

glowlayer

Experimental Glow Layer for Three.js
JavaScript
1
star
62

twotter

TWOTTER 🦆 - a little playground app for my Ruby on Rails trainings.
Ruby
1
star
63

compass-naked

An experimental Rack-only app I'm using to find the easiest way to integrate Compass with Tilt.
Ruby
1
star
64

trinity-examples

A collection of examples for (and experiments with) the Trinity framework.
JavaScript
1
star
65

schnitzel-rails-template

The Team Schnitzel Rails application template. \o/
Ruby
1
star
66

schnitzelpress-org

The source code for schnitzelpress.org.
Ruby
1
star
67

splodybox

A VFX/R3F demo
JavaScript
1
star
68

spacerage

TypeScript
1
star
69

schnitzelstyle

A tiny, light-weight, hopefully sane CSS framework with a Schnitzel flavor.
Ruby
1
star
70

hmans_net

My personal weblog, powered by SchnitzelPress (www.schnitzelpress.org)
Ruby
1
star
71

three-increments

TypeScript
1
star
72

fun-with-kittehs-presentation

Fun With Kittehs. Yeah.
1
star
73

learn-bevy-cube-of-cubes

Rust
1
star