Compare commits

..

1 Commits

Author SHA1 Message Date
Rob Phillips 156ab177d1 Xcode warnings fix 2017-05-13 09:43:14 -07:00
284 changed files with 36761 additions and 27583 deletions
@@ -1,9 +1,3 @@
---
name: Bug report
about: Help isolate and fix bugs
---
Please help prevent duplicate issues before submitting a new one:
* [ ] I've searched other open/closed issues for duplicates before opening up this new issue.
@@ -21,3 +15,5 @@ Please help prevent duplicate issues before submitting a new one:
## What happened instead?
Please replace this with what happened instead (e.g. the issue).
-23
View File
@@ -1,23 +0,0 @@
---
name: Feature request
about: Suggest an enhancement for this project
---
Please help prevent duplicate requests before submitting a new one:
* [ ] I've searched other open/closed issues for duplicates before opening up this new issue.
# Feature Request
## Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Describe the solution you'd like
A clear and concise description of what you want to happen.
## Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
-17
View File
@@ -1,17 +0,0 @@
name: SwiftLint
on:
pull_request:
paths:
- '.github/workflows/swiftlint.yml'
- '.swiftlint.yml'
- '**/*.swift'
jobs:
SwiftLint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: GitHub Action for SwiftLint
uses: norio-nomura/action-swiftlint@3.2.1
+1 -1
View File
@@ -1,9 +1,9 @@
Pods/
.build/
.DS_Store
xcuserdata
# additional ignores that will save us time
build/
*.pbxuser
!default.pbxuser
*.mode1v3
+5
View File
@@ -0,0 +1,5 @@
coverage_service: coveralls
xcodeproj: Down.xcodeproj
source_directory: Source
ignore:
- Source/cmark/*
+1
View File
@@ -0,0 +1 @@
3.0
-10
View File
@@ -1,10 +0,0 @@
included:
- Sources/Down
- Tests
large_tuple:
warning: 3
error: 4
cyclomatic_complexity:
ignores_case_statements: true
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
+7 -9
View File
@@ -1,12 +1,10 @@
osx_image: xcode12.2
osx_image: xcode8
language: objective-c
before_install:
- set -o pipefail
- xcrun simctl boot "iPhone 12" || echo "(Pre)Launched the simulator."
- gem install xcpretty slather -N
- xcrun instruments -w "iPhone 5 (9.3)" || echo "(Pre)Launched the simulator."
script:
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk iphonesimulator -destination "platform=iOS Simulator,OS=14.2,name=iPhone 12" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES -quiet test
- bash <(curl -s https://codecov.io/bash)
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk macosx -destination 'platform=OS X,arch=x86_64' -enableCodeCoverage YES -quiet test
- bash <(curl -s https://codecov.io/bash)
- travis_retry xcodebuild -project Down.xcodeproj -scheme "Down" -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV' -enableCodeCoverage YES -quiet test
- bash <(curl -s https://codecov.io/bash)
- set -o pipefail && xcodebuild -project Down.xcodeproj -scheme "Down" -destination "platform=iOS Simulator,name=iPhone 5,OS=9.3" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES test | xcpretty -c
- set -o pipefail && xcodebuild -project Down.xcodeproj -scheme "Down" -sdk macosx -destination 'platform=OS X,arch=x86_64' -enableCodeCoverage YES test | xcpretty -c
after_success:
- slather coverage --ignore "../**/*/Xcode*" --ignore "Source/cmark/*" --scheme "Down" Down.xcodeproj
+47 -568
View File
@@ -1,611 +1,90 @@
# Changelog
# Change Log
## [v0.11.0](https://github.com/johnxnguyen/Down/tree/v0.11.0) (2021-05-04)
## [v0.3.4](https://github.com/iwasrobbed/Down/tree/v0.3.4) (2017-05-13)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.3.3...v0.3.4)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.10.0...v0.11.0)
**Merged pull requests:**
- Suggested project fixes/changes [\#28](https://github.com/iwasrobbed/Down/pull/28) ([tonyarnold](https://github.com/tonyarnold))
- Add the ability to initialise a DownView using a custom template bundle [\#27](https://github.com/iwasrobbed/Down/pull/27) ([tonyarnold](https://github.com/tonyarnold))
## [v0.3.3](https://github.com/iwasrobbed/Down/tree/v0.3.3) (2017-03-09)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.3.2...v0.3.3)
**Implemented enhancements:**
- \[CodeCoverage\] Improve accuracy for combined code coverage reporting [\#205](https://github.com/johnxnguyen/Down/issues/205)
**Closed issues:**
- DownStyler not included when installed via CocoaPods [\#254](https://github.com/johnxnguyen/Down/issues/254)
- \[Commonmark\] Strikethrough not working / not supported [\#253](https://github.com/johnxnguyen/Down/issues/253)
- \[Attributed Strings\] Unordered list items with a single line appear further indented than those with multiple lines when using a custom font [\#246](https://github.com/johnxnguyen/Down/issues/246)
- Add OS X support [\#6](https://github.com/iwasrobbed/Down/issues/6)
**Merged pull requests:**
- \[Feature\] Custom list prefixes for AttributedStringVisitor [\#255](https://github.com/johnxnguyen/Down/pull/255) ([dloic](https://github.com/dloic))
- \[Chore\] Add SwiftLint [\#252](https://github.com/johnxnguyen/Down/pull/252) ([johnxnguyen](https://github.com/johnxnguyen))
- \[Chore\] Fix codecov report [\#251](https://github.com/johnxnguyen/Down/pull/251) ([johnxnguyen](https://github.com/johnxnguyen))
- \#6 macOS Support [\#25](https://github.com/iwasrobbed/Down/pull/25) ([128keaton](https://github.com/128keaton))
## [v0.10.0](https://github.com/johnxnguyen/Down/tree/v0.10.0) (2021-02-28)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.5...v0.10.0)
**Closed issues:**
- Does not build in 12.5 [\#244](https://github.com/johnxnguyen/Down/issues/244)
- \[Crash\] Missing resource bundle when using SPM [\#243](https://github.com/johnxnguyen/Down/issues/243)
**Merged pull requests:**
- \[Improvement\] Expose DownTextView's designated initializer [\#250](https://github.com/johnxnguyen/Down/pull/250) ([max-potapov](https://github.com/max-potapov))
- \[Chore\] Add arm64 as valid arch when building for simulator on M1 macs [\#249](https://github.com/johnxnguyen/Down/pull/249) ([michaelknoch](https://github.com/michaelknoch))
- \[Chore\] Reorganize project structure for SPM [\#248](https://github.com/johnxnguyen/Down/pull/248) ([johnxnguyen](https://github.com/johnxnguyen))
- \[Chore\] Use SPM to manage snapshot testing dependency [\#247](https://github.com/johnxnguyen/Down/pull/247) ([johnxnguyen](https://github.com/johnxnguyen))
## [v0.9.5](https://github.com/johnxnguyen/Down/tree/v0.9.5) (2021-02-12)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.4...v0.9.5)
**Closed issues:**
- Namespacing issues with Down "Node" type [\#242](https://github.com/johnxnguyen/Down/issues/242)
- GitHub actions build failure: `small method list` [\#238](https://github.com/johnxnguyen/Down/issues/238)
**Merged pull requests:**
- \[Fix\] Compilation failure with Xcode 12.5 and SPM [\#245](https://github.com/johnxnguyen/Down/pull/245) ([claurel](https://github.com/claurel))
- \[Chore\] Update readme [\#237](https://github.com/johnxnguyen/Down/pull/237) ([johnxnguyen](https://github.com/johnxnguyen))
## [v0.9.4](https://github.com/johnxnguyen/Down/tree/v0.9.4) (2020-10-21)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.3...v0.9.4)
## [v0.3.2](https://github.com/iwasrobbed/Down/tree/v0.3.2) (2017-02-26)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.3.1...v0.3.2)
**Implemented enhancements:**
- Create custom sequence to access child nodes [\#228](https://github.com/johnxnguyen/Down/pull/228) ([5sw](https://github.com/5sw))
- Create changelog [\#20](https://github.com/iwasrobbed/Down/issues/20)
**Closed issues:**
- DownStylerConfiguration Link Color Not Working [\#232](https://github.com/johnxnguyen/Down/issues/232)
- SwiftUI support [\#231](https://github.com/johnxnguyen/Down/issues/231)
- How to pre-calculate height needed for attributed string when using DownLayoutManager [\#226](https://github.com/johnxnguyen/Down/issues/226)
- How i can render both markdown and Latex ? [\#221](https://github.com/johnxnguyen/Down/issues/221)
- Emphasis + Strong [\#220](https://github.com/johnxnguyen/Down/issues/220)
- \[StackOverflow\] Creating a new Visitor leads to wrapping value error [\#218](https://github.com/johnxnguyen/Down/issues/218)
- 0.9.0/0.9.1 don't build with Swift 5.0.x [\#217](https://github.com/johnxnguyen/Down/issues/217)
- Unable to build Swift package in Xcode 11.4.1 [\#209](https://github.com/johnxnguyen/Down/issues/209)
- \[Feature\] Add support for Mac Catalyst [\#208](https://github.com/johnxnguyen/Down/issues/208)
- A faster substitute to NSHTMLTextDocumentType? [\#23](https://github.com/iwasrobbed/Down/issues/23)
- How to update DownView content and keep the style? [\#19](https://github.com/iwasrobbed/Down/issues/19)
**Merged pull requests:**
- \[Fix\] DownTextView renders incorrect link color [\#233](https://github.com/johnxnguyen/Down/pull/233) ([johnxnguyen](https://github.com/johnxnguyen))
- Added instructions for using the Swift Package Manager [\#230](https://github.com/johnxnguyen/Down/pull/230) ([klm1](https://github.com/klm1))
- Use case let as instead of case is and force casting later. [\#227](https://github.com/johnxnguyen/Down/pull/227) ([5sw](https://github.com/5sw))
- Add macOS arm64 platform [\#224](https://github.com/johnxnguyen/Down/pull/224) ([jasminlapalme](https://github.com/jasminlapalme))
- Add tvOS support [\#24](https://github.com/iwasrobbed/Down/pull/24) ([invliD](https://github.com/invliD))
- v0.3.1: Add the ability to update DownView content [\#22](https://github.com/iwasrobbed/Down/pull/22) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.9.3](https://github.com/johnxnguyen/Down/tree/v0.9.3) (2020-06-12)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.2...v0.9.3)
## [v0.3.1](https://github.com/iwasrobbed/Down/tree/v0.3.1) (2017-02-09)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.3...v0.3.1)
**Closed issues:**
- Line breaks between list items are not parsed correctly [\#214](https://github.com/johnxnguyen/Down/issues/214)
- Can't build with copied sources [\#211](https://github.com/johnxnguyen/Down/issues/211)
- hard blank line insertion after list [\#210](https://github.com/johnxnguyen/Down/issues/210)
- Cocoapod version 0.9.2 not available. [\#206](https://github.com/johnxnguyen/Down/issues/206)
- \[Feature\] Local images not accessible from WKWebView [\#198](https://github.com/johnxnguyen/Down/issues/198)
- How to keep UITextView font style [\#21](https://github.com/iwasrobbed/Down/issues/21)
- Define custom fonts [\#18](https://github.com/iwasrobbed/Down/issues/18)
- Render progress [\#17](https://github.com/iwasrobbed/Down/issues/17)
- Disable zoom WebView [\#16](https://github.com/iwasrobbed/Down/issues/16)
- Text Size of DownView too small [\#15](https://github.com/iwasrobbed/Down/issues/15)
- How to customize the Font? [\#14](https://github.com/iwasrobbed/Down/issues/14)
- Support Images [\#13](https://github.com/iwasrobbed/Down/issues/13)
- How to manually install \(w/o Carthage or CocoaPods\) [\#12](https://github.com/iwasrobbed/Down/issues/12)
- Add support for Carthage [\#8](https://github.com/iwasrobbed/Down/issues/8)
**Merged pull requests:**
- \[Chore\] Bump swift snapshot testing to 1.7.2 [\#216](https://github.com/johnxnguyen/Down/pull/216) ([johnxnguyen](https://github.com/johnxnguyen))
- Add tightness property to List node [\#215](https://github.com/johnxnguyen/Down/pull/215) ([johnxnguyen](https://github.com/johnxnguyen))
- Add styling options for level 4 to 6 headings [\#207](https://github.com/johnxnguyen/Down/pull/207) ([mathebox](https://github.com/mathebox))
- \[DownView\] Add parameter so bundle is writable [\#200](https://github.com/johnxnguyen/Down/pull/200) ([brunnobga](https://github.com/brunnobga))
## [v0.9.2](https://github.com/johnxnguyen/Down/tree/v0.9.2) (2020-03-03)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.1...v0.9.2)
**Closed issues:**
- Update Framework with Swift 5.1 [\#178](https://github.com/johnxnguyen/Down/issues/178)
**Merged pull requests:**
- Swift 5.1 Support [\#204](https://github.com/johnxnguyen/Down/pull/204) ([ghost](https://github.com/ghost))
- Resolves Swift Package Manager issue related to swift-snapshot-testing [\#203](https://github.com/johnxnguyen/Down/pull/203) ([ghost](https://github.com/ghost))
## [v0.9.1](https://github.com/johnxnguyen/Down/tree/v0.9.1) (2020-02-28)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.9.0...v0.9.1)
## [v0.3](https://github.com/iwasrobbed/Down/tree/v0.3) (2016-10-12)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.2...v0.3)
**Implemented enhancements:**
- Added Linux support. [\#172](https://github.com/johnxnguyen/Down/pull/172) ([vgorloff](https://github.com/vgorloff))
- Swift 3.0 support [\#10](https://github.com/iwasrobbed/Down/issues/10)
- Add web view for rendering output [\#3](https://github.com/iwasrobbed/Down/issues/3)
**Closed issues:**
- SwiftPM : Resolve apparent version incompatibility with swift-snapshot-testing [\#202](https://github.com/johnxnguyen/Down/issues/202)
- Release fixes made after 0.9.0 [\#201](https://github.com/johnxnguyen/Down/issues/201)
- Swift UI Support [\#199](https://github.com/johnxnguyen/Down/issues/199)
- 'BaseNode' initializer is inaccessible due to 'internal' protection level [\#196](https://github.com/johnxnguyen/Down/issues/196)
- Any emoji support? [\#195](https://github.com/johnxnguyen/Down/issues/195)
- Swift Packege maneger? [\#194](https://github.com/johnxnguyen/Down/issues/194)
- Regression: single newline syntax not working \(any variety\) [\#191](https://github.com/johnxnguyen/Down/issues/191)
- Down cannot convert this markdown string to html [\#190](https://github.com/johnxnguyen/Down/issues/190)
- App using xcframework with Down pod dependency causes crash [\#187](https://github.com/johnxnguyen/Down/issues/187)
- Is the text supposed to be rendering this large? [\#186](https://github.com/johnxnguyen/Down/issues/186)
- Issue with markdown render/convert to attribute string on macOS latest version [\#185](https://github.com/johnxnguyen/Down/issues/185)
- Table are not render [\#183](https://github.com/johnxnguyen/Down/issues/183)
- How to change text color? [\#182](https://github.com/johnxnguyen/Down/issues/182)
- incorrect parse for string that is a mixture of markdown and html [\#180](https://github.com/johnxnguyen/Down/issues/180)
- Can you give an example how to custom the parser? [\#9](https://github.com/iwasrobbed/Down/issues/9)
**Merged pull requests:**
- Improve configurability of DownStyler [\#188](https://github.com/johnxnguyen/Down/pull/188) ([mgacy](https://github.com/mgacy))
- Make color & font collection initializers public [\#184](https://github.com/johnxnguyen/Down/pull/184) ([johnxnguyen](https://github.com/johnxnguyen))
- Swift 3 [\#11](https://github.com/iwasrobbed/Down/pull/11) ([azeff](https://github.com/azeff))
- Adds a few extra tests where possible [\#7](https://github.com/iwasrobbed/Down/pull/7) ([iwasrobbed](https://github.com/iwasrobbed))
- DownView rendering to close \#3 [\#5](https://github.com/iwasrobbed/Down/pull/5) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.9.0](https://github.com/johnxnguyen/Down/tree/v0.9.0) (2019-10-06)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.6...v0.9.0)
**Closed issues:**
- Please add Styler example in the documentation [\#179](https://github.com/johnxnguyen/Down/issues/179)
- \[Attributed Strings\] Can the `Styler` know which list item marker was parsed? [\#176](https://github.com/johnxnguyen/Down/issues/176)
- Error: 'cmark\_export.h' file not found with \<angled\> include; use "quotes" instead [\#175](https://github.com/johnxnguyen/Down/issues/175)
- GIFF Support [\#174](https://github.com/johnxnguyen/Down/issues/174)
- Help: Set Default Font [\#168](https://github.com/johnxnguyen/Down/issues/168)
- \[Testing\] Adding a snapshot testing framework [\#165](https://github.com/johnxnguyen/Down/issues/165)
- Adding a snapshot test framework [\#164](https://github.com/johnxnguyen/Down/issues/164)
- XCode Beta 4 Build Error [\#162](https://github.com/johnxnguyen/Down/issues/162)
- \[Attributed Strings\] Create default `Styler` for attributed string rendering [\#138](https://github.com/johnxnguyen/Down/issues/138)
- \[Help out\] Collaborators wanted! Help us improve Down [\#105](https://github.com/johnxnguyen/Down/issues/105)
- \[DownView\] Support for internal links? [\#93](https://github.com/johnxnguyen/Down/issues/93)
**Merged pull requests:**
- \[Feature\] Create default `Styler` for attributed string rendering [\#177](https://github.com/johnxnguyen/Down/pull/177) ([johnxnguyen](https://github.com/johnxnguyen))
- Resolve xcode11beta4 issue. [\#170](https://github.com/johnxnguyen/Down/pull/170) ([ykphuah](https://github.com/ykphuah))
- Minor documentation fix [\#169](https://github.com/johnxnguyen/Down/pull/169) ([nighthawk](https://github.com/nighthawk))
## [v0.8.6](https://github.com/johnxnguyen/Down/tree/v0.8.6) (2019-07-11)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.5...v0.8.6)
**Closed issues:**
- Update Options to support Unsafe Rendering [\#159](https://github.com/johnxnguyen/Down/issues/159)
- .toAttributedString stylesheet parameter [\#158](https://github.com/johnxnguyen/Down/issues/158)
**Merged pull requests:**
- Updates for unsafe option [\#160](https://github.com/johnxnguyen/Down/pull/160) ([hbowie](https://github.com/hbowie))
- Fix permissions error on Catalina beta 2 [\#156](https://github.com/johnxnguyen/Down/pull/156) ([mdiep](https://github.com/mdiep))
## [v0.8.5](https://github.com/johnxnguyen/Down/tree/v0.8.5) (2019-06-13)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.4...v0.8.5)
**Closed issues:**
- DebugVisitor is missing a public initializer [\#152](https://github.com/johnxnguyen/Down/issues/152)
- Can't build with Swift 5.1 with SwiftPM [\#151](https://github.com/johnxnguyen/Down/issues/151)
**Merged pull requests:**
- \[SPM\] Fixes error with missing headers [\#154](https://github.com/johnxnguyen/Down/pull/154) ([aasimk2000](https://github.com/aasimk2000))
- Create Public Initializer for DebugVisitor [\#153](https://github.com/johnxnguyen/Down/pull/153) ([mfcollins3](https://github.com/mfcollins3))
## [v0.8.4](https://github.com/johnxnguyen/Down/tree/v0.8.4) (2019-06-04)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.3...v0.8.4)
**Closed issues:**
- \[Carthage\] Missing required module 'libcmark' [\#120](https://github.com/johnxnguyen/Down/issues/120)
**Merged pull requests:**
- Add Swift Package Manager support [\#150](https://github.com/johnxnguyen/Down/pull/150) ([aasimk2000](https://github.com/aasimk2000))
- \[AST\] Replace line separator with paragraph separator. [\#149](https://github.com/johnxnguyen/Down/pull/149) ([fgulan](https://github.com/fgulan))
## [v0.8.3](https://github.com/johnxnguyen/Down/tree/v0.8.3) (2019-05-15)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.2...v0.8.3)
**Closed issues:**
- Pass DownOptions to DownView [\#147](https://github.com/johnxnguyen/Down/issues/147)
**Merged pull requests:**
- Feature - pass DownOptions to init and update [\#148](https://github.com/johnxnguyen/Down/pull/148) ([ladislas](https://github.com/ladislas))
## [v0.8.2](https://github.com/johnxnguyen/Down/tree/v0.8.2) (2019-05-10)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.1...v0.8.2)
**Merged pull requests:**
- Mark as safe for app extension use. [\#146](https://github.com/johnxnguyen/Down/pull/146) ([sgoodwin](https://github.com/sgoodwin))
## [v0.8.1](https://github.com/johnxnguyen/Down/tree/v0.8.1) (2019-04-26)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.8.0...v0.8.1)
**Merged pull requests:**
- \[Swift\] Update to Swift 5.0 [\#145](https://github.com/johnxnguyen/Down/pull/145) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.8.0](https://github.com/johnxnguyen/Down/tree/v0.8.0) (2019-04-24)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.7.0...v0.8.0)
**Closed issues:**
- 0.7.0 problems with NSAttributedString.Key [\#139](https://github.com/johnxnguyen/Down/issues/139)
**Merged pull requests:**
- \[Down\] Add new `unsafe` option [\#143](https://github.com/johnxnguyen/Down/pull/143) ([iwasrobbed](https://github.com/iwasrobbed))
- Bump cmark to 0.29.0 [\#142](https://github.com/johnxnguyen/Down/pull/142) ([larryonoff](https://github.com/larryonoff))
## [v0.7.0](https://github.com/johnxnguyen/Down/tree/v0.7.0) (2019-04-24)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.6...v0.7.0)
## [v0.2](https://github.com/iwasrobbed/Down/tree/v0.2) (2016-06-02)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.1.1...v0.2)
**Implemented enhancements:**
- \[Documentation\] AST API [\#134](https://github.com/johnxnguyen/Down/issues/134)
- \[Attributed Strings\] Line spacing more than expected [\#121](https://github.com/johnxnguyen/Down/issues/121)
- \[Down\] Rendering to attributed string is really slow, requires main thread [\#100](https://github.com/johnxnguyen/Down/issues/100)
- Add attributed string support [\#2](https://github.com/iwasrobbed/Down/issues/2)
- Adds attributed string rendering [\#4](https://github.com/iwasrobbed/Down/pull/4) ([iwasrobbed](https://github.com/iwasrobbed))
**Merged pull requests:**
- Set Swift version 4.0 in podspec [\#140](https://github.com/johnxnguyen/Down/pull/140) ([larryonoff](https://github.com/larryonoff))
- \[Cleanup\] Comment docs, example apps, and whitespace [\#136](https://github.com/johnxnguyen/Down/pull/136) ([iwasrobbed](https://github.com/iwasrobbed))
- \[Feature\] Create API for parsing to AST and NSAttributedString [\#132](https://github.com/johnxnguyen/Down/pull/132) ([johnxnguyen](https://github.com/johnxnguyen))
## [v0.6.6](https://github.com/johnxnguyen/Down/tree/v0.6.6) (2019-04-11)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.5...v0.6.6)
**Closed issues:**
- Swift 4/5 compatibility [\#131](https://github.com/johnxnguyen/Down/issues/131)
**Merged pull requests:**
- Wrap openURL so that Down compiles in app extensions [\#133](https://github.com/johnxnguyen/Down/pull/133) ([nheagy](https://github.com/nheagy))
## [v0.6.5](https://github.com/johnxnguyen/Down/tree/v0.6.5) (2019-04-02)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.4...v0.6.5)
**Merged pull requests:**
- Fix Xcode 10.2 warnings [\#130](https://github.com/johnxnguyen/Down/pull/130) ([mdiep](https://github.com/mdiep))
## [v0.6.4](https://github.com/johnxnguyen/Down/tree/v0.6.4) (2019-03-30)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.3...v0.6.4)
**Closed issues:**
- Support SwiftPM [\#128](https://github.com/johnxnguyen/Down/issues/128)
- \[DownView\] Load multiple .md files \(link support\) [\#68](https://github.com/johnxnguyen/Down/issues/68)
**Merged pull requests:**
- Fix Swift module errors when used alongside Firestore [\#125](https://github.com/johnxnguyen/Down/pull/125) ([vzsg](https://github.com/vzsg))
## [v0.6.3](https://github.com/johnxnguyen/Down/tree/v0.6.3) (2019-03-27)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.2...v0.6.3)
## [v0.1.1](https://github.com/iwasrobbed/Down/tree/v0.1.1) (2016-06-01)
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.1...v0.1.1)
**Implemented enhancements:**
- \[DownView\] Doesn't reflow text on orientation change [\#111](https://github.com/johnxnguyen/Down/issues/111)
- Add CocoaPods support & cmark license [\#1](https://github.com/iwasrobbed/Down/pull/1) ([iwasrobbed](https://github.com/iwasrobbed))
**Fixed bugs:**
## [v0.1](https://github.com/iwasrobbed/Down/tree/v0.1) (2016-06-01)
- Crash rendering markdown [\#126](https://github.com/johnxnguyen/Down/issues/126)
**Closed issues:**
- Cocoapods: libcmark [\#124](https://github.com/johnxnguyen/Down/issues/124)
- Use with storyboards [\#123](https://github.com/johnxnguyen/Down/issues/123)
- support for audio markdown? [\#122](https://github.com/johnxnguyen/Down/issues/122)
- \[Down\] Can't render toAttributedString while app is in background [\#116](https://github.com/johnxnguyen/Down/issues/116)
**Merged pull requests:**
- Fix crash from missing parser.h include [\#129](https://github.com/johnxnguyen/Down/pull/129) ([phoney](https://github.com/phoney))
- Make the DownView reflow text on device rotation [\#127](https://github.com/johnxnguyen/Down/pull/127) ([phoney](https://github.com/phoney))
## [v0.6.2](https://github.com/johnxnguyen/Down/tree/v0.6.2) (2018-11-28)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.1...v0.6.2)
**Implemented enhancements:**
- \[cmark\] Some characters are escaped twice [\#99](https://github.com/johnxnguyen/Down/issues/99)
**Merged pull requests:**
- Add compiler flag to suppress implicit conversion warnings [\#118](https://github.com/johnxnguyen/Down/pull/118) ([phoney](https://github.com/phoney))
## [v0.6.1](https://github.com/johnxnguyen/Down/tree/v0.6.1) (2018-11-23)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.6.0...v0.6.1)
**Closed issues:**
- 2 Swift Compiler Errors when installing Down on iOS [\#117](https://github.com/johnxnguyen/Down/issues/117)
- How to update to the latest version of the cmark library [\#115](https://github.com/johnxnguyen/Down/issues/115)
**Merged pull requests:**
- \[travis\] Update to retry [\#114](https://github.com/johnxnguyen/Down/pull/114) ([iwasrobbed](https://github.com/iwasrobbed))
- Fix macOS Platform, Custom URL Scheme Handler, Polish Demos. [\#110](https://github.com/johnxnguyen/Down/pull/110) ([chriszielinski](https://github.com/chriszielinski))
## [v0.6.0](https://github.com/johnxnguyen/Down/tree/v0.6.0) (2018-11-10)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.5.3...v0.6.0)
**Implemented enhancements:**
- \[iOS 10+\] Warnings for WebKit signal service and latex.c [\#94](https://github.com/johnxnguyen/Down/issues/94)
- Update cmark version to latest stable release [\#84](https://github.com/johnxnguyen/Down/issues/84)
**Closed issues:**
- HTML to Markdowndow? [\#107](https://github.com/johnxnguyen/Down/issues/107)
- Blockquote does not work in NSAttributedString [\#106](https://github.com/johnxnguyen/Down/issues/106)
- Support for Dynamic Type [\#90](https://github.com/johnxnguyen/Down/issues/90)
**Merged pull requests:**
- \[Down\] Bump to v0.6.0 [\#113](https://github.com/johnxnguyen/Down/pull/113) ([iwasrobbed](https://github.com/iwasrobbed))
- \[cmark\] Update lib to v0.28.3 [\#112](https://github.com/johnxnguyen/Down/pull/112) ([phoney](https://github.com/phoney))
- Update project to Xcode 10 [\#109](https://github.com/johnxnguyen/Down/pull/109) ([funkyboy](https://github.com/funkyboy))
## [v0.5.3](https://github.com/johnxnguyen/Down/tree/v0.5.3) (2018-09-19)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.5.2...v0.5.3)
**Implemented enhancements:**
- &rdquo; not being rendered [\#95](https://github.com/johnxnguyen/Down/issues/95)
- Update issue templates [\#101](https://github.com/johnxnguyen/Down/pull/101) ([iwasrobbed](https://github.com/iwasrobbed))
**Fixed bugs:**
- \[Xcode 10\] Crash in XCBuildService; need to use old build system [\#91](https://github.com/johnxnguyen/Down/issues/91)
**Closed issues:**
- DownView font size on iPad is huge [\#102](https://github.com/johnxnguyen/Down/issues/102)
- Is there a way to convert NSAttributedString back to markdown? [\#98](https://github.com/johnxnguyen/Down/issues/98)
- Back Gesture [\#96](https://github.com/johnxnguyen/Down/issues/96)
- Access for [\#92](https://github.com/johnxnguyen/Down/issues/92)
- Image size NSAttributedString [\#89](https://github.com/johnxnguyen/Down/issues/89)
- Dependency analysis warnings with Cocoapods [\#88](https://github.com/johnxnguyen/Down/issues/88)
- WatchKit Support [\#71](https://github.com/johnxnguyen/Down/issues/71)
- Installation via Swift Package Manager [\#61](https://github.com/johnxnguyen/Down/issues/61)
**Merged pull requests:**
- \[Xcode 10\]\[Carthage\] Use new build system [\#104](https://github.com/johnxnguyen/Down/pull/104) ([torokzsolt](https://github.com/torokzsolt))
- Updates the project settings to use the Legacy Build System. [\#97](https://github.com/johnxnguyen/Down/pull/97) ([pieromattos](https://github.com/pieromattos))
- \[Release\] v0.5.2 [\#87](https://github.com/johnxnguyen/Down/pull/87) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.5.2](https://github.com/johnxnguyen/Down/tree/v0.5.2) (2018-05-05)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.5.1...v0.5.2)
**Merged pull requests:**
- \[Pods\] Only include files in source\_files that can be compiled [\#86](https://github.com/johnxnguyen/Down/pull/86) ([njdehoog](https://github.com/njdehoog))
## [v0.5.1](https://github.com/johnxnguyen/Down/tree/v0.5.1) (2018-03-03)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.5.0...v0.5.1)
**Closed issues:**
- `DocumentReadingOptionKey` Error via pod [\#80](https://github.com/johnxnguyen/Down/issues/80)
**Merged pull requests:**
- Add optional stylesheet argument for NSAttributedString renderer [\#79](https://github.com/johnxnguyen/Down/pull/79) ([kengruven](https://github.com/kengruven))
- Roll up cmark's COPYING sections into the top-level LICENSE file [\#78](https://github.com/johnxnguyen/Down/pull/78) ([kengruven](https://github.com/kengruven))
- Update supported versions in README [\#77](https://github.com/johnxnguyen/Down/pull/77) ([kengruven](https://github.com/kengruven))
## [v0.5.0](https://github.com/johnxnguyen/Down/tree/v0.5.0) (2018-02-24)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.4.2...v0.5.0)
**Implemented enhancements:**
- Fix/update example app [\#58](https://github.com/johnxnguyen/Down/pull/58) ([iwasrobbed](https://github.com/iwasrobbed))
**Fixed bugs:**
- Building for tvOS fails [\#49](https://github.com/johnxnguyen/Down/issues/49)
- Fix Carthage builds [\#72](https://github.com/johnxnguyen/Down/pull/72) ([tonyarnold](https://github.com/tonyarnold))
**Closed issues:**
- Swift 3+ convention for capitalization [\#74](https://github.com/johnxnguyen/Down/issues/74)
- macOS 10.11 support? [\#73](https://github.com/johnxnguyen/Down/issues/73)
- Installing with Carthage for Mac fails [\#70](https://github.com/johnxnguyen/Down/issues/70)
- Error building/installing Down [\#69](https://github.com/johnxnguyen/Down/issues/69)
- get heigth when add downview to other view? [\#67](https://github.com/johnxnguyen/Down/issues/67)
- iOS8 crash [\#66](https://github.com/johnxnguyen/Down/issues/66)
- Image caching [\#65](https://github.com/johnxnguyen/Down/issues/65)
- Some warnings to fix [\#64](https://github.com/johnxnguyen/Down/issues/64)
- build error [\#63](https://github.com/johnxnguyen/Down/issues/63)
- Lists and paragraph spacing [\#62](https://github.com/johnxnguyen/Down/issues/62)
- Converting Markdown string to HTML with emojis [\#60](https://github.com/johnxnguyen/Down/issues/60)
- Syntax highlighting themes [\#59](https://github.com/johnxnguyen/Down/issues/59)
- Compiling error on example project [\#57](https://github.com/johnxnguyen/Down/issues/57)
- Compilation error using Carthage [\#54](https://github.com/johnxnguyen/Down/issues/54)
**Merged pull requests:**
- Use lower-case Swift 3 convention for DownOptions [\#76](https://github.com/johnxnguyen/Down/pull/76) ([kengruven](https://github.com/kengruven))
- Lower MACOSX\_DEPLOYMENT\_TARGET to include El Capitan [\#75](https://github.com/johnxnguyen/Down/pull/75) ([kengruven](https://github.com/kengruven))
- WebKit not available on watchOS. [\#56](https://github.com/johnxnguyen/Down/pull/56) ([128keaton](https://github.com/128keaton))
- Update README.md [\#55](https://github.com/johnxnguyen/Down/pull/55) ([128keaton](https://github.com/128keaton))
- Updated Copyright year in ReadMe file [\#53](https://github.com/johnxnguyen/Down/pull/53) ([jobinsjohn](https://github.com/jobinsjohn))
## [v0.4.2](https://github.com/johnxnguyen/Down/tree/v0.4.2) (2017-10-21)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.4.1...v0.4.2)
**Closed issues:**
- Push v0.4.1 to cocoapods [\#51](https://github.com/johnxnguyen/Down/issues/51)
**Merged pull requests:**
- \[tvOS\] Conditionally compile DownView [\#52](https://github.com/johnxnguyen/Down/pull/52) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.4.1](https://github.com/johnxnguyen/Down/tree/v0.4.1) (2017-10-04)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.4.0...v0.4.1)
**Closed issues:**
- Carthage install fails: no such module 'libcmark' [\#43](https://github.com/johnxnguyen/Down/issues/43)
- Xcode 8.3 warnings [\#26](https://github.com/johnxnguyen/Down/issues/26)
**Merged pull requests:**
- Adds filters to remove Xcode-specific warnings [\#48](https://github.com/johnxnguyen/Down/pull/48) ([128keaton](https://github.com/128keaton))
- Fixes issue \#43 [\#47](https://github.com/johnxnguyen/Down/pull/47) ([128keaton](https://github.com/128keaton))
- Update to Swift 4 [\#46](https://github.com/johnxnguyen/Down/pull/46) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.4.0](https://github.com/johnxnguyen/Down/tree/v0.4.0) (2017-08-31)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3.5...v0.4.0)
**Implemented enhancements:**
- Example project [\#37](https://github.com/johnxnguyen/Down/issues/37)
- Markdown tables support [\#36](https://github.com/johnxnguyen/Down/issues/36)
**Closed issues:**
- Unable to build with Xcode 9 [\#41](https://github.com/johnxnguyen/Down/issues/41)
- Can not load local image and link to local .md file [\#40](https://github.com/johnxnguyen/Down/issues/40)
- Fenced code syntax highlighting [\#35](https://github.com/johnxnguyen/Down/issues/35)
- down.toAttributedString\(\) custom text font and image size [\#33](https://github.com/johnxnguyen/Down/issues/33)
**Merged pull requests:**
- Closes “Example” Issue [\#38](https://github.com/johnxnguyen/Down/pull/38) ([128keaton](https://github.com/128keaton))
- Prevent zoom documentation [\#34](https://github.com/johnxnguyen/Down/pull/34) ([Kumuluzz](https://github.com/Kumuluzz))
## [v0.3.5](https://github.com/johnxnguyen/Down/tree/v0.3.5) (2017-05-25)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3.4...v0.3.5)
**Implemented enhancements:**
- Disable analysis of cmark source code [\#31](https://github.com/johnxnguyen/Down/pull/31) ([tonyarnold](https://github.com/tonyarnold))
## [v0.3.4](https://github.com/johnxnguyen/Down/tree/v0.3.4) (2017-05-13)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3.3...v0.3.4)
**Merged pull requests:**
- Suggested project fixes/changes [\#28](https://github.com/johnxnguyen/Down/pull/28) ([tonyarnold](https://github.com/tonyarnold))
- Add the ability to initialise a DownView using a custom template bundle [\#27](https://github.com/johnxnguyen/Down/pull/27) ([tonyarnold](https://github.com/tonyarnold))
## [v0.3.3](https://github.com/johnxnguyen/Down/tree/v0.3.3) (2017-03-09)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3.2...v0.3.3)
**Implemented enhancements:**
- Add OS X support [\#6](https://github.com/johnxnguyen/Down/issues/6)
**Merged pull requests:**
- \#6 macOS Support [\#25](https://github.com/johnxnguyen/Down/pull/25) ([128keaton](https://github.com/128keaton))
## [v0.3.2](https://github.com/johnxnguyen/Down/tree/v0.3.2) (2017-02-26)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3.1...v0.3.2)
**Implemented enhancements:**
- Create changelog [\#20](https://github.com/johnxnguyen/Down/issues/20)
**Closed issues:**
- A faster substitute to NSHTMLTextDocumentType? [\#23](https://github.com/johnxnguyen/Down/issues/23)
- How to update DownView content and keep the style? [\#19](https://github.com/johnxnguyen/Down/issues/19)
**Merged pull requests:**
- Add tvOS support [\#24](https://github.com/johnxnguyen/Down/pull/24) ([invliD](https://github.com/invliD))
- v0.3.1: Add the ability to update DownView content [\#22](https://github.com/johnxnguyen/Down/pull/22) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.3.1](https://github.com/johnxnguyen/Down/tree/v0.3.1) (2017-02-09)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.3...v0.3.1)
**Closed issues:**
- How to keep UITextView font style [\#21](https://github.com/johnxnguyen/Down/issues/21)
- Define custom fonts [\#18](https://github.com/johnxnguyen/Down/issues/18)
- Render progress [\#17](https://github.com/johnxnguyen/Down/issues/17)
- Disable zoom WebView [\#16](https://github.com/johnxnguyen/Down/issues/16)
- Text Size of DownView too small [\#15](https://github.com/johnxnguyen/Down/issues/15)
- How to customize the Font? [\#14](https://github.com/johnxnguyen/Down/issues/14)
- Support Images [\#13](https://github.com/johnxnguyen/Down/issues/13)
- How to manually install \(w/o Carthage or CocoaPods\) [\#12](https://github.com/johnxnguyen/Down/issues/12)
- Add support for Carthage [\#8](https://github.com/johnxnguyen/Down/issues/8)
## [v0.3](https://github.com/johnxnguyen/Down/tree/v0.3) (2016-10-12)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.2...v0.3)
**Implemented enhancements:**
- Swift 3.0 support [\#10](https://github.com/johnxnguyen/Down/issues/10)
- Add web view for rendering output [\#3](https://github.com/johnxnguyen/Down/issues/3)
**Closed issues:**
- Can you give an example how to custom the parser? [\#9](https://github.com/johnxnguyen/Down/issues/9)
**Merged pull requests:**
- Swift 3 [\#11](https://github.com/johnxnguyen/Down/pull/11) ([azeff](https://github.com/azeff))
- Adds a few extra tests where possible [\#7](https://github.com/johnxnguyen/Down/pull/7) ([iwasrobbed](https://github.com/iwasrobbed))
- DownView rendering to close \#3 [\#5](https://github.com/johnxnguyen/Down/pull/5) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.2](https://github.com/johnxnguyen/Down/tree/v0.2) (2016-06-02)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.1.1...v0.2)
**Implemented enhancements:**
- Add attributed string support [\#2](https://github.com/johnxnguyen/Down/issues/2)
- Adds attributed string rendering [\#4](https://github.com/johnxnguyen/Down/pull/4) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.1.1](https://github.com/johnxnguyen/Down/tree/v0.1.1) (2016-06-01)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.1...v0.1.1)
**Implemented enhancements:**
- Add CocoaPods support & cmark license [\#1](https://github.com/johnxnguyen/Down/pull/1) ([iwasrobbed](https://github.com/iwasrobbed))
## [v0.1](https://github.com/johnxnguyen/Down/tree/v0.1) (2016-06-01)
[Full Changelog](https://github.com/johnxnguyen/Down/compare/69fba2a97e45a07360054a811cac018bec10e17d...v0.1)
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
@@ -1,645 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
14090A4C2185411800503C06 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14090A4B2185411800503C06 /* AppDelegate.swift */; };
14090A4E2185411800503C06 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14090A4D2185411800503C06 /* ViewController.swift */; };
14090A502185411A00503C06 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14090A4F2185411A00503C06 /* Assets.xcassets */; };
14090A532185411A00503C06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14090A512185411A00503C06 /* Main.storyboard */; };
1466417E218D2A18009627F9 /* Down.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D49980B51FA560F8004EE42E /* Down.framework */; };
1466417F218D2A18009627F9 /* Down.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D49980B51FA560F8004EE42E /* Down.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14954EA521A7DCB9001933C4 /* README-sample.md in Resources */ = {isa = PBXBuildFile; fileRef = 14954EA421A7DCA3001933C4 /* README-sample.md */; };
14954EA621A7DCBA001933C4 /* README-sample.md in Resources */ = {isa = PBXBuildFile; fileRef = 14954EA421A7DCA3001933C4 /* README-sample.md */; };
8A07D7D31F085EC6004D7141 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A07D7D21F085EC6004D7141 /* AppDelegate.swift */; };
8A07D7D51F085EC6004D7141 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A07D7D41F085EC6004D7141 /* ViewController.swift */; };
8A07D7D81F085EC6004D7141 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A07D7D61F085EC6004D7141 /* Main.storyboard */; };
8A07D7DA1F085EC6004D7141 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8A07D7D91F085EC6004D7141 /* Assets.xcassets */; };
8A07D7DD1F085EC6004D7141 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8A07D7DB1F085EC6004D7141 /* LaunchScreen.storyboard */; };
D4591E9C226D293F00EBD476 /* Down.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D49980B51FA560F8004EE42E /* Down.framework */; };
D4591E9D226D293F00EBD476 /* Down.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D49980B51FA560F8004EE42E /* Down.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
14664180218D2A18009627F9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8A569F3F1E6B3E50008BE2AC;
remoteInfo = Down;
};
D4591E9E226D293F00EBD476 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8A569F3F1E6B3E50008BE2AC;
remoteInfo = Down;
};
D49980B41FA560F8004EE42E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8A569F401E6B3E50008BE2AC;
remoteInfo = Down;
};
D49980B61FA560F8004EE42E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8AFAEAFB1E6E32E900E09B68;
remoteInfo = DownTests;
};
D4C77E06240EEB64004675B3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EEBA153A2344845500B54ECB;
remoteInfo = DownSnapshotTests;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
14664182218D2A18009627F9 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
1466417F218D2A18009627F9 /* Down.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D4591EA0226D293F00EBD476 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
D4591E9D226D293F00EBD476 /* Down.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
14090A492185411800503C06 /* macOS Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "macOS Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
14090A4B2185411800503C06 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
14090A4D2185411800503C06 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
14090A4F2185411A00503C06 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
14090A522185411A00503C06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
14090A542185411A00503C06 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
14090A5E2185443800503C06 /* macOS Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "macOS Demo.entitlements"; sourceTree = "<group>"; };
14954EA421A7DCA3001933C4 /* README-sample.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "README-sample.md"; sourceTree = "<group>"; };
8A07D7CF1F085EC6004D7141 /* Down-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Down-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
8A07D7D21F085EC6004D7141 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
8A07D7D41F085EC6004D7141 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
8A07D7D71F085EC6004D7141 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
8A07D7D91F085EC6004D7141 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8A07D7DC1F085EC6004D7141 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
8A07D7DE1F085EC6004D7141 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D49980AF1FA560F8004EE42E /* Down.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Down.xcodeproj; path = ../Down.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
14090A462185411800503C06 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D4591E9C226D293F00EBD476 /* Down.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8A07D7CC1F085EC6004D7141 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1466417E218D2A18009627F9 /* Down.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
14090A4A2185411800503C06 /* macOS Demo */ = {
isa = PBXGroup;
children = (
14090A5E2185443800503C06 /* macOS Demo.entitlements */,
14090A4B2185411800503C06 /* AppDelegate.swift */,
14090A4D2185411800503C06 /* ViewController.swift */,
14090A4F2185411A00503C06 /* Assets.xcassets */,
14090A512185411A00503C06 /* Main.storyboard */,
14090A542185411A00503C06 /* Info.plist */,
);
path = "macOS Demo";
sourceTree = "<group>";
};
14664175218D264A009627F9 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
14954EA321A7DCA3001933C4 /* Shared */ = {
isa = PBXGroup;
children = (
14954EA421A7DCA3001933C4 /* README-sample.md */,
);
path = Shared;
sourceTree = "<group>";
};
8A07D7C61F085EC6004D7141 = {
isa = PBXGroup;
children = (
D49980AF1FA560F8004EE42E /* Down.xcodeproj */,
8A07D7D11F085EC6004D7141 /* Down-Example */,
14090A4A2185411800503C06 /* macOS Demo */,
14954EA321A7DCA3001933C4 /* Shared */,
14664175218D264A009627F9 /* Frameworks */,
8A07D7D01F085EC6004D7141 /* Products */,
);
sourceTree = "<group>";
};
8A07D7D01F085EC6004D7141 /* Products */ = {
isa = PBXGroup;
children = (
8A07D7CF1F085EC6004D7141 /* Down-Example.app */,
14090A492185411800503C06 /* macOS Demo.app */,
);
name = Products;
sourceTree = "<group>";
};
8A07D7D11F085EC6004D7141 /* Down-Example */ = {
isa = PBXGroup;
children = (
8A07D7D21F085EC6004D7141 /* AppDelegate.swift */,
8A07D7D41F085EC6004D7141 /* ViewController.swift */,
8A07D7D61F085EC6004D7141 /* Main.storyboard */,
8A07D7D91F085EC6004D7141 /* Assets.xcassets */,
8A07D7DB1F085EC6004D7141 /* LaunchScreen.storyboard */,
8A07D7DE1F085EC6004D7141 /* Info.plist */,
);
path = "Down-Example";
sourceTree = "<group>";
};
D49980B01FA560F8004EE42E /* Products */ = {
isa = PBXGroup;
children = (
D49980B51FA560F8004EE42E /* Down.framework */,
D49980B71FA560F8004EE42E /* DownTests.xctest */,
D4C77E07240EEB64004675B3 /* DownSnapshotTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
14090A482185411800503C06 /* macOS Demo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 14090A562185411A00503C06 /* Build configuration list for PBXNativeTarget "macOS Demo" */;
buildPhases = (
14090A452185411800503C06 /* Sources */,
14090A462185411800503C06 /* Frameworks */,
14090A472185411800503C06 /* Resources */,
D4591EA0226D293F00EBD476 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
D4591E9F226D293F00EBD476 /* PBXTargetDependency */,
);
name = "macOS Demo";
productName = "macOS Demo";
productReference = 14090A492185411800503C06 /* macOS Demo.app */;
productType = "com.apple.product-type.application";
};
8A07D7CE1F085EC6004D7141 /* Down-Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8A07D7E11F085EC6004D7141 /* Build configuration list for PBXNativeTarget "Down-Example" */;
buildPhases = (
8A07D7CB1F085EC6004D7141 /* Sources */,
8A07D7CC1F085EC6004D7141 /* Frameworks */,
8A07D7CD1F085EC6004D7141 /* Resources */,
14664182218D2A18009627F9 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
14664181218D2A18009627F9 /* PBXTargetDependency */,
);
name = "Down-Example";
productName = "Down-Example";
productReference = 8A07D7CF1F085EC6004D7141 /* Down-Example.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
8A07D7C71F085EC6004D7141 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1000;
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = Down;
TargetAttributes = {
14090A482185411800503C06 = {
CreatedOnToolsVersion = 10.0;
DevelopmentTeam = 7V68668DJN;
LastSwiftMigration = 1020;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
8A07D7CE1F085EC6004D7141 = {
CreatedOnToolsVersion = 8.3.3;
LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = 8A07D7CA1F085EC6004D7141 /* Build configuration list for PBXProject "Down-Example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 8A07D7C61F085EC6004D7141;
productRefGroup = 8A07D7D01F085EC6004D7141 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = D49980B01FA560F8004EE42E /* Products */;
ProjectRef = D49980AF1FA560F8004EE42E /* Down.xcodeproj */;
},
);
projectRoot = "";
targets = (
8A07D7CE1F085EC6004D7141 /* Down-Example */,
14090A482185411800503C06 /* macOS Demo */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
D49980B51FA560F8004EE42E /* Down.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Down.framework;
remoteRef = D49980B41FA560F8004EE42E /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D49980B71FA560F8004EE42E /* DownTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = DownTests.xctest;
remoteRef = D49980B61FA560F8004EE42E /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D4C77E07240EEB64004675B3 /* DownSnapshotTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = DownSnapshotTests.xctest;
remoteRef = D4C77E06240EEB64004675B3 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
14090A472185411800503C06 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
14090A502185411A00503C06 /* Assets.xcassets in Resources */,
14090A532185411A00503C06 /* Main.storyboard in Resources */,
14954EA521A7DCB9001933C4 /* README-sample.md in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8A07D7CD1F085EC6004D7141 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
14954EA621A7DCBA001933C4 /* README-sample.md in Resources */,
8A07D7DD1F085EC6004D7141 /* LaunchScreen.storyboard in Resources */,
8A07D7DA1F085EC6004D7141 /* Assets.xcassets in Resources */,
8A07D7D81F085EC6004D7141 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
14090A452185411800503C06 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
14090A4E2185411800503C06 /* ViewController.swift in Sources */,
14090A4C2185411800503C06 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8A07D7CB1F085EC6004D7141 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8A07D7D51F085EC6004D7141 /* ViewController.swift in Sources */,
8A07D7D31F085EC6004D7141 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
14664181218D2A18009627F9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Down;
targetProxy = 14664180218D2A18009627F9 /* PBXContainerItemProxy */;
};
D4591E9F226D293F00EBD476 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Down;
targetProxy = D4591E9E226D293F00EBD476 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
14090A512185411A00503C06 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
14090A522185411A00503C06 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
8A07D7D61F085EC6004D7141 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
8A07D7D71F085EC6004D7141 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
8A07D7DB1F085EC6004D7141 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
8A07D7DC1F085EC6004D7141 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
14090A572185411A00503C06 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "macOS Demo/macOS Demo.entitlements";
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 7V68668DJN;
ENABLE_HARDENED_RUNTIME = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "macOS Demo/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.downMarkdown.macOS-Demo";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
14090A582185411A00503C06 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = "macOS Demo/macOS Demo.entitlements";
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = 7V68668DJN;
ENABLE_HARDENED_RUNTIME = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "macOS Demo/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.downMarkdown.macOS-Demo";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Release;
};
8A07D7DF1F085EC6004D7141 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
8A07D7E01F085EC6004D7141 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
8A07D7E21F085EC6004D7141 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Down-Example",
);
INFOPLIST_FILE = "Down-Example/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.downMarkdown.Down-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
8A07D7E31F085EC6004D7141 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Down-Example",
);
INFOPLIST_FILE = "Down-Example/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.downMarkdown.Down-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
14090A562185411A00503C06 /* Build configuration list for PBXNativeTarget "macOS Demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
14090A572185411A00503C06 /* Debug */,
14090A582185411A00503C06 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8A07D7CA1F085EC6004D7141 /* Build configuration list for PBXProject "Down-Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8A07D7DF1F085EC6004D7141 /* Debug */,
8A07D7E01F085EC6004D7141 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8A07D7E11F085EC6004D7141 /* Build configuration list for PBXNativeTarget "Down-Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8A07D7E21F085EC6004D7141 /* Debug */,
8A07D7E31F085EC6004D7141 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 8A07D7C71F085EC6004D7141 /* Project object */;
}
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Down-Example.xcodeproj">
</FileRef>
</Workspace>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,16 +0,0 @@
{
"object": {
"pins": [
{
"package": "SnapshotTesting",
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
"state": {
"branch": null,
"revision": "c466812aa2e22898f27557e2e780d3aad7a27203",
"version": "1.8.2"
}
}
]
},
"version": 1
}
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A07D7CE1F085EC6004D7141"
BuildableName = "Down-Example.app"
BlueprintName = "Down-Example"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A07D7CE1F085EC6004D7141"
BuildableName = "Down-Example.app"
BlueprintName = "Down-Example"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A07D7CE1F085EC6004D7141"
BuildableName = "Down-Example.app"
BlueprintName = "Down-Example"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A07D7CE1F085EC6004D7141"
BuildableName = "Down-Example.app"
BlueprintName = "Down-Example"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14090A482185411800503C06"
BuildableName = "macOS Demo.app"
BlueprintName = "macOS Demo"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14090A482185411800503C06"
BuildableName = "macOS Demo.app"
BlueprintName = "macOS Demo"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14090A482185411800503C06"
BuildableName = "macOS Demo.app"
BlueprintName = "macOS Demo"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14090A482185411800503C06"
BuildableName = "macOS Demo.app"
BlueprintName = "macOS Demo"
ReferencedContainer = "container:Down-Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,15 +0,0 @@
//
// AppDelegate.swift
// Down-Example
//
// Created by Keaton Burleson on 7/1/17.
// Copyright © 2016-2019 Down. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
}
@@ -1,98 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Down_Example" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
-49
View File
@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UIStatusBarHidden</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -1,69 +0,0 @@
//
// ViewController.swift
// Down-Example
//
// Created by Keaton Burleson on 7/1/17.
// Copyright © 2016-2019 Down. All rights reserved.
//
import UIKit
import Down
final class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
renderDownInWebView()
}
}
private extension ViewController {
func renderDownInWebView() {
guard let readMeURL = Bundle.main.url(forResource: nil, withExtension: "md"),
let readMeContents = try? String(contentsOf: readMeURL)
else {
showError(message: "Could not load readme contents.")
return
}
do {
let downView = try DownView(frame: view.bounds, markdownString: readMeContents, didLoadSuccessfully: {
print("Markdown was rendered.")
})
downView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(downView)
constrain(subview: downView)
createStatusBarBackgrounds(above: downView)
} catch {
showError(message: error.localizedDescription)
}
}
func createStatusBarBackgrounds(above subview: UIView) {
let blurEffect = UIBlurEffect(style: .prominent)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
view.insertSubview(blurEffectView, aboveSubview: subview)
constrain(subview: blurEffectView, bottomAnchor: topLayoutGuide.bottomAnchor)
}
func constrain(subview: UIView, bottomAnchor: NSLayoutYAxisAnchor? = nil) {
NSLayoutConstraint.activate([
subview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
subview.trailingAnchor.constraint(equalTo: view.trailingAnchor),
subview.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor),
subview.bottomAnchor.constraint(equalTo: bottomAnchor ?? bottomLayoutGuide.bottomAnchor)
])
}
func showError(message: String) {
let alertController = UIAlertController(title: "DownView Render Error",
message: message,
preferredStyle: .alert)
self.present(alertController, animated: true, completion: nil)
}
}
-238
View File
@@ -1,238 +0,0 @@
## Down
[![Build Status](https://travis-ci.org/iwasrobbed/Down.svg?branch=master)](https://travis-ci.org/iwasrobbed/Down)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
[![CocoaPods](https://img.shields.io/cocoapods/v/Down.svg?maxAge=10800)]()
[![Swift 4](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)
[![macOS](https://img.shields.io/badge/OS-macOS-orange.svg)](https://developer.apple.com/macos/)
[![iOS](https://img.shields.io/badge/OS-iOS-orange.svg)](https://developer.apple.com/ios/)
[![tvOS](https://img.shields.io/badge/OS-tvOS-orange.svg)](https://developer.apple.com/tvos/)
[![Coverage Status](https://coveralls.io/repos/github/iwasrobbed/Down/badge.svg?branch=master)](https://coveralls.io/github/iwasrobbed/Down?branch=master)
Blazing fast Markdown (CommonMark) rendering in Swift, built upon [cmark v0.28.3](https://github.com/commonmark/cmark).
Is your app using it? [Let us know!](mailto:rob@robphillips.me)
#### Maintainers
- [Rob Phillips](https://github.com/iwasrobbed)
- [John Nguyen](https://github.com/johnxnguyen)
- [Keaton Burleson](https://github.com/128keaton)
- [phoney](https://github.com/phoney)
- [Tony Arnold](https://github.com/tonyarnold)
- [Ken Harris](https://github.com/kengruven)
- [Chris Zielinski](https://github.com/chriszielinski)
- [Other contributors](https://github.com/iwasrobbed/Down/graphs/contributors) 🙌
### Installation
Note: Swift 4 support is now on the `master` branch and any tag >= 0.4.x (Swift 3 is 0.3.x)
Quickly install using [CocoaPods](https://cocoapods.org):
```ruby
pod 'Down'
```
Or [Carthage](https://github.com/Carthage/Carthage):
```
github "iwasrobbed/Down"
```
Due to limitations in Carthage regarding platform specification, you need to define the platform with Carthage.
e.g.
```carthage update --platform iOS```
Or manually install:
1. Clone this repository
2. Build the Down project
3. Add the resulting framework file to your project
4. ?
5. Profit
### Robust Performance
>[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.
> 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).
### Output Formats
* Web View (see DownView class)
* HTML
* XML
* LaTeX
* groff man
* CommonMark Markdown
* NSAttributedString
* AST (abstract syntax tree)
### View Rendering
The `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:
```swift
let downView = try? DownView(frame: self.view.bounds, markdownString: "**Oh Hai**") {
// Optional callback for loading finished
}
// Now add to view or constrain w/ Autolayout
// Or you could optionally update the contents at some point:
try? downView?.update(markdownString: "## [Google](https://google.com)") {
// Optional callback for loading finished
}
```
Meta example of rendering this README:
![Example gif](Images/ohhai.gif)
### Parsing API
The `Down` struct has everything you need if you just want out-of-the-box setup for parsing and conversion.
```swift
let down = Down(markdownString: "## [Down](https://github.com/iwasrobbed/Down)")
// Convert to HTML
let html = try? down.toHTML()
// "<h2><a href=\"https://github.com/iwasrobbed/Down\">Down</a></h2>\n"
// Convert to XML
let xml = try? down.toXML()
// "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n<document xmlns=\"http://commonmark.org/xml/1.0\">\n <heading level=\"2\">\n <link destination=\"https://github.com/iwasrobbed/Down\" title=\"\">\n <text>Down</text>\n </link>\n </heading>\n</document>\n"
// Convert to groff man
let man = try? down.toGroff()
// ".SS\nDown (https://github.com/iwasrobbed/Down)\n"
// Convert to LaTeX
let latex = try? down.toLaTeX()
// "\\subsection{\\href{https://github.com/iwasrobbed/Down}{Down}}\n"
// Convert to CommonMark Markdown
let commonMark = try? down.toCommonMark()
// "## [Down](https://github.com/iwasrobbed/Down)\n"
// Convert to an attributed string
let attributedString = try? down.toAttributedString()
// NSAttributedString representation of the rendered HTML;
// by default, uses a stylesheet that matches NSAttributedString's default font,
// but you can override this by passing in your own, using the 'stylesheet:' parameter.
// Convert to abstract syntax tree
let ast = try? down.toAST()
// Returns pointer to AST that you can manipulate
```
### Rendering Granularity
If 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:
* DownHTMLRenderable
* DownXMLRenderable
* DownLaTeXRenderable
* DownGroffRenderable
* DownCommonMarkRenderable
* DownASTRenderable
* DownAttributedStringRenderable
Example:
```swift
public struct MarkdownToHTML: DownHTMLRenderable {
/**
A string containing CommonMark Markdown
*/
public var markdownString: String
/**
Initializes the container with a CommonMark Markdown string which can then be rendered as HTML using `toHTML()`
- parameter markdownString: A string containing CommonMark Markdown
- returns: An instance of Self
*/
@warn_unused_result
public init(markdownString: String) {
self.markdownString = markdownString
}
}
```
### Configuration of `DownView`
`DownView` can be configured with a custom bundle using your own HTML / CSS or to do things like supporting
Dynamic Type or custom fonts, etc. It's completely configurable.
This option can be found in [DownView's instantiation function](https://github.com/iwasrobbed/Down/blob/master/Source/Views/DownView.swift#L26).
##### Prevent zoom
The default implementation of the `DownView` allows for zooming in the rendered content. If you want to disable this, then youll 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/iwasrobbed/Down/pull/30).
### Options
Each protocol has options that will influence either rendering or parsing:
```swift
/**
Default options
*/
public static let `default` = DownOptions(rawValue: 0)
// MARK: - Rendering Options
/**
Include a `data-sourcepos` attribute on all block elements
*/
public static let sourcePos = DownOptions(rawValue: 1 << 1)
/**
Render `softbreak` elements as hard line breaks.
*/
public static let hardBreaks = DownOptions(rawValue: 1 << 2)
/**
Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
`file:`, and `data:`, except for `image/png`, `image/gif`,
`image/jpeg`, or `image/webp` mime types). Raw HTML is replaced
by a placeholder HTML comment. Unsafe links are replaced by
empty strings.
*/
public static let safe = DownOptions(rawValue: 1 << 3)
// MARK: - Parsing Options
/**
Normalize tree by consolidating adjacent text nodes.
*/
public static let normalize = DownOptions(rawValue: 1 << 4)
/**
Validate UTF-8 in the input before parsing, replacing illegal
sequences with the replacement character U+FFFD.
*/
public static let validateUTF8 = DownOptions(rawValue: 1 << 5)
/**
Convert straight quotes to curly, --- to em dashes, -- to en dashes.
*/
public static let smart = DownOptions(rawValue: 1 << 6)
```
### Supports
Swift; iOS 9+, tvOS 9+, macOS 10.11+
### Markdown Specification
Down is built upon the [CommonMark](http://commonmark.org) specification.
### A little help from my friends
Please 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.
### Credit
This library is a wrapper around [cmark](https://github.com/commonmark/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.
[cmark](https://github.com/commonmark/cmark) is Copyright (c) 2014 - 2017, John MacFarlane. View [full license](https://github.com/commonmark/cmark/blob/master/COPYING).
-13
View File
@@ -1,13 +0,0 @@
//
// AppDelegate.swift
// macOS Demo
//
// Created by Chris Zielinski on 10/27/18.
// Copyright © 2016-2019 Down. All rights reserved.
//
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {}
@@ -1,58 +0,0 @@
{
"images" : [
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "16x16",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "32x32",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "128x128",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "256x256",
"scale" : "2x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "1x"
},
{
"idiom" : "mac",
"size" : "512x512",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -1,730 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="macOS Demo" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="macOS Demo" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About macOS Demo" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide macOS Demo" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit macOS Demo" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
<connections>
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
<items>
<menuItem title="Font" id="Gi5-1S-RQB">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
<connections>
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
<connections>
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
<menuItem title="Kern" id="jBQ-r6-VK2">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
<items>
<menuItem title="Use Default" id="GUa-eO-cwY">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
</connections>
</menuItem>
<menuItem title="Use None" id="cDB-IK-hbR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="46P-cB-AYj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="ogc-rX-tC1">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligatures" id="o6e-r0-MWq">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
<items>
<menuItem title="Use Default" id="agt-UL-0e3">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
</connections>
</menuItem>
<menuItem title="Use None" id="J7y-lM-qPV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
</connections>
</menuItem>
<menuItem title="Use All" id="xQD-1f-W4t">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="OaQ-X3-Vso">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
<items>
<menuItem title="Use Default" id="3Om-Ey-2VK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="Rqc-34-cIF">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="I0S-gh-46l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
</connections>
</menuItem>
<menuItem title="Raise" id="2h7-ER-AoG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
</connections>
</menuItem>
<menuItem title="Lower" id="1tx-W0-xDw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
<connections>
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="Fal-I4-PZk">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="d9c-me-L2H">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
<connections>
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
<connections>
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
</connections>
</menuItem>
<menuItem title="Justify" id="J5U-5w-g23">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
<connections>
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
<menuItem title="Writing Direction" id="H1b-Si-o9J">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
<items>
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="YGs-j5-SAR">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
</connections>
</menuItem>
<menuItem id="Lbh-J2-qVU">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
</connections>
</menuItem>
<menuItem id="jFq-tB-4Kx">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="Nop-cj-93Q">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
</connections>
</menuItem>
<menuItem id="BgM-ve-c93">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
</connections>
</menuItem>
<menuItem id="RB4-Sm-HuC">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
<menuItem title="Show Ruler" id="vLm-3I-IUL">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleSourceList:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
</connections>
</menuItem>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="p" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="macOS Demo Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="macOS_Demo" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="DownView" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" texturedBackground="YES" fullSizeContentView="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
</connections>
</window>
<connections>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
</connections>
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="74" y="247"/>
</scene>
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="macOS_Demo" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="900" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<visualEffectView appearanceType="inheritedVibrantLight" blendingMode="withinWindow" material="titlebar" state="active" translatesAutoresizingMaskIntoConstraints="NO" id="mkd-yO-PAt">
<rect key="frame" x="0.0" y="578" width="900" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="KaJ-za-bSI"/>
</constraints>
</visualEffectView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="mkd-yO-PAt" secondAttribute="trailing" id="ETW-Wk-5Bo"/>
<constraint firstItem="mkd-yO-PAt" firstAttribute="top" secondItem="m2S-Jp-Qdl" secondAttribute="top" id="Shf-qK-e0N"/>
<constraint firstItem="mkd-yO-PAt" firstAttribute="leading" secondItem="m2S-Jp-Qdl" secondAttribute="leading" id="Th9-5p-z2m"/>
</constraints>
</view>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="74" y="845"/>
</scene>
</scenes>
</document>
-32
View File
@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016-2019 Down. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
@@ -1,39 +0,0 @@
//
// ViewController.swift
// macOS Demo
//
// Created by Chris Zielinski on 10/27/18.
// Copyright © 2016-2019 Down. All rights reserved.
//
import Cocoa
import Down
final class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
renderDownInWebView()
}
}
private extension ViewController {
func renderDownInWebView() {
let readMeURL = Bundle.main.url(forResource: nil, withExtension: "md")!
let readMeContents = try! String(contentsOf: readMeURL)
do {
let downView = try DownView(frame: view.bounds, markdownString: readMeContents, didLoadSuccessfully: {
print("Markdown was rendered.")
})
downView.autoresizingMask = [.width, .height]
view.addSubview(downView, positioned: .below, relativeTo: nil)
} catch {
NSApp.presentError(error)
}
}
}
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
+13 -14
View File
@@ -1,23 +1,22 @@
Pod::Spec.new do |spec|
spec.name = "Down"
spec.summary = "Blazing fast Markdown rendering in Swift, built upon cmark."
spec.version = "0.11.0"
spec.homepage = "https://github.com/johnxnguyen/Down"
spec.version = "0.3.4"
spec.homepage = "https://github.com/iwasrobbed/Down"
spec.license = { :type => "MIT", :file => "LICENSE" }
spec.authors = { "John Nguyen" => "polyxo@protonmail.com" }
spec.source = { :git => "https://github.com/johnxnguyen/Down.git", :tag => "v" + spec.version.to_s }
spec.source_files = "Sources/Down/{AST,Enums & Options,Extensions,Renderers}/**/*.swift", "Sources/cmark/*.{h,c}", "Sources/Down/*"
spec.ios.source_files = "Sources/Down/Views/**"
spec.osx.source_files = "Sources/Down/Views/**"
spec.public_header_files = "Sources/Down/*.h"
spec.ios.deployment_target = "9.0"
spec.authors = { "Rob Phillips" => "rob@desideratalabs.co" }
spec.source = { :git => "https://github.com/iwasrobbed/Down.git", :tag => "v" + spec.version.to_s }
spec.source_files = "Source/{cmark,Enums & Options,Extensions,Renderers}/**", "Source/*"
spec.ios.source_files = "Source/Views/**"
spec.osx.source_files = "Source/Views/**"
spec.public_header_files = "Source/*.h"
spec.ios.deployment_target = "8.0"
spec.tvos.deployment_target = "9.0"
spec.osx.deployment_target = "10.11"
spec.requires_arc = true
spec.module_name = "Down"
spec.preserve_paths = "Sources/cmark/include/module.modulemap", "Sources/cmark/*.inc", "Sources/cmark/COPYING"
spec.pod_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(SRCROOT)/Down/Sources/cmark/**' }
spec.ios.resource = 'Sources/Down/Resources/DownView.bundle'
spec.osx.resource = 'Sources/Down/Resources/DownView.bundle'
spec.swift_versions = ['5.0', '5.1']
spec.preserve_path = 'Source/cmark/module.modulemap'
spec.pod_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(SRCROOT)/Down/Source/cmark/**' }
spec.ios.resource = ['Resources/DownView.bundle', 'Source/cmark/*.inc', 'Source/cmark/COPYING', 'Source/cmark/module.modulemap']
spec.osx.resource = ['Resources/DownView.bundle', 'Source/cmark/*.inc', 'Source/cmark/COPYING', 'Source/cmark/module.modulemap']
end
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "self:">
location = "self:Down.xcodeproj">
</FileRef>
</Workspace>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
@@ -1,16 +0,0 @@
{
"object": {
"pins": [
{
"package": "SnapshotTesting",
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
"state": {
"branch": null,
"revision": "c466812aa2e22898f27557e2e780d3aad7a27203",
"version": "1.8.2"
}
}
]
},
"version": 1
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -28,15 +28,6 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A569F3F1E6B3E50008BE2AC"
BuildableName = "Down.framework"
BlueprintName = "Down"
ReferencedContainer = "container:Down.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
@@ -49,6 +40,17 @@
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8A569F3F1E6B3E50008BE2AC"
BuildableName = "Down.framework"
BlueprintName = "Down"
ReferencedContainer = "container:Down.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -69,6 +71,8 @@
ReferencedContainer = "container:Down.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
+1 -198
View File
@@ -18,201 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----
cmark
Copyright (c) 2014, John MacFarlane
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
houdini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c,
html_unescape.gperf, html_unescape.h
derive from https://github.com/vmg/houdini (with some modifications)
Copyright (C) 2012 Vicent Martí
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-----
buffer.h, buffer.c, chunk.h
are derived from code (C) 2012 Github, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-----
utf8.c and utf8.c
are derived from utf8proc
(<http://www.public-software-group.org/utf8proc>),
(C) 2009 Public Software Group e. V., Berlin, Germany.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
-----
The normalization code in runtests.py was derived from the
markdowntest project, Copyright 2013 Karl Dubost:
The MIT License (MIT)
Copyright (c) 2013 Karl Dubost
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-----
The CommonMark spec (test/spec.txt) is
Copyright (C) 2014-15 John MacFarlane
Released under the Creative Commons CC-BY-SA 4.0 license:
<http://creativecommons.org/licenses/by-sa/4.0/>.
-----
The test software in test/ is
Copyright (c) 2014, John MacFarlane
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
The normalization code in runtests.py was derived from the
markdowntest project, Copyright 2013 Karl Dubost:
The MIT License (MIT)
Copyright (c) 2013 Karl Dubost
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE.
-7
View File
@@ -1,7 +0,0 @@
import XCTest
var tests = [XCTestCaseEntry]()
// FIXME: Run on macOS `swift test --generate-linuxmain` and maintain Linux Tests.
XCTMain(tests)
-64
View File
@@ -1,64 +0,0 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "Down",
platforms: [
.macOS("10.11"),
.iOS("9.0"),
.tvOS("9.0")
],
products: [
.library(
name: "Down",
targets: ["Down"]
)
],
targets: [
.target(
name: "libcmark",
dependencies: [],
path: "Sources/cmark",
exclude: [
"include",
"case_fold_switch.inc",
"entities.inc",
"COPYING"
],
publicHeadersPath: "./"
),
.target(
name: "Down",
dependencies: ["libcmark"],
path: "Sources/Down",
exclude: ["Down.h"],
resources: [
.copy("Resources/DownView.bundle"),
.copy("Resources/DownView (macOS).bundle"),
]
),
.testTarget(
name: "DownTests",
dependencies: ["Down"],
path: "Tests/DownTests",
exclude: [
"AST/VisitorTests.swift",
"AST/__Snapshots__",
"DownViewTests.swift",
"Fixtures",
"Styler/__Snapshots__",
"Styler/BlockQuoteStyleTests.swift",
"Styler/CodeBlockStyleTests.swift",
"Styler/DownDebugLayoutManagerTests.swift",
"Styler/HeadingStyleTests.swift",
"Styler/LinkStyleTests.swift",
"Styler/InlineStyleTests.swift",
"Styler/ListItemStyleTests.swift",
"Styler/StylerTestSuite.swift",
"Styler/ThematicBreakSyleTests.swift"
]
)
],
swiftLanguageVersions: [.v5]
)
+33 -99
View File
@@ -1,82 +1,42 @@
## Down
[![Build Status](https://travis-ci.com/johnxnguyen/Down.svg?branch=master)](https://travis-ci.com/johnxnguyen/Down)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/johnxnguyen/Down/blob/master/LICENSE)
[![CocoaPods](https://img.shields.io/cocoapods/v/Down)](https://cocoapods.org/pods/Down)
[![Swift 5](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)
[![Build Status](https://travis-ci.org/iwasrobbed/Down.svg?branch=master)](https://travis-ci.org/iwasrobbed/Down)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
[![CocoaPods](https://img.shields.io/cocoapods/v/Down.svg?maxAge=2592000)]()
[![Swift](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)
[![macOS](https://img.shields.io/badge/OS-macOS-orange.svg)](https://developer.apple.com/macos/)
[![iOS](https://img.shields.io/badge/OS-iOS-orange.svg)](https://developer.apple.com/ios/)
[![tvOS](https://img.shields.io/badge/OS-tvOS-orange.svg)](https://developer.apple.com/tvos/)
[![Linux](https://img.shields.io/badge/OS-Linux-orange.svg)](https://www.linux.org/)
[![Code Coverage](https://codecov.io/gh/johnxnguyen/Down/branch/master/graph/badge.svg)](https://codecov.io/gh/johnxnguyen/Down)
[![Coverage Status](https://coveralls.io/repos/github/iwasrobbed/Down/badge.svg?branch=master)](https://coveralls.io/github/iwasrobbed/Down?branch=master)
Blazing fast Markdown (CommonMark) rendering in Swift, built upon [cmark v0.29.0](https://github.com/commonmark/cmark).
Blazing fast Markdown rendering in Swift, built upon [cmark](https://github.com/jgm/cmark).
Is your app using it? [Let us know!](mailto:polyxo@protonmail.com)
If you're looking for `iwasrobbed/Down`, you found it! [Rob Phillips](https://github.com/iwasrobbed), the originator of this repository,
has 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
entrusting me with its care.
All existing references to `iwasrobbed/Down` should redirect to this repository. However, It is recommended to update those urls to point
to this repository.
#### Maintainers
- [John Nguyen](https://github.com/johnxnguyen)
- [Rob Phillips](https://github.com/iwasrobbed)
- [Keaton Burleson](https://github.com/128keaton)
- [phoney](https://github.com/phoney)
- [Tony Arnold](https://github.com/tonyarnold)
- [Ken Harris](https://github.com/kengruven)
- [Chris Zielinski](https://github.com/chriszielinski)
- [Other contributors](https://github.com/johnxnguyen/Down/graphs/contributors) 🙌
Is your app using it? [Let me know!](mailto:rob@desideratalabs.co)
### Installation
Note: Swift support is summarized in the table below.
|Swift Version|Tag|
| --- | --- |
| Swift 5.1 | >= 0.9.0 |
| Swift 5.0 | >= 0.8.1 |
| Swift 4 | >= 0.4.x |
| Swift 3 | 0.3.x |
now on the `master` branch and any tag >= 0.8.1 (Swift 4 is >= 0.4.x, Swift 3 is 0.3.x)
#### Quickly install using [CocoaPods](https://cocoapods.org):
Quickly install using [CocoaPods](https://cocoapods.org):
```ruby
pod 'Down'
```
#### Install using [Carthage](https://github.com/Carthage/Carthage):
Or [Carthage](https://github.com/Carthage/Carthage):
```
github "johnxnguyen/Down"
github "iwasrobbed/Down"
```
Due to limitations in Carthage regarding platform specification, you need to define the platform with Carthage.
e.g.
```carthage update --platform iOS```
#### Install using [Swift Package Manager](https://github.com/apple/swift-package-manager):
To add *Down* to your project, select `File → Swift Packages → Add Package Dependency` and enter the GitHub URL for *Down*.
See [Adding Package Dependencies to Your App](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) for detailed instructions.
#### Or manually install:
Or manually install:
1. Clone this repository
2. Drag and drop the Down project into your workspace file, adding the framework in the embedded framework section
2. Build and run your app
2. Build the Down project
3. Add the resulting framework file to your project
4. ?
5. Profit
### Robust Performance
>[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.
>[cmark](https://github.com/jgm/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/jgm/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.
> 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).
@@ -111,36 +71,34 @@ Meta example of rendering this README:
### Parsing API
The `Down` struct has everything you need if you just want out-of-the-box setup for parsing and conversion.
The `Down` struct has everything you need if you just want out-of-the-box setup for parsing and conversion.
```swift
let down = Down(markdownString: "## [Down](https://github.com/johnxnguyen/Down)")
let down = Down(markdownString: "## [Down](https://github.com/iwasrobbed/Down)")
// Convert to HTML
let html = try? down.toHTML()
// "<h2><a href=\"https://github.com/johnxnguyen/Down\">Down</a></h2>\n"
// "<h2><a href=\"https://github.com/iwasrobbed/Down\">Down</a></h2>\n"
// Convert to XML
let xml = try? down.toXML()
// "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n<document xmlns=\"http://commonmark.org/xml/1.0\">\n <heading level=\"2\">\n <link destination=\"https://github.com/johnxnguyen/Down\" title=\"\">\n <text>Down</text>\n </link>\n </heading>\n</document>\n"
// "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n<document xmlns=\"http://commonmark.org/xml/1.0\">\n <heading level=\"2\">\n <link destination=\"https://github.com/iwasrobbed/Down\" title=\"\">\n <text>Down</text>\n </link>\n </heading>\n</document>\n"
// Convert to groff man
let man = try? down.toGroff()
// ".SS\nDown (https://github.com/johnxnguyen/Down)\n"
// ".SS\nDown (https://github.com/iwasrobbed/Down)\n"
// Convert to LaTeX
let latex = try? down.toLaTeX()
// "\\subsection{\\href{https://github.com/johnxnguyen/Down}{Down}}\n"
// "\\subsection{\\href{https://github.com/iwasrobbed/Down}{Down}}\n"
// Convert to CommonMark Markdown
let commonMark = try? down.toCommonMark()
// "## [Down](https://github.com/johnxnguyen/Down)\n"
// "## [Down](https://github.com/iwasrobbed/Down)\n"
// Convert to an attributed string
let attributedString = try? down.toAttributedString()
// NSAttributedString representation of the rendered HTML;
// by default, uses a stylesheet that matches NSAttributedString's default font,
// but you can override this by passing in your own, using the 'stylesheet:' parameter.
// NSAttributedString representation of the rendered HTML
// Convert to abstract syntax tree
let ast = try? down.toAST()
@@ -183,17 +141,6 @@ public struct MarkdownToHTML: DownHTMLRenderable {
}
```
### Configuration of `DownView`
`DownView` can be configured with a custom bundle using your own HTML / CSS or to do things like supporting
Dynamic Type or custom fonts, etc. It's completely configurable.
This option can be found in [DownView's instantiation function](https://github.com/johnxnguyen/Down/blob/master/Source/Views/DownView.swift#L26).
##### Prevent zoom
The default implementation of the `DownView` allows for zooming in the rendered content. If you want to disable this, then youll 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).
### Options
Each protocol has options that will influence either rendering or parsing:
@@ -202,63 +149,50 @@ Each protocol has options that will influence either rendering or parsing:
/**
Default options
*/
public static let `default` = DownOptions(rawValue: 0)
public static let Default = DownOptions(rawValue: 0)
// MARK: - Rendering Options
/**
Include a `data-sourcepos` attribute on all block elements
*/
public static let sourcePos = DownOptions(rawValue: 1 << 1)
public static let SourcePos = DownOptions(rawValue: 1 << 1)
/**
Render `softbreak` elements as hard line breaks.
*/
public static let hardBreaks = DownOptions(rawValue: 1 << 2)
public static let HardBreaks = DownOptions(rawValue: 1 << 2)
/**
Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
`file:`, and `data:`, except for `image/png`, `image/gif`,
`image/jpeg`, or `image/webp` mime types). Raw HTML is replaced
by a placeholder HTML comment. Unsafe links are replaced by
empty strings. Note that this option is provided for backwards
compatibility, but safe mode is now the default.
empty strings.
*/
public static let safe = DownOptions(rawValue: 1 << 3)
/**
Allow raw HTML and unsafe links. Note that safe mode is now
the default, and the unsafe option must be used if rendering
of raw HTML and unsafe links is desired.
*/
public static let unsafe = DownOptions(rawValue: 1 << 17)
public static let Safe = DownOptions(rawValue: 1 << 3)
// MARK: - Parsing Options
/**
Normalize tree by consolidating adjacent text nodes.
*/
public static let normalize = DownOptions(rawValue: 1 << 4)
public static let Normalize = DownOptions(rawValue: 1 << 4)
/**
Validate UTF-8 in the input before parsing, replacing illegal
sequences with the replacement character U+FFFD.
*/
public static let validateUTF8 = DownOptions(rawValue: 1 << 5)
public static let ValidateUTF8 = DownOptions(rawValue: 1 << 5)
/**
Convert straight quotes to curly, --- to em dashes, -- to en dashes.
*/
public static let smart = DownOptions(rawValue: 1 << 6)
/**
Combine smart typography with HTML rendering.
*/
public static let smartUnsaFe = DownOptions(rawValue: (1 << 17) + (1 << 6))
public static let Smart = DownOptions(rawValue: 1 << 6)
```
### Supports
Swift; iOS 9+, tvOS 9+, macOS 10.11+
Swift, ARC & iOS 8+
### Markdown Specification
@@ -268,6 +202,6 @@ Down is built upon the [CommonMark](http://commonmark.org) specification.
Please 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.
### Credit
This library is a wrapper around [cmark](https://github.com/commonmark/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.
This library is a wrapper around [cmark](https://github.com/jgm/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.
[cmark](https://github.com/commonmark/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/commonmark/cmark/blob/master/COPYING).
[cmark](https://github.com/jgm/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/jgm/cmark/blob/master/COPYING).
@@ -0,0 +1,4 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0
MACOSX_DEPLOYMENT_TARGET = 10.12
TVOS_DEPLOYMENT_TARGET = 9.0
WATCHOS_DEPLOYMENT_TARGET = 3.0
@@ -12,7 +12,13 @@ TARGETED_DEVICE_FAMILY[sdk=iphone*] = 1,2
TARGETED_DEVICE_FAMILY[sdk=appletvsimulator*] = 3
TARGETED_DEVICE_FAMILY[sdk=appletv*] = 3
// Watch-specific default settings
TARGETED_DEVICE_FAMILY[sdk=watchsimulator*] = 4
TARGETED_DEVICE_FAMILY[sdk=watch*] = 4
ENABLE_BITCODE[sdk=macosx*] = NO
ENABLE_BITCODE[sdk=watchsimulator*] = YES
ENABLE_BITCODE[sdk=watch*] = YES
ENABLE_BITCODE[sdk=iphonesimulator*] = NO
ENABLE_BITCODE[sdk=iphone*] = YES
ENABLE_BITCODE[sdk=appletvsimulator*] = YES
@@ -1,7 +1,9 @@
SUPPORTED_PLATFORMS = macosx iphonesimulator iphoneos appletvos appletvsimulator
VALID_ARCHS[sdk=macosx*] = i386 x86_64 arm64
SUPPORTED_PLATFORMS = macosx iphonesimulator iphoneos watchos watchsimulator appletvos appletvsimulator
VALID_ARCHS[sdk=macosx*] = i386 x86_64
VALID_ARCHS[sdk=iphoneos*] = arm64 armv7 armv7s
VALID_ARCHS[sdk=iphonesimulator*] = i386 x86_64 arm64
VALID_ARCHS[sdk=iphonesimulator*] = i386 x86_64
VALID_ARCHS[sdk=watchos*] = armv7k
VALID_ARCHS[sdk=watchsimulator*] = i386
VALID_ARCHS[sdk=appletv*] = arm64
VALID_ARCHS[sdk=appletvsimulator*] = x86_64
@@ -9,5 +11,8 @@ VALID_ARCHS[sdk=appletvsimulator*] = x86_64
LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=iphoneos*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=watchos*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=watchsimulator*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=appletvos*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS[sdk=appletvsimulator*] = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
@@ -19,7 +19,7 @@
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016-2019 Down. All rights reserved.</string>
<string>Copyright © 2017 Glazed Donut, LLC. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
@@ -19,7 +19,7 @@
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016-2019 Down. All rights reserved.</string>
<string>Copyright © 2017 Glazed Donut, LLC. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=false"/>
<meta name="viewport" content="width=640"/>
<link charset="utf-8" href="css/down.min.css" rel="stylesheet">
<script charset="utf-8" src="js/highlight.min.js" type="text/javascript"></script>
<script charset="utf-8" src="js/down.js" type="text/javascript"></script>
+1 -1
View File
@@ -3,7 +3,7 @@
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016-2019 Down. All rights reserved.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
@import Foundation;
+30
View File
@@ -0,0 +1,30 @@
//
// Down.swift
// Down
//
// Created by Rob Phillips on 5/28/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
public struct Down: DownASTRenderable, DownHTMLRenderable, DownXMLRenderable,
DownLaTeXRenderable, DownGroffRenderable, DownCommonMarkRenderable,
DownAttributedStringRenderable {
/**
A string containing CommonMark Markdown
*/
public var markdownString: String
/**
Initializes the container with a CommonMark Markdown string which can then be rendered depending on protocol conformance
- parameter markdownString: A string containing CommonMark Markdown
- returns: An instance of Self
*/
public init(markdownString: String) {
self.markdownString = markdownString
}
}
+26
View File
@@ -0,0 +1,26 @@
//
// DownErrors.swift
// Down
//
// Created by Rob Phillips on 5/28/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
public enum DownErrors: Error {
/**
Thrown when there was an issue converting the Markdown into an abstract syntax tree
*/
case markdownToASTError
/**
Thrown when the abstract syntax tree could not be rendered into another format
*/
case astRenderingError
/**
Thrown when an HTML string cannot be converted into an `NSData` representation
*/
case htmlDataConversionError
}
+60
View File
@@ -0,0 +1,60 @@
//
// DownOptions.swift
// Down
//
// Created by Rob Phillips on 5/28/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public struct DownOptions: OptionSet {
public let rawValue: Int32
public init(rawValue: Int32) { self.rawValue = rawValue }
/**
Default options
*/
public static let Default = DownOptions(rawValue: CMARK_OPT_DEFAULT)
// MARK: - Rendering Options
/**
Include a `data-sourcepos` attribute on all block elements
*/
public static let SourcePos = DownOptions(rawValue: CMARK_OPT_SOURCEPOS)
/**
Render `softbreak` elements as hard line breaks.
*/
public static let HardBreaks = DownOptions(rawValue: CMARK_OPT_HARDBREAKS)
/**
Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
`file:`, and `data:`, except for `image/png`, `image/gif`,
`image/jpeg`, or `image/webp` mime types). Raw HTML is replaced
by a placeholder HTML comment. Unsafe links are replaced by
empty strings.
*/
public static let Safe = DownOptions(rawValue: CMARK_OPT_SAFE)
// MARK: - Parsing Options
/**
Normalize tree by consolidating adjacent text nodes.
*/
public static let Normalize = DownOptions(rawValue: CMARK_OPT_NORMALIZE)
/**
Validate UTF-8 in the input before parsing, replacing illegal
sequences with the replacement character U+FFFD.
*/
public static let ValidateUTF8 = DownOptions(rawValue: CMARK_OPT_VALIDATE_UTF8)
/**
Convert straight quotes to curly, --- to em dashes, -- to en dashes.
*/
public static let Smart = DownOptions(rawValue: CMARK_OPT_SMART)
}
@@ -0,0 +1,40 @@
//
// NSAttributedString+HTML.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
#if os(OSX)
import AppKit
#else
import UIKit
#endif
extension NSAttributedString {
/**
Instantiates an attributed string with the given HTML string
- parameter htmlString: An HTML string
- throws: `HTMLDataConversionError` or an instantiation error
- returns: An attributed string
*/
convenience init(htmlString: String) throws {
guard let data = htmlString.data(using: String.Encoding.utf8) else {
throw DownErrors.htmlDataConversionError
}
let options: [String: Any] = [
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSNumber(value: String.Encoding.utf8.rawValue)
]
try self.init(data: data, options: options, documentAttributes: nil)
}
}
+30
View File
@@ -0,0 +1,30 @@
//
// String+ToHTML.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
extension String {
/**
Generates an HTML string from the contents of the string (self), which should contain CommonMark Markdown
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `DownErrors` depending on the scenario
- returns: HTML string
*/
public func toHTML(_ options: DownOptions = .Default) throws -> String {
let ast = try DownASTRenderer.stringToAST(self, options: options)
let html = try DownHTMLRenderer.astToHTML(ast, options: options)
cmark_node_free(ast)
return html
}
}
+67
View File
@@ -0,0 +1,67 @@
//
// DownASTRenderable.swift
// Down
//
// Created by Rob Phillips on 5/31/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownASTRenderable: DownRenderable {
/**
Generates an abstract syntax tree from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- throws: `MarkdownToASTError` if conversion fails
- returns: An abstract syntax tree representation of the Markdown input
*/
func toAST(_ options: DownOptions) throws -> UnsafeMutablePointer<cmark_node>
}
public extension DownASTRenderable {
/**
Generates an abstract syntax tree from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `MarkdownToASTError` if conversion fails
- returns: An abstract syntax tree representation of the Markdown input
*/
public func toAST(_ options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
return try DownASTRenderer.stringToAST(markdownString, options: options)
}
}
public struct DownASTRenderer {
/**
Generates an abstract syntax tree from the given CommonMark Markdown string
**Important:** It is the caller's responsibility to call `cmark_node_free(ast)` on the returned value
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `MarkdownToASTError` if conversion fails
- returns: An abstract syntax tree representation of the Markdown input
*/
public static func stringToAST(_ string: String, options: DownOptions = .Default) throws -> UnsafeMutablePointer<cmark_node> {
var tree: UnsafeMutablePointer<cmark_node>?
string.withCString {
let stringLength = Int(strlen($0))
tree = cmark_parse_document($0, stringLength, options.rawValue)
}
guard let ast = tree else {
throw DownErrors.markdownToASTError
}
return ast
}
}
@@ -0,0 +1,41 @@
//
// DownAttributedStringRenderable.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownAttributedStringRenderable: DownHTMLRenderable {
/**
Generates an `NSAttributedString` from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- throws: `DownErrors` depending on the scenario
- returns: An `NSAttributedString`
*/
func toAttributedString(_ options: DownOptions) throws -> NSAttributedString
}
public extension DownAttributedStringRenderable {
/**
Generates an `NSAttributedString` from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `DownErrors` depending on the scenario
- returns: An `NSAttributedString`
*/
public func toAttributedString(_ options: DownOptions = .Default) throws -> NSAttributedString {
let html = try self.toHTML(options)
return try NSAttributedString(htmlString: html)
}
}
@@ -0,0 +1,75 @@
//
// DownCommonMarkRenderable.swift
// Down
//
// Created by Rob Phillips on 5/31/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownCommonMarkRenderable: DownRenderable {
/**
Generates a CommonMark Markdown string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- parameter width: The width to break on
- throws: `DownErrors` depending on the scenario
- returns: CommonMark Markdown string
*/
func toCommonMark(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownCommonMarkRenderable {
/**
Generates a CommonMark Markdown string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `DownErrors` depending on the scenario
- returns: CommonMark Markdown string
*/
public func toCommonMark(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let commonMark = try DownCommonMarkRenderer.astToCommonMark(ast, options: options, width: width)
cmark_node_free(ast)
return commonMark
}
}
public struct DownCommonMarkRenderer {
/**
Generates a CommonMark Markdown string from the given abstract syntax tree
**Note:** caller is responsible for calling `cmark_node_free(ast)` after this returns
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `ASTRenderingError` if the AST could not be converted
- returns: CommonMark Markdown string
*/
public static func astToCommonMark(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
guard let cCommonMarkString = cmark_render_commonmark(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cCommonMarkString) }
guard let commonMarkString = String(cString: cCommonMarkString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return commonMarkString
}
}
@@ -0,0 +1,75 @@
//
// DownGroffRenderable.swift
// Down
//
// Created by Rob Phillips on 5/31/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownGroffRenderable: DownRenderable {
/**
Generates a groff man string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- parameter width: The width to break on
- throws: `DownErrors` depending on the scenario
- returns: groff man string
*/
func toGroff(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownGroffRenderable {
/**
Generates a groff man string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `DownErrors` depending on the scenario
- returns: groff man string
*/
public func toGroff(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let groff = try DownGroffRenderer.astToGroff(ast, options: options, width: width)
cmark_node_free(ast)
return groff
}
}
public struct DownGroffRenderer {
/**
Generates a groff man string from the given abstract syntax tree
**Note:** caller is responsible for calling `cmark_node_free(ast)` after this returns
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `ASTRenderingError` if the AST could not be converted
- returns: groff man string
*/
public static func astToGroff(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
guard let cGroffString = cmark_render_man(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cGroffString) }
guard let groffString = String(cString: cGroffString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return groffString
}
}
+67
View File
@@ -0,0 +1,67 @@
//
// DownHTMLRenderable.swift
// Down
//
// Created by Rob Phillips on 5/28/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownHTMLRenderable: DownRenderable {
/**
Generates an HTML string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- throws: `DownErrors` depending on the scenario
- returns: HTML string
*/
func toHTML(_ options: DownOptions) throws -> String
}
public extension DownHTMLRenderable {
/**
Generates an HTML string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `DownErrors` depending on the scenario
- returns: HTML string
*/
public func toHTML(_ options: DownOptions = .Default) throws -> String {
return try markdownString.toHTML(options)
}
}
public struct DownHTMLRenderer {
/**
Generates an HTML string from the given abstract syntax tree
**Note:** caller is responsible for calling `cmark_node_free(ast)` after this returns
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `ASTRenderingError` if the AST could not be converted
- returns: HTML string
*/
public static func astToHTML(_ ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
guard let cHTMLString = cmark_render_html(ast, options.rawValue) else {
throw DownErrors.astRenderingError
}
defer { free(cHTMLString) }
guard let htmlString = String(cString: cHTMLString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return htmlString
}
}
@@ -0,0 +1,75 @@
//
// DownLaTeXRenderable.swift
// Down
//
// Created by Rob Phillips on 5/31/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownLaTeXRenderable: DownRenderable {
/**
Generates a LaTeX string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- parameter width: The width to break on
- throws: `DownErrors` depending on the scenario
- returns: LaTeX string
*/
func toLaTeX(_ options: DownOptions, width: Int32) throws -> String
}
public extension DownLaTeXRenderable {
/**
Generates a LaTeX string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `DownErrors` depending on the scenario
- returns: LaTeX string
*/
public func toLaTeX(_ options: DownOptions = .Default, width: Int32 = 0) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let latex = try DownLaTeXRenderer.astToLaTeX(ast, options: options, width: width)
cmark_node_free(ast)
return latex
}
}
public struct DownLaTeXRenderer {
/**
Generates a LaTeX string from the given abstract syntax tree
**Note:** caller is responsible for calling `cmark_node_free(ast)` after this returns
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- parameter width: The width to break on, defaulting to 0
- throws: `ASTRenderingError` if the AST could not be converted
- returns: LaTeX string
*/
public static func astToLaTeX(_ ast: UnsafeMutablePointer<cmark_node>,
options: DownOptions = .Default,
width: Int32 = 0) throws -> String {
guard let cLatexString = cmark_render_latex(ast, options.rawValue, width) else {
throw DownErrors.astRenderingError
}
defer { free(cLatexString) }
guard let latexString = String(cString: cLatexString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return latexString
}
}
@@ -3,15 +3,14 @@
// Down
//
// Created by Rob Phillips on 5/28/16.
// Copyright © 2016-2019 Down. All rights reserved.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
public protocol DownRenderable {
/// A string containing CommonMark Markdown.
/**
A string containing CommonMark Markdown
*/
var markdownString: String { get set }
}
}
+70
View File
@@ -0,0 +1,70 @@
//
// DownXMLRenderable.swift
// Down
//
// Created by Rob Phillips on 5/31/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import Foundation
import libcmark
public protocol DownXMLRenderable: DownRenderable {
/**
Generates an XML string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering
- throws: `DownErrors` depending on the scenario
- returns: XML string
*/
func toXML(_ options: DownOptions) throws -> String
}
public extension DownXMLRenderable {
/**
Generates an XML string from the `markdownString` property
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `DownErrors` depending on the scenario
- returns: XML string
*/
public func toXML(_ options: DownOptions = .Default) throws -> String {
let ast = try DownASTRenderer.stringToAST(markdownString, options: options)
let xml = try DownXMLRenderer.astToXML(ast, options: options)
cmark_node_free(ast)
return xml
}
}
public struct DownXMLRenderer {
/**
Generates an XML string from the given abstract syntax tree
**Note:** caller is responsible for calling `cmark_node_free(ast)` after this returns
- parameter options: `DownOptions` to modify parsing or rendering, defaulting to `.Default`
- throws: `ASTRenderingError` if the AST could not be converted
- returns: XML string
*/
public static func astToXML(_ ast: UnsafeMutablePointer<cmark_node>, options: DownOptions = .Default) throws -> String {
guard let cXMLString = cmark_render_xml(ast, options.rawValue) else {
throw DownErrors.astRenderingError
}
defer { free(cXMLString) }
guard let xmlString = String(cString: cXMLString, encoding: String.Encoding.utf8) else {
throw DownErrors.astRenderingError
}
return xmlString
}
}
+121
View File
@@ -0,0 +1,121 @@
//
// DownView.swift
// Down
//
// Created by Rob Phillips on 6/1/16.
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
//
import WebKit
// MARK: - Public API
public typealias DownViewClosure = () -> ()
open class DownView: WKWebView {
/**
Initializes a web view with the results of rendering a CommonMark Markdown string
- parameter frame: The frame size of the web view
- parameter markdownString: A string containing CommonMark Markdown
- parameter openLinksInBrowser: Whether or not to open links using an external browser
- parameter templateBundle: Optional custom template bundle. Leaving this as `nil` will use the bundle included with Down.
- parameter didLoadSuccessfully: Optional callback for when the web content has loaded successfully
- returns: An instance of Self
*/
public init(frame: CGRect, markdownString: String, openLinksInBrowser: Bool = true, templateBundle: Bundle? = nil, didLoadSuccessfully: DownViewClosure? = nil) throws {
self.didLoadSuccessfully = didLoadSuccessfully
if let templateBundle = templateBundle {
self.bundle = templateBundle
} else {
let classBundle = Bundle(for: DownView.self)
let url = classBundle.url(forResource: "DownView", withExtension: "bundle")!
self.bundle = Bundle(url: url)!
}
super.init(frame: frame, configuration: WKWebViewConfiguration())
if openLinksInBrowser || didLoadSuccessfully != nil { navigationDelegate = self }
try loadHTMLView(markdownString)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - API
/**
Renders the given CommonMark Markdown string into HTML and updates the DownView while keeping the style intact
- parameter markdownString: A string containing CommonMark Markdown
- parameter didLoadSuccessfully: Optional callback for when the web content has loaded successfully
- throws: `DownErrors` depending on the scenario
*/
public func update(markdownString: String, didLoadSuccessfully: DownViewClosure? = nil) throws {
// Note: As the init method takes this callback already, we only overwrite it here if
// a non-nil value is passed in
if let didLoadSuccessfully = didLoadSuccessfully {
self.didLoadSuccessfully = didLoadSuccessfully
}
try loadHTMLView(markdownString)
}
// MARK: - Private Properties
let bundle: Bundle
fileprivate lazy var baseURL: URL = {
return self.bundle.url(forResource: "index", withExtension: "html")!
}()
fileprivate var didLoadSuccessfully: DownViewClosure?
}
// MARK: - Private API
private extension DownView {
func loadHTMLView(_ markdownString: String) throws {
let htmlString = try markdownString.toHTML()
let pageHTMLString = try htmlFromTemplate(htmlString)
loadHTMLString(pageHTMLString, baseURL: baseURL)
}
func htmlFromTemplate(_ htmlString: String) throws -> String {
let template = try NSString(contentsOf: baseURL, encoding: String.Encoding.utf8.rawValue)
return template.replacingOccurrences(of: "DOWN_HTML", with: htmlString)
}
}
// MARK: - WKNavigationDelegate
extension DownView: WKNavigationDelegate {
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url else { return }
switch navigationAction.navigationType {
case .linkActivated:
decisionHandler(.cancel)
#if os(iOS)
UIApplication.shared.openURL(url)
#elseif os(OSX)
NSWorkspace.shared().open(url)
#endif
default:
decisionHandler(.allow)
}
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
didLoadSuccessfully?()
}
}
+24 -2
View File
@@ -27,7 +27,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
houdini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c
houdini.h, houdini_href_e.c, houdini_html_e.c, houdini_html_u.c,
html_unescape.gperf, html_unescape.h
derive from https://github.com/vmg/houdini (with some modifications)
@@ -103,7 +104,7 @@ DEALINGS IN THE SOFTWARE.
-----
The normalization code in normalize.py was derived from the
The normalization code in runtests.py was derived from the
markdowntest project, Copyright 2013 Karl Dubost:
The MIT License (MIT)
@@ -168,3 +169,24 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----
The normalization code in runtests.py was derived from the
markdowntest project, Copyright 2013 Karl Dubost:
The MIT License (MIT)
Copyright (c) 2013 Karl Dubost
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+297 -388
View File
File diff suppressed because it is too large Load Diff
+56 -22
View File
@@ -5,7 +5,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include "config.h"
#include "cmark_ctype.h"
@@ -20,9 +19,7 @@ unsigned char cmark_strbuf__initbuf[1];
#define MIN(x, y) ((x < y) ? x : y)
#endif
void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,
bufsize_t initial_size) {
buf->mem = mem;
void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size) {
buf->asize = 0;
buf->size = 0;
buf->ptr = cmark_strbuf__initbuf;
@@ -31,32 +28,68 @@ void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,
cmark_strbuf_grow(buf, initial_size);
}
static CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) {
cmark_strbuf_grow(buf, buf->size + add);
void cmark_strbuf_overflow_err() {
fprintf(stderr, "String buffer overflow");
abort();
}
static CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, size_t add) {
size_t target_size = (size_t)buf->size + add;
if (target_size < add /* Integer overflow. */
|| target_size > BUFSIZE_MAX /* Truncation overflow. */
) {
cmark_strbuf_overflow_err();
return; /* unreachable */
}
if ((bufsize_t)target_size >= buf->asize)
cmark_strbuf_grow(buf, (bufsize_t)target_size);
}
void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) {
assert(target_size > 0);
unsigned char *new_ptr;
if (target_size < buf->asize)
return;
if (target_size > (bufsize_t)(INT32_MAX / 2)) {
fprintf(stderr,
"[cmark] cmark_strbuf_grow requests buffer with size > %d, aborting\n",
(INT32_MAX / 2));
abort();
if (buf->asize == 0) {
new_ptr = NULL;
} else {
new_ptr = buf->ptr;
}
/* Oversize the buffer by 50% to guarantee amortized linear time
* complexity on append operations. */
bufsize_t new_size = target_size + target_size / 2;
size_t new_size = (size_t)target_size + (size_t)target_size / 2;
/* Account for terminating null byte. */
new_size += 1;
/* round allocation up to multiple of 8 */
new_size = (new_size + 7) & ~7;
buf->ptr = (unsigned char *)buf->mem->realloc(buf->asize ? buf->ptr : NULL,
new_size);
buf->asize = new_size;
if (new_size < (size_t)target_size /* Integer overflow. */
|| new_size > BUFSIZE_MAX /* Truncation overflow. */
) {
if (target_size >= BUFSIZE_MAX) {
/* No space for terminating null byte. */
cmark_strbuf_overflow_err();
return; /* unreachable */
}
/* Oversize by the maximum possible amount. */
new_size = BUFSIZE_MAX;
}
new_ptr = (unsigned char *)realloc(new_ptr, new_size);
if (!new_ptr) {
perror("realloc in cmark_strbuf_grow");
abort();
}
buf->asize = (bufsize_t)new_size;
buf->ptr = new_ptr;
}
bufsize_t cmark_strbuf_len(const cmark_strbuf *buf) { return buf->size; }
@@ -66,9 +99,9 @@ void cmark_strbuf_free(cmark_strbuf *buf) {
return;
if (buf->ptr != cmark_strbuf__initbuf)
buf->mem->free(buf->ptr);
free(buf->ptr);
cmark_strbuf_init(buf->mem, buf, 0);
cmark_strbuf_init(buf, 0);
}
void cmark_strbuf_clear(cmark_strbuf *buf) {
@@ -95,7 +128,7 @@ void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,
void cmark_strbuf_sets(cmark_strbuf *buf, const char *string) {
cmark_strbuf_set(buf, (const unsigned char *)string,
string ? strlen(string) : 0);
string ? cmark_strbuf_safe_strlen(string) : 0);
}
void cmark_strbuf_putc(cmark_strbuf *buf, int c) {
@@ -116,7 +149,8 @@ void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,
}
void cmark_strbuf_puts(cmark_strbuf *buf, const char *string) {
cmark_strbuf_put(buf, (const unsigned char *)string, strlen(string));
cmark_strbuf_put(buf, (const unsigned char *)string,
cmark_strbuf_safe_strlen(string));
}
void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,
@@ -150,10 +184,10 @@ unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) {
if (buf->asize == 0) {
/* return an empty string */
return (unsigned char *)buf->mem->calloc(1, 1);
return (unsigned char *)calloc(1, 1);
}
cmark_strbuf_init(buf->mem, buf, 0);
cmark_strbuf_init(buf, 0);
return data;
}
+20 -9
View File
@@ -5,35 +5,32 @@
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>
#include "config.h"
#include "cmark.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int32_t bufsize_t;
typedef int bufsize_t;
typedef struct {
cmark_mem *mem;
unsigned char *ptr;
bufsize_t asize, size;
} cmark_strbuf;
extern unsigned char cmark_strbuf__initbuf[];
#define CMARK_BUF_INIT(mem) \
{ mem, cmark_strbuf__initbuf, 0, 0 }
#define GH_BUF_INIT \
{ cmark_strbuf__initbuf, 0, 0 }
#define BUFSIZE_MAX INT_MAX
/**
* Initialize a cmark_strbuf structure.
*
* For the cases where CMARK_BUF_INIT cannot be used to do static
* For the cases where GH_BUF_INIT cannot be used to do static
* initialization.
*/
void cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,
bufsize_t initial_size);
void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size);
/**
* Grow the buffer to hold at least `target_size` bytes.
@@ -75,6 +72,20 @@ void cmark_strbuf_trim(cmark_strbuf *buf);
void cmark_strbuf_normalize_whitespace(cmark_strbuf *s);
void cmark_strbuf_unescape(cmark_strbuf *s);
/* Print error and abort. */
void cmark_strbuf_overflow_err(void);
static CMARK_INLINE bufsize_t cmark_strbuf_check_bufsize(size_t size) {
if (size > BUFSIZE_MAX) {
cmark_strbuf_overflow_err();
}
return (bufsize_t)size;
}
static CMARK_INLINE bufsize_t cmark_strbuf_safe_strlen(const char *str) {
return cmark_strbuf_check_bufsize(strlen(str));
}
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
+17 -21
View File
@@ -4,9 +4,8 @@
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "cmark.h"
#include "buffer.h"
#include "cmark_ctype.h"
#include "buffer.h"
#define CMARK_CHUNK_EMPTY \
{ NULL, 0, 0 }
@@ -17,9 +16,9 @@ typedef struct {
bufsize_t alloc; // also implies a NULL-terminated string
} cmark_chunk;
static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) {
static CMARK_INLINE void cmark_chunk_free(cmark_chunk *c) {
if (c->alloc)
mem->free(c->data);
free(c->data);
c->data = NULL;
c->alloc = 0;
@@ -36,8 +35,6 @@ static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {
}
static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) {
assert(!c->alloc);
while (c->len > 0) {
if (!cmark_isspace(c->data[c->len - 1]))
break;
@@ -58,44 +55,43 @@ static CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,
return p ? (bufsize_t)(p - ch->data) : ch->len;
}
static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem,
cmark_chunk *c) {
static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_chunk *c) {
unsigned char *str;
if (c->alloc) {
return (char *)c->data;
}
str = (unsigned char *)mem->calloc(c->len + 1, 1);
if (c->len > 0) {
memcpy(str, c->data, c->len);
str = (unsigned char *)malloc(c->len + 1);
if (str != NULL) {
if (c->len > 0) {
memcpy(str, c->data, c->len);
}
str[c->len] = 0;
}
str[c->len] = 0;
c->data = str;
c->alloc = 1;
return (char *)str;
}
static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c,
const char *str) {
unsigned char *old = c->alloc ? c->data : NULL;
static CMARK_INLINE void cmark_chunk_set_cstr(cmark_chunk *c, const char *str) {
if (c->alloc) {
free(c->data);
}
if (str == NULL) {
c->len = 0;
c->data = NULL;
c->alloc = 0;
} else {
c->len = (bufsize_t)strlen(str);
c->data = (unsigned char *)mem->calloc(c->len + 1, 1);
c->len = cmark_strbuf_safe_strlen(str);
c->data = (unsigned char *)malloc(c->len + 1);
c->alloc = 1;
memcpy(c->data, str, c->len + 1);
}
if (old != NULL) {
mem->free(old);
}
}
static CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) {
bufsize_t len = data ? (bufsize_t)strlen(data) : 0;
bufsize_t len = data ? cmark_strbuf_safe_strlen(data) : 0;
cmark_chunk c = {(unsigned char *)data, len, 0};
return c;
}
-20
View File
@@ -10,26 +10,6 @@ int cmark_version() { return CMARK_VERSION; }
const char *cmark_version_string() { return CMARK_VERSION_STRING; }
static void *xcalloc(size_t nmem, size_t size) {
void *ptr = calloc(nmem, size);
if (!ptr) {
fprintf(stderr, "[cmark] calloc returned null pointer, aborting\n");
abort();
}
return ptr;
}
static void *xrealloc(void *ptr, size_t size) {
void *new_ptr = realloc(ptr, size);
if (!new_ptr) {
fprintf(stderr, "[cmark] realloc returned null pointer, aborting\n");
abort();
}
return new_ptr;
}
cmark_mem DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, free};
char *cmark_markdown_to_html(const char *text, size_t len, int options) {
cmark_node *doc;
char *result;
+19 -70
View File
@@ -21,8 +21,7 @@ extern "C" {
/** Convert 'text' (assumed to be a UTF-8 encoded string with length
* 'len') from CommonMark Markdown to HTML, returning a null-terminated,
* UTF-8-encoded string. It is the caller's responsibility
* to free the returned buffer.
* UTF-8-encoded string.
*/
CMARK_EXPORT
char *cmark_markdown_to_html(const char *text, size_t len, int options);
@@ -87,19 +86,6 @@ typedef struct cmark_node cmark_node;
typedef struct cmark_parser cmark_parser;
typedef struct cmark_iter cmark_iter;
/**
* ## Custom memory allocator support
*/
/** Defines the memory allocation functions to be used by CMark
* when parsing and allocating a document tree
*/
typedef struct cmark_mem {
void *(*calloc)(size_t, size_t);
void *(*realloc)(void *, size_t);
void (*free)(void *);
} cmark_mem;
/**
* ## Creating and Destroying Nodes
*/
@@ -110,13 +96,6 @@ typedef struct cmark_mem {
*/
CMARK_EXPORT cmark_node *cmark_node_new(cmark_node_type type);
/** Same as `cmark_node_new`, but explicitly listing the memory
* allocator used to allocate the node. Note: be sure to use the same
* allocator for every node in a tree, or bad things can happen.
*/
CMARK_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type,
cmark_mem *mem);
/** Frees the memory allocated for a node and any children.
*/
CMARK_EXPORT void cmark_node_free(cmark_node *node);
@@ -200,9 +179,7 @@ typedef enum {
} cmark_event_type;
/** Creates a new iterator starting at 'root'. The current node and event
* type are undefined until 'cmark_iter_next' is called for the first time.
* The memory allocated for the iterator should be released using
* 'cmark_iter_free' when it is no longer needed.
* type are undefined until `cmark_iter_next` is called for the first time.
*/
CMARK_EXPORT
cmark_iter *cmark_iter_new(cmark_node *root);
@@ -265,8 +242,7 @@ CMARK_EXPORT
const char *cmark_node_get_type_string(cmark_node *node);
/** Returns the string contents of 'node', or an empty
string if none is set. Returns NULL if called on a
node that does not have string content.
string if none is set.
*/
CMARK_EXPORT const char *cmark_node_get_literal(cmark_node *node);
@@ -335,8 +311,7 @@ CMARK_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);
CMARK_EXPORT int cmark_node_set_fence_info(cmark_node *node, const char *info);
/** Returns the URL of a link or image 'node', or an empty string
if no URL is set. Returns NULL if called on a node that is
not a link or image.
if no URL is set.
*/
CMARK_EXPORT const char *cmark_node_get_url(cmark_node *node);
@@ -346,8 +321,7 @@ CMARK_EXPORT const char *cmark_node_get_url(cmark_node *node);
CMARK_EXPORT int cmark_node_set_url(cmark_node *node, const char *url);
/** Returns the title of a link or image 'node', or an empty
string if no title is set. Returns NULL if called on a node
that is not a link or image.
string if no title is set.
*/
CMARK_EXPORT const char *cmark_node_get_title(cmark_node *node);
@@ -357,8 +331,7 @@ CMARK_EXPORT const char *cmark_node_get_title(cmark_node *node);
CMARK_EXPORT int cmark_node_set_title(cmark_node *node, const char *title);
/** Returns the literal "on enter" text for a custom 'node', or
an empty string if no on_enter is set. Returns NULL if called
on a non-custom node.
an empty string if no on_enter is set.
*/
CMARK_EXPORT const char *cmark_node_get_on_enter(cmark_node *node);
@@ -370,8 +343,7 @@ CMARK_EXPORT int cmark_node_set_on_enter(cmark_node *node,
const char *on_enter);
/** Returns the literal "on exit" text for a custom 'node', or
an empty string if no on_exit is set. Returns NULL if
called on a non-custom node.
an empty string if no on_exit is set.
*/
CMARK_EXPORT const char *cmark_node_get_on_exit(cmark_node *node);
@@ -462,11 +434,6 @@ CMARK_EXPORT void cmark_consolidate_text_nodes(cmark_node *root);
CMARK_EXPORT
cmark_parser *cmark_parser_new(int options);
/** Creates a new parser object with the given memory allocator
*/
CMARK_EXPORT
cmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem);
/** Frees memory allocated for a parser object.
*/
CMARK_EXPORT
@@ -483,16 +450,13 @@ CMARK_EXPORT
cmark_node *cmark_parser_finish(cmark_parser *parser);
/** Parse a CommonMark document in 'buffer' of length 'len'.
* Returns a pointer to a tree of nodes. The memory allocated for
* the node tree should be released using 'cmark_node_free'
* when it is no longer needed.
* Returns a pointer to a tree of nodes.
*/
CMARK_EXPORT
cmark_node *cmark_parse_document(const char *buffer, size_t len, int options);
/** Parse a CommonMark document in file 'f', returning a pointer to
* a tree of nodes. The memory allocated for the node tree should be
* released using 'cmark_node_free' when it is no longer needed.
* a tree of nodes.
*/
CMARK_EXPORT
cmark_node *cmark_parse_file(FILE *f, int options);
@@ -501,33 +465,28 @@ cmark_node *cmark_parse_file(FILE *f, int options);
* ## Rendering
*/
/** Render a 'node' tree as XML. It is the caller's responsibility
* to free the returned buffer.
/** Render a 'node' tree as XML.
*/
CMARK_EXPORT
char *cmark_render_xml(cmark_node *root, int options);
/** Render a 'node' tree as an HTML fragment. It is up to the user
* to add an appropriate header and footer. It is the caller's
* responsibility to free the returned buffer.
* to add an appropriate header and footer.
*/
CMARK_EXPORT
char *cmark_render_html(cmark_node *root, int options);
/** Render a 'node' tree as a groff man page, without the header.
* It is the caller's responsibility to free the returned buffer.
*/
CMARK_EXPORT
char *cmark_render_man(cmark_node *root, int options, int width);
/** Render a 'node' tree as a commonmark document.
* It is the caller's responsibility to free the returned buffer.
*/
CMARK_EXPORT
char *cmark_render_commonmark(cmark_node *root, int options, int width);
/** Render a 'node' tree as a LaTeX document.
* It is the caller's responsibility to free the returned buffer.
*/
CMARK_EXPORT
char *cmark_render_latex(cmark_node *root, int options, int width);
@@ -552,29 +511,19 @@ char *cmark_render_latex(cmark_node *root, int options, int width);
*/
#define CMARK_OPT_HARDBREAKS (1 << 2)
/** `CMARK_OPT_SAFE` is defined here for API compatibility,
but it no longer has any effect. "Safe" mode is now the default:
set `CMARK_OPT_UNSAFE` to disable it.
/** Suppress raw HTML and unsafe links (`javascript:`, `vbscript:`,
* `file:`, and `data:`, except for `image/png`, `image/gif`,
* `image/jpeg`, or `image/webp` mime types). Raw HTML is replaced
* by a placeholder HTML comment. Unsafe links are replaced by
* empty strings.
*/
#define CMARK_OPT_SAFE (1 << 3)
/** Render raw HTML and unsafe links (`javascript:`, `vbscript:`,
* `file:`, and `data:`, except for `image/png`, `image/gif`,
* `image/jpeg`, or `image/webp` mime types). By default,
* raw HTML is replaced by a placeholder HTML comment. Unsafe
* links are replaced by empty strings.
*/
#define CMARK_OPT_UNSAFE (1 << 17)
/** Render `softbreak` elements as spaces.
*/
#define CMARK_OPT_NOBREAKS (1 << 4)
/**
* ### Options affecting parsing
*/
/** Legacy option (no effect).
/** Normalize tree by consolidating adjacent text nodes.
*/
#define CMARK_OPT_NORMALIZE (1 << 8)
@@ -601,13 +550,13 @@ char *cmark_render_latex(cmark_node *root, int options, int width);
* In hexadecimal format, the number 0x010203 represents version 1.2.3.
*/
CMARK_EXPORT
int cmark_version(void);
int cmark_version();
/** The library version string for runtime checks. Also available as
* macro CMARK_VERSION_STRING for compile time checks.
*/
CMARK_EXPORT
const char *cmark_version_string(void);
const char *cmark_version_string();
/** # AUTHORS
*
-2
View File
@@ -40,5 +40,3 @@ int cmark_isalnum(char c) {
}
int cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; }
int cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; }
-2
View File
@@ -17,8 +17,6 @@ int cmark_isalnum(char c);
int cmark_isdigit(char c);
int cmark_isalpha(char c);
#ifdef __cplusplus
}
#endif
@@ -33,10 +33,9 @@
# define CMARK_DEPRECATED_NO_EXPORT CMARK_NO_EXPORT CMARK_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef CMARK_NO_DEPRECATED
# define CMARK_NO_DEPRECATED
# endif
#define DEFINE_NO_DEPRECATED 0
#if DEFINE_NO_DEPRECATED
# define CMARK_NO_DEPRECATED
#endif
#endif /* CMARK_EXPORT_H */
#endif
+7
View File
@@ -0,0 +1,7 @@
#ifndef CMARK_VERSION_H
#define CMARK_VERSION_H
#define CMARK_VERSION ((0 << 16) | (25 << 8) | 2)
#define CMARK_VERSION_STRING "0.25.2"
#endif
+41 -66
View File
@@ -1,8 +1,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <ctype.h>
#include "config.h"
#include "cmark.h"
@@ -12,6 +12,7 @@
#include "scanners.h"
#include "render.h"
#define safe_strlen(s) cmark_strbuf_safe_strlen(s)
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
#define CR() renderer->cr(renderer)
@@ -22,7 +23,7 @@
// Functions to convert cmark_nodes to commonmark strings.
static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
int32_t c, unsigned char nextc) {
bool needs_escaping = false;
bool follows_digit =
renderer->buffer->size > 0 &&
@@ -30,37 +31,31 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
char encoded[ENCODED_SIZE];
needs_escaping =
c < 0x80 && escape != LITERAL &&
escape != LITERAL &&
((escape == NORMAL &&
(c < 0x20 ||
c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
(c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
c == '>' || c == '\\' || c == '`' || c == '!' ||
(c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
(c == '&' && isalpha(nextc)) || (c == '!' && nextc == '[') ||
(renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
// begin_content doesn't get set to false til we've passed digits
// at the beginning of line, so...
!follows_digit) ||
(renderer->begin_content && (c == '.' || c == ')') && follows_digit &&
(nextc == 0 || cmark_isspace(nextc))))) ||
(escape == URL &&
(c == '`' || c == '<' || c == '>' || cmark_isspace(c) || c == '\\' ||
c == ')' || c == '(')) ||
(escape == URL && (c == '`' || c == '<' || c == '>' || isspace(c) ||
c == '\\' || c == ')' || c == '(')) ||
(escape == TITLE &&
(c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
if (needs_escaping) {
if (escape == URL && cmark_isspace(c)) {
if (isspace(c)) {
// use percent encoding for spaces
snprintf(encoded, ENCODED_SIZE, "%%%2X", c);
snprintf(encoded, ENCODED_SIZE, "%%%2x", c);
cmark_strbuf_puts(renderer->buffer, encoded);
renderer->column += 3;
} else if (cmark_ispunct(c)) {
} else {
cmark_render_ascii(renderer, "\\");
cmark_render_code_point(renderer, c);
} else { // render as entity
snprintf(encoded, ENCODED_SIZE, "&#%d;", c);
cmark_strbuf_puts(renderer->buffer, encoded);
renderer->column += strlen(encoded);
}
} else {
cmark_render_code_point(renderer, c);
@@ -71,7 +66,7 @@ static int longest_backtick_sequence(const char *code) {
int longest = 0;
int current = 0;
size_t i = 0;
size_t code_len = strlen(code);
size_t code_len = safe_strlen(code);
while (i <= code_len) {
if (code[i] == '`') {
current++;
@@ -87,18 +82,16 @@ static int longest_backtick_sequence(const char *code) {
}
static int shortest_unused_backtick_sequence(const char *code) {
// note: if the shortest sequence is >= 32, this returns 32
// so as not to overflow the bit array.
uint32_t used = 1;
int32_t used = 1;
int current = 0;
size_t i = 0;
size_t code_len = strlen(code);
size_t code_len = safe_strlen(code);
while (i <= code_len) {
if (code[i] == '`') {
current++;
} else {
if (current > 0 && current < 32) {
used |= (1U << current);
if (current) {
used |= (1 << current);
}
current = 0;
}
@@ -106,7 +99,7 @@ static int shortest_unused_backtick_sequence(const char *code) {
}
// return number of first bit that is 0:
i = 0;
while (i < 32 && used & 1) {
while (used & 1) {
used = used >> 1;
i++;
}
@@ -172,18 +165,13 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
int list_number;
cmark_delim_type list_delim;
int numticks;
bool extra_spaces;
int i;
bool entering = (ev_type == CMARK_EVENT_ENTER);
const char *info, *code, *title;
char fencechar[2] = {'\0', '\0'};
size_t info_len, code_len;
char listmarker[LISTMARKER_SIZE];
char *emph_delim;
bool first_in_list_item;
bufsize_t marker_width;
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
!(CMARK_OPT_HARDBREAKS & options);
// Don't adjust tight list status til we've started the list.
// Otherwise we loose the blank line between a paragraph and
@@ -216,7 +204,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
case CMARK_NODE_LIST:
if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
node->next->type == CMARK_NODE_LIST)) {
// this ensures that a following indented code block or list will be
// this ensures that a following code block or list will be
// inteprereted correctly.
CR();
LIT("<!-- end list -->");
@@ -241,7 +229,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number,
list_delim == CMARK_PAREN_DELIM ? ")" : ".",
list_number < 10 ? " " : " ");
marker_width = strlen(listmarker);
marker_width = safe_strlen(listmarker);
}
if (entering) {
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
@@ -268,32 +256,27 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
}
LIT(" ");
renderer->begin_content = true;
renderer->no_linebreaks = true;
renderer->no_wrap = true;
} else {
renderer->no_linebreaks = false;
renderer->no_wrap = false;
BLANKLINE();
}
break;
case CMARK_NODE_CODE_BLOCK:
first_in_list_item = node->prev == NULL && node->parent &&
node->parent->type == CMARK_NODE_ITEM;
if (!first_in_list_item) {
BLANKLINE();
}
BLANKLINE();
info = cmark_node_get_fence_info(node);
info_len = strlen(info);
fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';
info_len = safe_strlen(info);
code = cmark_node_get_literal(node);
code_len = strlen(code);
code_len = safe_strlen(code);
// use indented form if no info, and code doesn't
// begin or end with a blank line, and code isn't
// first thing in a list item
if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&
!(cmark_isspace(code[code_len - 1]) &&
cmark_isspace(code[code_len - 2]))) &&
!first_in_list_item) {
if (info_len == 0 &&
(code_len > 2 && !isspace((unsigned char)code[0]) &&
!(isspace((unsigned char)code[code_len - 1]) && isspace((unsigned char)code[code_len - 2]))) &&
!(node->prev == NULL && node->parent &&
node->parent->type == CMARK_NODE_ITEM)) {
LIT(" ");
cmark_strbuf_puts(renderer->prefix, " ");
OUT(cmark_node_get_literal(node), false, LITERAL);
@@ -304,7 +287,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
numticks = 3;
}
for (i = 0; i < numticks; i++) {
LIT(fencechar);
LIT("`");
}
LIT(" ");
OUT(info, false, LITERAL);
@@ -312,7 +295,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
OUT(cmark_node_get_literal(node), false, LITERAL);
CR();
for (i = 0; i < numticks; i++) {
LIT(fencechar);
LIT("`");
}
}
BLANKLINE();
@@ -344,7 +327,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_TEXT:
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
OUT(cmark_node_get_literal(node), true, NORMAL);
break;
case CMARK_NODE_LINEBREAK:
@@ -355,33 +338,25 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_SOFTBREAK:
if (CMARK_OPT_HARDBREAKS & options) {
LIT(" ");
CR();
} else if (!renderer->no_linebreaks && renderer->width == 0 &&
!(CMARK_OPT_HARDBREAKS & options) &&
!(CMARK_OPT_NOBREAKS & options)) {
if (renderer->width == 0 && !(CMARK_OPT_HARDBREAKS & options)) {
CR();
} else {
OUT(" ", allow_wrap, LITERAL);
OUT(" ", true, LITERAL);
}
break;
case CMARK_NODE_CODE:
code = cmark_node_get_literal(node);
code_len = strlen(code);
code_len = safe_strlen(code);
numticks = shortest_unused_backtick_sequence(code);
extra_spaces = code_len == 0 ||
code[0] == '`' || code[code_len - 1] == '`' ||
code[0] == ' ' || code[code_len - 1] == ' ';
for (i = 0; i < numticks; i++) {
LIT("`");
}
if (extra_spaces) {
if (code_len == 0 || code[0] == '`') {
LIT(" ");
}
OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
if (extra_spaces) {
OUT(cmark_node_get_literal(node), true, LITERAL);
if (code_len == 0 || code[code_len - 1] == '`') {
LIT(" ");
}
for (i = 0; i < numticks; i++) {
@@ -442,7 +417,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
LIT("](");
OUT(cmark_node_get_url(node), false, URL);
title = cmark_node_get_title(node);
if (strlen(title) > 0) {
if (safe_strlen(title) > 0) {
LIT(" \"");
OUT(title, false, TITLE);
LIT("\"");
@@ -459,8 +434,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
LIT("](");
OUT(cmark_node_get_url(node), false, URL);
title = cmark_node_get_title(node);
if (strlen(title) > 0) {
OUT(" \"", allow_wrap, LITERAL);
if (safe_strlen(title) > 0) {
OUT(" \"", true, LITERAL);
OUT(title, false, TITLE);
LIT("\"");
}
View File
+36
View File
@@ -0,0 +1,36 @@
#ifndef CMARK_DEBUG_H
#define CMARK_DEBUG_H
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef NDEBUG
#define debug(M, ...)
#else
#define debug(M, ...) \
fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#endif
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_err(M, ...) \
fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, \
clean_errno(), ##__VA_ARGS__)
#define log_warn(M, ...) \
fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, \
clean_errno(), ##__VA_ARGS__)
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, \
__LINE__, ##__VA_ARGS__)
#define check(A, M, ...) \
if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
#define sentinel(M, ...) \
{ log_err(M, ##__VA_ARGS__); errno=0; goto error; }
#define check_debug(A, M, ...) \
if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
#endif
+1 -1
View File
@@ -6,7 +6,7 @@ struct cmark_entity_node {
};
#define CMARK_ENTITY_MIN_LENGTH 2
#define CMARK_ENTITY_MAX_LENGTH 32
#define CMARK_ENTITY_MAX_LENGTH 31
#define CMARK_NUM_ENTITIES 2125
static const struct cmark_entity_node cmark_entities[] = {
View File
+1 -1
View File
@@ -15,7 +15,7 @@
* - The characters which are *not* safe to be in
* an URL because they are RESERVED characters.
*
* We assume (lazily) that any RESERVED char that
* We asume (lazily) that any RESERVED char that
* appears inside an URL is actually meant to
* have its native function (i.e. as an URL
* component/separator) and hence needs no escaping.
View File
+1 -1
View File
@@ -16,7 +16,7 @@ static const unsigned char *S_lookup(int i, int low, int hi,
strncmp((const char *)s, (const char *)cmark_entities[i].entity, len);
if (cmp == 0 && cmark_entities[i].entity[len] == 0) {
return (const unsigned char *)cmark_entities[i].bytes;
} else if (cmp <= 0 && i > low) {
} else if (cmp < 0 && i > low) {
j = i - ((i - low) / 2);
if (j == i)
j -= 1;
+7 -9
View File
@@ -170,7 +170,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_HTML_BLOCK:
cr(html);
if (!(options & CMARK_OPT_UNSAFE)) {
if (options & CMARK_OPT_SAFE) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
@@ -228,8 +228,6 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_SOFTBREAK:
if (options & CMARK_OPT_HARDBREAKS) {
cmark_strbuf_puts(html, "<br />\n");
} else if (options & CMARK_OPT_NOBREAKS) {
cmark_strbuf_putc(html, ' ');
} else {
cmark_strbuf_putc(html, '\n');
}
@@ -242,7 +240,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
break;
case CMARK_NODE_HTML_INLINE:
if (!(options & CMARK_OPT_UNSAFE)) {
if (options & CMARK_OPT_SAFE) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
@@ -278,8 +276,8 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_LINK:
if (entering) {
cmark_strbuf_puts(html, "<a href=\"");
if ((options & CMARK_OPT_UNSAFE) ||
!(scan_dangerous_url(&node->as.link.url, 0))) {
if (!((options & CMARK_OPT_SAFE) &&
scan_dangerous_url(&node->as.link.url, 0))) {
houdini_escape_href(html, node->as.link.url.data,
node->as.link.url.len);
}
@@ -296,8 +294,8 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_IMAGE:
if (entering) {
cmark_strbuf_puts(html, "<img src=\"");
if ((options & CMARK_OPT_UNSAFE) ||
!(scan_dangerous_url(&node->as.link.url, 0))) {
if (!((options & CMARK_OPT_SAFE) &&
scan_dangerous_url(&node->as.link.url, 0))) {
houdini_escape_href(html, node->as.link.url.data,
node->as.link.url.len);
}
@@ -324,7 +322,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
char *cmark_render_html(cmark_node *root, int options) {
char *result;
cmark_strbuf html = CMARK_BUF_INIT(cmark_node_mem(root));
cmark_strbuf html = GH_BUF_INIT;
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = {&html, NULL};
File diff suppressed because it is too large Load Diff
+262 -478
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
#ifndef CMARK_INLINES_H
#define CMARK_INLINES_H
#import "references.h"
#ifdef __cplusplus
extern "C" {
#endif
cmark_chunk cmark_clean_url(cmark_chunk *url);
cmark_chunk cmark_clean_title(cmark_chunk *title);
void cmark_parse_inlines(cmark_node *parent, cmark_reference_map *refmap,
int options);
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input,
cmark_reference_map *refmap);
#ifdef __cplusplus
}
#endif
#endif
+7 -7
View File
@@ -16,9 +16,10 @@ cmark_iter *cmark_iter_new(cmark_node *root) {
if (root == NULL) {
return NULL;
}
cmark_mem *mem = root->content.mem;
cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter));
iter->mem = mem;
cmark_iter *iter = (cmark_iter *)malloc(sizeof(cmark_iter));
if (iter == NULL) {
return NULL;
}
iter->root = root;
iter->cur.ev_type = CMARK_EVENT_NONE;
iter->cur.node = NULL;
@@ -27,7 +28,7 @@ cmark_iter *cmark_iter_new(cmark_node *root) {
return iter;
}
void cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); }
void cmark_iter_free(cmark_iter *iter) { free(iter); }
static bool S_is_leaf(cmark_node *node) {
return ((1 << node->type) & S_leaf_mask) != 0;
@@ -92,7 +93,7 @@ void cmark_consolidate_text_nodes(cmark_node *root) {
return;
}
cmark_iter *iter = cmark_iter_new(root);
cmark_strbuf buf = CMARK_BUF_INIT(iter->mem);
cmark_strbuf buf = GH_BUF_INIT;
cmark_event_type ev_type;
cmark_node *cur, *tmp, *next;
@@ -106,12 +107,11 @@ void cmark_consolidate_text_nodes(cmark_node *root) {
while (tmp && tmp->type == CMARK_NODE_TEXT) {
cmark_iter_next(iter); // advance pointer
cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len);
cur->end_column = tmp->end_column;
next = tmp->next;
cmark_node_free(tmp);
tmp = next;
}
cmark_chunk_free(iter->mem, &cur->as.literal);
cmark_chunk_free(&cur->as.literal);
cur->as.literal = cmark_chunk_buf_detach(&buf);
}
}
-1
View File
@@ -13,7 +13,6 @@ typedef struct {
} cmark_iter_state;
struct cmark_iter {
cmark_mem *mem;
cmark_node *root;
cmark_iter_state cur;
cmark_iter_state next;
+20 -37
View File
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "config.h"
#include "cmark.h"
@@ -11,6 +12,7 @@
#include "scanners.h"
#include "render.h"
#define safe_strlen(s) cmark_strbuf_safe_strlen(s)
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
#define CR() renderer->cr(renderer)
@@ -18,7 +20,7 @@
#define LIST_NUMBER_STRING_SIZE 20
static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
int32_t c, unsigned char nextc) {
if (escape == LITERAL) {
cmark_render_code_point(renderer, c);
return;
@@ -42,7 +44,7 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
break;
case 45: // '-'
if (nextc == 45) { // prevent ligature
cmark_render_ascii(renderer, "-{}");
cmark_render_ascii(renderer, "\\-");
} else {
cmark_render_ascii(renderer, "-");
}
@@ -167,24 +169,20 @@ static link_type get_link_type(cmark_node *node) {
return INTERNAL_LINK;
}
url_len = strlen(url);
url_len = safe_strlen(url);
if (url_len == 0 || scan_scheme(&url_chunk, 0) == 0) {
return NO_LINK;
}
const char *title = cmark_node_get_title(node);
title_len = strlen(title);
title_len = safe_strlen(title);
// if it has a title, we can't treat it as an autolink:
if (title_len == 0) {
link_text = node->first_child;
cmark_consolidate_text_nodes(link_text);
if (!link_text)
return NO_LINK;
realurl = (char *)url;
realurllen = (int)url_len;
realurllen = url_len;
if (strncmp(realurl, "mailto:", 7) == 0) {
realurl += 7;
realurllen -= 7;
@@ -220,11 +218,11 @@ static int S_get_enumlevel(cmark_node *node) {
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
int list_number;
int enumlevel;
char list_number_string[LIST_NUMBER_STRING_SIZE];
bool entering = (ev_type == CMARK_EVENT_ENTER);
cmark_list_type list_type;
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
const char *roman_numerals[] = {"", "i", "ii", "iii", "iv", "v",
"vi", "vii", "viii", "ix", "x"};
// avoid warning about unused parameter:
(void)(options);
@@ -252,24 +250,13 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
CR();
list_number = cmark_node_get_list_start(node);
if (list_number > 1) {
enumlevel = S_get_enumlevel(node);
// latex normally supports only five levels
if (enumlevel >= 1 && enumlevel <= 5) {
snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
list_number);
LIT("\\setcounter{enum");
switch (enumlevel) {
case 1: LIT("i"); break;
case 2: LIT("ii"); break;
case 3: LIT("iii"); break;
case 4: LIT("iv"); break;
case 5: LIT("v"); break;
default: LIT("i"); break;
}
LIT("}{");
OUT(list_number_string, false, NORMAL);
LIT("}");
}
snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, "%d",
list_number);
LIT("\\setcounter{enum");
LIT((char *)roman_numerals[S_get_enumlevel(node)]);
LIT("}{");
OUT(list_number_string, false, NORMAL);
LIT("}");
CR();
}
} else {
@@ -347,7 +334,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_TEXT:
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
OUT(cmark_node_get_literal(node), true, NORMAL);
break;
case CMARK_NODE_LINEBREAK:
@@ -356,13 +343,10 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_SOFTBREAK:
if (options & CMARK_OPT_HARDBREAKS) {
LIT("\\\\");
CR();
} else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {
if (renderer->width == 0) {
CR();
} else {
OUT(" ", allow_wrap, NORMAL);
OUT(" ", true, NORMAL);
}
break;
@@ -404,8 +388,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
case URL_AUTOLINK:
LIT("\\url{");
OUT(url, false, URL);
LIT("}");
return 0; // Don't process further nodes to avoid double-rendering artefacts
break;
case EMAIL_AUTOLINK:
LIT("\\href{");
OUT(url, false, URL);
+5 -9
View File
@@ -75,7 +75,6 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_node *tmp;
int list_number;
bool entering = (ev_type == CMARK_EVENT_ENTER);
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
// avoid unused parameter error:
(void)(options);
@@ -174,7 +173,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_TEXT:
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
OUT(cmark_node_get_literal(node), true, NORMAL);
break;
case CMARK_NODE_LINEBREAK:
@@ -183,19 +182,16 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
break;
case CMARK_NODE_SOFTBREAK:
if (options & CMARK_OPT_HARDBREAKS) {
LIT(".PD 0\n.P\n.PD");
CR();
} else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {
if (renderer->width == 0) {
CR();
} else {
OUT(" ", allow_wrap, LITERAL);
OUT(" ", true, LITERAL);
}
break;
case CMARK_NODE_CODE:
LIT("\\f[C]");
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
OUT(cmark_node_get_literal(node), true, NORMAL);
LIT("\\f[]");
break;
@@ -226,7 +222,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
case CMARK_NODE_LINK:
if (!entering) {
LIT(" (");
OUT(cmark_node_get_url(node), allow_wrap, URL);
OUT(cmark_node_get_url(node), true, URL);
LIT(")");
}
break;
@@ -1,4 +1,5 @@
module libcmark [system][extern_c] {
header "../node.h"
header "node.h"
header "cmark.h"
export *
}
}
+30 -36
View File
@@ -6,8 +6,6 @@
static void S_node_unlink(cmark_node *node);
#define NODE_MEM(node) cmark_node_mem(node)
static CMARK_INLINE bool S_is_block(cmark_node *node) {
if (node == NULL) {
return false;
@@ -72,10 +70,9 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
return false;
}
cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
cmark_strbuf_init(mem, &node->content, 0);
node->type = (uint16_t)type;
cmark_node *cmark_node_new(cmark_node_type type) {
cmark_node *node = (cmark_node *)calloc(1, sizeof(*node));
node->type = type;
switch (node->type) {
case CMARK_NODE_HEADING:
@@ -85,7 +82,7 @@ cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
case CMARK_NODE_LIST: {
cmark_list *list = &node->as.list;
list->list_type = CMARK_BULLET_LIST;
list->start = 0;
list->start = 1;
list->tight = false;
break;
}
@@ -97,36 +94,33 @@ cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
return node;
}
cmark_node *cmark_node_new(cmark_node_type type) {
extern cmark_mem DEFAULT_MEM_ALLOCATOR;
return cmark_node_new_with_mem(type, &DEFAULT_MEM_ALLOCATOR);
}
// Free a cmark_node list and any children.
static void S_free_nodes(cmark_node *e) {
cmark_node *next;
while (e != NULL) {
cmark_strbuf_free(&e->content);
if (S_is_block(e)) {
cmark_strbuf_free(&e->string_content);
}
switch (e->type) {
case CMARK_NODE_CODE_BLOCK:
cmark_chunk_free(NODE_MEM(e), &e->as.code.info);
cmark_chunk_free(NODE_MEM(e), &e->as.code.literal);
cmark_chunk_free(&e->as.code.info);
cmark_chunk_free(&e->as.code.literal);
break;
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
case CMARK_NODE_HTML_BLOCK:
cmark_chunk_free(NODE_MEM(e), &e->as.literal);
cmark_chunk_free(&e->as.literal);
break;
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
cmark_chunk_free(NODE_MEM(e), &e->as.link.url);
cmark_chunk_free(NODE_MEM(e), &e->as.link.title);
cmark_chunk_free(&e->as.link.url);
cmark_chunk_free(&e->as.link.title);
break;
case CMARK_NODE_CUSTOM_BLOCK:
case CMARK_NODE_CUSTOM_INLINE:
cmark_chunk_free(NODE_MEM(e), &e->as.custom.on_enter);
cmark_chunk_free(NODE_MEM(e), &e->as.custom.on_exit);
cmark_chunk_free(&e->as.custom.on_enter);
cmark_chunk_free(&e->as.custom.on_exit);
break;
default:
break;
@@ -137,7 +131,7 @@ static void S_free_nodes(cmark_node *e) {
e->next = e->first_child;
}
next = e->next;
NODE_MEM(e)->free(e);
free(e);
e = next;
}
}
@@ -152,7 +146,7 @@ cmark_node_type cmark_node_get_type(cmark_node *node) {
if (node == NULL) {
return CMARK_NODE_NONE;
} else {
return (cmark_node_type)node->type;
return node->type;
}
}
@@ -275,10 +269,10 @@ const char *cmark_node_get_literal(cmark_node *node) {
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.literal);
return cmark_chunk_to_cstr(&node->as.literal);
case CMARK_NODE_CODE_BLOCK:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.literal);
return cmark_chunk_to_cstr(&node->as.code.literal);
default:
break;
@@ -297,11 +291,11 @@ int cmark_node_set_literal(cmark_node *node, const char *content) {
case CMARK_NODE_TEXT:
case CMARK_NODE_HTML_INLINE:
case CMARK_NODE_CODE:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.literal, content);
cmark_chunk_set_cstr(&node->as.literal, content);
return 1;
case CMARK_NODE_CODE_BLOCK:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.literal, content);
cmark_chunk_set_cstr(&node->as.code.literal, content);
return 1;
default:
@@ -458,7 +452,7 @@ const char *cmark_node_get_fence_info(cmark_node *node) {
}
if (node->type == CMARK_NODE_CODE_BLOCK) {
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.info);
return cmark_chunk_to_cstr(&node->as.code.info);
} else {
return NULL;
}
@@ -470,7 +464,7 @@ int cmark_node_set_fence_info(cmark_node *node, const char *info) {
}
if (node->type == CMARK_NODE_CODE_BLOCK) {
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.info, info);
cmark_chunk_set_cstr(&node->as.code.info, info);
return 1;
} else {
return 0;
@@ -485,7 +479,7 @@ const char *cmark_node_get_url(cmark_node *node) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.url);
return cmark_chunk_to_cstr(&node->as.link.url);
default:
break;
}
@@ -501,7 +495,7 @@ int cmark_node_set_url(cmark_node *node, const char *url) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.url, url);
cmark_chunk_set_cstr(&node->as.link.url, url);
return 1;
default:
break;
@@ -518,7 +512,7 @@ const char *cmark_node_get_title(cmark_node *node) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.title);
return cmark_chunk_to_cstr(&node->as.link.title);
default:
break;
}
@@ -534,7 +528,7 @@ int cmark_node_set_title(cmark_node *node, const char *title) {
switch (node->type) {
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.title, title);
cmark_chunk_set_cstr(&node->as.link.title, title);
return 1;
default:
break;
@@ -551,7 +545,7 @@ const char *cmark_node_get_on_enter(cmark_node *node) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_enter);
return cmark_chunk_to_cstr(&node->as.custom.on_enter);
default:
break;
}
@@ -567,7 +561,7 @@ int cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_enter, on_enter);
cmark_chunk_set_cstr(&node->as.custom.on_enter, on_enter);
return 1;
default:
break;
@@ -584,7 +578,7 @@ const char *cmark_node_get_on_exit(cmark_node *node) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_exit);
return cmark_chunk_to_cstr(&node->as.custom.on_exit);
default:
break;
}
@@ -600,7 +594,7 @@ int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {
switch (node->type) {
case CMARK_NODE_CUSTOM_INLINE:
case CMARK_NODE_CUSTOM_BLOCK:
cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit);
cmark_chunk_set_cstr(&node->as.custom.on_exit, on_exit);
return 1;
default:
break;
+11 -17
View File
@@ -25,10 +25,11 @@ typedef struct {
typedef struct {
cmark_chunk info;
cmark_chunk literal;
uint8_t fence_length;
uint8_t fence_offset;
int fence_length;
/* fence_offset must be 0-3, so we can use int8_t */
int8_t fence_offset;
unsigned char fence_char;
int8_t fenced;
bool fenced;
} cmark_code;
typedef struct {
@@ -46,15 +47,7 @@ typedef struct {
cmark_chunk on_exit;
} cmark_custom;
enum cmark_node__internal_flags {
CMARK_NODE__OPEN = (1 << 0),
CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),
};
struct cmark_node {
cmark_strbuf content;
struct cmark_node *next;
struct cmark_node *prev;
struct cmark_node *parent;
@@ -67,9 +60,13 @@ struct cmark_node {
int start_column;
int end_line;
int end_column;
int internal_offset;
uint16_t type;
uint16_t flags;
cmark_node_type type;
bool open;
bool last_line_blank;
cmark_strbuf string_content;
union {
cmark_chunk literal;
@@ -82,9 +79,6 @@ struct cmark_node {
} as;
};
static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
return node->content.mem;
}
CMARK_EXPORT int cmark_node_check(cmark_node *node, FILE *out);
#ifdef __cplusplus
+2 -5
View File
@@ -2,7 +2,6 @@
#define CMARK_AST_H
#include <stdio.h>
#include "references.h"
#include "node.h"
#include "buffer.h"
@@ -13,7 +12,6 @@ extern "C" {
#define MAX_LINK_LABEL_LENGTH 1000
struct cmark_parser {
struct cmark_mem *mem;
struct cmark_reference_map *refmap;
struct cmark_node *root;
struct cmark_node *current;
@@ -22,13 +20,12 @@ struct cmark_parser {
bufsize_t column;
bufsize_t first_nonspace;
bufsize_t first_nonspace_column;
bufsize_t thematic_break_kill_pos;
int indent;
bool blank;
bool partially_consumed_tab;
cmark_strbuf curline;
cmark_strbuf *curline;
bufsize_t last_line_length;
cmark_strbuf linebuf;
cmark_strbuf *linebuf;
int options;
bool last_buffer_ended_with_cr;
};
+26 -28
View File
@@ -14,13 +14,12 @@ static unsigned int refhash(const unsigned char *link_ref) {
return hash;
}
static void reference_free(cmark_reference_map *map, cmark_reference *ref) {
cmark_mem *mem = map->mem;
static void reference_free(cmark_reference *ref) {
if (ref != NULL) {
mem->free(ref->label);
cmark_chunk_free(mem, &ref->url);
cmark_chunk_free(mem, &ref->title);
mem->free(ref);
free(ref->label);
cmark_chunk_free(&ref->url);
cmark_chunk_free(&ref->title);
free(ref);
}
}
@@ -28,8 +27,8 @@ static void reference_free(cmark_reference_map *map, cmark_reference *ref) {
// remove leading/trailing whitespace, case fold
// Return NULL if the reference name is actually empty (i.e. composed
// solely from whitespace)
static unsigned char *normalize_reference(cmark_mem *mem, cmark_chunk *ref) {
cmark_strbuf normalized = CMARK_BUF_INIT(mem);
static unsigned char *normalize_reference(cmark_chunk *ref) {
cmark_strbuf normalized = GH_BUF_INIT;
unsigned char *result;
if (ref == NULL)
@@ -46,7 +45,7 @@ static unsigned char *normalize_reference(cmark_mem *mem, cmark_chunk *ref) {
assert(result);
if (result[0] == '\0') {
mem->free(result);
free(result);
return NULL;
}
@@ -58,7 +57,7 @@ static void add_reference(cmark_reference_map *map, cmark_reference *ref) {
while (t) {
if (t->hash == ref->hash && !strcmp((char *)t->label, (char *)ref->label)) {
reference_free(map, ref);
reference_free(ref);
return;
}
@@ -71,20 +70,22 @@ static void add_reference(cmark_reference_map *map, cmark_reference *ref) {
void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label,
cmark_chunk *url, cmark_chunk *title) {
cmark_reference *ref;
unsigned char *reflabel = normalize_reference(map->mem, label);
unsigned char *reflabel = normalize_reference(label);
/* empty reference name, or composed from only whitespace */
if (reflabel == NULL)
return;
ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref));
ref->label = reflabel;
ref->hash = refhash(ref->label);
ref->url = cmark_clean_url(map->mem, url);
ref->title = cmark_clean_title(map->mem, title);
ref->next = NULL;
ref = (cmark_reference *)calloc(1, sizeof(*ref));
if (ref != NULL) {
ref->label = reflabel;
ref->hash = refhash(ref->label);
ref->url = cmark_clean_url(url);
ref->title = cmark_clean_title(title);
ref->next = NULL;
add_reference(map, ref);
add_reference(map, ref);
}
}
// Returns reference if refmap contains a reference with matching
@@ -95,13 +96,13 @@ cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
unsigned char *norm;
unsigned int hash;
if (label->len < 1 || label->len > MAX_LINK_LABEL_LENGTH)
if (label->len > MAX_LINK_LABEL_LENGTH)
return NULL;
if (map == NULL)
return NULL;
norm = normalize_reference(map->mem, label);
norm = normalize_reference(label);
if (norm == NULL)
return NULL;
@@ -114,7 +115,7 @@ cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
ref = ref->next;
}
map->mem->free(norm);
free(norm);
return ref;
}
@@ -130,17 +131,14 @@ void cmark_reference_map_free(cmark_reference_map *map) {
while (ref) {
next = ref->next;
reference_free(map, ref);
reference_free(ref);
ref = next;
}
}
map->mem->free(map);
free(map);
}
cmark_reference_map *cmark_reference_map_new(cmark_mem *mem) {
cmark_reference_map *map =
(cmark_reference_map *)mem->calloc(1, sizeof(cmark_reference_map));
map->mem = mem;
return map;
cmark_reference_map *cmark_reference_map_new(void) {
return (cmark_reference_map *)calloc(1, sizeof(cmark_reference_map));
}
+1 -2
View File
@@ -20,13 +20,12 @@ struct cmark_reference {
typedef struct cmark_reference cmark_reference;
struct cmark_reference_map {
cmark_mem *mem;
cmark_reference *table[REFMAP_SIZE];
};
typedef struct cmark_reference_map cmark_reference_map;
cmark_reference_map *cmark_reference_map_new(cmark_mem *mem);
cmark_reference_map *cmark_reference_map_new(void);
void cmark_reference_map_free(cmark_reference_map *map);
cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
cmark_chunk *label);
+25 -31
View File
@@ -4,7 +4,6 @@
#include "cmark.h"
#include "utf8.h"
#include "render.h"
#include "node.h"
static CMARK_INLINE void S_cr(cmark_renderer *renderer) {
if (renderer->need_cr < 1) {
@@ -20,7 +19,7 @@ static CMARK_INLINE void S_blankline(cmark_renderer *renderer) {
static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
cmark_escaping escape) {
int length = strlen(source);
int length = cmark_strbuf_safe_strlen(source);
unsigned char nextc;
int32_t c;
int i = 0;
@@ -29,7 +28,7 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
cmark_chunk remainder = cmark_chunk_literal("");
int k = renderer->buffer->size - 1;
wrap = wrap && !renderer->no_linebreaks;
wrap = wrap && !renderer->no_wrap;
if (renderer->in_tight_list_item && renderer->need_cr > 1) {
renderer->need_cr = 1;
@@ -45,7 +44,6 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
}
}
renderer->column = 0;
renderer->last_breakable = 0;
renderer->begin_line = true;
renderer->begin_content = true;
renderer->need_cr -= 1;
@@ -82,23 +80,21 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
}
}
} else if (c == 10) {
cmark_strbuf_putc(renderer->buffer, '\n');
renderer->column = 0;
renderer->begin_line = true;
renderer->begin_content = true;
renderer->last_breakable = 0;
} else if (escape == LITERAL) {
if (c == 10) {
cmark_strbuf_putc(renderer->buffer, '\n');
renderer->column = 0;
renderer->begin_line = true;
renderer->begin_content = true;
renderer->last_breakable = 0;
} else {
cmark_render_code_point(renderer, c);
renderer->begin_line = false;
// we don't set 'begin_content' to false til we've
// finished parsing a digit. Reason: in commonmark
// we need to escape a potential list marker after
// a digit:
renderer->begin_content =
renderer->begin_content && cmark_isdigit(c) == 1;
}
cmark_render_code_point(renderer, c);
renderer->begin_line = false;
// we don't set 'begin_content' to false til we've
// finished parsing a digit. Reason: in commonmark
// we need to escape a potential list marker after
// a digit:
renderer->begin_content =
renderer->begin_content && cmark_isdigit(c) == 1;
} else {
(renderer->outc)(renderer, escape, c, nextc);
renderer->begin_line = false;
@@ -112,9 +108,8 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
!renderer->begin_line && renderer->last_breakable > 0) {
// copy from last_breakable to remainder
cmark_chunk_set_cstr(renderer->mem, &remainder,
(char *)renderer->buffer->ptr +
renderer->last_breakable + 1);
cmark_chunk_set_cstr(&remainder, (char *)renderer->buffer->ptr +
renderer->last_breakable + 1);
// truncate at last_breakable
cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);
// add newline, prefix, and remainder
@@ -123,7 +118,7 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
renderer->prefix->size);
cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);
renderer->column = renderer->prefix->size + remainder.len;
cmark_chunk_free(renderer->mem, &remainder);
cmark_chunk_free(&remainder);
renderer->last_breakable = 0;
renderer->begin_line = false;
renderer->begin_content = false;
@@ -151,17 +146,16 @@ char *cmark_render(cmark_node *root, int options, int width,
int (*render_node)(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type, int options)) {
cmark_mem *mem = cmark_node_mem(root);
cmark_strbuf pref = CMARK_BUF_INIT(mem);
cmark_strbuf buf = CMARK_BUF_INIT(mem);
cmark_strbuf pref = GH_BUF_INIT;
cmark_strbuf buf = GH_BUF_INIT;
cmark_node *cur;
cmark_event_type ev_type;
char *result;
cmark_iter *iter = cmark_iter_new(root);
cmark_renderer renderer = {mem, &buf, &pref, 0, width,
0, 0, true, true, false,
false, outc, S_cr, S_blankline, S_out};
cmark_renderer renderer = {&buf, &pref, 0, width, 0,
0, true, true, false, false,
outc, S_cr, S_blankline, S_out};
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
@@ -174,7 +168,7 @@ char *cmark_render(cmark_node *root, int options, int width,
}
// ensure final newline
if (renderer.buffer->size == 0 || renderer.buffer->ptr[renderer.buffer->size - 1] != '\n') {
if (renderer.buffer->ptr[renderer.buffer->size - 1] != '\n') {
cmark_strbuf_putc(renderer.buffer, '\n');
}

Some files were not shown because too many files have changed in this diff Show More