{"id":20059978,"url":"https://github.com/chrisdhaan/cdmarkdownkit","last_synced_at":"2025-04-06T20:10:19.919Z","repository":{"id":40696228,"uuid":"73038312","full_name":"chrisdhaan/CDMarkdownKit","owner":"chrisdhaan","description":"An extensive Swift framework providing simple and customizable markdown parsing.","archived":false,"fork":false,"pushed_at":"2023-07-17T12:40:46.000Z","size":373,"stargazers_count":259,"open_issues_count":15,"forks_count":66,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-30T18:08:30.674Z","etag":null,"topics":["carthage","cocoapods","ios","label","macos","markdown","swift","swift-package-manager","textview","tvos","watchos","xcode"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisdhaan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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-11-07T03:17:10.000Z","updated_at":"2025-03-05T07:46:07.000Z","dependencies_parsed_at":"2022-07-21T21:18:57.805Z","dependency_job_id":"386182f7-c7e0-4b3b-934c-d4fa8630d9b6","html_url":"https://github.com/chrisdhaan/CDMarkdownKit","commit_stats":{"total_commits":68,"total_committers":3,"mean_commits":"22.666666666666668","dds":0.02941176470588236,"last_synced_commit":"b08981016f9406eb6d18150a3c8caa4288983d2e"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisdhaan%2FCDMarkdownKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisdhaan%2FCDMarkdownKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisdhaan%2FCDMarkdownKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisdhaan%2FCDMarkdownKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisdhaan","download_url":"https://codeload.github.com/chrisdhaan/CDMarkdownKit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247543591,"owners_count":20955865,"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":["carthage","cocoapods","ios","label","macos","markdown","swift","swift-package-manager","textview","tvos","watchos","xcode"],"created_at":"2024-11-13T13:11:24.550Z","updated_at":"2025-04-06T20:10:19.898Z","avatar_url":"https://github.com/chrisdhaan.png","language":"Swift","readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/chrisdhaan/CDMarkdownKit\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/chrisdhaan/CDMarkdownKit/master/Documentation/cdmarkdownkit.png\" alt=\"CDMarkdownKit\" width=\"850\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/chrisdhaan/CDMarkdownKit\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/chrisdhaan/CDMarkdownKit/master/Documentation/github.png\" alt=\"Star CDMarkdownKit On Github\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://stackoverflow.com/questions/tagged/cdmarkdownkit\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/chrisdhaan/CDMarkdownKit/master/Documentation/stackoverflow.png\" alt=\"Stack Overflow\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/chrisdhaan/CDMarkdownKit/actions/workflows/ci.yml\"\u003e\n        \u003cimg src=\"https://github.com/chrisdhaan/CDMarkdownKit/actions/workflows/ci.yml/badge.svg\" alt=\"CI Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/chrisdhaan/CDMarkdownKit/releases\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/release/chrisdhaan/CDMarkdownKit.svg\" alt=\"GitHub Release\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.swift.org\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Swift-5.3_5.4_5.5_5.6_5.7-orange?style=flat\" alt=\"Swift Versions\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://cocoapods.org/pods/CDMarkdownKit\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/p/CDMarkdownKit.svg?style=flat\" alt=\"Platforms\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://cocoapods.org/pods/CDMarkdownKit\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/v/CDMarkdownKit.svg?style=flat\" alt=\"CocoaPods Compatible\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\" alt=\"Carthage compatible\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.swift.org/package-manager\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat\" alt=\"Swift Package Manager Compatible\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://cocoapods.org/pods/CDMarkdownKit\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/l/CDMarkdownKit.svg?style=flat\" alt=\"License\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\nThis Swift framework handles standard markdown parsing along with the ability to parse custom elements.\n\nFor a demonstration of the capabilities of CDMarkdownKit; run the iOS Example project after cloning the repo.\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Contributing](#contributing)\n- [Usage](#usage)\n    - [Initialization](#initialization)\n    - [Customization](#customization)\n    - [Supported Markdown Elements](#supported-markdown-elements)\n    - [CDMarkdownTextView](#cdmarkdowntextview)\n    - [CDMarkdownLabel](#cdmarkdownlabel)\n- [Author](#author)\n- [Credits](#credits)\n- [License](#license)\n\n---\n\n## Features\n\n- [x] Markdown Parsing\n    - [x] Italic\n    - [x] Bold\n    - [x] Header\n    - [x] Quote\n    - [x] List\n    - [x] Code\n    - [x] Syntax\n    - [x] Link\n    - [x] Image\n- [x] UITextView With Markdown Formatting\n- [x] UILabel With Markdown Formatting\n- [x] Platform Support\n  - [x] iOS\n  - [x] macOS\n  - [x] tvOS\n  - [x] watchOS\n- [x] Documentation\n\n---\n\n## Requirements\n\n- iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+\n- Swift 5.3+\n\n---\n\n## Installation\n\n### CocoaPods\n\n[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate CDMarkdownKit into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\npod 'CDMarkdownKit', '2.5.1'\n```\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate CDMarkdownKit into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"chrisdhaan/CDMarkdownKit\" == 2.5.1\n```\n\n### Swift Package Manager\n\nThe [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler.\n\nOnce you have your Swift package set up, adding CDMarkdownKit as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/chrisdhaan/CDMarkdownKit.git\", .upToNextMajor(from: \"2.5.1\"))\n]\n```\n\n### Git Submodule\n\nIf you prefer not to use any of the aforementioned dependency managers, you can integrate CDMarkdownKit into your project manually.\n\n- Open up Terminal, `cd` into your top-level project directory, and run the following command \"if\" your project is not initialized as a git repository:\n\n```bash\n$ git init\n```\n\n- Add CDMarkdownKit as a git [submodule](https://git-scm.com/docs/git-submodule) by running the following command:\n\n```git\ngit submodule add https://github.com/chrisdhaan/CDMarkdownKit.git\n```\n\n- Open the new `CDMarkdownKit` folder, and drag the `CDMarkdownKit.xcodeproj` into the Project Navigator of your application's Xcode project.\n\n    \u003e It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.\n\n- Select the `CDMarkdownKit.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target.\n- Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the \"Targets\" heading in the sidebar.\n- In the tab bar at the top of that window, open the \"General\" panel.\n- Click on the `+` button under the \"Embedded Binaries\" section.\n- You will see two different `CDMarkdownKit.xcodeproj` folders each with two different versions of the `CDMarkdownKit.framework` nested inside a `Products` folder.\n\n    \u003e It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `CDMarkdownKit.framework`.\n\n- Select the top `CDMarkdownKit.framework` for iOS and the bottom one for macOS.\n\n    \u003e You can verify which one you selected by inspecting the build log for your project. The build target for `CDMarkdownKit` will be listed as either `CDMarkdownKit iOS`, `CDMarkdownKit macOS`, `CDMarkdownKit tvOS` or `CDMarkdownKit watchOS`.\n\n- And that's it!\n\n  \u003e The `CDMarkdownKit.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.\n\n---\n\n## Contributing\n\nBefore contributing to CDMarkdownKit, please read the instructions detailed in our [contribution guide](https://github.com/chrisdhaan/CDMarkdownKit/blob/master/CONTRIBUTING.md).\n\n---\n\n## Usage\n\n### Initialization\n\n```swift\n// Create parser\nlet markdownParser = CDMarkdownParser()\n// Parse markdown\nlet markdown = \"This *framework* helps **with** parsing `markdown`.\"\nlabel.attributedText = markdownParser.parse(markdown)\n```\n\n### Customization\n\n```swift\n// Create parser\nlet markdownParser = CDMarkdownParser(font: UIFont(name: \"HelveticaNeue\", size: 16),\n                                      boldFont: UIFont(name: \"HelveticaNeue-Bold\", size: 16),\n                                      italicFont: UIFont(name: \"HelveticaNeue-Thin\", size: 16),\n                                      fontColor: UIColor.darkGray,\n                                      backgroundColor: UIColor.lightGray,\n                                      squashNewlines: false)\n// Customize elements\n/// Bold\nmarkdownParser.bold.color = UIColor.cyan\nmarkdownParser.bold.backgroundColor = UIColor.purple\nmarkdownParser.bold.underlineColor = UIColor.red\nmarkdownParser.bold.underlineStyle = .double\n/// Header\nmarkdownParser.header.color = UIColor.black\nmarkdownParser.header.backgroundColor = UIColor.orange\n/// List\nmarkdownParser.list.color = UIColor.black\nmarkdownParser.list.backgroundColor = UIColor.red\n/// Quote\nmarkdownParser.quote.color = UIColor.gray\nmarkdownParser.quote.backgroundColor = UIColor.clear\n/// Link\nmarkdownParser.link.color = UIColor.blue\nmarkdownParser.link.backgroundColor = UIColor.green\nlet linkParagraphStyle = NSMutableParagraphStyle()\nlinkParagraphStyle.paragraphSpacing = 20\nlinkParagraphStyle.paragraphSpacingBefore = 0\nlinkParagraphStyle.lineSpacing = 20.38\nmarkdownParser.link.paragraphStyle = linkParagraphStyle\nmarkdownParser.automaticLink.color = UIColor.blue\nmarkdownParser.automaticLink.backgroundColor = UIColor.green\n/// Italic\nmarkdownParser.italic.color = UIColor.gray\nmarkdownParser.italic.backgroundColor = UIColor.clear\n/// Code\nmarkdownParser.code.font = UIFont.systemFont(ofSize: 17)\nmarkdownParser.code.color = UIColor.red\nmarkdownParser.code.backgroundColor = UIColor.black\n/// Syntax\nmarkdownParser.syntax.font = UIFont.systemFont(ofSize: 15)\nmarkdownParser.syntax.color = UIColor.lightGray\nmarkdownParser.syntax.backgroundColor = UIColor.black\n/// Image\nmarkdownParser.image.size = CGSize(width: 100,\n                                   height: 50)\n/// Strikethrough\nmarkdownParser.strikethrough.font = UIFont.systemFont(ofSize: 20)\nmarkdownParser.strikethrough.color = UIColor.magenta\nmarkdownParser.strikethrough.strikethroughColor = UIColor.darkGray\nmarkdownParser.strikethrough.strikethroughStyle = .double\n// Parse markdown\nlet markdown = \"This *framework* helps **with** parsing `markdown`.\"\nlabel.attributedText = markdownParser.parse(markdown)\n```\n\n### Supported Markdown Elements\n\n```\n*italic* or _italic_\n**bold** or __bold__\n\n# Header 1\n## Header 2\n### Header 3\n#### Header 4\n##### Header 5\n###### Header 6\n\n\u003e Quote\n\n* List\n- List\n+ List\n\n`code`\n\n```syntax```\n\n[Link](url)\n![Image](url)\n```\n\n### CDMarkdownTextView\n\n**It is recommended that any CDMarkdownTextView objects be initialized programmatically** as it uses custom text drawing objects to render attributed strings.\n\nA CDMarkdownTextView object will still render when initialized via a storyboard but the default behavior for the following properties will be overridden:\n\n- ```isScrollEnabled = true```\n- ```isSelectable = false```\n- ```isEditable = false```\n\n**These defaults are set to avoid crashes. There still may be unforeseen crashes that occur when initializing a CDMarkdownTextView object via a storyboard.**\n\n#### Programmatic Example\n\n```swift\nlet rect = CGRect(x: 20,\n                  y: 10,\n                  width: CGFloat(self.frame.size.width - 40),\n                  height: CGFloat(self.frame.size.height - 30))\n/// Create custom text container\nlet textContainer = NSTextContainer(size: rect.size)\n/// Create custom layout manager\nlet layoutManager = CDMarkdownLayoutManager()\nlayoutManager.addTextContainer(textContainer)\n/// Initialization\nlet textView = CDMarkdownTextView(frame: rect, \n                                  textContainer: textContainer, \n                                  layoutManager: layoutManager)\ntextView.translatesAutoresizingMaskIntoConstraints = false\n/// Standard markdown UI formatting\ntextView.roundCodeCorners = true\ntextView.roundSyntaxCorners = true\n/// Custom markdown UI formatting\ntextView.roundAllCorners = true\n/// Add constraints so intrinsic content size is set correctly\nlet topConstraint = NSLayoutConstraint(item: textView,\n                                       attribute: NSLayoutAttribute.top,\n                                       relatedBy: NSLayoutRelation.equal,\n                                       toItem: textView.superview,\n                                       attribute: NSLayoutAttribute.bottom,\n                                       multiplier: 1,\n                                       constant: 10)\nlet leadingConstraint = NSLayoutConstraint(item: textView,\n                                           attribute: NSLayoutAttribute.leading,\n                                           relatedBy: NSLayoutRelation.equal,\n                                           toItem: textView.superview,\n                                           attribute: NSLayoutAttribute.leadingMargin,\n                                           multiplier: 1,\n                                           constant: 0)\nlet trailingConstraint = NSLayoutConstraint(item: textView,\n                                            attribute: NSLayoutAttribute.trailing,\n                                            relatedBy: NSLayoutRelation.equal,\n                                            toItem: textView.superview,\n                                            attribute: NSLayoutAttribute.trailingMargin,\n                                            multiplier: 1,\n                                            constant: 0)\nlet bottomConstraint = NSLayoutConstraint(item: self.bottomLayoutGuide,\n                                          attribute: NSLayoutAttribute.top,\n                                          relatedBy: NSLayoutRelation.equal,\n                                          toItem: textView,\n                                          attribute: NSLayoutAttribute.bottom,\n                                          multiplier: 1,\n                                          constant: 20)\nself.view.addConstraints([topConstraint,\n                          leadingConstraint,\n                          trailingConstraint,\n                          bottomConstraint])\n/// Add to view hierarchy\nself.view.addSubview(textView)\n```\n\n#### Storyboard Example\n\n```swift\n/// Initialization\n@IBOutlet fileprivate weak var textView: CDMarkdownTextView!\n/// Standard markdown UI formatting\nself.textView.roundCodeCorners = true\nself.textView.roundSyntaxCorners = true\n/// Custom markdown UI formatting\nself.textView.roundAllCorners = true\n```\n\n### CDMarkdownLabel\n\n#### Programmatic Example\n\n```swift\nlet size = self.frame.size\nlet rect = CGRect(x: 10, \n                  y: 10,\n                  width: CGFloat(size.width - 20),\n                  height: CGFloat(size.height - 20))\n/// Initialization\nlet label = CDMarkdownLabel(frame: rect)\nlabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n/// Standard markdown UI formatting\nlabel.roundCodeCorners = true\nlabel.roundSyntaxCorners = true\n/// Custom markdown UI formatting\nlabel.roundAllCorners = true\n\nself.view.addSubview(label)\n```\n\n#### Storyboard Example\n\n```swift\n/// Initialization\n@IBOutlet fileprivate weak var label: CDMarkdownLabel!\n/// Standard markdown UI formatting\nself.label.roundCodeCorners = true\nself.label.roundSyntaxCorners = true\n/// Custom markdown UI formatting\nself.label.roundAllCorners = true\n```\n\n---\n\n## Author\n\nChristopher de Haan, contact@christopherdehaan.me\n\n---\n\n## Credits\n\nCDMarkdownKit was influenced by [MarkdownKit](https://github.com/ivanbruel/MarkdownKit), a markdown parsing library developed by Ivan Bruel.\n\nCDMarkdownKit adds the following functionalities:\n- Fixed header element parsing\n- Image element parsing\n- Strikethrough element parsing\n- Ability to customize font for all elements\n- Ability to customize color for all elements\n- Ability to customize background color for all elements\n- Ability to customize paragraph style for all elements\n- Ability to customize underline color style for all elements\n- Ability to customize underline style style for all elements\n- UITextView with the ability to round background text color corners for code, syntax, or all elements\n- UILabel with the ability to round background text color corners for code, syntax, or all elements\n- macOS, tvOS, and watchOS support\n\n---\n\n## License\n\nCDMarkdownKit is available under the MIT license. See the LICENSE file for more info.\n\n---\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisdhaan%2Fcdmarkdownkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisdhaan%2Fcdmarkdownkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisdhaan%2Fcdmarkdownkit/lists"}