{"id":15025401,"url":"https://github.com/johnxnguyen/down","last_synced_at":"2025-05-14T19:09:38.037Z","repository":{"id":37382449,"uuid":"59919932","full_name":"johnxnguyen/Down","owner":"johnxnguyen","description":"Blazing fast Markdown / CommonMark rendering in Swift, built upon cmark.","archived":false,"fork":false,"pushed_at":"2023-07-15T08:03:25.000Z","size":19670,"stargazers_count":2376,"open_issues_count":42,"forks_count":346,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-05-14T19:09:33.915Z","etag":null,"topics":["ast","cmark","commonmark","html","ios","mac","macos","markdown","parsing","swift","tvos"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnxnguyen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-05-29T00:28:59.000Z","updated_at":"2025-05-13T12:27:34.000Z","dependencies_parsed_at":"2022-08-03T06:00:54.864Z","dependency_job_id":"c371ed36-4e1a-43de-b223-860c91fd069c","html_url":"https://github.com/johnxnguyen/Down","commit_stats":{"total_commits":204,"total_committers":47,"mean_commits":4.340425531914893,"dds":0.7107843137254901,"last_synced_commit":"e754ab1c80920dd51a8e08290c912ac1c2ac8b58"},"previous_names":["iwasrobbed/down"],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnxnguyen%2FDown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnxnguyen%2FDown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnxnguyen%2FDown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnxnguyen%2FDown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnxnguyen","download_url":"https://codeload.github.com/johnxnguyen/Down/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","cmark","commonmark","html","ios","mac","macos","markdown","parsing","swift","tvos"],"created_at":"2024-09-24T20:02:17.202Z","updated_at":"2025-05-14T19:09:35.545Z","avatar_url":"https://github.com/johnxnguyen.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Down\n[![Build Status](https://travis-ci.com/johnxnguyen/Down.svg?branch=master)](https://travis-ci.com/johnxnguyen/Down)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/johnxnguyen/Down/blob/master/LICENSE)\n[![CocoaPods](https://img.shields.io/cocoapods/v/Down)](https://cocoapods.org/pods/Down)\n[![Swift 5](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)\n[![macOS](https://img.shields.io/badge/OS-macOS-orange.svg)](https://developer.apple.com/macos/)\n[![iOS](https://img.shields.io/badge/OS-iOS-orange.svg)](https://developer.apple.com/ios/)\n[![tvOS](https://img.shields.io/badge/OS-tvOS-orange.svg)](https://developer.apple.com/tvos/)\n[![Linux](https://img.shields.io/badge/OS-Linux-orange.svg)](https://www.linux.org/)\n[![Code Coverage](https://codecov.io/gh/johnxnguyen/Down/branch/master/graph/badge.svg)](https://codecov.io/gh/johnxnguyen/Down)\n\nBlazing fast Markdown (CommonMark) rendering in Swift, built upon [cmark v0.29.0](https://github.com/commonmark/cmark).\n\nIs your app using it? [Let us know!](mailto:polyxo@protonmail.com)\n\nIf you're looking for `iwasrobbed/Down`, you found it! [Rob Phillips](https://github.com/iwasrobbed), the originator of this repository,\nhas transferred it to me as I will be the primary maintainer from now on. Thanks to Rob for bringing Down as far as it has come and for\nentrusting me with its care.\n\nAll existing references to `iwasrobbed/Down` should redirect to this repository. However, It is recommended to update those urls to point\nto this repository.\n\n#### Maintainers\n\n- [John Nguyen](https://github.com/johnxnguyen)\n- [Rob Phillips](https://github.com/iwasrobbed)\n- [Keaton Burleson](https://github.com/128keaton)\n- [phoney](https://github.com/phoney)\n- [Tony Arnold](https://github.com/tonyarnold)\n- [Ken Harris](https://github.com/kengruven)\n- [Chris Zielinski](https://github.com/chriszielinski)\n- [Other contributors](https://github.com/johnxnguyen/Down/graphs/contributors) 🙌\n\n### Installation\n\nNote: Swift support is summarized in the table below.\n\n|Swift Version|Tag|\n| --- | --- |\n| Swift 5.1 | \u003e= 0.9.0 |\n| Swift 5.0 | \u003e= 0.8.1 |\n| Swift 4 | \u003e= 0.4.x |\n| Swift 3 | 0.3.x |\n\n now on the `master` branch and any tag \u003e= 0.8.1 (Swift 4 is \u003e= 0.4.x, Swift 3 is 0.3.x)\n\n#### Quickly install using [CocoaPods](https://cocoapods.org):\n\n```ruby\npod 'Down'\n```\n\n#### Install using [Carthage](https://github.com/Carthage/Carthage):\n\n```\ngithub \"johnxnguyen/Down\"\n```\nDue to limitations in Carthage regarding platform specification, you need to define the platform with Carthage.\n\ne.g.\n\n```carthage update --platform iOS```\n\n#### Install using [Swift Package Manager](https://github.com/apple/swift-package-manager):\n\nTo add *Down* to your project, select `File → Swift Packages → Add Package Dependency` and enter the GitHub URL for *Down*. \nSee [Adding Package Dependencies to Your App](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) for detailed instructions.\n\n#### Or manually install:\n\n1. Clone this repository\n2. Drag and drop the Down project into your workspace file, adding the framework in the embedded framework section\n2. Build and run your app\n4. ?\n5. Profit\n\n### Robust Performance\n\n\u003e[cmark](https://github.com/commonmark/cmark) can render a Markdown version of War and Peace in the blink of an eye (127 milliseconds on a ten year old laptop, vs. 100-400 milliseconds for an eye blink). In our [benchmarks](https://github.com/commonmark/cmark/blob/master/benchmarks.md), cmark is 10,000 times faster than the original Markdown.pl, and on par with the very fastest available Markdown processors.\n\n\u003e The library has been extensively fuzz-tested using [american fuzzy lop](http://lcamtuf.coredump.cx/afl). The test suite includes pathological cases that bring many other Markdown parsers to a crawl (for example, thousands-deep nested bracketed text or block quotes).\n\n### Output Formats\n* Web View (see DownView class)\n* HTML\n* XML\n* LaTeX\n* groff man\n* CommonMark Markdown\n* NSAttributedString\n* AST (abstract syntax tree)\n\n### View Rendering\n\nThe `DownView` class offers a very simple way to parse a UTF-8 encoded string with Markdown and convert it to a web view that can be added to any view:\n\n```swift\nlet downView = try? DownView(frame: self.view.bounds, markdownString: \"**Oh Hai**\") {\n    // Optional callback for loading finished\n}\n// Now add to view or constrain w/ Autolayout\n// Or you could optionally update the contents at some point:\ntry? downView?.update(markdownString:  \"## [Google](https://google.com)\") {\n    // Optional callback for loading finished\n}\n```\n\nMeta example of rendering this README:\n\n![Example gif](Images/ohhai.gif)\n\n### Parsing API\n\nThe `Down` struct has everything you need if you just want out-of-the-box setup for parsing and conversion.\n\n```swift\nlet down = Down(markdownString: \"## [Down](https://github.com/johnxnguyen/Down)\")\n\n// Convert to HTML\nlet html = try? down.toHTML()\n// \"\u003ch2\u003e\u003ca href=\\\"https://github.com/johnxnguyen/Down\\\"\u003eDown\u003c/a\u003e\u003c/h2\u003e\\n\"\n\n// Convert to XML\nlet xml = try? down.toXML()\n// \"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\\n\u003c!DOCTYPE document SYSTEM \\\"CommonMark.dtd\\\"\u003e\\n\u003cdocument xmlns=\\\"http://commonmark.org/xml/1.0\\\"\u003e\\n  \u003cheading level=\\\"2\\\"\u003e\\n    \u003clink destination=\\\"https://github.com/johnxnguyen/Down\\\" title=\\\"\\\"\u003e\\n      \u003ctext\u003eDown\u003c/text\u003e\\n    \u003c/link\u003e\\n  \u003c/heading\u003e\\n\u003c/document\u003e\\n\"\n\n// Convert to groff man\nlet man = try? down.toGroff()\n// \".SS\\nDown (https://github.com/johnxnguyen/Down)\\n\"\n\n// Convert to LaTeX\nlet latex = try? down.toLaTeX()\n// \"\\\\subsection{\\\\href{https://github.com/johnxnguyen/Down}{Down}}\\n\"\n\n// Convert to CommonMark Markdown\nlet commonMark = try? down.toCommonMark()\n// \"## [Down](https://github.com/johnxnguyen/Down)\\n\"\n\n// Convert to an attributed string\nlet attributedString = try? down.toAttributedString()\n// NSAttributedString representation of the rendered HTML;\n// by default, uses a stylesheet that matches NSAttributedString's default font,\n// but you can override this by passing in your own, using the 'stylesheet:' parameter.\n\n// Convert to abstract syntax tree\nlet ast = try? down.toAST()\n// Returns pointer to AST that you can manipulate\n\n```\n\n### Rendering Granularity\n\nIf you'd like more granularity for the output types you want to support, you can create your own struct conforming to at least one of the renderable protocols:\n\n* DownHTMLRenderable\n* DownXMLRenderable\n* DownLaTeXRenderable\n* DownGroffRenderable\n* DownCommonMarkRenderable\n* DownASTRenderable\n* DownAttributedStringRenderable\n\nExample:\n\n```swift\npublic struct MarkdownToHTML: DownHTMLRenderable {\n    /**\n     A string containing CommonMark Markdown\n    */\n    public var markdownString: String\n\n    /**\n     Initializes the container with a CommonMark Markdown string which can then be rendered as HTML using `toHTML()`\n\n     - parameter markdownString: A string containing CommonMark Markdown\n\n     - returns: An instance of Self\n     */\n    @warn_unused_result\n    public init(markdownString: String) {\n        self.markdownString = markdownString\n    }\n}\n```\n\n### Configuration of `DownView`\n\n`DownView` can be configured with a custom bundle using your own HTML / CSS or to do things like supporting\nDynamic Type or custom fonts, etc. It's completely configurable.\n\nThis option can be found in [DownView's instantiation function](https://github.com/johnxnguyen/Down/blob/master/Source/Views/DownView.swift#L26).\n\n##### Prevent zoom\n\nThe default implementation of the `DownView` allows for zooming in the rendered content. If you want to disable this, then you’ll need to instantiate the `DownView` with a custom bundle where the `viewport` in `index.html` has been assigned `user-scalable=no`. More info can be found [here](https://github.com/johnxnguyen/Down/pull/30).\n\n### Options\n\nEach protocol has options that will influence either rendering or parsing:\n\n```swift\n/**\n Default options\n*/\npublic static let `default` = DownOptions(rawValue: 0)\n\n// MARK: - Rendering Options\n\n/**\n Include a `data-sourcepos` attribute on all block elements\n*/\npublic static let sourcePos = DownOptions(rawValue: 1 \u003c\u003c 1)\n\n/**\n Render `softbreak` elements as hard line breaks.\n*/\npublic static let hardBreaks = DownOptions(rawValue: 1 \u003c\u003c 2)\n\n/**\n Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,\n `file:`, and `data:`, except for `image/png`, `image/gif`,\n `image/jpeg`, or `image/webp` mime types).  Raw HTML is replaced\n by a placeholder HTML comment. Unsafe links are replaced by\n empty strings. Note that this option is provided for backwards\n compatibility, but safe mode is now the default.\n*/\npublic static let safe = DownOptions(rawValue: 1 \u003c\u003c 3)\n\n/**\n Allow raw HTML and unsafe links. Note that safe mode is now\n the default, and the unsafe option must be used if rendering\n of raw HTML and unsafe links is desired.\n*/\npublic static let unsafe = DownOptions(rawValue: 1 \u003c\u003c 17)\n\n// MARK: - Parsing Options\n\n/**\n Normalize tree by consolidating adjacent text nodes.\n*/\npublic static let normalize = DownOptions(rawValue: 1 \u003c\u003c 4)\n\n/**\n Validate UTF-8 in the input before parsing, replacing illegal\n sequences with the replacement character U+FFFD.\n*/\npublic static let validateUTF8 = DownOptions(rawValue: 1 \u003c\u003c 5)\n\n/**\n Convert straight quotes to curly, --- to em dashes, -- to en dashes.\n*/\npublic static let smart = DownOptions(rawValue: 1 \u003c\u003c 6)\n\n/**\n Combine smart typography with HTML rendering.\n*/\npublic static let smartUnsaFe = DownOptions(rawValue: (1 \u003c\u003c 17) + (1 \u003c\u003c 6))\n```\n\n### Supports\nSwift; iOS 9+, tvOS 9+, macOS 10.11+\n\n### Markdown Specification\n\nDown is built upon the [CommonMark](http://commonmark.org) specification.\n\n### A little help from my friends\nPlease feel free to fork and create a pull request for bug fixes or improvements, being sure to maintain the general coding style, adding tests, and adding comments as necessary.\n\n### Credit\nThis library is a wrapper around [cmark](https://github.com/commonmark/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.\n\n[cmark](https://github.com/commonmark/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/commonmark/cmark/blob/master/COPYING).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnxnguyen%2Fdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnxnguyen%2Fdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnxnguyen%2Fdown/lists"}