Skip to content

Commit

Permalink
Merge pull request #13 from vapor-community/3
Browse files Browse the repository at this point in the history
Leaf Markdown 3
  • Loading branch information
0xTim authored Nov 17, 2020
2 parents 4fc2837 + c94b507 commit 20c8213
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 101 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ coverage:
range: "0...100"
ignore:
- "Tests/"
- ".build/"
13 changes: 8 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
name: CI
on:
- push
push:
branches:
- master
pull_request:
jobs:
xenial:
container:
image: vapor/swift:5.1-xenial
image: vapor/swift:5.2-xenial
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- run: swift test --enable-test-discovery --enable-code-coverage
bionic:
container:
image: vapor/swift:5.1-bionic
image: vapor/swift:5.2-bionic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Run Bionic Tests
run: swift test --enable-test-discovery --enable-code-coverage
- name: Setup container for codecov upload
run: apt-get update && apt-get install curl
run: apt-get update && apt-get install -y curl
- name: Process coverage file
run: llvm-cov show .build/x86_64-unknown-linux/debug/LeafMarkdownPackageTests.xctest -instr-profile=.build/x86_64-unknown-linux/debug/codecov/default.profdata > coverage.txt
run: llvm-cov show .build/x86_64-unknown-linux-gnu/debug/LeafMarkdownPackageTests.xctest -instr-profile=.build/debug/codecov/default.profdata > coverage.txt
- name: Upload code coverage
uses: codecov/codecov-action@v1
with:
Expand Down
20 changes: 14 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
// swift-tools-version:5.1
// swift-tools-version:5.2

import PackageDescription

let package = Package(
name: "LeafMarkdown",
platforms: [
.macOS(.v10_15)
],
products: [
.library(name: "LeafMarkdown", targets: ["LeafMarkdown"]),
],
dependencies: [
.package(url: "https://github.com/vapor/template-kit.git", from: "1.4.0"),
.package(url: "https://github.com/vapor-community/markdown.git", from: "0.6.1"),
.package(url: "https://github.com/vapor/leaf.git", from: "3.0.0"),
.package(name: "SwiftMarkdown", url: "https://github.com/vapor-community/markdown.git", from: "0.6.1"),
.package(url: "https://github.com/vapor/leaf-kit.git", from: "1.0.0"),
],
targets: [
.target(name: "LeafMarkdown", dependencies: ["TemplateKit", "SwiftMarkdown"]),
.testTarget(name: "LeafMarkdownTests", dependencies: ["LeafMarkdown", "Leaf"]),
.target(name: "LeafMarkdown", dependencies: [
.product(name: "LeafKit", package: "leaf-kit"),
.product(name: "SwiftMarkdown", package: "SwiftMarkdown"),
]),
.testTarget(name: "LeafMarkdownTests", dependencies: [
.target(name: "LeafMarkdown"),
.product(name: "LeafKit", package: "leaf-kit"),
]),
]
)
19 changes: 0 additions & 19 deletions [email protected]

This file was deleted.

34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Leaf Markdown

