1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-11-28 19:47:41 +03:00
vimr/VimR/MarkdownRenderer.swift

87 lines
2.5 KiB
Swift
Raw Normal View History

/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Cocoa
import RxSwift
import PureLayout
import CocoaMarkdown
2016-12-23 14:15:26 +03:00
protocol PreviewRenderer: class {
}
enum PreviewRendererAction {
2016-12-26 11:04:03 +03:00
case htmlString(renderer: PreviewRenderer, html: String, baseUrl: URL)
2016-12-23 14:15:26 +03:00
case error(renderer: PreviewRenderer)
}
2016-12-23 14:15:26 +03:00
class MarkdownRenderer: StandardFlow, PreviewRenderer {
2016-12-26 11:36:23 +03:00
fileprivate let scheduler = ConcurrentDispatchQueueScheduler(qos: .userInitiated)
2016-12-26 11:04:03 +03:00
fileprivate let baseUrl = Bundle.main.resourceURL!.appendingPathComponent("markdown")
fileprivate let extensions = Set(["md", "markdown", ])
fileprivate let template: String
override init(source: Observable<Any>) {
guard let templateUrl = Bundle.main.url(forResource: "template",
withExtension: "html",
subdirectory: "markdown")
else {
preconditionFailure("ERROR Cannot load markdown template")
}
guard let template = try? String(contentsOf: templateUrl) else {
preconditionFailure("ERROR Cannot load markdown template")
}
self.template = template
super.init(source: source)
}
fileprivate func filledTemplate(body: String, title: String) -> String {
return self.template
.replacingOccurrences(of: "{{ title }}", with: title)
.replacingOccurrences(of: "{{ body }}", with: body)
}
2016-12-23 14:15:26 +03:00
fileprivate func canRender(fileExtension: String) -> Bool {
return extensions.contains(fileExtension)
}
override func subscription(source: Observable<Any>) -> Disposable {
return source
2016-12-26 11:36:23 +03:00
.observeOn(self.scheduler)
.filter { $0 is PreviewAction }
.map { $0 as! PreviewAction }
2016-12-23 14:15:26 +03:00
.map { action in
switch action {
2016-12-23 14:15:26 +03:00
case let .automaticRefresh(url):
return url
}
2016-12-23 14:15:26 +03:00
}
.filter { self.canRender(fileExtension: $0.pathExtension) }
.subscribe(onNext: { [unowned self] url in self.render(from: url) })
}
fileprivate func render(from url: URL) {
2016-12-26 11:04:03 +03:00
NSLog("\(#function): \(url)")
2016-12-26 12:17:01 +03:00
let doc = CMDocument(contentsOfFile: url.path, options: .sourcepos)
let renderer = CMHTMLRenderer(document: doc)
2016-12-26 11:04:03 +03:00
guard let body = renderer?.render() else {
self.publish(event: PreviewRendererAction.error)
return
}
2016-12-26 11:04:03 +03:00
let html = filledTemplate(body: body, title: url.lastPathComponent)
try? html.write(toFile: "/tmp/markdown-preview.html", atomically: false, encoding: .utf8)
self.publish(event: PreviewRendererAction.htmlString(renderer: self, html: html, baseUrl: self.baseUrl))
}
}