Skip to content

Instantly share code, notes, and snippets.

@sonsongithub
Created September 23, 2015 09:19
Show Gist options
  • Save sonsongithub/bca9ffa733f21460e297 to your computer and use it in GitHub Desktop.
Save sonsongithub/bca9ffa733f21460e297 to your computer and use it in GitHub Desktop.
very simple, reddit markdown parser
//
// RedditParser.swift
// redditParser
//
// Created by sonson on 2015/09/22.
// Copyright © 2015年 sonson. All rights reserved.
//
import Foundation
let regex = try! NSRegularExpression(pattern: "(\\n{0,1}\\s*\\*\\s)|(~~([^\\s]+?)~~)|(\\*\\*([^\\s^\\*]+?)\\*\\*)|(\\*([^\\s^\\*]+?)\\*)|(\\[(.+)\\]\\(([%!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~]+)\\))|(\\^([^\\s\\^]+))|(https{0,1}://[%!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~]+)", options: NSRegularExpressionOptions.CaseInsensitive)
let parser = NSAttributedStringMarkdownParser()
public enum Attribute {
case Link(String, Int, Int)
case Bold(Int, Int)
case Italic(Int, Int)
case Superscript(Int, Int)
case Strike(Int, Int)
}
extension String {
func redditParse() -> String {
let casted = self as NSString
let copied:NSMutableString = (self as NSString).mutableCopy() as! NSMutableString
let results = regex.matchesInString(self, options: NSMatchingOptions(), range:NSMakeRange(0, casted.length))
// for result in results {
//// for i in 0...(result.numberOfRanges-1) {
//// print((self as NSString).substringWithRange(result.rangeAtIndex(0)))
//// }
// }
results.reverse().forEach { (result) -> () in
if result.rangeAtIndex(1).length > 0 {
// *
let r = NSMakeRange(result.rangeAtIndex(1).location, result.rangeAtIndex(1).length)
copied.replaceCharactersInRange(r, withString: "\n・")
}
if result.rangeAtIndex(2).length > 0 {
// ~~ ~~
let r1 = NSMakeRange(result.rangeAtIndex(2).location, result.rangeAtIndex(2).length)
let r2 = NSMakeRange(result.rangeAtIndex(3).location, result.rangeAtIndex(3).length)
let sub = copied.substringWithRange(r2)
copied.replaceCharactersInRange(r1, withString: sub)
}
if result.rangeAtIndex(4).length > 0 {
// * *
let r1 = NSMakeRange(result.rangeAtIndex(4).location, result.rangeAtIndex(4).length)
let r2 = NSMakeRange(result.rangeAtIndex(5).location, result.rangeAtIndex(5).length)
let sub = copied.substringWithRange(r2)
copied.replaceCharactersInRange(r1, withString: sub)
}
if result.rangeAtIndex(6).length > 0 {
// []()
let r1 = NSMakeRange(result.rangeAtIndex(6).location, result.rangeAtIndex(6).length)
let rangeOfTitle = NSMakeRange(result.rangeAtIndex(7).location, result.rangeAtIndex(7).length)
let rangeOfLink = NSMakeRange(result.rangeAtIndex(8).location, result.rangeAtIndex(8).length)
let title = copied.substringWithRange(rangeOfTitle)
let url = copied.substringWithRange(rangeOfLink)
copied.replaceCharactersInRange(r1, withString: "<a href=\(url)>\(title)</a>")
// copied.replaceCharactersInRange(r1, withString: sub)
}
if result.rangeAtIndex(9).length > 0 {
// ^
let r1 = NSMakeRange(result.rangeAtIndex(9).location, result.rangeAtIndex(9).length)
let r2 = NSMakeRange(result.rangeAtIndex(10).location, result.rangeAtIndex(10).length)
let sub = copied.substringWithRange(r2)
copied.replaceCharactersInRange(r1, withString: "^^^\(sub)")
}
if result.rangeAtIndex(11).length > 0 {
// ^
let r1 = NSMakeRange(result.rangeAtIndex(11).location, result.rangeAtIndex(11).length)
let r2 = NSMakeRange(result.rangeAtIndex(11).location, result.rangeAtIndex(11).length)
let sub = copied.substringWithRange(r2)
copied.replaceCharactersInRange(r1, withString: "<a href=\(sub)>\(sub)</a>")
}
}
return copied as String
}
func redditParse3() -> String {
// NSAttributedStringMarkdownParser* parser = [[NSAttributedStringMarkdownParser alloc] init];
// NSAttributedString* string = [parser attributedStringFromMarkdownString:
// @"This is __rad__."];
// let attr = parser.attributedStringFromMarkdownString(self)
let str = NSString.convert(self as String)
return str
}
func redditParse2() -> String {
let casted = self as NSString
let copied:NSMutableString = (self as NSString).mutableCopy() as! NSMutableString
let results = regex.matchesInString(self, options: NSMatchingOptions(), range:NSMakeRange(0, casted.length))
var buf = ""
var pointer = 0
var attrs = [Attribute]()
results.forEach { (result) -> () in
if result.rangeAtIndex(1).length > 0 {
if result.rangeAtIndex(1).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(1).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
buf.appendContentsOf("\n・")
pointer = (result.rangeAtIndex(1).location + result.rangeAtIndex(1).length)
}
if result.rangeAtIndex(2).length > 0 {
if result.rangeAtIndex(2).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(2).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
// ~~ ~~
let r2 = NSMakeRange(result.rangeAtIndex(3).location, result.rangeAtIndex(3).length)
let sub = copied.substringWithRange(r2)
buf.appendContentsOf(sub)
attrs.append(Attribute.Strike(buf.characters.count - sub.characters.count, sub.characters.count))
pointer = (result.rangeAtIndex(2).location + result.rangeAtIndex(2).length)
}
if result.rangeAtIndex(4).length > 0 {
if result.rangeAtIndex(4).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(4).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
// * *
let r2 = NSMakeRange(result.rangeAtIndex(5).location, result.rangeAtIndex(5).length)
let sub = copied.substringWithRange(r2)
buf.appendContentsOf(sub)
attrs.append(Attribute.Bold(buf.characters.count - result.rangeAtIndex(5).length, result.rangeAtIndex(5).length))
pointer = (result.rangeAtIndex(4).location + result.rangeAtIndex(4).length)
}
if result.rangeAtIndex(6).length > 0 {
if result.rangeAtIndex(6).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(6).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
// * *
let r2 = NSMakeRange(result.rangeAtIndex(7).location, result.rangeAtIndex(7).length)
let sub = copied.substringWithRange(r2)
buf.appendContentsOf(sub)
attrs.append(Attribute.Italic(buf.characters.count - result.rangeAtIndex(7).length, result.rangeAtIndex(7).length))
pointer = (result.rangeAtIndex(6).location + result.rangeAtIndex(6).length)
}
if result.rangeAtIndex(8).length > 0 {
if result.rangeAtIndex(8).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(8).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
let rangeOfTitle = NSMakeRange(result.rangeAtIndex(9).location, result.rangeAtIndex(9).length)
let rangeOfLink = NSMakeRange(result.rangeAtIndex(10).location, result.rangeAtIndex(10).length)
let title = copied.substringWithRange(rangeOfTitle)
let url = copied.substringWithRange(rangeOfLink)
buf.appendContentsOf(title)
attrs.append(Attribute.Link(url, buf.characters.count - title.characters.count, title.characters.count))
pointer = (result.rangeAtIndex(8).location + result.rangeAtIndex(8).length)
}
if result.rangeAtIndex(11).length > 0 {
if result.rangeAtIndex(11).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(11).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
// ^
let r2 = NSMakeRange(result.rangeAtIndex(12).location, result.rangeAtIndex(12).length)
let sub = copied.substringWithRange(r2)
buf.appendContentsOf(sub)
attrs.append(Attribute.Superscript(buf.characters.count - sub.characters.count, sub.characters.count))
pointer = (result.rangeAtIndex(11).location + result.rangeAtIndex(11).length)
}
if result.rangeAtIndex(13).length > 0 {
if result.rangeAtIndex(13).location - pointer > 0 {
let r0 = NSMakeRange(pointer, result.rangeAtIndex(13).location - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
// ^
let r2 = NSMakeRange(result.rangeAtIndex(13).location, result.rangeAtIndex(13).length)
let sub = copied.substringWithRange(r2)
buf.appendContentsOf(sub)
attrs.append(Attribute.Link(sub, buf.characters.count - sub.characters.count, sub.characters.count))
pointer = (result.rangeAtIndex(13).location + result.rangeAtIndex(13).length)
}
}
if copied.length - pointer > 0 {
let r0 = NSMakeRange(pointer, copied.length - pointer)
buf.appendContentsOf(copied.substringWithRange(r0))
}
attrs.forEach { print($0) }
print(buf.characters.count)
return buf as String
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment