Compare commits
215 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e754ab1c80 | |||
| 3b07bb52cf | |||
| 055f818ed7 | |||
| 9997dc00cb | |||
| e2b597d469 | |||
| bf24fcbb2d | |||
| f34b166be1 | |||
| 0586cec03b | |||
| 2524b62470 | |||
| f83e9a2566 | |||
| 3ac921e3a9 | |||
| d127a624d3 | |||
| 0bcd20dc56 | |||
| 4fb13c2fac | |||
| 4c1c888152 | |||
| 5abcbcca06 | |||
| 69c7029e1f | |||
| 21d522d876 | |||
| f2e4658f79 | |||
| 277507d0af | |||
| cbe21adfdc | |||
| 5a0b527000 | |||
| 731f6bbab2 | |||
| 8f380a5558 | |||
| 6689a8fb6b | |||
| 968ef0d4ba | |||
| fdfa661aa7 | |||
| ff68cfec88 | |||
| 296ad5409a | |||
| a23efb1527 | |||
| 427aec0a0a | |||
| 6638a36b26 | |||
| c389ca6624 | |||
| dd2a448eb4 | |||
| de6c58760f | |||
| 2aada56e6a | |||
| 69a006cd1b | |||
| 79c3d29f13 | |||
| 907d67cb59 | |||
| cd1a3f6565 | |||
| b99cbca24f | |||
| 0095468027 | |||
| c20e8e2d4c | |||
| 5aa5a55193 | |||
| 940b173fc1 | |||
| 02d90cc5ff | |||
| 3f5dfe3ed8 | |||
| cea0e2df5a | |||
| 4c72856a5c | |||
| 2e2a8f2f0c | |||
| 7c5d45ac9e | |||
| dcf86dcce5 | |||
| 805e537949 | |||
| 0e383bc1bb | |||
| 4e4ddcef85 | |||
| 5f54bc0168 | |||
| 6d63c13cc1 | |||
| 589545794f | |||
| 0afc8c18d9 | |||
| d94b270cff | |||
| 80d8b2d50d | |||
| 5396a85265 | |||
| 2b25ee0a0c | |||
| 7b25a10457 | |||
| f7dacd7d2c | |||
| 2d64aae0d0 | |||
| cb9ee72196 | |||
| 4a1ad245e0 | |||
| ae031a3668 | |||
| d32bc14333 | |||
| f82b61ff8e | |||
| 606c1e14dd | |||
| 49b3ebae4d | |||
| c0660dcda8 | |||
| a0535b7222 | |||
| 17a5842293 | |||
| 25fde3d7c8 | |||
| 3d044c766b | |||
| 4c35c7b0c5 | |||
| 410e45c77b | |||
| bc65c735bc | |||
| 8c96f29e91 | |||
| c70d824918 | |||
| 6e566e2d45 | |||
| 54664f90be | |||
| 07a117ef4a | |||
| a146258961 | |||
| 1685184749 | |||
| 1fecb4b3a4 | |||
| 8b1f549ace | |||
| 421a92f5df | |||
| bdd5215c9a | |||
| 23e7744b67 | |||
| 3e1e986138 | |||
| 4d947996fc | |||
| 8d0dcae7c1 | |||
| 8db18023dd | |||
| d93f3650c8 | |||
| d02f0f1d6e | |||
| 1c90cbbd7d | |||
| b38d1d6e63 | |||
| fc5081d065 | |||
| d71ec73d27 | |||
| 0c5cd04c76 | |||
| d753044f9d | |||
| 954004ba80 | |||
| b50767598c | |||
| b3094ba7c1 | |||
| 604bc5085e | |||
| 9c4c1881b6 | |||
| 6b0e3d87c3 | |||
| a2d6ee7fc7 | |||
| 121441f803 | |||
| b5c9b4f123 | |||
| 9a7f648504 | |||
| 5982d7792f | |||
| 0b9f0a2f72 | |||
| 17c07067f2 | |||
| 9d6ca2e042 | |||
| 267d8e7e10 | |||
| 7f1fd50d8c | |||
| b4de8302a1 | |||
| 35c2a7cc6a | |||
| 1f58905c61 | |||
| 1c3c8db4fc | |||
| 534a0f3fee | |||
| 713f5705dc | |||
| 69ac9c228e | |||
| 8b1392c3f4 | |||
| c5c571487e | |||
| f1ea78c18d | |||
| a681d1e3f9 | |||
| 4082c8d943 | |||
| 5fe883cbef | |||
| 2faeff48e8 | |||
| 09b9b54a04 | |||
| 0f3fe145a9 | |||
| daf6bce726 | |||
| d0c23a3def | |||
| 423c98a17b | |||
| abb00d0756 | |||
| c6cf863532 | |||
| df33533798 | |||
| a11a6f83a4 | |||
| 506db5128f | |||
| ba35dda81a | |||
| a6a67fdbe6 | |||
| 44cb14325a | |||
| c3a1504cf6 | |||
| 791ecf04a2 | |||
| d501d0e2d9 | |||
| 243644f583 | |||
| c6757b3a6a | |||
| 6f9249dcf9 | |||
| 9b9b30958c | |||
| fbf9ef54b5 | |||
| eb4e820a8c | |||
| 640f3e5aeb | |||
| 2af0b93890 | |||
| 642c5644c4 | |||
| 52111e7efc | |||
| 37b856b04c | |||
| dc60b14231 | |||
| 9da82b4d7d | |||
| 043b7c636e | |||
| b6f073e5a1 | |||
| cc9e4124f5 | |||
| ec725d5af2 | |||
| 7a9c1f028c | |||
| 11b56bffc2 | |||
| 66061e44e8 | |||
| 2dd538e24d | |||
| bcee193880 | |||
| d695bbdc08 | |||
| 395ff4df4e | |||
| 789fa2184b | |||
| 06508b4457 | |||
| a062be8d06 | |||
| c511eee32b | |||
| dd5646c849 | |||
| 611a8189d6 | |||
| 0ca1ac1b0f | |||
| 01b5edabbf | |||
| 26b6766ff1 | |||
| 18eb466f48 | |||
| 5c92541e6b | |||
| 0b196213dd | |||
| 79bf4deccc | |||
| d9b87e6c4d | |||
| 4caf6aa81f | |||
| c482ac3d9f | |||
| 3860c80b14 | |||
| f680a4e191 | |||
| 66b00301fc | |||
| 5145cb34b7 | |||
| e62d91c120 | |||
| dd7448fd7f | |||
| 17821440fc | |||
| a3abd8057b | |||
| 142e930838 | |||
| 507838b52b | |||
| 7abb635d7b | |||
| 43241e5096 | |||
| ce4517d9fd | |||
| 806fc0b78a | |||
| addc2350d7 | |||
| b043c749c1 | |||
| b944f1a4cd | |||
| f2169a1f4f | |||
| fa5eb4b655 | |||
| c53646a15b | |||
| 23332a3ee1 | |||
| 544f788b76 | |||
| c1ff17e14f | |||
| 65f1c47699 |
@@ -1,3 +1,9 @@
|
||||
---
|
||||
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.
|
||||
@@ -15,5 +21,3 @@ Please help prevent duplicate issues before submitting a new one:
|
||||
## What happened instead?
|
||||
|
||||
ℹ Please replace this with what happened instead (e.g. the issue).
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
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.
|
||||
@@ -0,0 +1,17 @@
|
||||
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
@@ -1,9 +1,9 @@
|
||||
Pods/
|
||||
.build/
|
||||
.DS_Store
|
||||
xcuserdata
|
||||
|
||||
# additional ignores that will save us time
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
coverage_service: coveralls
|
||||
xcodeproj: Down.xcodeproj
|
||||
source_directory: Source
|
||||
ignore:
|
||||
- Source/cmark/*
|
||||
@@ -1 +0,0 @@
|
||||
3.0
|
||||
@@ -0,0 +1,10 @@
|
||||
included:
|
||||
- Sources/Down
|
||||
- Tests
|
||||
|
||||
large_tuple:
|
||||
warning: 3
|
||||
error: 4
|
||||
|
||||
cyclomatic_complexity:
|
||||
ignores_case_statements: true
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+10
-7
@@ -1,9 +1,12 @@
|
||||
osx_image: xcode8
|
||||
osx_image: xcode12.2
|
||||
language: objective-c
|
||||
before_install:
|
||||
- gem install xcpretty slather -N
|
||||
- xcrun instruments -w "iPhone 5 (9.3)" || echo "(Pre)Launched the simulator."
|
||||
before_install:
|
||||
- set -o pipefail
|
||||
- xcrun simctl boot "iPhone 12" || echo "(Pre)Launched the simulator."
|
||||
script:
|
||||
- set -o pipefail && xcodebuild test -project Down.xcodeproj -scheme "Down-iOS" -destination "platform=iOS Simulator,name=iPhone 5,OS=9.3" -enableCodeCoverage YES ONLY_ACTIVE_ARCH=YES | xcpretty -c
|
||||
after_success:
|
||||
- slather coverage --ignore "../**/*/Xcode*" --ignore "Source/cmark/*" --scheme "Down-iOS" Down.xcodeproj
|
||||
- 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)
|
||||
|
||||
+589
-40
@@ -1,62 +1,611 @@
|
||||
# Change Log
|
||||
# Changelog
|
||||
|
||||
## [Unreleased](https://github.com/iwasrobbed/Down/tree/HEAD)
|
||||
## [v0.11.0](https://github.com/johnxnguyen/Down/tree/v0.11.0) (2021-05-04)
|
||||
|
||||
[Full Changelog](https://github.com/iwasrobbed/Down/compare/v0.3.1...HEAD)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- How to update DownView content and keep the style? [\#19](https://github.com/iwasrobbed/Down/issues/19)
|
||||
|
||||
## [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:**
|
||||
|
||||
- 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)
|
||||
|
||||
## [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)
|
||||
[Full Changelog](https://github.com/johnxnguyen/Down/compare/v0.10.0...v0.11.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- 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)
|
||||
- \[CodeCoverage\] Improve accuracy for combined code coverage reporting [\#205](https://github.com/johnxnguyen/Down/issues/205)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Can you give an example how to custom the parser? [\#9](https://github.com/iwasrobbed/Down/issues/9)
|
||||
- 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)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- 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))
|
||||
- \[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))
|
||||
|
||||
## [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)
|
||||
## [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)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- 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))
|
||||
- Create custom sequence to access child nodes [\#228](https://github.com/johnxnguyen/Down/pull/228) ([5sw](https://github.com/5sw))
|
||||
|
||||
## [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)
|
||||
**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)
|
||||
|
||||
**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))
|
||||
|
||||
## [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)
|
||||
|
||||
**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)
|
||||
|
||||
**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)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Add CocoaPods support & cmark license [\#1](https://github.com/iwasrobbed/Down/pull/1) ([iwasrobbed](https://github.com/iwasrobbed))
|
||||
- Added Linux support. [\#172](https://github.com/johnxnguyen/Down/pull/172) ([vgorloff](https://github.com/vgorloff))
|
||||
|
||||
## [v0.1](https://github.com/iwasrobbed/Down/tree/v0.1) (2016-06-01)
|
||||
**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)
|
||||
|
||||
**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))
|
||||
|
||||
## [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)
|
||||
|
||||
**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)
|
||||
|
||||
**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)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- \[DownView\] Doesn't reflow text on orientation change [\#111](https://github.com/johnxnguyen/Down/issues/111)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- 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:**
|
||||
|
||||
- ” 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 Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
||||
|
||||
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
||||
|
||||
@@ -0,0 +1,645 @@
|
||||
// !$*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 */;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Down-Example.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?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>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "SnapshotTesting",
|
||||
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c466812aa2e22898f27557e2e780d3aad7a27203",
|
||||
"version": "1.8.2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?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>
|
||||
+28
-21
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0820"
|
||||
LastUpgradeVersion = "1130"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -14,10 +14,10 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "24F833A91E62706000590E90"
|
||||
BuildableName = "Down-tvOS.framework"
|
||||
BlueprintName = "Down-tvOS"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
BlueprintIdentifier = "14090A482185411800503C06"
|
||||
BuildableName = "macOS Demo.app"
|
||||
BlueprintName = "macOS Demo"
|
||||
ReferencedContainer = "container:Down-Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -27,10 +27,17 @@
|
||||
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>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -42,17 +49,16 @@
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "24F833A91E62706000590E90"
|
||||
BuildableName = "Down-tvOS.framework"
|
||||
BlueprintName = "Down-tvOS"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
BlueprintIdentifier = "14090A482185411800503C06"
|
||||
BuildableName = "macOS Demo.app"
|
||||
BlueprintName = "macOS Demo"
|
||||
ReferencedContainer = "container:Down-Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
@@ -60,15 +66,16 @@
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "24F833A91E62706000590E90"
|
||||
BuildableName = "Down-tvOS.framework"
|
||||
BlueprintName = "Down-tvOS"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
BlueprintIdentifier = "14090A482185411800503C06"
|
||||
BuildableName = "macOS Demo.app"
|
||||
BlueprintName = "macOS Demo"
|
||||
ReferencedContainer = "container:Down-Example.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// 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?
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
## Down
|
||||
[](https://travis-ci.org/iwasrobbed/Down)
|
||||
[](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
|
||||
[]()
|
||||
[](https://swift.org)
|
||||
[](https://developer.apple.com/macos/)
|
||||
[](https://developer.apple.com/ios/)
|
||||
[](https://developer.apple.com/tvos/)
|
||||
[](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:
|
||||
|
||||

|
||||
|
||||
### 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 you’ll need to instantiate the `DownView` with a custom bundle where the `viewport` in `index.html` has been assigned `user-scalable=no`. More info can be found [here](https://github.com/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).
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// 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 {}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,730 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?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>
|
||||
+15
-11
@@ -1,19 +1,23 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Down"
|
||||
spec.summary = "Blazing fast Markdown rendering in Swift, built upon cmark."
|
||||
spec.version = "0.3.2"
|
||||
spec.homepage = "https://github.com/iwasrobbed/Down"
|
||||
spec.version = "0.11.0"
|
||||
spec.homepage = "https://github.com/johnxnguyen/Down"
|
||||
spec.license = { :type => "MIT", :file => "LICENSE" }
|
||||
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.public_header_files = "Source/*.h"
|
||||
spec.ios.deployment_target = "8.0"
|
||||
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.tvos.deployment_target = "9.0"
|
||||
spec.osx.deployment_target = "10.11"
|
||||
spec.requires_arc = true
|
||||
spec.module_name = "Down"
|
||||
spec.preserve_path = 'Source/cmark/module.modulemap'
|
||||
spec.pod_target_xcconfig = { 'SWIFT_INCLUDE_PATHS' => '$(SRCROOT)/Down/Source/cmark/**' }
|
||||
spec.ios.resource = 'Resources/DownView.bundle'
|
||||
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']
|
||||
end
|
||||
|
||||
+861
-459
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -2,6 +2,6 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Down.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "SnapshotTesting",
|
||||
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c466812aa2e22898f27557e2e780d3aad7a27203",
|
||||
"version": "1.8.2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"version": 1
|
||||
}
|
||||
+22
-25
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "1130"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -14,9 +14,9 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4201E7F1CFA5151008EEC6E"
|
||||
BuildableName = "Down-iOS.framework"
|
||||
BlueprintName = "Down-iOS"
|
||||
BlueprintIdentifier = "8A569F3F1E6B3E50008BE2AC"
|
||||
BuildableName = "Down.framework"
|
||||
BlueprintName = "Down"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
@@ -26,30 +26,29 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
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">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4201E891CFA5151008EEC6E"
|
||||
BlueprintIdentifier = "8AFAEAFA1E6E32E900E09B68"
|
||||
BuildableName = "DownTests.xctest"
|
||||
BlueprintName = "DownTests"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4201E7F1CFA5151008EEC6E"
|
||||
BuildableName = "Down-iOS.framework"
|
||||
BlueprintName = "Down-iOS"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -64,14 +63,12 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4201E7F1CFA5151008EEC6E"
|
||||
BuildableName = "Down-iOS.framework"
|
||||
BlueprintName = "Down-iOS"
|
||||
BlueprintIdentifier = "8A569F3F1E6B3E50008BE2AC"
|
||||
BuildableName = "Down.framework"
|
||||
BlueprintName = "Down"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
@@ -82,9 +79,9 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4201E7F1CFA5151008EEC6E"
|
||||
BuildableName = "Down-iOS.framework"
|
||||
BlueprintName = "Down-iOS"
|
||||
BlueprintIdentifier = "8A569F3F1E6B3E50008BE2AC"
|
||||
BuildableName = "Down.framework"
|
||||
BlueprintName = "Down"
|
||||
ReferencedContainer = "container:Down.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
@@ -18,4 +18,201 @@ 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.
|
||||
|
||||
-----
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,7 @@
|
||||
import XCTest
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
|
||||
// FIXME: Run on macOS `swift test --generate-linuxmain` and maintain Linux Tests.
|
||||
|
||||
XCTMain(tests)
|
||||
@@ -0,0 +1,64 @@
|
||||
// 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]
|
||||
)
|
||||
@@ -1,41 +1,82 @@
|
||||
## Down
|
||||
[](https://travis-ci.org/iwasrobbed/Down)
|
||||
[](https://github.com/iwasrobbed/Down/blob/master/LICENSE)
|
||||
[]()
|
||||
[](https://swift.org)
|
||||
[](https://developer.apple.com/ios/)
|
||||
[](https://developer.apple.com/tvos/)
|
||||
[](https://coveralls.io/github/iwasrobbed/Down?branch=master)
|
||||
[](https://travis-ci.com/johnxnguyen/Down)
|
||||
[](https://github.com/johnxnguyen/Down/blob/master/LICENSE)
|
||||
[](https://cocoapods.org/pods/Down)
|
||||
[](https://swift.org)
|
||||
[](https://developer.apple.com/macos/)
|
||||
[](https://developer.apple.com/ios/)
|
||||
[](https://developer.apple.com/tvos/)
|
||||
[](https://www.linux.org/)
|
||||
[](https://codecov.io/gh/johnxnguyen/Down)
|
||||
|
||||
Blazing fast Markdown rendering in Swift, built upon [cmark](https://github.com/jgm/cmark).
|
||||
Blazing fast Markdown (CommonMark) rendering in Swift, built upon [cmark v0.29.0](https://github.com/commonmark/cmark).
|
||||
|
||||
Is your app using it? [Let me know!](mailto:rob@desideratalabs.co)
|
||||
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) 🙌
|
||||
|
||||
### Installation
|
||||
|
||||
Quickly install using [CocoaPods](https://cocoapods.org):
|
||||
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):
|
||||
|
||||
```ruby
|
||||
pod 'Down'
|
||||
```
|
||||
|
||||
Or [Carthage](https://github.com/Carthage/Carthage):
|
||||
#### Install using [Carthage](https://github.com/Carthage/Carthage):
|
||||
|
||||
```
|
||||
github "iwasrobbed/Down"
|
||||
github "johnxnguyen/Down"
|
||||
```
|
||||
Due to limitations in Carthage regarding platform specification, you need to define the platform with Carthage.
|
||||
|
||||
Or manually install:
|
||||
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:
|
||||
|
||||
1. Clone this repository
|
||||
2. Build the Down project
|
||||
3. Add the resulting framework file to your project
|
||||
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
|
||||
4. ?
|
||||
5. Profit
|
||||
|
||||
### Robust Performance
|
||||
|
||||
>[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.
|
||||
>[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).
|
||||
|
||||
@@ -70,34 +111,36 @@ 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/iwasrobbed/Down)")
|
||||
let down = Down(markdownString: "## [Down](https://github.com/johnxnguyen/Down)")
|
||||
|
||||
// Convert to HTML
|
||||
let html = try? down.toHTML()
|
||||
// "<h2><a href=\"https://github.com/iwasrobbed/Down\">Down</a></h2>\n"
|
||||
// "<h2><a href=\"https://github.com/johnxnguyen/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"
|
||||
// "<?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"
|
||||
|
||||
// Convert to groff man
|
||||
let man = try? down.toGroff()
|
||||
// ".SS\nDown (https://github.com/iwasrobbed/Down)\n"
|
||||
// ".SS\nDown (https://github.com/johnxnguyen/Down)\n"
|
||||
|
||||
// Convert to LaTeX
|
||||
let latex = try? down.toLaTeX()
|
||||
// "\\subsection{\\href{https://github.com/iwasrobbed/Down}{Down}}\n"
|
||||
// "\\subsection{\\href{https://github.com/johnxnguyen/Down}{Down}}\n"
|
||||
|
||||
// Convert to CommonMark Markdown
|
||||
let commonMark = try? down.toCommonMark()
|
||||
// "## [Down](https://github.com/iwasrobbed/Down)\n"
|
||||
// "## [Down](https://github.com/johnxnguyen/Down)\n"
|
||||
|
||||
// Convert to an attributed string
|
||||
let attributedString = try? down.toAttributedString()
|
||||
// NSAttributedString representation of the rendered HTML
|
||||
// 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()
|
||||
@@ -140,6 +183,17 @@ 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 you’ll need to instantiate the `DownView` with a custom bundle where the `viewport` in `index.html` has been assigned `user-scalable=no`. More info can be found [here](https://github.com/johnxnguyen/Down/pull/30).
|
||||
|
||||
### Options
|
||||
|
||||
Each protocol has options that will influence either rendering or parsing:
|
||||
@@ -148,50 +202,63 @@ 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.
|
||||
empty strings. Note that this option is provided for backwards
|
||||
compatibility, but safe mode is now the default.
|
||||
*/
|
||||
public static let Safe = DownOptions(rawValue: 1 << 3)
|
||||
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)
|
||||
|
||||
// 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)
|
||||
public static let smart = DownOptions(rawValue: 1 << 6)
|
||||
|
||||
/**
|
||||
Combine smart typography with HTML rendering.
|
||||
*/
|
||||
public static let smartUnsaFe = DownOptions(rawValue: (1 << 17) + (1 << 6))
|
||||
```
|
||||
|
||||
### Supports
|
||||
Swift, ARC & iOS 8+
|
||||
Swift; iOS 9+, tvOS 9+, macOS 10.11+
|
||||
|
||||
### Markdown Specification
|
||||
|
||||
@@ -201,6 +268,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/jgm/cmark), which is built upon the [CommonMark](http://commonmark.org) Markdown specification.
|
||||
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/jgm/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/jgm/cmark/blob/master/COPYING).
|
||||
[cmark](https://github.com/commonmark/cmark) is Copyright (c) 2014, John MacFarlane. View [full license](https://github.com/commonmark/cmark/blob/master/COPYING).
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
//
|
||||
// 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)
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
//
|
||||
// NSAttributedString+HTML.swift
|
||||
// Down
|
||||
//
|
||||
// Created by Rob Phillips on 6/1/16.
|
||||
// Copyright © 2016 Glazed Donut, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
//
|
||||
// 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 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, didLoadSuccessfully: DownViewClosure? = nil) throws {
|
||||
self.didLoadSuccessfully = didLoadSuccessfully
|
||||
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
|
||||
|
||||
fileprivate let bundle: Bundle = {
|
||||
let bundle = Bundle(for: DownView.self)
|
||||
let url = bundle.url(forResource: "DownView", withExtension: "bundle")!
|
||||
return Bundle(url: url)!
|
||||
}()
|
||||
|
||||
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)
|
||||
UIApplication.shared.openURL(url)
|
||||
default:
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
}
|
||||
|
||||
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
didLoadSuccessfully?()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef CMARK_VERSION_H
|
||||
#define CMARK_VERSION_H
|
||||
|
||||
#define CMARK_VERSION ((0 << 16) | (25 << 8) | 2)
|
||||
#define CMARK_VERSION_STRING "0.25.2"
|
||||
|
||||
#endif
|
||||
@@ -1,36 +0,0 @@
|
||||
#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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
#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
|
||||
-21263
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// BaseNode.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 21.04.19.
|
||||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class BaseNode: Node {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public let cmarkNode: CMarkNode
|
||||
|
||||
public private(set) lazy var children: [Node] = Array(childSequence)
|
||||
|
||||
public private(set) lazy var nestDepth: Int = {
|
||||
var depth = 0
|
||||
var next = cmarkNode.parent
|
||||
|
||||
while let current = next {
|
||||
depth += current.type == cmarkNode.type ? 1 : 0
|
||||
next = current.parent
|
||||
}
|
||||
return depth
|
||||
}()
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
init(cmarkNode: CMarkNode) {
|
||||
self.cmarkNode = cmarkNode
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// BlockQuote.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class BlockQuote: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension BlockQuote: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Block Quote"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// ChildSequence.swift
|
||||
// Down
|
||||
//
|
||||
// Created by Sven Weidauer on 05.10.2020
|
||||
//
|
||||
|
||||
import libcmark
|
||||
|
||||
/// Sequence of child nodes.
|
||||
|
||||
public struct ChildSequence: Sequence {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
let node: CMarkNode
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
public func makeIterator() -> Iterator {
|
||||
return Iterator(node: cmark_node_first_child(node))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Iterator
|
||||
|
||||
public extension ChildSequence {
|
||||
|
||||
struct Iterator: IteratorProtocol {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var node: CMarkNode?
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
public mutating func next() -> Node? {
|
||||
guard let node = node else { return nil }
|
||||
defer { self.node = cmark_node_next(node) }
|
||||
|
||||
guard let result = node.wrap() else {
|
||||
assertionFailure("Couldn't wrap node of type: \(node.type)")
|
||||
return nil
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Code.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Code: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The code content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Code: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Code - \(literal ?? "nil")"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// CodeBlock.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class CodeBlock: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The code content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
/// The fence info is an optional string that trails the opening sequence of backticks.
|
||||
/// It can be used to provide some contextual information about the block, such as
|
||||
/// the name of a programming language.
|
||||
///
|
||||
/// For example:
|
||||
/// ```
|
||||
/// '''<fence info>
|
||||
/// <literal>
|
||||
/// '''
|
||||
/// ```
|
||||
///
|
||||
|
||||
public private(set) lazy var fenceInfo: String? = cmarkNode.fenceInfo
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension CodeBlock: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
let content = (literal ?? "nil").replacingOccurrences(of: "\n", with: "\\n")
|
||||
return "Code Block - fenceInfo: \(fenceInfo ?? "nil"), content: \(content)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// CustomBlock.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class CustomBlock: BaseNode {
|
||||
|
||||
// MARK: - Properfies
|
||||
|
||||
/// The custom content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension CustomBlock: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Custom Block - \(literal ?? "nil")"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// CustomInline.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class CustomInline: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The custom content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension CustomInline: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Custom Inline - \(literal ?? "nil")"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Document.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Document: BaseNode {
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
deinit {
|
||||
cmark_node_free(cmarkNode)
|
||||
}
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
/// Accepts the given visitor and return its result.
|
||||
|
||||
@discardableResult
|
||||
public func accept<T: Visitor>(_ visitor: T) -> T.Result {
|
||||
return visitor.visit(document: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Document: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Document"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Emphasis.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Emphasis: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Emphasis: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Emphasis"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Heading.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Heading: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The level of the heading, a value between 1 and 6.
|
||||
|
||||
public private(set) lazy var headingLevel: Int = cmarkNode.headingLevel
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Heading: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Heading - L\(headingLevel)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// HtmlBlock.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class HtmlBlock: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The html content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension HtmlBlock: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
let content = (literal ?? "nil").replacingOccurrences(of: "\n", with: "\\n")
|
||||
return "Html Block - content: \(content)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// HtmlInline.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class HtmlInline: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The html tag, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension HtmlInline: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Html Inline - \(literal ?? "nil")"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Image.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Image: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The title of the image, if present.
|
||||
///
|
||||
/// In the example below, the first line is a reference link, with the reference at the
|
||||
/// bottom. `<text>` is literal text belonging to children nodes. The title occurs
|
||||
/// after the url and is optional.
|
||||
///
|
||||
/// ```
|
||||
/// ![<text>][<id>]
|
||||
/// ...
|
||||
/// [<id>]: <url> "<title>"
|
||||
/// ```
|
||||
|
||||
public private(set) lazy var title: String? = cmarkNode.title
|
||||
|
||||
/// The url of the image, if present.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```
|
||||
/// 
|
||||
/// ```
|
||||
|
||||
public private(set) lazy var url: String? = cmarkNode.url
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Image: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Image - title: \(title ?? "nil"), url: \(url ?? "nil"))"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Item.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Item: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Item: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Item"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// LineBreak.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class LineBreak: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension LineBreak: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Line Break"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Link.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Link: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The title of the link, if present.
|
||||
///
|
||||
/// In the example below, the first line is a reference link, with the reference at the
|
||||
/// bottom. `<text>` is literal text belonging to children nodes. The title occurs
|
||||
/// after the url and is optional.
|
||||
///
|
||||
/// ```
|
||||
/// [<text>][<id>]
|
||||
/// ...
|
||||
/// [<id>]: <url> "<title>"
|
||||
/// ```
|
||||
|
||||
public private(set) lazy var title: String? = cmarkNode.title
|
||||
|
||||
/// The url of the link, if present.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```
|
||||
/// [<text>](<url>)
|
||||
/// ```
|
||||
|
||||
public private(set) lazy var url: String? = cmarkNode.url
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Link: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Link - title: \(title ?? "nil"), url: \(url ?? "nil"))"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// List.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class List: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The type of the list, either bullet or ordered.
|
||||
|
||||
public lazy var listType: ListType = {
|
||||
guard let type = ListType(cmarkNode: cmarkNode) else {
|
||||
assertionFailure("Unsupported or missing list type. Defaulting to .bullet.")
|
||||
return .bullet
|
||||
}
|
||||
|
||||
return type
|
||||
}()
|
||||
|
||||
/// The number of items in the list.
|
||||
|
||||
public lazy var numberOfItems: Int = children.count
|
||||
|
||||
/// Whether the list is "tight".
|
||||
///
|
||||
/// If any of the list items are separated by a blank line, then this property is `false`. This value is
|
||||
/// a hint to render the list with more (loose) or less (tight) spacing between items.
|
||||
|
||||
public lazy var isTight: Bool = cmark_node_get_list_tight(cmarkNode) == 1
|
||||
|
||||
/// The list delimiter.
|
||||
|
||||
public lazy var delimiter: Delimiter? = Delimiter(cmarkNode.listDelimiter)
|
||||
}
|
||||
|
||||
// MARK: - List Type
|
||||
|
||||
public extension List {
|
||||
|
||||
enum Delimiter {
|
||||
case period
|
||||
case paren
|
||||
|
||||
init?(_ cmark: cmark_delim_type) {
|
||||
switch cmark {
|
||||
case CMARK_NO_DELIM: return nil
|
||||
case CMARK_PERIOD_DELIM: self = .period
|
||||
case CMARK_PAREN_DELIM: self = .paren
|
||||
default: preconditionFailure("Invalid delim type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ListType: CustomDebugStringConvertible {
|
||||
case bullet
|
||||
case ordered(start: Int)
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .bullet: return "Bullet"
|
||||
case .ordered(let start): return "Ordered (start: \(start))"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
init?(cmarkNode: CMarkNode) {
|
||||
switch cmarkNode.listType {
|
||||
case CMARK_BULLET_LIST: self = .bullet
|
||||
case CMARK_ORDERED_LIST: self = .ordered(start: cmarkNode.listStart)
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension List: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
var result = "List - type: \(listType), isTight: \(isTight)"
|
||||
if let delim = delimiter {
|
||||
result += ", delimiter: \(delim)"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension List.Delimiter: CustomDebugStringConvertible {
|
||||
public var debugDescription: String {
|
||||
switch self {
|
||||
case .paren: return "paren"
|
||||
case .period: return "period"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// Node.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 07.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
/// A node is a wrapper of a raw `CMarkNode` belonging to the abstract syntax tree
|
||||
/// generated by cmark.
|
||||
|
||||
public protocol Node {
|
||||
|
||||
/// The wrapped node.
|
||||
|
||||
var cmarkNode: CMarkNode { get }
|
||||
|
||||
/// The wrapped child nodes.
|
||||
|
||||
var children: [Node] { get }
|
||||
|
||||
}
|
||||
|
||||
public extension Node {
|
||||
|
||||
/// True iff the node has a sibling that succeeds it.
|
||||
|
||||
var hasSuccessor: Bool {
|
||||
return cmark_node_next(cmarkNode) != nil
|
||||
}
|
||||
|
||||
/// Sequence of wrapped child nodes.
|
||||
|
||||
var childSequence: ChildSequence {
|
||||
return ChildSequence(node: cmarkNode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helper extensions
|
||||
|
||||
public typealias CMarkNode = UnsafeMutablePointer<cmark_node>
|
||||
|
||||
public extension CMarkNode {
|
||||
|
||||
/// Wraps the cmark node referred to by this pointer.
|
||||
|
||||
func wrap() -> Node? {
|
||||
switch type {
|
||||
case CMARK_NODE_DOCUMENT: return Document(cmarkNode: self)
|
||||
case CMARK_NODE_BLOCK_QUOTE: return BlockQuote(cmarkNode: self)
|
||||
case CMARK_NODE_LIST: return List(cmarkNode: self)
|
||||
case CMARK_NODE_ITEM: return Item(cmarkNode: self)
|
||||
case CMARK_NODE_CODE_BLOCK: return CodeBlock(cmarkNode: self)
|
||||
case CMARK_NODE_HTML_BLOCK: return HtmlBlock(cmarkNode: self)
|
||||
case CMARK_NODE_CUSTOM_BLOCK: return CustomBlock(cmarkNode: self)
|
||||
case CMARK_NODE_PARAGRAPH: return Paragraph(cmarkNode: self)
|
||||
case CMARK_NODE_HEADING: return Heading(cmarkNode: self)
|
||||
case CMARK_NODE_THEMATIC_BREAK: return ThematicBreak(cmarkNode: self)
|
||||
case CMARK_NODE_TEXT: return Text(cmarkNode: self)
|
||||
case CMARK_NODE_SOFTBREAK: return SoftBreak(cmarkNode: self)
|
||||
case CMARK_NODE_LINEBREAK: return LineBreak(cmarkNode: self)
|
||||
case CMARK_NODE_CODE: return Code(cmarkNode: self)
|
||||
case CMARK_NODE_HTML_INLINE: return HtmlInline(cmarkNode: self)
|
||||
case CMARK_NODE_CUSTOM_INLINE: return CustomInline(cmarkNode: self)
|
||||
case CMARK_NODE_EMPH: return Emphasis(cmarkNode: self)
|
||||
case CMARK_NODE_STRONG: return Strong(cmarkNode: self)
|
||||
case CMARK_NODE_LINK: return Link(cmarkNode: self)
|
||||
case CMARK_NODE_IMAGE: return Image(cmarkNode: self)
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var parent: CMarkNode? {
|
||||
return cmark_node_parent(self)
|
||||
}
|
||||
|
||||
var type: cmark_node_type {
|
||||
return cmark_node_get_type(self)
|
||||
}
|
||||
|
||||
var literal: String? {
|
||||
return String(cString: cmark_node_get_literal(self))
|
||||
}
|
||||
|
||||
var fenceInfo: String? {
|
||||
return String(cString: cmark_node_get_fence_info(self))
|
||||
}
|
||||
|
||||
var headingLevel: Int {
|
||||
return Int(cmark_node_get_heading_level(self))
|
||||
}
|
||||
|
||||
var listType: cmark_list_type {
|
||||
return cmark_node_get_list_type(self)
|
||||
}
|
||||
|
||||
var listStart: Int {
|
||||
return Int(cmark_node_get_list_start(self))
|
||||
}
|
||||
|
||||
var listDelimiter: cmark_delim_type {
|
||||
return cmark_node_get_list_delim(self)
|
||||
}
|
||||
|
||||
var url: String? {
|
||||
return String(cString: cmark_node_get_url(self))
|
||||
}
|
||||
|
||||
var title: String? {
|
||||
return String(cString: cmark_node_get_title(self))
|
||||
}
|
||||
}
|
||||
|
||||
private extension String {
|
||||
|
||||
init?(cString: UnsafePointer<Int8>?) {
|
||||
guard let unwrapped = cString else { return nil }
|
||||
let result = String(cString: unwrapped)
|
||||
guard !result.isEmpty else { return nil }
|
||||
self = result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Paragraph.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Paragraph: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Paragraph: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Paragraph"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// SoftBreak.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class SoftBreak: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension SoftBreak: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Soft Break"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Strong.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Strong: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Strong: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Strong"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Text.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class Text: BaseNode {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// The text content, if present.
|
||||
|
||||
public private(set) lazy var literal: String? = cmarkNode.literal
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension Text: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Text - \(literal ?? "nil")"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// ThematicBreak.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 09.04.19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import libcmark
|
||||
|
||||
public class ThematicBreak: BaseNode {}
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
extension ThematicBreak: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
return "Thematic Break"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// ColorCollection.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 27.07.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
public typealias DownColor = UIColor
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
public typealias DownColor = NSColor
|
||||
|
||||
#endif
|
||||
|
||||
public protocol ColorCollection {
|
||||
|
||||
var heading1: DownColor { get }
|
||||
var heading2: DownColor { get }
|
||||
var heading3: DownColor { get }
|
||||
var heading4: DownColor { get }
|
||||
var heading5: DownColor { get }
|
||||
var heading6: DownColor { get }
|
||||
var body: DownColor { get }
|
||||
var code: DownColor { get }
|
||||
var link: DownColor { get }
|
||||
var quote: DownColor { get }
|
||||
var quoteStripe: DownColor { get }
|
||||
var thematicBreak: DownColor { get }
|
||||
var listItemPrefix: DownColor { get }
|
||||
var codeBlockBackground: DownColor { get }
|
||||
|
||||
}
|
||||
|
||||
public struct StaticColorCollection: ColorCollection {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var heading1: DownColor
|
||||
public var heading2: DownColor
|
||||
public var heading3: DownColor
|
||||
public var heading4: DownColor
|
||||
public var heading5: DownColor
|
||||
public var heading6: DownColor
|
||||
public var body: DownColor
|
||||
public var code: DownColor
|
||||
public var link: DownColor
|
||||
public var quote: DownColor
|
||||
public var quoteStripe: DownColor
|
||||
public var thematicBreak: DownColor
|
||||
public var listItemPrefix: DownColor
|
||||
public var codeBlockBackground: DownColor
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(
|
||||
heading1: DownColor = .black,
|
||||
heading2: DownColor = .black,
|
||||
heading3: DownColor = .black,
|
||||
heading4: DownColor = .black,
|
||||
heading5: DownColor = .black,
|
||||
heading6: DownColor = .black,
|
||||
body: DownColor = .black,
|
||||
code: DownColor = .black,
|
||||
link: DownColor = .blue,
|
||||
quote: DownColor = .darkGray,
|
||||
quoteStripe: DownColor = .darkGray,
|
||||
thematicBreak: DownColor = .init(white: 0.9, alpha: 1),
|
||||
listItemPrefix: DownColor = .lightGray,
|
||||
codeBlockBackground: DownColor = .init(red: 0.96, green: 0.97, blue: 0.98, alpha: 1)
|
||||
) {
|
||||
self.heading1 = heading1
|
||||
self.heading2 = heading2
|
||||
self.heading3 = heading3
|
||||
self.heading4 = heading4
|
||||
self.heading5 = heading5
|
||||
self.heading6 = heading6
|
||||
self.body = body
|
||||
self.code = code
|
||||
self.link = link
|
||||
self.quote = quote
|
||||
self.quoteStripe = quoteStripe
|
||||
self.thematicBreak = thematicBreak
|
||||
self.listItemPrefix = listItemPrefix
|
||||
self.codeBlockBackground = codeBlockBackground
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// FontCollection.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 22.06.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
public typealias DownFont = UIFont
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
public typealias DownFont = NSFont
|
||||
|
||||
#endif
|
||||
|
||||
public protocol FontCollection {
|
||||
|
||||
var heading1: DownFont { get }
|
||||
var heading2: DownFont { get }
|
||||
var heading3: DownFont { get }
|
||||
var heading4: DownFont { get }
|
||||
var heading5: DownFont { get }
|
||||
var heading6: DownFont { get }
|
||||
var body: DownFont { get }
|
||||
var code: DownFont { get }
|
||||
var listItemPrefix: DownFont { get }
|
||||
|
||||
}
|
||||
|
||||
public struct StaticFontCollection: FontCollection {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var heading1: DownFont
|
||||
public var heading2: DownFont
|
||||
public var heading3: DownFont
|
||||
public var heading4: DownFont
|
||||
public var heading5: DownFont
|
||||
public var heading6: DownFont
|
||||
public var body: DownFont
|
||||
public var code: DownFont
|
||||
public var listItemPrefix: DownFont
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(
|
||||
heading1: DownFont = .boldSystemFont(ofSize: 28),
|
||||
heading2: DownFont = .boldSystemFont(ofSize: 24),
|
||||
heading3: DownFont = .boldSystemFont(ofSize: 20),
|
||||
heading4: DownFont = .boldSystemFont(ofSize: 20),
|
||||
heading5: DownFont = .boldSystemFont(ofSize: 20),
|
||||
heading6: DownFont = .boldSystemFont(ofSize: 20),
|
||||
body: DownFont = .systemFont(ofSize: 17),
|
||||
code: DownFont = DownFont(name: "menlo", size: 17) ?? .systemFont(ofSize: 17),
|
||||
listItemPrefix: DownFont = DownFont.monospacedDigitSystemFont(ofSize: 17, weight: .regular)
|
||||
) {
|
||||
self.heading1 = heading1
|
||||
self.heading2 = heading2
|
||||
self.heading3 = heading3
|
||||
self.heading4 = heading4
|
||||
self.heading5 = heading5
|
||||
self.heading6 = heading6
|
||||
self.body = body
|
||||
self.code = code
|
||||
self.listItemPrefix = listItemPrefix
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// ParagraphStyleCollection.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 27.07.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
public protocol ParagraphStyleCollection {
|
||||
|
||||
var heading1: NSParagraphStyle { get }
|
||||
var heading2: NSParagraphStyle { get }
|
||||
var heading3: NSParagraphStyle { get }
|
||||
var heading4: NSParagraphStyle { get }
|
||||
var heading5: NSParagraphStyle { get }
|
||||
var heading6: NSParagraphStyle { get }
|
||||
var body: NSParagraphStyle { get }
|
||||
var code: NSParagraphStyle { get }
|
||||
|
||||
}
|
||||
|
||||
public struct StaticParagraphStyleCollection: ParagraphStyleCollection {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var heading1: NSParagraphStyle
|
||||
public var heading2: NSParagraphStyle
|
||||
public var heading3: NSParagraphStyle
|
||||
public var heading4: NSParagraphStyle
|
||||
public var heading5: NSParagraphStyle
|
||||
public var heading6: NSParagraphStyle
|
||||
public var body: NSParagraphStyle
|
||||
public var code: NSParagraphStyle
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init() {
|
||||
let headingStyle = NSMutableParagraphStyle()
|
||||
headingStyle.paragraphSpacing = 8
|
||||
|
||||
let bodyStyle = NSMutableParagraphStyle()
|
||||
bodyStyle.paragraphSpacingBefore = 8
|
||||
bodyStyle.paragraphSpacing = 8
|
||||
bodyStyle.lineSpacing = 8
|
||||
|
||||
let codeStyle = NSMutableParagraphStyle()
|
||||
codeStyle.paragraphSpacingBefore = 8
|
||||
codeStyle.paragraphSpacing = 8
|
||||
|
||||
heading1 = headingStyle
|
||||
heading2 = headingStyle
|
||||
heading3 = headingStyle
|
||||
heading4 = headingStyle
|
||||
heading5 = headingStyle
|
||||
heading6 = headingStyle
|
||||
body = bodyStyle
|
||||
code = codeStyle
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// BlockBackgroundColorAttribute.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 11.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
struct BlockBackgroundColorAttribute {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var color: DownColor
|
||||
var inset: CGFloat
|
||||
|
||||
}
|
||||
|
||||
extension NSAttributedString.Key {
|
||||
|
||||
static let blockBackgroundColor = NSAttributedString.Key("blockBackgroundColor")
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// QuoteStripeAttrbute.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 03.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
struct QuoteStripeAttribute {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var color: DownColor
|
||||
var thickness: CGFloat
|
||||
var spacingAfter: CGFloat
|
||||
var locations: [CGFloat]
|
||||
|
||||
var layoutWidth: CGFloat {
|
||||
return thickness + spacingAfter
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
init(color: DownColor, thickness: CGFloat, spacingAfter: CGFloat, locations: [CGFloat]) {
|
||||
self.color = color
|
||||
self.thickness = thickness
|
||||
self.spacingAfter = spacingAfter
|
||||
self.locations = locations
|
||||
}
|
||||
|
||||
init(level: Int, color: DownColor, options: QuoteStripeOptions) {
|
||||
self.init(color: color, thickness: options.thickness, spacingAfter: options.spacingAfter, locations: [])
|
||||
locations = (0..<level).map { CGFloat($0) * layoutWidth }
|
||||
}
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
func indented(by indentation: CGFloat) -> QuoteStripeAttribute {
|
||||
var copy = self
|
||||
copy.locations = locations.map { $0 + indentation }
|
||||
return copy
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NSAttributedString.Key {
|
||||
|
||||
static let quoteStripe = NSAttributedString.Key(rawValue: "quoteStripe")
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// ThematicBreaAttributek.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 02.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
struct ThematicBreakAttribute {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var thickness: CGFloat
|
||||
var color: DownColor
|
||||
|
||||
}
|
||||
|
||||
extension NSAttributedString.Key {
|
||||
|
||||
static let thematicBreak = NSAttributedString.Key(rawValue: "thematicBreak")
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// CGPoint+Translate.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 12.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
extension CGPoint {
|
||||
|
||||
func translated(by point: CGPoint) -> CGPoint {
|
||||
return CGPoint(x: x + point.x, y: y + point.y)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// CGRect+Helpers.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 12.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
extension CGRect {
|
||||
|
||||
init(minX: CGFloat, minY: CGFloat, maxX: CGFloat, maxY: CGFloat) {
|
||||
self.init(x: minX, y: minY, width: maxX - minX, height: maxY - minY)
|
||||
}
|
||||
|
||||
func translated(by point: CGPoint) -> CGRect {
|
||||
return CGRect(origin: origin.translated(by: point), size: size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// NSAttributedString+Helpers.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 22.06.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension NSAttributedString {
|
||||
|
||||
typealias Attributes = [NSAttributedString.Key: Any]
|
||||
|
||||
// MARK: - Ranges
|
||||
|
||||
var wholeRange: NSRange {
|
||||
return NSRange(location: 0, length: length)
|
||||
}
|
||||
|
||||
func ranges(of key: Key) -> [NSRange] {
|
||||
return ranges(of: key, in: wholeRange)
|
||||
}
|
||||
|
||||
func ranges(of key: Key, in range: NSRange) -> [NSRange] {
|
||||
return ranges(for: key, in: range, where: { $0 != nil })
|
||||
}
|
||||
|
||||
func rangesMissingAttribute(for key: Key) -> [NSRange] {
|
||||
return rangesMissingAttribute(for: key, in: wholeRange)
|
||||
}
|
||||
|
||||
func rangesMissingAttribute(for key: Key, in range: NSRange) -> [NSRange] {
|
||||
return ranges(for: key, in: range, where: { $0 == nil })
|
||||
}
|
||||
|
||||
private func ranges(for key: Key, in range: NSRange, where predicate: (Any?) -> Bool) -> [NSRange] {
|
||||
var ranges = [NSRange]()
|
||||
|
||||
enumerateAttribute(key, in: range, options: []) { value, attrRange, _ in
|
||||
if predicate(value) {
|
||||
ranges.append(attrRange)
|
||||
}
|
||||
}
|
||||
|
||||
return ranges
|
||||
}
|
||||
|
||||
func paragraphRanges() -> [NSRange] {
|
||||
guard length > 0 else { return [] }
|
||||
|
||||
func nextParagraphRange(at location: Int) -> NSRange {
|
||||
return NSString(string: string).paragraphRange(for: NSRange(location: location, length: 1))
|
||||
}
|
||||
|
||||
var result = [nextParagraphRange(at: 0)]
|
||||
|
||||
while let currentLocation = result.last?.upperBound, currentLocation < length {
|
||||
result.append(nextParagraphRange(at: currentLocation))
|
||||
}
|
||||
|
||||
return result.filter { $0.length > 1 }
|
||||
}
|
||||
|
||||
// MARK: - Enumerate attributes
|
||||
|
||||
func enumerateAttributes<A>(for key: Key, block: (_ attr: A, _ range: NSRange) -> Void) {
|
||||
enumerateAttributes(for: key, in: wholeRange, block: block)
|
||||
}
|
||||
|
||||
func enumerateAttributes<A>(for key: Key, in range: NSRange, block: (_ attr: A, _ range: NSRange) -> Void) {
|
||||
enumerateAttribute(key, in: range, options: []) { value, range, _ in
|
||||
if let value = value as? A {
|
||||
block(value, range)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// NSMutableAttributedString+Attributes.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 22.06.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension NSMutableAttributedString {
|
||||
|
||||
func setAttributes(_ attrs: Attributes) {
|
||||
setAttributes(attrs, range: wholeRange)
|
||||
}
|
||||
|
||||
func addAttributes(_ attrs: Attributes) {
|
||||
addAttributes(attrs, range: wholeRange)
|
||||
}
|
||||
|
||||
func addAttribute(for key: Key, value: Any) {
|
||||
addAttribute(key, value: value, range: wholeRange)
|
||||
}
|
||||
|
||||
func removeAttribute(for key: Key) {
|
||||
removeAttribute(key, range: wholeRange)
|
||||
}
|
||||
|
||||
func replaceAttribute(for key: Key, value: Any) {
|
||||
replaceAttribute(for: key, value: value, inRange: wholeRange)
|
||||
}
|
||||
|
||||
func replaceAttribute(for key: Key, value: Any, inRange range: NSRange) {
|
||||
removeAttribute(key, range: range)
|
||||
addAttribute(key, value: value, range: range)
|
||||
}
|
||||
|
||||
func updateExistingAttributes<A>(for key: Key, using transform: (A) -> A) {
|
||||
updateExistingAttributes(for: key, in: wholeRange, using: transform)
|
||||
}
|
||||
|
||||
func updateExistingAttributes<A>(for key: Key, in range: NSRange, using transform: (A) -> A) {
|
||||
var existingValues = [(value: A, range: NSRange)]()
|
||||
enumerateAttributes(for: key, in: range) { existingValues.append(($0, $1)) }
|
||||
existingValues.forEach { addAttribute(key, value: transform($0.0), range: $0.1) }
|
||||
}
|
||||
|
||||
func addAttributeInMissingRanges<A>(for key: Key, value: A) {
|
||||
addAttributeInMissingRanges(for: key, value: value, within: wholeRange)
|
||||
}
|
||||
|
||||
func addAttributeInMissingRanges<A>(for key: Key, value: A, within range: NSRange) {
|
||||
rangesMissingAttribute(for: key, in: range).forEach {
|
||||
addAttribute(key, value: value, range: $0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// UIFont+Traits.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 22.06.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
public typealias DownFontDescriptor = UIFontDescriptor
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
public typealias DownFontDescriptor = NSFontDescriptor
|
||||
|
||||
#endif
|
||||
|
||||
extension DownFont {
|
||||
|
||||
var isStrong: Bool {
|
||||
return contains(.strong)
|
||||
}
|
||||
|
||||
var isEmphasized: Bool {
|
||||
return contains(.emphasis)
|
||||
}
|
||||
|
||||
var isMonospace: Bool {
|
||||
return contains(.monoSpace)
|
||||
}
|
||||
|
||||
var strong: DownFont {
|
||||
return with(.strong) ?? self
|
||||
}
|
||||
|
||||
var emphasis: DownFont {
|
||||
return with(.emphasis) ?? self
|
||||
}
|
||||
|
||||
var monospace: DownFont {
|
||||
return with(.monoSpace) ?? self
|
||||
}
|
||||
|
||||
private func with(_ trait: DownFontDescriptor.SymbolicTraits) -> DownFont? {
|
||||
guard !contains(trait) else { return self }
|
||||
|
||||
var traits = fontDescriptor.symbolicTraits
|
||||
traits.insert(trait)
|
||||
|
||||
#if canImport(UIKit)
|
||||
guard let newDescriptor = fontDescriptor.withSymbolicTraits(traits) else { return self }
|
||||
return DownFont(descriptor: newDescriptor, size: pointSize)
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
let newDescriptor = fontDescriptor.withSymbolicTraits(traits)
|
||||
return DownFont(descriptor: newDescriptor, size: pointSize)
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
private func contains(_ trait: DownFontDescriptor.SymbolicTraits) -> Bool {
|
||||
return fontDescriptor.symbolicTraits.contains(trait)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
private extension DownFontDescriptor.SymbolicTraits {
|
||||
|
||||
static let strong = DownFontDescriptor.SymbolicTraits.traitBold
|
||||
static let emphasis = DownFontDescriptor.SymbolicTraits.traitItalic
|
||||
static let monoSpace = DownFontDescriptor.SymbolicTraits.traitMonoSpace
|
||||
|
||||
}
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
private extension DownFontDescriptor.SymbolicTraits {
|
||||
|
||||
static let strong = DownFontDescriptor.SymbolicTraits.bold
|
||||
static let emphasis = DownFontDescriptor.SymbolicTraits.italic
|
||||
static let monoSpace = DownFontDescriptor.SymbolicTraits.monoSpace
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// ParagraphStyler.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 25.06.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
/// A convenient class used to format lists, such that list item prefixes
|
||||
/// are right aligned and list item content left aligns.
|
||||
|
||||
public class ListItemParagraphStyler {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var indentation: CGFloat {
|
||||
return largestPrefixWidth + options.spacingAfterPrefix
|
||||
}
|
||||
|
||||
/// The paragraph style intended for all paragraphs excluding the first.
|
||||
|
||||
public var trailingParagraphStyle: NSParagraphStyle {
|
||||
let contentIndentation = indentation
|
||||
let style = baseStyle
|
||||
style.firstLineHeadIndent = contentIndentation
|
||||
style.headIndent = contentIndentation
|
||||
return style
|
||||
}
|
||||
|
||||
private let options: ListItemOptions
|
||||
private let largestPrefixWidth: CGFloat
|
||||
|
||||
private var baseStyle: NSMutableParagraphStyle {
|
||||
let style = NSMutableParagraphStyle()
|
||||
style.paragraphSpacingBefore = options.spacingAbove
|
||||
style.paragraphSpacing = options.spacingBelow
|
||||
style.alignment = options.alignment
|
||||
return style
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(options: ListItemOptions, prefixFont: DownFont) {
|
||||
self.options = options
|
||||
self.largestPrefixWidth = prefixFont.widthOfNumberedPrefix(digits: options.maxPrefixDigits)
|
||||
}
|
||||
|
||||
// MARK: - Methods
|
||||
|
||||
/// The paragraph style intended for the first paragraph of the list item.
|
||||
///
|
||||
/// - Parameter prefixWidth: the width (in points) of the list item prefix.
|
||||
|
||||
public func leadingParagraphStyle(prefixWidth: CGFloat) -> NSParagraphStyle {
|
||||
let contentIndentation = indentation
|
||||
let prefixIndentation: CGFloat = contentIndentation - options.spacingAfterPrefix - prefixWidth
|
||||
let prefixSpill = max(0, prefixWidth - largestPrefixWidth)
|
||||
let firstLineContentIndentation = contentIndentation + prefixSpill
|
||||
|
||||
let style = baseStyle
|
||||
style.firstLineHeadIndent = prefixIndentation
|
||||
style.tabStops = [tabStop(at: firstLineContentIndentation)]
|
||||
style.headIndent = contentIndentation
|
||||
return style
|
||||
}
|
||||
|
||||
private func tabStop(at location: CGFloat) -> NSTextTab {
|
||||
return NSTextTab(textAlignment: options.alignment, location: location, options: [:])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension DownFont {
|
||||
|
||||
func widthOfNumberedPrefix(digits: UInt) -> CGFloat {
|
||||
return widthOfLargestDigit * CGFloat(digits) + widthOfPeriod
|
||||
}
|
||||
|
||||
private var widthOfLargestDigit: CGFloat {
|
||||
return Int.decimalDigits
|
||||
.map { NSAttributedString(string: "\($0)", attributes: [.font: self]).size().width }
|
||||
.max()!
|
||||
}
|
||||
|
||||
private var widthOfPeriod: CGFloat {
|
||||
return NSAttributedString(string: ".", attributes: [.font: self])
|
||||
.size()
|
||||
.width
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension Int {
|
||||
|
||||
static var decimalDigits: [Int] {
|
||||
return Array(0...9)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// DownDebugLayoutManager.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 06.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
/// A layout manager that draws the line fragments.
|
||||
///
|
||||
/// Line fragments are the areas with a document that contain lines of text. There
|
||||
/// are two types.
|
||||
///
|
||||
/// 1. A *line rect* (drawn in red) indicates the maximum rect enclosing the line.
|
||||
/// This inlcudes not only the textual content, but also the padding (if any) around that text.
|
||||
/// 2. A *line used rect* (drawn in blue) is the smallest rect enclosing the textual content.
|
||||
///
|
||||
/// The visualization of these rects is useful when determining the paragraph styles
|
||||
/// of a `DownStyler`.
|
||||
///
|
||||
/// Insert this into a TextKit stack manually, or use the provided `DownDebugTextView`.
|
||||
|
||||
public class DownDebugLayoutManager: DownLayoutManager {
|
||||
|
||||
// MARK: - Drawing
|
||||
|
||||
override public func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
|
||||
super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
|
||||
drawLineFragments(forGlyphRange: glyphsToShow, at: origin)
|
||||
}
|
||||
|
||||
private func drawLineFragments(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
|
||||
enumerateLineFragments(forGlyphRange: glyphsToShow) { rect, usedRect, _, _, _ in
|
||||
[(usedRect, DownColor.blue), (rect, DownColor.red)].forEach { rectToDraw, color in
|
||||
let adjustedRect = rectToDraw.translated(by: origin)
|
||||
self.drawRect(adjustedRect, color: color.cgColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func drawRect(_ rect: CGRect, color: CGColor) {
|
||||
guard let context = context else { return }
|
||||
push(context: context)
|
||||
defer { popContext() }
|
||||
|
||||
context.setStrokeColor(color)
|
||||
context.stroke(rect)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// DownLayoutManager.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 02.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
/// A layout manager capable of drawing the custom attributes set by the `DownStyler`.
|
||||
///
|
||||
/// Insert this into a TextKit stack manually, or use the provided `DownTextView`.
|
||||
|
||||
public class DownLayoutManager: NSLayoutManager {
|
||||
|
||||
// MARK: - Graphic context
|
||||
|
||||
#if canImport(UIKit)
|
||||
var context: CGContext? {
|
||||
return UIGraphicsGetCurrentContext()
|
||||
}
|
||||
|
||||
func push(context: CGContext) {
|
||||
UIGraphicsPushContext(context)
|
||||
}
|
||||
|
||||
func popContext() {
|
||||
UIGraphicsPopContext()
|
||||
}
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
var context: CGContext? {
|
||||
return NSGraphicsContext.current?.cgContext
|
||||
}
|
||||
|
||||
func push(context: CGContext) {
|
||||
NSGraphicsContext.saveGraphicsState()
|
||||
}
|
||||
|
||||
func popContext() {
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - Drawing
|
||||
|
||||
override public func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
|
||||
drawCustomBackgrounds(forGlyphRange: glyphsToShow, at: origin)
|
||||
super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
|
||||
drawCustomAttributes(forGlyphRange: glyphsToShow, at: origin)
|
||||
}
|
||||
|
||||
private func drawCustomBackgrounds(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
|
||||
guard let context = context else { return }
|
||||
push(context: context)
|
||||
defer { popContext() }
|
||||
|
||||
guard let textStorage = textStorage else { return }
|
||||
|
||||
let characterRange = self.characterRange(forGlyphRange: glyphsToShow, actualGlyphRange: nil)
|
||||
|
||||
textStorage.enumerateAttributes(for: .blockBackgroundColor,
|
||||
in: characterRange) { (attr: BlockBackgroundColorAttribute, blockRange) in
|
||||
let inset = attr.inset
|
||||
|
||||
context.setFillColor(attr.color.cgColor)
|
||||
|
||||
let allBlockColorRanges = glyphRanges(for: .blockBackgroundColor,
|
||||
in: textStorage,
|
||||
inCharacterRange: blockRange)
|
||||
|
||||
let glyphRange = self.glyphRange(forCharacterRange: blockRange, actualCharacterRange: nil)
|
||||
|
||||
enumerateLineFragments(forGlyphRange: glyphRange) { lineRect, lineUsedRect, container, lineGlyphRange, _ in
|
||||
let isLineStartOfBlock = allBlockColorRanges.contains {
|
||||
lineGlyphRange.overlapsStart(of: $0)
|
||||
}
|
||||
|
||||
let isLineEndOfBlock = allBlockColorRanges.contains {
|
||||
lineGlyphRange.overlapsEnd(of: $0)
|
||||
}
|
||||
|
||||
let minX = lineUsedRect.minX + container.lineFragmentPadding - inset
|
||||
let maxX = lineRect.maxX
|
||||
let minY = isLineStartOfBlock ? lineUsedRect.minY - inset : lineRect.minY
|
||||
let maxY = isLineEndOfBlock ? lineUsedRect.maxY + inset : lineUsedRect.maxY
|
||||
let blockRect = CGRect(minX: minX, minY: minY, maxX: maxX, maxY: maxY).translated(by: origin)
|
||||
|
||||
context.fill(blockRect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func drawCustomAttributes(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
|
||||
let characterRange = self.characterRange(forGlyphRange: glyphsToShow, actualGlyphRange: nil)
|
||||
drawThematicBreakIfNeeded(in: characterRange, at: origin)
|
||||
drawQuoteStripeIfNeeded(in: characterRange, at: origin)
|
||||
}
|
||||
|
||||
private func drawThematicBreakIfNeeded(in characterRange: NSRange, at origin: CGPoint) {
|
||||
guard let context = context else { return }
|
||||
push(context: context)
|
||||
defer { popContext() }
|
||||
|
||||
textStorage?.enumerateAttributes(for: .thematicBreak,
|
||||
in: characterRange) { (attr: ThematicBreakAttribute, range) in
|
||||
|
||||
let firstGlyphIndex = glyphIndexForCharacter(at: range.lowerBound)
|
||||
|
||||
let lineRect = lineFragmentRect(forGlyphAt: firstGlyphIndex, effectiveRange: nil)
|
||||
let usedRect = lineFragmentUsedRect(forGlyphAt: firstGlyphIndex, effectiveRange: nil)
|
||||
|
||||
let lineStart = usedRect.minX + fragmentPadding(forGlyphAt: firstGlyphIndex)
|
||||
|
||||
let width = lineRect.width - lineStart
|
||||
let height = lineRect.height
|
||||
|
||||
let boundingRect = CGRect(x: lineStart, y: lineRect.minY, width: width, height: height)
|
||||
let adjustedLineRect = boundingRect.translated(by: origin)
|
||||
|
||||
drawThematicBreak(with: context, in: adjustedLineRect, attr: attr)
|
||||
}
|
||||
}
|
||||
|
||||
private func fragmentPadding(forGlyphAt glyphIndex: Int) -> CGFloat {
|
||||
let textContainer = self.textContainer(forGlyphAt: glyphIndex, effectiveRange: nil)
|
||||
return textContainer?.lineFragmentPadding ?? 0
|
||||
}
|
||||
|
||||
private func drawThematicBreak(with context: CGContext, in rect: CGRect, attr: ThematicBreakAttribute) {
|
||||
context.setStrokeColor(attr.color.cgColor)
|
||||
context.setLineWidth(attr.thickness)
|
||||
context.move(to: CGPoint(x: rect.minX, y: rect.midY))
|
||||
context.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
|
||||
context.strokePath()
|
||||
}
|
||||
|
||||
private func drawQuoteStripeIfNeeded(in characterRange: NSRange, at origin: CGPoint) {
|
||||
guard let context = context else { return }
|
||||
push(context: context)
|
||||
defer { popContext() }
|
||||
|
||||
textStorage?.enumerateAttributes(for: .quoteStripe,
|
||||
in: characterRange) { (attr: QuoteStripeAttribute, quoteRange) in
|
||||
|
||||
context.setFillColor(attr.color.cgColor)
|
||||
|
||||
let glyphRangeOfQuote = self.glyphRange(forCharacterRange: quoteRange, actualCharacterRange: nil)
|
||||
|
||||
enumerateLineFragments(forGlyphRange: glyphRangeOfQuote) { lineRect, _, container, _, _ in
|
||||
let locations = attr.locations.map {
|
||||
CGPoint(x: $0 + container.lineFragmentPadding, y: 0)
|
||||
.translated(by: lineRect.origin)
|
||||
.translated(by: origin)
|
||||
}
|
||||
|
||||
let stripeSize = CGSize(width: attr.thickness, height: lineRect.height)
|
||||
self.drawQuoteStripes(with: context, locations: locations, size: stripeSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func drawQuoteStripes(with context: CGContext, locations: [CGPoint], size: CGSize) {
|
||||
locations.forEach {
|
||||
let stripeRect = CGRect(origin: $0, size: size)
|
||||
context.fill(stripeRect)
|
||||
}
|
||||
}
|
||||
|
||||
private func glyphRanges(for key: NSAttributedString.Key,
|
||||
in storage: NSTextStorage,
|
||||
inCharacterRange range: NSRange) -> [NSRange] {
|
||||
|
||||
return storage
|
||||
.ranges(of: key, in: range)
|
||||
.map { self.glyphRange(forCharacterRange: $0, actualCharacterRange: nil) }
|
||||
.mergeNeighbors()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private extension NSRange {
|
||||
|
||||
func overlapsStart(of range: NSRange) -> Bool {
|
||||
return lowerBound <= range.lowerBound && upperBound > range.lowerBound
|
||||
}
|
||||
|
||||
func overlapsEnd(of range: NSRange) -> Bool {
|
||||
return lowerBound < range.upperBound && upperBound >= range.upperBound
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension Array where Element == NSRange {
|
||||
|
||||
func mergeNeighbors() -> [Element] {
|
||||
let sorted = self.sorted { $0.lowerBound <= $1.lowerBound }
|
||||
|
||||
let result = sorted.reduce(into: [NSRange]()) { acc, next in
|
||||
guard let last = acc.popLast() else {
|
||||
acc.append(next)
|
||||
return
|
||||
}
|
||||
|
||||
guard last.upperBound == next.lowerBound else {
|
||||
acc.append(contentsOf: [last, next])
|
||||
return
|
||||
}
|
||||
|
||||
acc.append(NSRange(location: last.lowerBound, length: next.upperBound - last.lowerBound))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// CodeBlockOptions.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 12.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
public struct CodeBlockOptions {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var containerInset: CGFloat
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(containerInset: CGFloat = 8) {
|
||||
self.containerInset = containerInset
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// ListItemOptions.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 04.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
public struct ListItemOptions {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var maxPrefixDigits: UInt
|
||||
public var spacingAfterPrefix: CGFloat
|
||||
public var spacingAbove: CGFloat
|
||||
public var spacingBelow: CGFloat
|
||||
public var alignment: NSTextAlignment
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(maxPrefixDigits: UInt = 2,
|
||||
spacingAfterPrefix: CGFloat = 8,
|
||||
spacingAbove: CGFloat = 4,
|
||||
spacingBelow: CGFloat = 8,
|
||||
alignment: NSTextAlignment = .natural) {
|
||||
|
||||
self.maxPrefixDigits = maxPrefixDigits
|
||||
self.spacingAfterPrefix = spacingAfterPrefix
|
||||
self.spacingAbove = spacingAbove
|
||||
self.spacingBelow = spacingBelow
|
||||
self.alignment = alignment
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// QuoteStripeOptions.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 04.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
public struct QuoteStripeOptions {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var thickness: CGFloat
|
||||
public var spacingAfter: CGFloat
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(thickness: CGFloat = 2, spacingAfter: CGFloat = 8) {
|
||||
self.thickness = thickness
|
||||
self.spacingAfter = spacingAfter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// ThematicBreakOptions.swift
|
||||
// Down
|
||||
//
|
||||
// Created by John Nguyen on 04.08.19.
|
||||
// Copyright © 2016-2019 Down. All rights reserved.
|
||||
//
|
||||
|
||||
#if !os(watchOS) && !os(Linux)
|
||||
|
||||
#if canImport(UIKit)
|
||||
|
||||
import UIKit
|
||||
|
||||
#elseif canImport(AppKit)
|
||||
|
||||
import AppKit
|
||||
|
||||
#endif
|
||||
|
||||
public struct ThematicBreakOptions {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public var thickness: CGFloat
|
||||
public var indentation: CGFloat
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
public init(thickness: CGFloat = 1, indentation: CGFloat = 0) {
|
||||
self.thickness = thickness
|
||||
self.indentation = indentation
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user