[![Language](https://img.shields.io/badge/Swift-5.1-brightgreen.svg)](http://swift.org)
[![Build Status](https://github.com/vapor-community/leaf-markdown/workflows/CI/badge.svg?branch=master)](https://github.com/vapor-community/leaf-markdown/actions)
[![codecov](https://codecov.io/gh/vapor-community/leaf-markdown/branch/master/graph/badge.svg)](https://codecov.io/gh/vapor-community/leaf-markdown)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/vapor-community/leaf-markdown/master/LICENSE)
[![Language](https://img.shields.io/badge/Swift-5.2-brightgreen.svg)](http://swift.org)
[![Build Status](https://github.com/vapor-community/leaf-markdown/workflows/CI/badge.svg?branch=main)](https://github.com/vapor-community/leaf-markdown/actions)
[![codecov](https://codecov.io/gh/vapor-community/leaf-markdown/branch/main/graph/badge.svg)](https://codecov.io/gh/vapor-community/leaf-markdown)
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/vapor-community/leaf-markdown/main/LICENSE)

A Markdown renderer for Vapor and Leaf. This uses the [Vapor Markdown](https://github.com/vapor/markdown) package to wrap [cmark](https://github.com/jgm/cmark) (though a [fork](https://github.com/brokenhandsio/cmark-gfm) is used to make it work with Swift PM), so it understands [Common Mark](http://commonmark.org). A quick reference guide for Common Mark can be found [here](http://commonmark.org/help/). It also supports [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/).
A Markdown renderer for Vapor and Leaf. This uses the [Vapor Markdown](https://github.com/vapor/markdown) package to wrap [cmark](https://github.com/github/cmark-gfm) (though a [fork](https://github.com/brokenhandsio/cmark-gfm) is used to make it work with Swift PM), so it understands [Common Mark](http://commonmark.org). A quick reference guide for Common Mark can be found [here](http://commonmark.org/help/). It also supports [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/).

## Usage

Expand All @@ -32,21 +32,29 @@ Add Leaf Markdown as a dependency in your `Package.swift` file:
```swift
dependencies: [
...,
.package(url: "https://github.com/vapor-community/leaf-markdown.git", .upToNextMajor(from: "2.0.0"))
.package(name: "LeafMarkdown", url: "https://github.com/vapor-community/leaf-markdown.git", .upToNextMajor(from: "3.0.0")),
]
```

Then add the dependency to your target:

```swift
.target(
name: "App",
dependencies: [
// ...
"LeafMarkdown"
],
// ...
)
```

### Register with Leaf

To add the tag to Leaf, add it to your `LeafTagConfig`:
Register the tag with Leaf so Leaf knows about it:

```swift
try services.register(LeafProvider())
var tags = LeafTagConfig.default()
tags.use(Markdown(), as: "markdown")
services.register(tags)
app.leaf.tags["markdown"] = Markdown()
```

**Note:** it's important that you register the `LeafProvider` first otherwise this will override your `LeafTagConfig`.

Don't forget to import LeafMarkdown in the file you register the tag with `import LeafMarkdown`.
42 changes: 17 additions & 25 deletions Sources/LeafMarkdown/Tag.swift
Original file line number Diff line number Diff line change
@@ -1,42 +1,34 @@
import TemplateKit
import LeafKit
import SwiftMarkdown

public final class Markdown: TagRenderer {

public struct Markdown: LeafTag {
public enum Error: Swift.Error {
case invalidArgument(TemplateData?)
case invalidArgument(LeafData?)
}

public let name = "markdown"


private let options: MarkdownOptions?

public init(options: MarkdownOptions? = nil) {
self.options = options
}

public func render(tag: TagContext) throws -> Future<TemplateData> {


public func render(_ ctx: LeafContext) throws -> LeafData {
var markdown = ""

if let markdownArgument = tag.parameters.first, !markdownArgument.isNull {
if let markdownArgument = ctx.parameters.first, !markdownArgument.isNil {
guard let markdownArgumentValue = markdownArgument.string else {
throw Error.invalidArgument(tag.parameters.first)
throw Error.invalidArgument(ctx.parameters.first)
}
markdown = markdownArgumentValue
}

let markdownHTML: String = try {
if let options = options {
return try markdownToHTML(markdown, options: options)
} else {
return try markdownToHTML(markdown)
}
}()

return Future.map(on: tag) {
.string(markdownHTML)
let markdownHTML: String
if let options = options {
markdownHTML = try markdownToHTML(markdown, options: options)
} else {
markdownHTML = try markdownToHTML(markdown)
}
}

return .string(markdownHTML)
}
}
63 changes: 30 additions & 33 deletions Tests/LeafMarkdownTests/LeafTests.swift
Original file line number Diff line number Diff line change
@@ -1,73 +1,70 @@
import XCTest
@testable import Leaf
@testable import LeafKit
import LeafMarkdown
import NIO

class LeafTests: XCTestCase {

class MarkdownTests: XCTestCase {
// MARK: - Properties

var renderer: LeafRenderer!
let template = "#markdown(data)"
var ast: [Syntax]!
var markdownTag: Markdown!

// MARK: - Overrides

override func setUp() {
let queue = EmbeddedEventLoop()
let container = BasicContainer(config: .init(), environment: .testing, services: .init(), on: queue)
let tag = Markdown()
var leafTagConfig = LeafTagConfig.default()
leafTagConfig.use(tag, as: tag.name)
self.renderer = LeafRenderer(config: LeafConfig(tags: leafTagConfig, viewsDir: "", shouldCache: false), using: container)
override func setUpWithError() throws {
var lexer = LeafLexer(name: "markdowntest", template: "#markdown(data)")
let tokens = try lexer.lex()
var parser = LeafParser(name: "markdowntest", tokens: tokens)
ast = try parser.parse()
markdownTag = Markdown()
}

// MARK: - Helper
func render(context: [String: LeafData]) throws -> String {
var serializer = LeafSerializer(
ast: ast,
context: context,
tags: ["markdown": markdownTag]
)
let view = try serializer.serialize()
return view.getString(at: view.readerIndex, length: view.readableBytes) ?? ""
}

// MARK: - Tests

func testRunTag() throws {
let inputMarkdown = "# This is a test\n\nWe have some text in a tag"
let data = TemplateData.dictionary(["data": .string(inputMarkdown)])
let expectedHtml = "<h1>This is a test</h1>\n<p>We have some text in a tag</p>\n"

let result = try renderer.render(template: template.data(using: .utf8)!, data).wait()
let resultString = String(data: result.data, encoding: .utf8)!
let resultString = try render(context: ["data": .string(inputMarkdown)])
XCTAssertEqual(resultString, expectedHtml)
}

func testNilParameterDoesNotCrashLeaf() throws {
let data = TemplateData.dictionary(["data": .null])
let expectedHtml = ""

let result = try renderer.render(template: template.data(using: .utf8)!, data).wait()
let resultString = String(data: result.data, encoding: .utf8)!
let resultString = try render(context: ["data": .trueNil])
XCTAssertEqual(resultString, expectedHtml)
}

func testStripHtml() throws {
let inputMarkdown = "<br>"
let data = TemplateData.dictionary(["data": .string(inputMarkdown)])
let expectedHtml = "<!-- raw HTML omitted -->\n"

let result = try renderer.render(template: template.data(using: .utf8)!, data).wait()
let resultString = String(data: result.data, encoding: .utf8)!
let resultString = try render(context: ["data": .string(inputMarkdown)])
XCTAssertEqual(resultString, expectedHtml)
}

func testRejectBadData() throws {
XCTAssertThrowsError(try render(context: ["data": .dictionary(["something": .string("somethingelese")])]))
}

func testDoNotStripHtml() throws {

let queue = EmbeddedEventLoop()
let container = BasicContainer(config: .init(), environment: .testing, services: .init(), on: queue)
let tag = Markdown(options: [.unsafe])
var leafTagConfig = LeafTagConfig.default()
leafTagConfig.use(tag, as: tag.name)
let renderer = LeafRenderer(config: LeafConfig(tags: leafTagConfig, viewsDir: "", shouldCache: false),
using: container)
markdownTag = Markdown(options: [.unsafe])

let inputMarkdown = "<br>"
let data = TemplateData.dictionary(["data": .string(inputMarkdown)])
let expectedHtml = "<br>\n"

let result = try renderer.render(template: template.data(using: .utf8)!, data).wait()
let resultString = String(data: result.data, encoding: .utf8)!
let resultString = try render(context: ["data": .string(inputMarkdown)])
XCTAssertEqual(resultString, expectedHtml)
}
}

0 comments on commit 20c8213

Please sign in to comment.