├── .gitattributes ├── .gitignore ├── BUCK ├── DEFS ├── LICENSE ├── README.md ├── YAS.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── Test.xcscheme ├── bin ├── YAS.framework │ ├── Headers │ │ ├── YAS-Swift.h │ │ ├── YAS.h │ │ ├── YASObjcExceptionHandler.h │ │ └── yaml.h │ ├── Info.plist │ ├── Modules │ │ ├── YAS.swiftmodule │ │ │ ├── i386.swiftdoc │ │ │ ├── i386.swiftmodule │ │ │ ├── x86_64.swiftdoc │ │ │ └── x86_64.swiftmodule │ │ └── module.modulemap │ ├── YAS │ └── _CodeSignature │ │ └── CodeResources └── dist.zip ├── configs ├── Debug.xcconfig └── Release.xcconfig ├── docs └── logo.png ├── project.yml ├── src ├── ConstExpr.swift ├── DynamicLookup.swift ├── Info.plist ├── ObjectExpr.swift ├── Rule.swift ├── Style.swift ├── Stylesheet.swift ├── StylesheetContext.swift ├── View.swift ├── YAS.h ├── deps │ ├── Expression.swift │ ├── YAMLBridge.swift │ ├── YASObjcExceptionHandler.h │ ├── YASObjcExceptionHandler.m │ ├── yaml.c │ └── yaml.h └── helpers │ ├── UIKit+ConstExpr.swift │ ├── UIKit+Helpers.swift │ └── UIKit+ObjectExpr.swift └── test ├── Info.plist └── Test.swift /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c linguist-language=Swift 2 | *.m linguist-language=Swift 3 | *.mm linguist-language=Swift 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | .DS_Store 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | *.DS_Store 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /BUCK: -------------------------------------------------------------------------------- 1 | apple_libreary( 2 | name = 'Emit', 3 | visibility = ['PUBLIC'], 4 | preprocessor_flags = ['-D', 'PRODUCT_NAME=Emit'], 5 | exported_headers = glob([ 6 | 'src/**/*.h' 7 | ]), 8 | srcs = glob([ 9 | 'src/**/*.swift', 10 | ]), 11 | ) 12 | 13 | apple_resource( 14 | name = 'DemoResources', 15 | dirs = [], 16 | files = glob(['res/**/*']), 17 | ) 18 | 19 | apple_binary( 20 | name = 'DemoBinary', 21 | srcs = glob(['demo/src/*.swift']), 22 | deps = [':Emit'], 23 | frameworks = [ 24 | '$SDKROOT/System/Library/Frameworks/Foundation.framework', 25 | '$SDKROOT/System/Library/Frameworks/UIKit.framework', 26 | ], 27 | ) 28 | 29 | apple_bundle( 30 | name = 'DemoApp', 31 | binary = ':DemoBinary', 32 | deps = [':DemoResources'], 33 | extension = 'app', 34 | info_plist = 'demo/src/Info.plist', 35 | ) 36 | -------------------------------------------------------------------------------- /DEFS: -------------------------------------------------------------------------------- 1 | swift_version_from_config = '4' 2 | 3 | original_apple_library = apple_library 4 | def apple_library( 5 | name, 6 | swift_version = swift_version_from_config, 7 | **kwargs 8 | ): 9 | original_apple_library( 10 | name=name, 11 | swift_version=swift_version, 12 | **kwargs 13 | ) 14 | 15 | # TODO: Is this really required? 16 | original_apple_test = apple_test 17 | def apple_test( 18 | name, 19 | swift_version = swift_version_from_config, 20 | **kwargs 21 | ): 22 | original_apple_test( 23 | name=name, 24 | swift_version=swift_version, 25 | **kwargs 26 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Alex Usbergo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # YAS [![Swift](https://img.shields.io/badge/swift-5-orange.svg?style=flat)](#) [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT) 2 | 3 | Logo 4 | 5 | **YAS** is a YAML-based stylesheet engine written in Swift. 6 | 7 | ### Installing the framework 8 | 9 | ```bash 10 | cd {PROJECT_ROOT_DIRECTORY} 11 | curl "https://raw.githubusercontent.com/alexdrone/YAS/master/bin/dist.zip" > dist.zip && unzip dist.zip && rm dist.zip; 12 | ``` 13 | 14 | Drag `YAS.framework` in your project and add it as an embedded binary. 15 | 16 | If you are using [xcodegen](https://github.com/yonaskolb/XcodeGen) add the framework to your *project.yml* like so: 17 | 18 | ```yaml 19 | targets: 20 | YOUR_APP_TARGET: 21 | ... 22 | dependencies: 23 | - framework: PATH/TO/YOUR/DEPS/YAS.framework 24 | ``` 25 | 26 | If you are using **Carthage**: 27 | Add the following line to your `Cartfile`: 28 | 29 | ```ruby 30 | github "alexdrone/YAS" "master" 31 | ``` 32 | 33 | ### Getting Started 34 | 35 | Create a new YAML stylesheet and save it in a file named `style.yaml`. 36 | 37 | ```yaml 38 | FooStyle: 39 | backgroundColor: {_type: color, hex: ff0000} 40 | margin: 10.0 41 | ``` 42 | 43 | Load it up and access to its member using the built-in dynamic lookup proxy. 44 | 45 | ```swift 46 | try! StylesheetContext.manager.load("style.yaml") 47 | let margin = StylesheetContext.lookup.FooStyle.margin.cgFloat //10.0 48 | let backgroundColor = StylesheetContext.lookup.FooStyle.backgroundColor.color //UIColor(...) 49 | ``` 50 | 51 | or automatically apply the style to your `UIView`: 52 | 53 | ```swift 54 | view.apply(style: Yas.lookup.FooStyle) 55 | ``` 56 | 57 | ### Built-in types 58 | 59 | ```yaml 60 | Example: 61 | cgFloat: 42.0 62 | bool: true 63 | integer: 42 64 | # Symbols can be exported by calling ConstExpr.export([:]) 65 | enum: ${NSTextAlignment.right} 66 | # ${...} is the expression delimiter 67 | cgFloatExpression: ${41+1} 68 | boolExpression: ${1 == 1 && true} 69 | integerExpression: ${41+1} 70 | # Custom objects. 71 | # Use the reserved _type attribute to distinguish the object type. 72 | # New object types can be exported by calling ObjectExpr.export(...) 73 | # {_type: color, hex: ffffff, (darken: [0-100]), (lighten: [0-100]), (alpha: [0-1])} 74 | color: {_type: color, hex: ff0000} 75 | # {_type: font, (name: [fontname]), size: [size], (weight: [light...])} 76 | font: {_type: font, name: Arial, size: 42} 77 | fontWeight: {_type: font, weight: bold, size: 12} 78 | # {_type: animator, duration: 1, (curve: [easeIn...]), (damping: [0-1])} 79 | animator: {_type: animator, curve: easeIn, duration: 1} 80 | # {_type: text, (name: [fontname]), size: [size], (weight: [light...]), (kern: [0..n]), (hex: [hex colorcode]), (supportDynamicType: [bool])} 81 | textStyle: {_type: text, name: Arial, size: 42, kern: 2, hex: ff0000} 82 | ``` 83 | 84 | ### References and anchors 85 | 86 | By using YAML anchors and references you can reuse values across your stylesheet: 87 | 88 | ```yaml 89 | Foo: 90 | fooValue: &_fooValue 42.0 91 | Bar: 92 | bar: *_fooValue 93 | baz: 2 94 | ``` 95 | 96 | You can also copy the whole style using the YAML extension construct: 97 | 98 | ```yaml 99 | Foo: &_Foo 100 | aValue: 42.0 101 | anotherValue: "Hello" 102 | someColor: {_type: color, hex: ff0000} 103 | Bar: 104 | <<: *_Foo 105 | yetAnotherValue: 2 106 | ``` 107 | 108 | #### Real life example 109 | 110 | ```yaml 111 | Palette: 112 | primaryColorHex: &_primaryColorHex ff0000 113 | primaryColor: &_primaryColor {_type: color, hex: *_primaryColorHex} 114 | primaryColor600: &_primaryColor600 {_type: color, hex: *_primaryColorHex, darken: 10} 115 | primaryColor700: &_primaryColor700 {_type: color, hex: *_primaryColorHex, darken: 20} 116 | Typography: 117 | primaryFontName: &_primaryFontName "Open Sans" 118 | secondaryFontName: &_secondaryFontName "Rubik" 119 | body1: &_body1 {_type: attributedString, name: *_secondaryFontName, size: 14.26, kern: 0.25, color: *_primaryColorHex} 120 | body2: &_body2 {_type: attributedString, weight: medium, size: 12.22, kern: 0.5, color: *_primaryColorHex} 121 | LandingPage: 122 | titleText: *_body1 123 | backgroundColor: *_primaryColor600 124 | topMargin: 12 125 | shouldHideHero: ${horizontalSizeClass == compact} 126 | tileSize: ${screenSize.width/2 - 8} 127 | 128 | ``` 129 | 130 | ### Cascade imports 131 | 132 | Stylesheets can be split into smaller modules by using the `import` rule at the top of the main stylesheet file. 133 | 134 | ```yaml 135 | 136 | import: [typography.yaml, palette.yaml, buttons.yaml] 137 | 138 | ``` 139 | 140 | ### Custom types 141 | 142 | You can define your own custom object expressions by creating a new `ObjectExpr` 143 | subclass. 144 | 145 | ```swift 146 | 147 | @objc class MyCustomObjectExpression : ObjectExprBase { 148 | // Your arguments must be marked with @obj and dynamic. 149 | @objc dynamic var foo: Int = 0 150 | @objc dynamic var bar: String = "" 151 | 152 | override func eval() -> Any? { 153 | // Build your desired return types 154 | return MyCustomObject(foo: foo, bar: bar) 155 | } 156 | } 157 | ``` 158 | 159 | Finally register your `ObjectExpr` in the shared `ObjectExprRegistry`. 160 | 161 | ```swift 162 | StylesheetContext.objectExpr.export(ObjectExprFactory( 163 | type: MyCustomObjectExpression.self, 164 | name: "myObject") 165 | ``` 166 | 167 | Use your custom define object expression in any stylesheet rule. 168 | 169 | ```yaml 170 | 171 | MyStyle: 172 | myCustomRule: {_type: myObject, foo: 42, bar: "Hello"} 173 | ``` 174 | 175 | ### Reacting to stylesheet changes 176 | 177 | `Notification.Name.StylesheetContextDidChange` is posted whenever the stylesheet has been reloaded. 178 | 179 | ### Dependencies and credits 180 | 181 | Deps forked from: 182 | 183 | * [yaml/libyaml](https://github.com/yaml/libyaml) 184 | * [nicklockwood/Expression](https://github.com/nicklockwood/Expression) 185 | -------------------------------------------------------------------------------- /YAS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0D23E76BB287D6F41226E2C8F44982E9 /* YASObjcExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 229274DFEE800CE5C1EE80BB87511463 /* YASObjcExceptionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 0E957F9D236E5D3CCBDE3019ADBE6239 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AA5ACA430504B8AC34A51BC7676DE9 /* Expression.swift */; }; 12 | 17BC6FDAEBB0FD50E86605385038A439 /* Rule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E002CAEE504314E51003FE8E3E55F99 /* Rule.swift */; }; 13 | 1B7ABDDAD63430C28F84542DD4726F0F /* YAMLBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93F875ED05E49E495E87298C594CE1A2 /* YAMLBridge.swift */; }; 14 | 1E1294F51153474617DB81B6C1B57015 /* UIKit+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37764DFDD8CAD9A61FB82D9645B91EA2 /* UIKit+Helpers.swift */; }; 15 | 21EB4D3EB09921AB3E983FA6E54CEB0C /* Stylesheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D29B7FD2FCA4108480759BEB224E5CD /* Stylesheet.swift */; }; 16 | 28A731E59410497D9B25F12D401B2C7D /* Stylesheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D29B7FD2FCA4108480759BEB224E5CD /* Stylesheet.swift */; }; 17 | 28FB7560F3DB54EDBDB8D63EFAE0F08A /* DynamicLookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8990FCDEF3CC71536F25D6721C3069F7 /* DynamicLookup.swift */; }; 18 | 2CD517803AAC283D51B90DD300B12B7A /* Rule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E002CAEE504314E51003FE8E3E55F99 /* Rule.swift */; }; 19 | 2D443EA970C351CD01F01FC29BB375B6 /* UIKit+ObjectExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0501F7EA96A9F71F5D0A0122C73BD9A0 /* UIKit+ObjectExpr.swift */; }; 20 | 350B76DE3B2B9A6298FD3A4153F9C572 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ACB7C39D07538D75B64E3E7ADD5A358 /* View.swift */; }; 21 | 3732C434428DCADCEB1E9BF9009394E1 /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21740FA52173BD193F27984E625EA549 /* Test.swift */; }; 22 | 3FA07314552471638B48E911DAB6AD06 /* YAMLBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93F875ED05E49E495E87298C594CE1A2 /* YAMLBridge.swift */; }; 23 | 4147B89F0F752BB233BE13D02A137FE6 /* yaml.c in Sources */ = {isa = PBXBuildFile; fileRef = F3988AFE6521B66342B7DA63668A5285 /* yaml.c */; }; 24 | 45C2494BEDFB141D0A1CD4E8D218449C /* StylesheetContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FB22ABD74EFB6B97E9DFE88DF3891 /* StylesheetContext.swift */; }; 25 | 47DDF6216E7E03C843017E97BD37D0B4 /* UIKit+ConstExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7091F77773429C305FB387499A6F72AA /* UIKit+ConstExpr.swift */; }; 26 | 506B5894F3DCA1A59C7D5C0BA4C9E4EB /* Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D24B6472F1C7E30CB18D9741B28D62 /* Style.swift */; }; 27 | 56708BD6744276E7FDE9635B55F1C549 /* YAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 906F703065FD00EA4130D33A0DF05DDA /* YAS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | 598C255F655D87016A438C5399883F66 /* YASObjcExceptionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 229274DFEE800CE5C1EE80BB87511463 /* YASObjcExceptionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 5C00A1AA483BFAF4B57904DF15DCF525 /* UIKit+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37764DFDD8CAD9A61FB82D9645B91EA2 /* UIKit+Helpers.swift */; }; 30 | 6279093B4802A21DAB06605E2EB15391 /* StylesheetContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FB22ABD74EFB6B97E9DFE88DF3891 /* StylesheetContext.swift */; }; 31 | 693C87E588FF93D9FA971A6C0EF84275 /* YAS.h in Headers */ = {isa = PBXBuildFile; fileRef = 906F703065FD00EA4130D33A0DF05DDA /* YAS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 6D803326E601B3C3711608A8E07442FA /* YASObjcExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C2EE9854B6C5C08617A7E6C6D8F72EE1 /* YASObjcExceptionHandler.m */; }; 33 | 7769148C77426EE712559F8F07516595 /* Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24D24B6472F1C7E30CB18D9741B28D62 /* Style.swift */; }; 34 | 7816B78BB815F3D5F1E2EF4AC338885E /* YAS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3DE8E23ED35D99507AB89A79AA09C5B /* YAS.framework */; }; 35 | 79AE0A2DD8C77312B5B979AF7AD64304 /* ConstExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54858AF3C05FC18FC0F3FFDFEA9875B /* ConstExpr.swift */; }; 36 | 8354DE7B854817D495B27C9DD42149D5 /* yaml.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B7CDBD7ED51A0F5D74B0ACCFD53DB6 /* yaml.h */; settings = {ATTRIBUTES = (Public, ); }; }; 37 | 932E88DAA47A7680B870957F92C0D6F3 /* UIKit+ObjectExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0501F7EA96A9F71F5D0A0122C73BD9A0 /* UIKit+ObjectExpr.swift */; }; 38 | 9B879B18B000C3A9FC1E48170AF92062 /* ObjectExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A88C4FD6392881C52763D7248C19B42 /* ObjectExpr.swift */; }; 39 | A671CA982D41753FD8282439F58CC598 /* YASObjcExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C2EE9854B6C5C08617A7E6C6D8F72EE1 /* YASObjcExceptionHandler.m */; }; 40 | C66E02EF248D2D11E5F711FE04A77435 /* DynamicLookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8990FCDEF3CC71536F25D6721C3069F7 /* DynamicLookup.swift */; }; 41 | D00E06B4CD783983ED7379678B3468AF /* yaml.c in Sources */ = {isa = PBXBuildFile; fileRef = F3988AFE6521B66342B7DA63668A5285 /* yaml.c */; }; 42 | D2332FAE73B6FDA16D4E9947CBCBFF3F /* yaml.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B7CDBD7ED51A0F5D74B0ACCFD53DB6 /* yaml.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43 | D29056271B86202170DD36F6E6D5EF54 /* YAS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D3DE8E23ED35D99507AB89A79AA09C5B /* YAS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 44 | D2D238509FB29EB12851BDB52B6C7CAA /* UIKit+ConstExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7091F77773429C305FB387499A6F72AA /* UIKit+ConstExpr.swift */; }; 45 | DAD524E3D5F909062A037A0F0BEBA964 /* ObjectExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A88C4FD6392881C52763D7248C19B42 /* ObjectExpr.swift */; }; 46 | ECF6189DFF8B68B8F8A4B341CD6807F1 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ACB7C39D07538D75B64E3E7ADD5A358 /* View.swift */; }; 47 | F80934E3F15B72ABB59846A21FF0E559 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7AA5ACA430504B8AC34A51BC7676DE9 /* Expression.swift */; }; 48 | FEFCC41DE514351BA9E2999CF6FF4CF2 /* ConstExpr.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54858AF3C05FC18FC0F3FFDFEA9875B /* ConstExpr.swift */; }; 49 | /* End PBXBuildFile section */ 50 | 51 | /* Begin PBXContainerItemProxy section */ 52 | 9CC11871BB09C144A2E743F81BC2D3A5 /* PBXContainerItemProxy */ = { 53 | isa = PBXContainerItemProxy; 54 | containerPortal = 60D68265D8B4D0045F19A05B75B65CA5 /* Project object */; 55 | proxyType = 1; 56 | remoteGlobalIDString = A7E551D272B1EB988493A7162322095C; 57 | remoteInfo = YAS_iOS; 58 | }; 59 | /* End PBXContainerItemProxy section */ 60 | 61 | /* Begin PBXCopyFilesBuildPhase section */ 62 | DC79195BF602504A3364ED9CD8E5950C /* Embed Frameworks */ = { 63 | isa = PBXCopyFilesBuildPhase; 64 | buildActionMask = 2147483647; 65 | dstPath = ""; 66 | dstSubfolderSpec = 10; 67 | files = ( 68 | D29056271B86202170DD36F6E6D5EF54 /* YAS.framework in Embed Frameworks */, 69 | ); 70 | name = "Embed Frameworks"; 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXCopyFilesBuildPhase section */ 74 | 75 | /* Begin PBXFileReference section */ 76 | 0501F7EA96A9F71F5D0A0122C73BD9A0 /* UIKit+ObjectExpr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+ObjectExpr.swift"; sourceTree = ""; }; 77 | 0D29B7FD2FCA4108480759BEB224E5CD /* Stylesheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stylesheet.swift; sourceTree = ""; }; 78 | 21740FA52173BD193F27984E625EA549 /* Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test.swift; sourceTree = ""; }; 79 | 229274DFEE800CE5C1EE80BB87511463 /* YASObjcExceptionHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YASObjcExceptionHandler.h; sourceTree = ""; }; 80 | 24D24B6472F1C7E30CB18D9741B28D62 /* Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Style.swift; sourceTree = ""; }; 81 | 3768C1142EEB9D782E88482F92BDCEE8 /* YAS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = YAS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 82 | 37764DFDD8CAD9A61FB82D9645B91EA2 /* UIKit+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+Helpers.swift"; sourceTree = ""; }; 83 | 3FBADAE708EE25C5BAD353BDB537DE25 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84 | 68D7C42EEF5CCAE743BA662A883BC2C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | 7091F77773429C305FB387499A6F72AA /* UIKit+ConstExpr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+ConstExpr.swift"; sourceTree = ""; }; 86 | 7A88C4FD6392881C52763D7248C19B42 /* ObjectExpr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectExpr.swift; sourceTree = ""; }; 87 | 8990FCDEF3CC71536F25D6721C3069F7 /* DynamicLookup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicLookup.swift; sourceTree = ""; }; 88 | 8E91795E3B13734300E9753DF1FC52B6 /* Test.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = Test.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | 906F703065FD00EA4130D33A0DF05DDA /* YAS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YAS.h; sourceTree = ""; }; 90 | 93B7CDBD7ED51A0F5D74B0ACCFD53DB6 /* yaml.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = yaml.h; sourceTree = ""; }; 91 | 93F875ED05E49E495E87298C594CE1A2 /* YAMLBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YAMLBridge.swift; sourceTree = ""; }; 92 | 9ACB7C39D07538D75B64E3E7ADD5A358 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; }; 93 | 9E002CAEE504314E51003FE8E3E55F99 /* Rule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Rule.swift; sourceTree = ""; }; 94 | C2EE9854B6C5C08617A7E6C6D8F72EE1 /* YASObjcExceptionHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = YASObjcExceptionHandler.m; sourceTree = ""; }; 95 | C33FB22ABD74EFB6B97E9DFE88DF3891 /* StylesheetContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StylesheetContext.swift; sourceTree = ""; }; 96 | D3DE8E23ED35D99507AB89A79AA09C5B /* YAS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = YAS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 97 | D7AA5ACA430504B8AC34A51BC7676DE9 /* Expression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = ""; }; 98 | F3988AFE6521B66342B7DA63668A5285 /* yaml.c */ = {isa = PBXFileReference; path = yaml.c; sourceTree = ""; }; 99 | F54858AF3C05FC18FC0F3FFDFEA9875B /* ConstExpr.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstExpr.swift; sourceTree = ""; }; 100 | /* End PBXFileReference section */ 101 | 102 | /* Begin PBXFrameworksBuildPhase section */ 103 | 09BC6D227637A74BB0D609DA44CFF807 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | 7816B78BB815F3D5F1E2EF4AC338885E /* YAS.framework in Frameworks */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | /* End PBXFrameworksBuildPhase section */ 112 | 113 | /* Begin PBXGroup section */ 114 | 1619ABEFBD5BA1F95AA4FB54D776FB27 /* deps */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | D7AA5ACA430504B8AC34A51BC7676DE9 /* Expression.swift */, 118 | F3988AFE6521B66342B7DA63668A5285 /* yaml.c */, 119 | 93B7CDBD7ED51A0F5D74B0ACCFD53DB6 /* yaml.h */, 120 | 93F875ED05E49E495E87298C594CE1A2 /* YAMLBridge.swift */, 121 | 229274DFEE800CE5C1EE80BB87511463 /* YASObjcExceptionHandler.h */, 122 | C2EE9854B6C5C08617A7E6C6D8F72EE1 /* YASObjcExceptionHandler.m */, 123 | ); 124 | path = deps; 125 | sourceTree = ""; 126 | }; 127 | 6C781762C1F9311AFC6EF4368E663796 /* src */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | F54858AF3C05FC18FC0F3FFDFEA9875B /* ConstExpr.swift */, 131 | 8990FCDEF3CC71536F25D6721C3069F7 /* DynamicLookup.swift */, 132 | 3FBADAE708EE25C5BAD353BDB537DE25 /* Info.plist */, 133 | 7A88C4FD6392881C52763D7248C19B42 /* ObjectExpr.swift */, 134 | 9E002CAEE504314E51003FE8E3E55F99 /* Rule.swift */, 135 | 24D24B6472F1C7E30CB18D9741B28D62 /* Style.swift */, 136 | 0D29B7FD2FCA4108480759BEB224E5CD /* Stylesheet.swift */, 137 | C33FB22ABD74EFB6B97E9DFE88DF3891 /* StylesheetContext.swift */, 138 | 9ACB7C39D07538D75B64E3E7ADD5A358 /* View.swift */, 139 | 906F703065FD00EA4130D33A0DF05DDA /* YAS.h */, 140 | 1619ABEFBD5BA1F95AA4FB54D776FB27 /* deps */, 141 | 86E9132FD5AD875CEA8596B4FFB58D3A /* helpers */, 142 | ); 143 | path = src; 144 | sourceTree = ""; 145 | }; 146 | 7A4587B1C54592B92861F126876E2163 /* test */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 68D7C42EEF5CCAE743BA662A883BC2C8 /* Info.plist */, 150 | 21740FA52173BD193F27984E625EA549 /* Test.swift */, 151 | ); 152 | path = test; 153 | sourceTree = ""; 154 | }; 155 | 86E9132FD5AD875CEA8596B4FFB58D3A /* helpers */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 7091F77773429C305FB387499A6F72AA /* UIKit+ConstExpr.swift */, 159 | 37764DFDD8CAD9A61FB82D9645B91EA2 /* UIKit+Helpers.swift */, 160 | 0501F7EA96A9F71F5D0A0122C73BD9A0 /* UIKit+ObjectExpr.swift */, 161 | ); 162 | path = helpers; 163 | sourceTree = ""; 164 | }; 165 | 94DAA74142BFE4DDDA734C7848E85BE1 /* Products */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 8E91795E3B13734300E9753DF1FC52B6 /* Test.xctest */, 169 | D3DE8E23ED35D99507AB89A79AA09C5B /* YAS.framework */, 170 | 3768C1142EEB9D782E88482F92BDCEE8 /* YAS.framework */, 171 | ); 172 | name = Products; 173 | sourceTree = ""; 174 | }; 175 | DF03D5FDA584EE956412F2EED3AFFC07 = { 176 | isa = PBXGroup; 177 | children = ( 178 | 6C781762C1F9311AFC6EF4368E663796 /* src */, 179 | 7A4587B1C54592B92861F126876E2163 /* test */, 180 | 94DAA74142BFE4DDDA734C7848E85BE1 /* Products */, 181 | ); 182 | indentWidth = 2; 183 | sourceTree = ""; 184 | usesTabs = 0; 185 | }; 186 | /* End PBXGroup section */ 187 | 188 | /* Begin PBXHeadersBuildPhase section */ 189 | 4B4DE705C41E7F26431A811BB6383F4D /* Headers */ = { 190 | isa = PBXHeadersBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | 56708BD6744276E7FDE9635B55F1C549 /* YAS.h in Headers */, 194 | 0D23E76BB287D6F41226E2C8F44982E9 /* YASObjcExceptionHandler.h in Headers */, 195 | D2332FAE73B6FDA16D4E9947CBCBFF3F /* yaml.h in Headers */, 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | CC39CF02FEBB643DD9702018878932FD /* Headers */ = { 200 | isa = PBXHeadersBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 693C87E588FF93D9FA971A6C0EF84275 /* YAS.h in Headers */, 204 | 598C255F655D87016A438C5399883F66 /* YASObjcExceptionHandler.h in Headers */, 205 | 8354DE7B854817D495B27C9DD42149D5 /* yaml.h in Headers */, 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | }; 209 | /* End PBXHeadersBuildPhase section */ 210 | 211 | /* Begin PBXNativeTarget section */ 212 | 84BDC1B13198A3791BBFF46D81994080 /* YAS_macOS */ = { 213 | isa = PBXNativeTarget; 214 | buildConfigurationList = DD517478C5DDF56C3ED69EB2E0424038 /* Build configuration list for PBXNativeTarget "YAS_macOS" */; 215 | buildPhases = ( 216 | CC39CF02FEBB643DD9702018878932FD /* Headers */, 217 | 9B2063F7651B7C4A2EFFE42921B4A768 /* Sources */, 218 | 8A92E55D62ED4AA39212E041A7D2DBF0 /* Run Script */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | ); 224 | name = YAS_macOS; 225 | productName = YAS_macOS; 226 | productReference = 3768C1142EEB9D782E88482F92BDCEE8 /* YAS.framework */; 227 | productType = "com.apple.product-type.framework"; 228 | }; 229 | A7E551D272B1EB988493A7162322095C /* YAS_iOS */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = 353F3F48EB3CBED9756A4D154E553DA1 /* Build configuration list for PBXNativeTarget "YAS_iOS" */; 232 | buildPhases = ( 233 | 4B4DE705C41E7F26431A811BB6383F4D /* Headers */, 234 | A0077F705BB35BDB69999F4B2EECB9D1 /* Sources */, 235 | B810D778288A0657583212E23E5FFC13 /* Run Script */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | ); 241 | name = YAS_iOS; 242 | productName = YAS_iOS; 243 | productReference = D3DE8E23ED35D99507AB89A79AA09C5B /* YAS.framework */; 244 | productType = "com.apple.product-type.framework"; 245 | }; 246 | E8C22B6F9FF2F06729D4365F109970F3 /* Test */ = { 247 | isa = PBXNativeTarget; 248 | buildConfigurationList = 62B6CBC6F997A3A22D6BEFF19F08B95F /* Build configuration list for PBXNativeTarget "Test" */; 249 | buildPhases = ( 250 | 43300E027786F56B2C483B0E036395A2 /* Sources */, 251 | 09BC6D227637A74BB0D609DA44CFF807 /* Frameworks */, 252 | DC79195BF602504A3364ED9CD8E5950C /* Embed Frameworks */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | 06FC12081F5EF1D90679E4238C56EADD /* PBXTargetDependency */, 258 | ); 259 | name = Test; 260 | productName = Test; 261 | productReference = 8E91795E3B13734300E9753DF1FC52B6 /* Test.xctest */; 262 | productType = "com.apple.product-type.bundle.unit-test"; 263 | }; 264 | /* End PBXNativeTarget section */ 265 | 266 | /* Begin PBXProject section */ 267 | 60D68265D8B4D0045F19A05B75B65CA5 /* Project object */ = { 268 | isa = PBXProject; 269 | attributes = { 270 | LastUpgradeCheck = 1020; 271 | }; 272 | buildConfigurationList = DF84BD5D916B59DBEE570196D8542E09 /* Build configuration list for PBXProject "YAS" */; 273 | compatibilityVersion = "Xcode 9.3"; 274 | developmentRegion = en; 275 | hasScannedForEncodings = 0; 276 | knownRegions = ( 277 | en, 278 | ); 279 | mainGroup = DF03D5FDA584EE956412F2EED3AFFC07; 280 | projectDirPath = ""; 281 | projectRoot = ""; 282 | targets = ( 283 | E8C22B6F9FF2F06729D4365F109970F3 /* Test */, 284 | A7E551D272B1EB988493A7162322095C /* YAS_iOS */, 285 | 84BDC1B13198A3791BBFF46D81994080 /* YAS_macOS */, 286 | ); 287 | }; 288 | /* End PBXProject section */ 289 | 290 | /* Begin PBXShellScriptBuildPhase section */ 291 | 8A92E55D62ED4AA39212E041A7D2DBF0 /* Run Script */ = { 292 | isa = PBXShellScriptBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | inputFileListPaths = ( 297 | ); 298 | inputPaths = ( 299 | ); 300 | name = "Run Script"; 301 | outputFileListPaths = ( 302 | ); 303 | outputPaths = ( 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | shellPath = /bin/sh; 307 | shellScript = "NAME=\"YAS\";PRODUCT=\"${BUILT_PRODUCTS_DIR}\";cp -R \"${PRODUCT}/${NAME}.framework\" ./bin;cp -R \"${PRODUCT}/${NAME}.framework.dSYM\" ./bin;cd ./bin;zip -r dist.zip *;"; 308 | }; 309 | B810D778288A0657583212E23E5FFC13 /* Run Script */ = { 310 | isa = PBXShellScriptBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | inputFileListPaths = ( 315 | ); 316 | inputPaths = ( 317 | ); 318 | name = "Run Script"; 319 | outputFileListPaths = ( 320 | ); 321 | outputPaths = ( 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | shellPath = /bin/sh; 325 | shellScript = "NAME=\"YAS\";PRODUCT=\"${BUILT_PRODUCTS_DIR}\";cp -R \"${PRODUCT}/${NAME}.framework\" ./bin;cp -R \"${PRODUCT}/${NAME}.framework.dSYM\" ./bin;cd ./bin;zip -r dist.zip *;"; 326 | }; 327 | /* End PBXShellScriptBuildPhase section */ 328 | 329 | /* Begin PBXSourcesBuildPhase section */ 330 | 43300E027786F56B2C483B0E036395A2 /* Sources */ = { 331 | isa = PBXSourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | 3732C434428DCADCEB1E9BF9009394E1 /* Test.swift in Sources */, 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | 9B2063F7651B7C4A2EFFE42921B4A768 /* Sources */ = { 339 | isa = PBXSourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | 79AE0A2DD8C77312B5B979AF7AD64304 /* ConstExpr.swift in Sources */, 343 | C66E02EF248D2D11E5F711FE04A77435 /* DynamicLookup.swift in Sources */, 344 | F80934E3F15B72ABB59846A21FF0E559 /* Expression.swift in Sources */, 345 | DAD524E3D5F909062A037A0F0BEBA964 /* ObjectExpr.swift in Sources */, 346 | 17BC6FDAEBB0FD50E86605385038A439 /* Rule.swift in Sources */, 347 | 506B5894F3DCA1A59C7D5C0BA4C9E4EB /* Style.swift in Sources */, 348 | 21EB4D3EB09921AB3E983FA6E54CEB0C /* Stylesheet.swift in Sources */, 349 | 6279093B4802A21DAB06605E2EB15391 /* StylesheetContext.swift in Sources */, 350 | D2D238509FB29EB12851BDB52B6C7CAA /* UIKit+ConstExpr.swift in Sources */, 351 | 5C00A1AA483BFAF4B57904DF15DCF525 /* UIKit+Helpers.swift in Sources */, 352 | 932E88DAA47A7680B870957F92C0D6F3 /* UIKit+ObjectExpr.swift in Sources */, 353 | ECF6189DFF8B68B8F8A4B341CD6807F1 /* View.swift in Sources */, 354 | 1B7ABDDAD63430C28F84542DD4726F0F /* YAMLBridge.swift in Sources */, 355 | A671CA982D41753FD8282439F58CC598 /* YASObjcExceptionHandler.m in Sources */, 356 | 4147B89F0F752BB233BE13D02A137FE6 /* yaml.c in Sources */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | A0077F705BB35BDB69999F4B2EECB9D1 /* Sources */ = { 361 | isa = PBXSourcesBuildPhase; 362 | buildActionMask = 2147483647; 363 | files = ( 364 | FEFCC41DE514351BA9E2999CF6FF4CF2 /* ConstExpr.swift in Sources */, 365 | 28FB7560F3DB54EDBDB8D63EFAE0F08A /* DynamicLookup.swift in Sources */, 366 | 0E957F9D236E5D3CCBDE3019ADBE6239 /* Expression.swift in Sources */, 367 | 9B879B18B000C3A9FC1E48170AF92062 /* ObjectExpr.swift in Sources */, 368 | 2CD517803AAC283D51B90DD300B12B7A /* Rule.swift in Sources */, 369 | 7769148C77426EE712559F8F07516595 /* Style.swift in Sources */, 370 | 28A731E59410497D9B25F12D401B2C7D /* Stylesheet.swift in Sources */, 371 | 45C2494BEDFB141D0A1CD4E8D218449C /* StylesheetContext.swift in Sources */, 372 | 47DDF6216E7E03C843017E97BD37D0B4 /* UIKit+ConstExpr.swift in Sources */, 373 | 1E1294F51153474617DB81B6C1B57015 /* UIKit+Helpers.swift in Sources */, 374 | 2D443EA970C351CD01F01FC29BB375B6 /* UIKit+ObjectExpr.swift in Sources */, 375 | 350B76DE3B2B9A6298FD3A4153F9C572 /* View.swift in Sources */, 376 | 3FA07314552471638B48E911DAB6AD06 /* YAMLBridge.swift in Sources */, 377 | 6D803326E601B3C3711608A8E07442FA /* YASObjcExceptionHandler.m in Sources */, 378 | D00E06B4CD783983ED7379678B3468AF /* yaml.c in Sources */, 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | }; 382 | /* End PBXSourcesBuildPhase section */ 383 | 384 | /* Begin PBXTargetDependency section */ 385 | 06FC12081F5EF1D90679E4238C56EADD /* PBXTargetDependency */ = { 386 | isa = PBXTargetDependency; 387 | target = A7E551D272B1EB988493A7162322095C /* YAS_iOS */; 388 | targetProxy = 9CC11871BB09C144A2E743F81BC2D3A5 /* PBXContainerItemProxy */; 389 | }; 390 | /* End PBXTargetDependency section */ 391 | 392 | /* Begin XCBuildConfiguration section */ 393 | 1CD3519AECBB441B7FBE2BB30F9F1F30 /* Debug */ = { 394 | isa = XCBuildConfiguration; 395 | buildSettings = { 396 | BUNDLE_LOADER = "$(TEST_HOST)"; 397 | INFOPLIST_FILE = test/Info.plist; 398 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 399 | SDKROOT = iphoneos; 400 | TARGETED_DEVICE_FAMILY = "1,2"; 401 | }; 402 | name = Debug; 403 | }; 404 | 1E138F568EBF8266F93400D657B9CE99 /* Release */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | CODE_SIGN_IDENTITY = ""; 408 | CURRENT_PROJECT_VERSION = 1; 409 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 410 | DEFINES_MODULE = YES; 411 | DYLIB_COMPATIBILITY_VERSION = 1; 412 | DYLIB_CURRENT_VERSION = 1; 413 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 414 | GCC_DEBUGGING_SYMBOLS = "full,"; 415 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 416 | INFOPLIST_FILE = src/Info.plist; 417 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 418 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 419 | ONLY_ACTIVE_ARCH = NO; 420 | PLATFORM = "platform iOS"; 421 | PRODUCT_BUNDLE_IDENTIFIER = io.alexdrone.yas; 422 | PRODUCT_NAME = YAS; 423 | SDKROOT = iphoneos; 424 | SKIP_INSTALL = YES; 425 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 426 | SWIFT_VERSION = 5; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | VERSIONING_SYSTEM = "apple-generic"; 429 | }; 430 | name = Release; 431 | }; 432 | 1E760C101F803960F5FAF906ADC09965 /* Release */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | CODE_SIGN_IDENTITY = ""; 436 | COMBINE_HIDPI_IMAGES = YES; 437 | CURRENT_PROJECT_VERSION = 1; 438 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 439 | DEFINES_MODULE = YES; 440 | DYLIB_COMPATIBILITY_VERSION = 1; 441 | DYLIB_CURRENT_VERSION = 1; 442 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 443 | GCC_DEBUGGING_SYMBOLS = "full,"; 444 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 445 | INFOPLIST_FILE = src/Info.plist; 446 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 447 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 448 | ONLY_ACTIVE_ARCH = NO; 449 | PLATFORM = "platform macOS"; 450 | PRODUCT_BUNDLE_IDENTIFIER = io.alexdrone.yas; 451 | PRODUCT_NAME = YAS; 452 | SDKROOT = macosx; 453 | SKIP_INSTALL = YES; 454 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 455 | SWIFT_VERSION = 5; 456 | VERSIONING_SYSTEM = "apple-generic"; 457 | }; 458 | name = Release; 459 | }; 460 | 4CB4745D498C37D608E84F95C5517FF2 /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ALWAYS_SEARCH_USER_PATHS = NO; 464 | CLANG_ANALYZER_NONNULL = YES; 465 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 466 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 467 | CLANG_CXX_LIBRARY = "libc++"; 468 | CLANG_ENABLE_MODULES = YES; 469 | CLANG_ENABLE_OBJC_ARC = YES; 470 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 471 | CLANG_WARN_BOOL_CONVERSION = YES; 472 | CLANG_WARN_COMMA = YES; 473 | CLANG_WARN_CONSTANT_CONVERSION = YES; 474 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 475 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 476 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 477 | CLANG_WARN_EMPTY_BODY = YES; 478 | CLANG_WARN_ENUM_CONVERSION = YES; 479 | CLANG_WARN_INFINITE_RECURSION = YES; 480 | CLANG_WARN_INT_CONVERSION = YES; 481 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 482 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 483 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 484 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 485 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 486 | CLANG_WARN_STRICT_PROTOTYPES = YES; 487 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 488 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 489 | CLANG_WARN_UNREACHABLE_CODE = YES; 490 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 491 | COPY_PHASE_STRIP = NO; 492 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 493 | ENABLE_NS_ASSERTIONS = NO; 494 | ENABLE_STRICT_OBJC_MSGSEND = YES; 495 | GCC_C_LANGUAGE_STANDARD = gnu11; 496 | GCC_NO_COMMON_BLOCKS = YES; 497 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 498 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 499 | GCC_WARN_UNDECLARED_SELECTOR = YES; 500 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 501 | GCC_WARN_UNUSED_FUNCTION = YES; 502 | GCC_WARN_UNUSED_VARIABLE = YES; 503 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 504 | MACOSX_DEPLOYMENT_TARGET = 10.12; 505 | PRODUCT_NAME = "$(TARGET_NAME)"; 506 | SWIFT_COMPILATION_MODE = wholemodule; 507 | SWIFT_VERSION = 5.0; 508 | VALIDATE_PRODUCT = YES; 509 | }; 510 | name = Release; 511 | }; 512 | 791CF3C76FD28B0D29D10E27D5D034F8 /* Debug */ = { 513 | isa = XCBuildConfiguration; 514 | buildSettings = { 515 | CODE_SIGN_IDENTITY = ""; 516 | COMBINE_HIDPI_IMAGES = YES; 517 | CURRENT_PROJECT_VERSION = 1; 518 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 519 | DEFINES_MODULE = YES; 520 | DYLIB_COMPATIBILITY_VERSION = 1; 521 | DYLIB_CURRENT_VERSION = 1; 522 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 523 | GCC_DEBUGGING_SYMBOLS = "full,"; 524 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 525 | INFOPLIST_FILE = src/Info.plist; 526 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 527 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 528 | ONLY_ACTIVE_ARCH = NO; 529 | PLATFORM = "platform macOS"; 530 | PRODUCT_BUNDLE_IDENTIFIER = io.alexdrone.yas; 531 | PRODUCT_NAME = YAS; 532 | SDKROOT = macosx; 533 | SKIP_INSTALL = YES; 534 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 535 | SWIFT_VERSION = 5; 536 | VERSIONING_SYSTEM = "apple-generic"; 537 | }; 538 | name = Debug; 539 | }; 540 | 7BFE9D02A2091A42C43B39F7E8D326AE /* Debug */ = { 541 | isa = XCBuildConfiguration; 542 | buildSettings = { 543 | ALWAYS_SEARCH_USER_PATHS = NO; 544 | CLANG_ANALYZER_NONNULL = YES; 545 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 546 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 547 | CLANG_CXX_LIBRARY = "libc++"; 548 | CLANG_ENABLE_MODULES = YES; 549 | CLANG_ENABLE_OBJC_ARC = YES; 550 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 551 | CLANG_WARN_BOOL_CONVERSION = YES; 552 | CLANG_WARN_COMMA = YES; 553 | CLANG_WARN_CONSTANT_CONVERSION = YES; 554 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 555 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 556 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 557 | CLANG_WARN_EMPTY_BODY = YES; 558 | CLANG_WARN_ENUM_CONVERSION = YES; 559 | CLANG_WARN_INFINITE_RECURSION = YES; 560 | CLANG_WARN_INT_CONVERSION = YES; 561 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 562 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 563 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 564 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 565 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 566 | CLANG_WARN_STRICT_PROTOTYPES = YES; 567 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 568 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 569 | CLANG_WARN_UNREACHABLE_CODE = YES; 570 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 571 | COPY_PHASE_STRIP = NO; 572 | DEBUG_INFORMATION_FORMAT = dwarf; 573 | ENABLE_STRICT_OBJC_MSGSEND = YES; 574 | ENABLE_TESTABILITY = YES; 575 | GCC_C_LANGUAGE_STANDARD = gnu11; 576 | GCC_DYNAMIC_NO_PIC = NO; 577 | GCC_NO_COMMON_BLOCKS = YES; 578 | GCC_OPTIMIZATION_LEVEL = 0; 579 | GCC_PREPROCESSOR_DEFINITIONS = ( 580 | "$(inherited)", 581 | "DEBUG=1", 582 | ); 583 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 584 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 585 | GCC_WARN_UNDECLARED_SELECTOR = YES; 586 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 587 | GCC_WARN_UNUSED_FUNCTION = YES; 588 | GCC_WARN_UNUSED_VARIABLE = YES; 589 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 590 | MACOSX_DEPLOYMENT_TARGET = 10.12; 591 | MTL_ENABLE_DEBUG_INFO = YES; 592 | ONLY_ACTIVE_ARCH = YES; 593 | PRODUCT_NAME = "$(TARGET_NAME)"; 594 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 595 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 596 | SWIFT_VERSION = 5.0; 597 | }; 598 | name = Debug; 599 | }; 600 | 925F8EA44F99298A95138BC16447963C /* Release */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | BUNDLE_LOADER = "$(TEST_HOST)"; 604 | INFOPLIST_FILE = test/Info.plist; 605 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 606 | SDKROOT = iphoneos; 607 | TARGETED_DEVICE_FAMILY = "1,2"; 608 | }; 609 | name = Release; 610 | }; 611 | A29FAB0FDC1EF148FDECF58C47143370 /* Debug */ = { 612 | isa = XCBuildConfiguration; 613 | buildSettings = { 614 | CODE_SIGN_IDENTITY = ""; 615 | CURRENT_PROJECT_VERSION = 1; 616 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 617 | DEFINES_MODULE = YES; 618 | DYLIB_COMPATIBILITY_VERSION = 1; 619 | DYLIB_CURRENT_VERSION = 1; 620 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 621 | GCC_DEBUGGING_SYMBOLS = "full,"; 622 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 623 | INFOPLIST_FILE = src/Info.plist; 624 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 625 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 626 | ONLY_ACTIVE_ARCH = NO; 627 | PLATFORM = "platform iOS"; 628 | PRODUCT_BUNDLE_IDENTIFIER = io.alexdrone.yas; 629 | PRODUCT_NAME = YAS; 630 | SDKROOT = iphoneos; 631 | SKIP_INSTALL = YES; 632 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 633 | SWIFT_VERSION = 5; 634 | TARGETED_DEVICE_FAMILY = "1,2"; 635 | VERSIONING_SYSTEM = "apple-generic"; 636 | }; 637 | name = Debug; 638 | }; 639 | /* End XCBuildConfiguration section */ 640 | 641 | /* Begin XCConfigurationList section */ 642 | 353F3F48EB3CBED9756A4D154E553DA1 /* Build configuration list for PBXNativeTarget "YAS_iOS" */ = { 643 | isa = XCConfigurationList; 644 | buildConfigurations = ( 645 | A29FAB0FDC1EF148FDECF58C47143370 /* Debug */, 646 | 1E138F568EBF8266F93400D657B9CE99 /* Release */, 647 | ); 648 | defaultConfigurationIsVisible = 0; 649 | defaultConfigurationName = ""; 650 | }; 651 | 62B6CBC6F997A3A22D6BEFF19F08B95F /* Build configuration list for PBXNativeTarget "Test" */ = { 652 | isa = XCConfigurationList; 653 | buildConfigurations = ( 654 | 1CD3519AECBB441B7FBE2BB30F9F1F30 /* Debug */, 655 | 925F8EA44F99298A95138BC16447963C /* Release */, 656 | ); 657 | defaultConfigurationIsVisible = 0; 658 | defaultConfigurationName = ""; 659 | }; 660 | DD517478C5DDF56C3ED69EB2E0424038 /* Build configuration list for PBXNativeTarget "YAS_macOS" */ = { 661 | isa = XCConfigurationList; 662 | buildConfigurations = ( 663 | 791CF3C76FD28B0D29D10E27D5D034F8 /* Debug */, 664 | 1E760C101F803960F5FAF906ADC09965 /* Release */, 665 | ); 666 | defaultConfigurationIsVisible = 0; 667 | defaultConfigurationName = ""; 668 | }; 669 | DF84BD5D916B59DBEE570196D8542E09 /* Build configuration list for PBXProject "YAS" */ = { 670 | isa = XCConfigurationList; 671 | buildConfigurations = ( 672 | 7BFE9D02A2091A42C43B39F7E8D326AE /* Debug */, 673 | 4CB4745D498C37D608E84F95C5517FF2 /* Release */, 674 | ); 675 | defaultConfigurationIsVisible = 0; 676 | defaultConfigurationName = Debug; 677 | }; 678 | /* End XCConfigurationList section */ 679 | }; 680 | rootObject = 60D68265D8B4D0045F19A05B75B65CA5 /* Project object */; 681 | } 682 | -------------------------------------------------------------------------------- /YAS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /YAS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /YAS.xcodeproj/xcshareddata/xcschemes/Test.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 91 | 92 | 93 | 94 | 95 | 96 | 102 | 104 | 110 | 111 | 112 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /bin/YAS.framework/Headers/YAS-Swift.h: -------------------------------------------------------------------------------- 1 | #if 0 2 | #elif defined(__x86_64__) && __x86_64__ 3 | // Generated by Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5) 4 | #pragma clang diagnostic push 5 | #pragma clang diagnostic ignored "-Wgcc-compat" 6 | 7 | #if !defined(__has_include) 8 | # define __has_include(x) 0 9 | #endif 10 | #if !defined(__has_attribute) 11 | # define __has_attribute(x) 0 12 | #endif 13 | #if !defined(__has_feature) 14 | # define __has_feature(x) 0 15 | #endif 16 | #if !defined(__has_warning) 17 | # define __has_warning(x) 0 18 | #endif 19 | 20 | #if __has_include() 21 | # include 22 | #endif 23 | 24 | #pragma clang diagnostic ignored "-Wauto-import" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #if !defined(SWIFT_TYPEDEFS) 31 | # define SWIFT_TYPEDEFS 1 32 | # if __has_include() 33 | # include 34 | # elif !defined(__cplusplus) 35 | typedef uint_least16_t char16_t; 36 | typedef uint_least32_t char32_t; 37 | # endif 38 | typedef float swift_float2 __attribute__((__ext_vector_type__(2))); 39 | typedef float swift_float3 __attribute__((__ext_vector_type__(3))); 40 | typedef float swift_float4 __attribute__((__ext_vector_type__(4))); 41 | typedef double swift_double2 __attribute__((__ext_vector_type__(2))); 42 | typedef double swift_double3 __attribute__((__ext_vector_type__(3))); 43 | typedef double swift_double4 __attribute__((__ext_vector_type__(4))); 44 | typedef int swift_int2 __attribute__((__ext_vector_type__(2))); 45 | typedef int swift_int3 __attribute__((__ext_vector_type__(3))); 46 | typedef int swift_int4 __attribute__((__ext_vector_type__(4))); 47 | typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); 48 | typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); 49 | typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); 50 | #endif 51 | 52 | #if !defined(SWIFT_PASTE) 53 | # define SWIFT_PASTE_HELPER(x, y) x##y 54 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 55 | #endif 56 | #if !defined(SWIFT_METATYPE) 57 | # define SWIFT_METATYPE(X) Class 58 | #endif 59 | #if !defined(SWIFT_CLASS_PROPERTY) 60 | # if __has_feature(objc_class_property) 61 | # define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ 62 | # else 63 | # define SWIFT_CLASS_PROPERTY(...) 64 | # endif 65 | #endif 66 | 67 | #if __has_attribute(objc_runtime_name) 68 | # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) 69 | #else 70 | # define SWIFT_RUNTIME_NAME(X) 71 | #endif 72 | #if __has_attribute(swift_name) 73 | # define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) 74 | #else 75 | # define SWIFT_COMPILE_NAME(X) 76 | #endif 77 | #if __has_attribute(objc_method_family) 78 | # define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) 79 | #else 80 | # define SWIFT_METHOD_FAMILY(X) 81 | #endif 82 | #if __has_attribute(noescape) 83 | # define SWIFT_NOESCAPE __attribute__((noescape)) 84 | #else 85 | # define SWIFT_NOESCAPE 86 | #endif 87 | #if __has_attribute(warn_unused_result) 88 | # define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 89 | #else 90 | # define SWIFT_WARN_UNUSED_RESULT 91 | #endif 92 | #if __has_attribute(noreturn) 93 | # define SWIFT_NORETURN __attribute__((noreturn)) 94 | #else 95 | # define SWIFT_NORETURN 96 | #endif 97 | #if !defined(SWIFT_CLASS_EXTRA) 98 | # define SWIFT_CLASS_EXTRA 99 | #endif 100 | #if !defined(SWIFT_PROTOCOL_EXTRA) 101 | # define SWIFT_PROTOCOL_EXTRA 102 | #endif 103 | #if !defined(SWIFT_ENUM_EXTRA) 104 | # define SWIFT_ENUM_EXTRA 105 | #endif 106 | #if !defined(SWIFT_CLASS) 107 | # if __has_attribute(objc_subclassing_restricted) 108 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA 109 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 110 | # else 111 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 112 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 113 | # endif 114 | #endif 115 | 116 | #if !defined(SWIFT_PROTOCOL) 117 | # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 118 | # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 119 | #endif 120 | 121 | #if !defined(SWIFT_EXTENSION) 122 | # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) 123 | #endif 124 | 125 | #if !defined(OBJC_DESIGNATED_INITIALIZER) 126 | # if __has_attribute(objc_designated_initializer) 127 | # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 128 | # else 129 | # define OBJC_DESIGNATED_INITIALIZER 130 | # endif 131 | #endif 132 | #if !defined(SWIFT_ENUM_ATTR) 133 | # if defined(__has_attribute) && __has_attribute(enum_extensibility) 134 | # define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) 135 | # else 136 | # define SWIFT_ENUM_ATTR(_extensibility) 137 | # endif 138 | #endif 139 | #if !defined(SWIFT_ENUM) 140 | # define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 141 | # if __has_feature(generalized_swift_name) 142 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 143 | # else 144 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) 145 | # endif 146 | #endif 147 | #if !defined(SWIFT_UNAVAILABLE) 148 | # define SWIFT_UNAVAILABLE __attribute__((unavailable)) 149 | #endif 150 | #if !defined(SWIFT_UNAVAILABLE_MSG) 151 | # define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) 152 | #endif 153 | #if !defined(SWIFT_AVAILABILITY) 154 | # define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) 155 | #endif 156 | #if !defined(SWIFT_DEPRECATED) 157 | # define SWIFT_DEPRECATED __attribute__((deprecated)) 158 | #endif 159 | #if !defined(SWIFT_DEPRECATED_MSG) 160 | # define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) 161 | #endif 162 | #if __has_feature(attribute_diagnose_if_objc) 163 | # define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) 164 | #else 165 | # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) 166 | #endif 167 | #if __has_feature(modules) 168 | #if __has_warning("-Watimport-in-framework-header") 169 | #pragma clang diagnostic ignored "-Watimport-in-framework-header" 170 | #endif 171 | @import Foundation; 172 | @import ObjectiveC; 173 | @import UIKit; 174 | #endif 175 | 176 | #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" 177 | #pragma clang diagnostic ignored "-Wduplicate-method-arg" 178 | #if __has_warning("-Wpragma-clang-attribute") 179 | # pragma clang diagnostic ignored "-Wpragma-clang-attribute" 180 | #endif 181 | #pragma clang diagnostic ignored "-Wunknown-pragmas" 182 | #pragma clang diagnostic ignored "-Wnullability" 183 | 184 | #if __has_attribute(external_source_symbol) 185 | # pragma push_macro("any") 186 | # undef any 187 | # pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="YAS",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) 188 | # pragma pop_macro("any") 189 | #endif 190 | 191 | 192 | 193 | 194 | 195 | 196 | SWIFT_CLASS("_TtC3YAS14ObjectExprBase") 197 | @interface ObjectExprBase : NSObject 198 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 199 | @end 200 | 201 | 202 | /// Fonts and its attributes. 203 | SWIFT_CLASS("_TtC3YAS9TextStyle") 204 | @interface TextStyle : NSObject 205 | - (nonnull instancetype)init SWIFT_UNAVAILABLE; 206 | + (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable"); 207 | @end 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | #if __has_attribute(external_source_symbol) 218 | # pragma clang attribute pop 219 | #endif 220 | #pragma clang diagnostic pop 221 | 222 | #elif defined(__i386__) && __i386__ 223 | // Generated by Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5) 224 | #pragma clang diagnostic push 225 | #pragma clang diagnostic ignored "-Wgcc-compat" 226 | 227 | #if !defined(__has_include) 228 | # define __has_include(x) 0 229 | #endif 230 | #if !defined(__has_attribute) 231 | # define __has_attribute(x) 0 232 | #endif 233 | #if !defined(__has_feature) 234 | # define __has_feature(x) 0 235 | #endif 236 | #if !defined(__has_warning) 237 | # define __has_warning(x) 0 238 | #endif 239 | 240 | #if __has_include() 241 | # include 242 | #endif 243 | 244 | #pragma clang diagnostic ignored "-Wauto-import" 245 | #include 246 | #include 247 | #include 248 | #include 249 | 250 | #if !defined(SWIFT_TYPEDEFS) 251 | # define SWIFT_TYPEDEFS 1 252 | # if __has_include() 253 | # include 254 | # elif !defined(__cplusplus) 255 | typedef uint_least16_t char16_t; 256 | typedef uint_least32_t char32_t; 257 | # endif 258 | typedef float swift_float2 __attribute__((__ext_vector_type__(2))); 259 | typedef float swift_float3 __attribute__((__ext_vector_type__(3))); 260 | typedef float swift_float4 __attribute__((__ext_vector_type__(4))); 261 | typedef double swift_double2 __attribute__((__ext_vector_type__(2))); 262 | typedef double swift_double3 __attribute__((__ext_vector_type__(3))); 263 | typedef double swift_double4 __attribute__((__ext_vector_type__(4))); 264 | typedef int swift_int2 __attribute__((__ext_vector_type__(2))); 265 | typedef int swift_int3 __attribute__((__ext_vector_type__(3))); 266 | typedef int swift_int4 __attribute__((__ext_vector_type__(4))); 267 | typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); 268 | typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); 269 | typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); 270 | #endif 271 | 272 | #if !defined(SWIFT_PASTE) 273 | # define SWIFT_PASTE_HELPER(x, y) x##y 274 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 275 | #endif 276 | #if !defined(SWIFT_METATYPE) 277 | # define SWIFT_METATYPE(X) Class 278 | #endif 279 | #if !defined(SWIFT_CLASS_PROPERTY) 280 | # if __has_feature(objc_class_property) 281 | # define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ 282 | # else 283 | # define SWIFT_CLASS_PROPERTY(...) 284 | # endif 285 | #endif 286 | 287 | #if __has_attribute(objc_runtime_name) 288 | # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) 289 | #else 290 | # define SWIFT_RUNTIME_NAME(X) 291 | #endif 292 | #if __has_attribute(swift_name) 293 | # define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) 294 | #else 295 | # define SWIFT_COMPILE_NAME(X) 296 | #endif 297 | #if __has_attribute(objc_method_family) 298 | # define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) 299 | #else 300 | # define SWIFT_METHOD_FAMILY(X) 301 | #endif 302 | #if __has_attribute(noescape) 303 | # define SWIFT_NOESCAPE __attribute__((noescape)) 304 | #else 305 | # define SWIFT_NOESCAPE 306 | #endif 307 | #if __has_attribute(warn_unused_result) 308 | # define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 309 | #else 310 | # define SWIFT_WARN_UNUSED_RESULT 311 | #endif 312 | #if __has_attribute(noreturn) 313 | # define SWIFT_NORETURN __attribute__((noreturn)) 314 | #else 315 | # define SWIFT_NORETURN 316 | #endif 317 | #if !defined(SWIFT_CLASS_EXTRA) 318 | # define SWIFT_CLASS_EXTRA 319 | #endif 320 | #if !defined(SWIFT_PROTOCOL_EXTRA) 321 | # define SWIFT_PROTOCOL_EXTRA 322 | #endif 323 | #if !defined(SWIFT_ENUM_EXTRA) 324 | # define SWIFT_ENUM_EXTRA 325 | #endif 326 | #if !defined(SWIFT_CLASS) 327 | # if __has_attribute(objc_subclassing_restricted) 328 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA 329 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 330 | # else 331 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 332 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 333 | # endif 334 | #endif 335 | 336 | #if !defined(SWIFT_PROTOCOL) 337 | # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 338 | # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 339 | #endif 340 | 341 | #if !defined(SWIFT_EXTENSION) 342 | # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) 343 | #endif 344 | 345 | #if !defined(OBJC_DESIGNATED_INITIALIZER) 346 | # if __has_attribute(objc_designated_initializer) 347 | # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 348 | # else 349 | # define OBJC_DESIGNATED_INITIALIZER 350 | # endif 351 | #endif 352 | #if !defined(SWIFT_ENUM_ATTR) 353 | # if defined(__has_attribute) && __has_attribute(enum_extensibility) 354 | # define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) 355 | # else 356 | # define SWIFT_ENUM_ATTR(_extensibility) 357 | # endif 358 | #endif 359 | #if !defined(SWIFT_ENUM) 360 | # define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 361 | # if __has_feature(generalized_swift_name) 362 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type 363 | # else 364 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) 365 | # endif 366 | #endif 367 | #if !defined(SWIFT_UNAVAILABLE) 368 | # define SWIFT_UNAVAILABLE __attribute__((unavailable)) 369 | #endif 370 | #if !defined(SWIFT_UNAVAILABLE_MSG) 371 | # define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) 372 | #endif 373 | #if !defined(SWIFT_AVAILABILITY) 374 | # define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) 375 | #endif 376 | #if !defined(SWIFT_DEPRECATED) 377 | # define SWIFT_DEPRECATED __attribute__((deprecated)) 378 | #endif 379 | #if !defined(SWIFT_DEPRECATED_MSG) 380 | # define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) 381 | #endif 382 | #if __has_feature(attribute_diagnose_if_objc) 383 | # define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) 384 | #else 385 | # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) 386 | #endif 387 | #if __has_feature(modules) 388 | #if __has_warning("-Watimport-in-framework-header") 389 | #pragma clang diagnostic ignored "-Watimport-in-framework-header" 390 | #endif 391 | @import Foundation; 392 | @import ObjectiveC; 393 | @import UIKit; 394 | #endif 395 | 396 | #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" 397 | #pragma clang diagnostic ignored "-Wduplicate-method-arg" 398 | #if __has_warning("-Wpragma-clang-attribute") 399 | # pragma clang diagnostic ignored "-Wpragma-clang-attribute" 400 | #endif 401 | #pragma clang diagnostic ignored "-Wunknown-pragmas" 402 | #pragma clang diagnostic ignored "-Wnullability" 403 | 404 | #if __has_attribute(external_source_symbol) 405 | # pragma push_macro("any") 406 | # undef any 407 | # pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="YAS",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) 408 | # pragma pop_macro("any") 409 | #endif 410 | 411 | 412 | 413 | 414 | 415 | 416 | SWIFT_CLASS("_TtC3YAS14ObjectExprBase") 417 | @interface ObjectExprBase : NSObject 418 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 419 | @end 420 | 421 | 422 | /// Fonts and its attributes. 423 | SWIFT_CLASS("_TtC3YAS9TextStyle") 424 | @interface TextStyle : NSObject 425 | - (nonnull instancetype)init SWIFT_UNAVAILABLE; 426 | + (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable"); 427 | @end 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | #if __has_attribute(external_source_symbol) 438 | # pragma clang attribute pop 439 | #endif 440 | #pragma clang diagnostic pop 441 | 442 | #endif 443 | -------------------------------------------------------------------------------- /bin/YAS.framework/Headers/YAS.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | 6 | FOUNDATION_EXPORT double YASVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char YASVersionString[]; 8 | -------------------------------------------------------------------------------- /bin/YAS.framework/Headers/YASObjcExceptionHandler.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface YASObjcExceptionHandler : NSObject 6 | 7 | + (void)tryBlock:(nonnull void (^)(void))tryBlock 8 | catchAndRethrowBlock:(nullable BOOL (^)(_Nonnull id))catchAndRethrowBlock 9 | finallyBlock:(nullable void (^)(void))finallyBlock; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /bin/YAS.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/Info.plist -------------------------------------------------------------------------------- /bin/YAS.framework/Modules/YAS.swiftmodule/i386.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/Modules/YAS.swiftmodule/i386.swiftdoc -------------------------------------------------------------------------------- /bin/YAS.framework/Modules/YAS.swiftmodule/i386.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/Modules/YAS.swiftmodule/i386.swiftmodule -------------------------------------------------------------------------------- /bin/YAS.framework/Modules/YAS.swiftmodule/x86_64.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/Modules/YAS.swiftmodule/x86_64.swiftdoc -------------------------------------------------------------------------------- /bin/YAS.framework/Modules/YAS.swiftmodule/x86_64.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/Modules/YAS.swiftmodule/x86_64.swiftmodule -------------------------------------------------------------------------------- /bin/YAS.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module YAS { 2 | umbrella header "YAS.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | 8 | module YAS.Swift { 9 | header "YAS-Swift.h" 10 | requires objc 11 | } 12 | -------------------------------------------------------------------------------- /bin/YAS.framework/YAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/YAS.framework/YAS -------------------------------------------------------------------------------- /bin/YAS.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Headers/YAS-Swift.h 8 | 9 | Jsyycx4S5mofeQTpTN0G2JGy8Rs= 10 | 11 | Headers/YAS.h 12 | 13 | p6qkvM3YL2NdQb5V4AtsTmplwTg= 14 | 15 | Headers/YASObjcExceptionHandler.h 16 | 17 | uc8wol8MtYno3aPXjYBB9lzvr9Y= 18 | 19 | Headers/yaml.h 20 | 21 | hfh1yUQNmmTMQs8/9B12J/coVew= 22 | 23 | Info.plist 24 | 25 | 7BUgsvpdButFVvaSuKkZQIBkDjc= 26 | 27 | Modules/YAS.swiftmodule/i386.swiftdoc 28 | 29 | EnPq4b+aci0yW8bME7Yq8b5ZN94= 30 | 31 | Modules/YAS.swiftmodule/i386.swiftmodule 32 | 33 | V5KDU2Z7EiMKcfWX1TXSzVQH8aY= 34 | 35 | Modules/YAS.swiftmodule/x86_64.swiftdoc 36 | 37 | 79aXNkcvIJegYRol6X/WTMvv5B8= 38 | 39 | Modules/YAS.swiftmodule/x86_64.swiftmodule 40 | 41 | fO+XuHjw6jqrSD5yvh3Q65Ir/ew= 42 | 43 | Modules/module.modulemap 44 | 45 | XxgY1484r7PxECRhkYudRkvbCRI= 46 | 47 | 48 | files2 49 | 50 | Headers/YAS-Swift.h 51 | 52 | hash 53 | 54 | Jsyycx4S5mofeQTpTN0G2JGy8Rs= 55 | 56 | hash2 57 | 58 | f2X50IuNFiIRTBWmGJLtCIc73ZWV7jd1Hx5sanJG8dw= 59 | 60 | 61 | Headers/YAS.h 62 | 63 | hash 64 | 65 | p6qkvM3YL2NdQb5V4AtsTmplwTg= 66 | 67 | hash2 68 | 69 | JK/7SlviLoHFZG1w5ixYIKMcvlWabarnkDSQW2hxuTc= 70 | 71 | 72 | Headers/YASObjcExceptionHandler.h 73 | 74 | hash 75 | 76 | uc8wol8MtYno3aPXjYBB9lzvr9Y= 77 | 78 | hash2 79 | 80 | GjNpkPGoRV00mlgIxUfxliz7JF1GusgXxs6yHfGAIkQ= 81 | 82 | 83 | Headers/yaml.h 84 | 85 | hash 86 | 87 | hfh1yUQNmmTMQs8/9B12J/coVew= 88 | 89 | hash2 90 | 91 | OQIF5ergmz2uAw/u900rYcTR0evRWj45TNK4lviOMr8= 92 | 93 | 94 | Modules/YAS.swiftmodule/i386.swiftdoc 95 | 96 | hash 97 | 98 | EnPq4b+aci0yW8bME7Yq8b5ZN94= 99 | 100 | hash2 101 | 102 | zWccDHg/l0xlgeoLKKnpnoofNsta/l7ZuhFO0TUTSck= 103 | 104 | 105 | Modules/YAS.swiftmodule/i386.swiftmodule 106 | 107 | hash 108 | 109 | V5KDU2Z7EiMKcfWX1TXSzVQH8aY= 110 | 111 | hash2 112 | 113 | 4Vs8OTW0AmwshB8joUEgWeNOrxYhV5/UDy38VlP2cfc= 114 | 115 | 116 | Modules/YAS.swiftmodule/x86_64.swiftdoc 117 | 118 | hash 119 | 120 | 79aXNkcvIJegYRol6X/WTMvv5B8= 121 | 122 | hash2 123 | 124 | yCmavtDJaU04WuapD58xuy8KGeulCerfhNOCxbINR8M= 125 | 126 | 127 | Modules/YAS.swiftmodule/x86_64.swiftmodule 128 | 129 | hash 130 | 131 | fO+XuHjw6jqrSD5yvh3Q65Ir/ew= 132 | 133 | hash2 134 | 135 | heuhLx3snpbV8FloQLUfFwpE/x8Q97UVccIKaxqEesM= 136 | 137 | 138 | Modules/module.modulemap 139 | 140 | hash 141 | 142 | XxgY1484r7PxECRhkYudRkvbCRI= 143 | 144 | hash2 145 | 146 | QA0A0N+sd+g5I52obqqvXOt4QfMdjX/KeuJsDf/xJis= 147 | 148 | 149 | 150 | rules 151 | 152 | ^.* 153 | 154 | ^.*\.lproj/ 155 | 156 | optional 157 | 158 | weight 159 | 1000 160 | 161 | ^.*\.lproj/locversion.plist$ 162 | 163 | omit 164 | 165 | weight 166 | 1100 167 | 168 | ^Base\.lproj/ 169 | 170 | weight 171 | 1010 172 | 173 | ^version.plist$ 174 | 175 | 176 | rules2 177 | 178 | .*\.dSYM($|/) 179 | 180 | weight 181 | 11 182 | 183 | ^(.*/)?\.DS_Store$ 184 | 185 | omit 186 | 187 | weight 188 | 2000 189 | 190 | ^.* 191 | 192 | ^.*\.lproj/ 193 | 194 | optional 195 | 196 | weight 197 | 1000 198 | 199 | ^.*\.lproj/locversion.plist$ 200 | 201 | omit 202 | 203 | weight 204 | 1100 205 | 206 | ^Base\.lproj/ 207 | 208 | weight 209 | 1010 210 | 211 | ^Info\.plist$ 212 | 213 | omit 214 | 215 | weight 216 | 20 217 | 218 | ^PkgInfo$ 219 | 220 | omit 221 | 222 | weight 223 | 20 224 | 225 | ^embedded\.provisionprofile$ 226 | 227 | weight 228 | 20 229 | 230 | ^version\.plist$ 231 | 232 | weight 233 | 20 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /bin/dist.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/bin/dist.zip -------------------------------------------------------------------------------- /configs/Debug.xcconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/configs/Debug.xcconfig -------------------------------------------------------------------------------- /configs/Release.xcconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/configs/Release.xcconfig -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexdrone/YAS/216087c1a62ba68635176818fe278fbb98d4b9c2/docs/logo.png -------------------------------------------------------------------------------- /project.yml: -------------------------------------------------------------------------------- 1 | name: YAS 2 | options: 3 | deploymentTarget: 4 | iOS: 10.0 5 | macOS: 10.12 6 | usesTabs: false 7 | indentWidth: 2 8 | targets: 9 | Test: 10 | platform: iOS 11 | type: bundle.unit-test 12 | sources: 13 | - test 14 | dependencies: 15 | - target: YAS_iOS 16 | scheme: 17 | testTargets: 18 | - Test 19 | gatherCoverageData: true 20 | environmentVariables: 21 | - variable: TEST 22 | value: YES 23 | isEnabled: true 24 | YAS: 25 | platform: [iOS, macOS] 26 | type: framework 27 | sources: 28 | - src 29 | settings: 30 | base: 31 | INFOPLIST_FILE: src/Info.plist 32 | PRODUCT_BUNDLE_IDENTIFIER: io.alexdrone.yas 33 | PLATFORM: platform $platform 34 | GCC_GENERATE_DEBUGGING_SYMBOLS: YES 35 | GCC_DEBUGGING_SYMBOLS: full, 36 | DEBUG_INFORMATION_FORMAT: dwarf-with-dsym 37 | ONLY_ACTIVE_ARCH: NO 38 | SWIFT_OPTIMIZATION_LEVEL: -Owholemodule 39 | SWIFT_VERSION: 5 40 | configFiles: 41 | Debug: configs/Debug.xcconfig 42 | Release: configs/Release.xcconfig 43 | postbuildScripts: 44 | - name: Dist 45 | - script: NAME="YAS";PRODUCT="${BUILT_PRODUCTS_DIR}";cp -R "${PRODUCT}/${NAME}.framework" ./bin;cp -R "${PRODUCT}/${NAME}.framework.dSYM" ./bin;cd ./bin;zip -r dist.zip *; 46 | -------------------------------------------------------------------------------- /src/ConstExpr.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if canImport(UIKit) 3 | import UIKit 4 | #endif 5 | 6 | public protocol EnumRepresentable { 7 | /// Every `EnumRepresentable` must be backed by an integer store. 8 | init?(rawValue: Int) 9 | /// Returns every enum value as a map between a 'key' and its integer representation. 10 | static func expressionConstants() -> [String: Double] 11 | } 12 | 13 | public extension EnumRepresentable { 14 | /// Export this enum into the stylesheet global symbols. 15 | static func export() { 16 | ConstExpr.export(constants: expressionConstants()) 17 | } 18 | } 19 | 20 | public struct ConstExpr { 21 | #if canImport(UIKit) 22 | private static let defaultConstants = defaultUIKitConstExpr 23 | private static let defaultSymbols = defaultUIKitSymbols 24 | private static var exportedConstants = defaultConstants 25 | private static var exportedConstantsInitialised = false 26 | #else 27 | private static var exportedConstants: [String: Double] = [:] 28 | #endif 29 | 30 | /// Export this enum into the stylesheet global symbols. 31 | static public func export(constants: [String: Double]) { 32 | assert(Thread.isMainThread) 33 | for (key, value) in constants { 34 | exportedConstants[key] = value 35 | } 36 | } 37 | 38 | /// The default `Expression` builder function. 39 | static func builder(_ string: String) -> Expression { 40 | #if canImport(UIKit) 41 | if !ConstExpr.exportedConstantsInitialised { 42 | ConstExpr.exportedConstantsInitialised = true 43 | NSTextAlignment.export() 44 | NSLineBreakMode.export() 45 | UIImage.Orientation.export() 46 | UIImage.ResizingMode.export() 47 | UIView.ContentMode.export() 48 | } 49 | return Expression( 50 | string, 51 | options: [Expression.Options.boolSymbols, Expression.Options.pureSymbols], 52 | constants: ConstExpr.exportedConstants, 53 | symbols: ConstExpr.defaultSymbols) 54 | #else 55 | return Expression( 56 | string, 57 | options: [Expression.Options.boolSymbols, Expression.Options.pureSymbols], 58 | constants: ConstExpr.exportedConstants, 59 | symbols: [:]) 60 | #endif 61 | } 62 | 63 | /// Parse an expression. 64 | /// - note: The expression delimiter is ${EXPR}. 65 | static func sanitize(expression: String) -> String? { 66 | struct Token { 67 | /// Expression escape char. 68 | static let escape = "$" 69 | /// Expression brackets. 70 | static let block = ("{", "}") 71 | } 72 | guard expression.hasPrefix(Token.escape) else { return nil } 73 | let substring = expression 74 | .replacingOccurrences(of: Token.escape, with: "") 75 | .replacingOccurrences(of: Token.block.0, with: "") 76 | .replacingOccurrences(of: Token.block.1, with: "") 77 | return substring 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/DynamicLookup.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | @dynamicMemberLookup 4 | public struct RuleDynamicLookup { 5 | /// The style identifier. 6 | public let id: String 7 | /// Returns the current style definitions. 8 | public var style: [String: Rule] { 9 | guard let style = StylesheetManager.default.properties(forStyle: id) else { 10 | warn("Unable to find style \(id).") 11 | return [:] 12 | } 13 | return style 14 | } 15 | 16 | init(id: String) { 17 | self.id = id 18 | } 19 | 20 | public subscript(dynamicMember member: String) -> Rule { 21 | let manager = StylesheetManager.default 22 | guard let rule = manager.property(style: id, name: member) else { 23 | fatalError("error: \(id) does not declare \(member) as a property.") 24 | } 25 | return rule 26 | } 27 | } 28 | 29 | @dynamicMemberLookup 30 | public struct StyleDynamicLookup { 31 | /// Returns a `RuleDynamicLookup` pointing at the style passed as argument. 32 | public subscript(dynamicMember member: String) -> RuleDynamicLookup { 33 | return RuleDynamicLookup(id: member) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | io.alexdrone.yas 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | YAS 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/ObjectExpr.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// The arguments of this object props. 4 | public protocol ObjectExpr: NSObjectProtocol { 5 | init() 6 | /// The result of this object expression. 7 | func eval() -> Any? 8 | } 9 | 10 | @objc open class ObjectExprBase: NSObject, ObjectExpr { 11 | public required override init() {} 12 | 13 | public func eval() -> Any? { 14 | return nil 15 | } 16 | } 17 | 18 | public protocol ObjectExprFactoryProtocol { 19 | /// The object name. 20 | var name: String { get } 21 | /// The return type for this compound. 22 | var returnType: Rule.ValueType { get } 23 | /// Build a new argument object. 24 | func build() -> ObjectExpr 25 | } 26 | 27 | public final class ObjectExprRegistry { 28 | /// Singleton instance. 29 | static let `default` = ObjectExprRegistry() 30 | /// The objects factories registered. 31 | private var factories: [ObjectExprFactoryProtocol] = [] 32 | /// All of the registered `_type` identifiers. 33 | lazy var exportedObjectTypes: [String] = { 34 | return factories.map { factory in factory.name } 35 | }(); 36 | 37 | private init() { 38 | objectExprRegisterDefaults(self) 39 | } 40 | 41 | /// Adds a new function to the registry. 42 | public func export(_ object: ObjectExprFactoryProtocol) { 43 | factories.append(object) 44 | } 45 | 46 | /// Tentatively returns the value for a registered object expression. 47 | func eval(fromYaml yaml: YAMLNode) -> (Rule.ValueType, Any?) { 48 | guard let factory = factory(fromYaml: yaml), let object = object(fromYaml: yaml) else { 49 | return (.undefined, nil) 50 | } 51 | return (factory.returnType, object.eval()) 52 | } 53 | 54 | private func factory(fromYaml yaml: YAMLNode) -> ObjectExprFactoryProtocol? { 55 | guard yaml.isMapping, 56 | let type = yaml.mapping?[Rule.Reserved.type]?.string else { 57 | return nil 58 | } 59 | guard let objectFactory = factories.filter({ $0.name == type }).first else { 60 | return nil 61 | } 62 | return objectFactory 63 | } 64 | 65 | private func object(fromYaml yaml: YAMLNode) -> ObjectExpr? { 66 | guard let factory = factory(fromYaml: yaml) else { 67 | return nil 68 | } 69 | let object = factory.build() 70 | let nsObject = object as? NSObject 71 | 72 | for (k, v) in yaml.mapping! { 73 | guard v.isScalar, let key = k.string, key != Rule.Reserved.type else { 74 | continue 75 | } 76 | YASObjcExceptionHandler.try({ 77 | if let value = v.bool { 78 | nsObject?.setValue(NSNumber(value: value), forKey: key) 79 | } 80 | if let value = v.int { 81 | nsObject?.setValue(NSNumber(value:value), forKey: key) 82 | } 83 | if let value = v.float { 84 | nsObject?.setValue(NSNumber(value: value), forKey: key) 85 | } 86 | if let value = v.string { 87 | nsObject?.setValue(value, forKey: key) 88 | } 89 | }, catchAndRethrow: nil, finallyBlock: nil) 90 | } 91 | return object 92 | } 93 | } 94 | 95 | public class ObjectExprFactory: ObjectExprFactoryProtocol { 96 | public let name: String 97 | public let returnType: Rule.ValueType 98 | private let builder: () -> T 99 | 100 | public init( 101 | type: T.Type, 102 | name: String, 103 | builder: @escaping () -> T 104 | ) { 105 | self.name = name 106 | self.returnType = Rule.ValueType.object 107 | self.builder = builder 108 | } 109 | 110 | public func build() -> ObjectExpr { 111 | return builder() 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/Rule.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Represents a stylesheet rule (expressed in the form of [key]: ([value]|[object]). 4 | public class Rule: CustomStringConvertible { 5 | /// Primitive type categories for the right-hand side of the expression. 6 | public enum ValueType: String { 7 | /// Numerical expression (e.g. ${x > 0}). 8 | case expression 9 | /// Boolean (`true`|`false`). 10 | case bool 11 | /// Numerical value (See `integer`, `cgFloat` or `nsNumber` getters). 12 | case number 13 | /// Yaml-parsed string value. 14 | case string 15 | /// A custom Yaml mapping (Must have the `_type`:[String] mapping to discern its object type). 16 | case object 17 | /// Undefined value (Used whenever a value is malformed). 18 | case undefined 19 | } 20 | 21 | /// Reserved keywords. 22 | struct Reserved { 23 | /// The type keyword used to discern the object type. 24 | static let type = "_type" 25 | } 26 | 27 | /// The rule identifier (the left-hand side expression). 28 | private var key: String 29 | /// The value type. 30 | private var type: ValueType? 31 | /// The value store, 32 | private var store: Any? 33 | 34 | /// Construct a rule from a Yaml subtree. 35 | /// Fails if the right-hand side of the expression is a malformed value. 36 | init(key: String, value: YAMLNode) throws { 37 | guard value.isScalar || value.isMapping else { 38 | throw ParseError.malformedRule( 39 | message: "Rhs of \(key) must be a scalar or a mapping.") 40 | } 41 | let registry = ObjectExprRegistry.default; 42 | let optionalObjType = value.mapping?[Rule.Reserved.type]?.string; 43 | guard !value.isMapping || optionalObjType != nil else { 44 | throw ParseError.malformedRule( 45 | message: "Rhs of \(key) is a mapping but is missing the \(Reserved.type) attribute.") 46 | } 47 | if let objType = optionalObjType, !registry.exportedObjectTypes.contains(objType) { 48 | throw ParseError.malformedRule( 49 | message: "\(objType) is an undefined \(Reserved.type).") 50 | } 51 | self.key = key 52 | let (type, store) = try parseValue(for: value) 53 | (self.type, self.store) = (type, store) 54 | } 55 | 56 | /// Returns this rule evaluated as an integer. 57 | /// - note: The default value is 0. 58 | public var integer: Int { 59 | return (nsNumber as? Int) ?? 0 60 | } 61 | 62 | /// Returns this rule evaluated as a boolean. 63 | /// - note: The default value is `false`. 64 | public var bool: Bool { 65 | return (nsNumber as? Bool) ?? false 66 | } 67 | 68 | /// Returns this rule evaluated as a string. 69 | /// - note: The default value is an empty string. 70 | public var string: String { 71 | return cast(type: .string, default: String.init()) 72 | } 73 | 74 | /// Opaque `rhs` value for this rule. 75 | public var object: AnyObject? { 76 | guard let type = type else { return NSObject() } 77 | switch type { 78 | case .bool, .number, .expression: 79 | return nsNumber 80 | case .string: 81 | return (string as NSString) 82 | case .object: 83 | return cast(type: .object, default: nil) 84 | default: 85 | return nil 86 | } 87 | } 88 | 89 | /// Returns the rule value as the desired return type. 90 | /// - note: The enum type should be backed by an integer store. 91 | public func `enum`( 92 | _ type: T.Type, 93 | default: T = T.init(rawValue: 0)! 94 | ) -> T { 95 | return T.init(rawValue: integer) ?? `default` 96 | } 97 | 98 | /// Main entry point for numeric return types and expressions. 99 | /// - note: If it fails evaluating this rule value, `NSNumber` 0.\ 100 | public var nsNumber: NSNumber { 101 | let `default` = NSNumber(value: 0) 102 | // If the store is an expression, it must be evaluated first. 103 | if type == .expression { 104 | let expression = cast(type: .expression, default: Rule.defaultExpression) 105 | return NSNumber(value: evaluate(expression: expression)) 106 | } 107 | // The store is `NSNumber` obj. 108 | if type == .bool || type == .number, let nsNumber = store as? NSNumber { 109 | return nsNumber 110 | } 111 | return `default` 112 | } 113 | 114 | // Tentatively casts the rhs value to the desired type. 115 | public func cast(type: ValueType, default: T) -> T { 116 | /// There`s a type mismatch between the desired type and the type currently associated to this 117 | /// rule. 118 | guard self.type == type else { 119 | warn("type mismatch – wanted \(type), found \(String(describing: self.type)).") 120 | return `default` 121 | } 122 | /// Casts the store value as the desired type `T`. 123 | if let value = self.store as? T { 124 | return value 125 | } 126 | return `default` 127 | } 128 | 129 | /// A textual representation of this instance. 130 | public var description: String { 131 | return type?.rawValue ?? "undefined" 132 | } 133 | 134 | // MARK: - Private 135 | 136 | private func evaluate(expression: Expression?) -> Double { 137 | guard let expression = expression else { 138 | warn("nil expression.") 139 | return 0 140 | } 141 | do { 142 | return try expression.evaluate() 143 | } catch { 144 | warn("Unable to evaluate expression: \(expression.description).") 145 | return 0 146 | } 147 | } 148 | 149 | private func parseValue(for yaml: YAMLNode) throws -> (ValueType, Any?) { 150 | if yaml.isScalar { 151 | if let v = yaml.bool { 152 | return(.bool, v) } 153 | if let v = yaml.int { 154 | return(.number, v) 155 | } 156 | if let v = yaml.float { 157 | return(.number, v) 158 | } 159 | if let v = yaml.string { 160 | let result = try parse(string: v) 161 | return (result.0, result.1) 162 | } 163 | } 164 | if let _ = yaml.mapping { 165 | return try parse(mapping: yaml) 166 | } 167 | return (.undefined, nil) 168 | } 169 | 170 | private func parse(string: String) throws -> (ValueType, Any?) { 171 | // - `${expression}` to evaluate an expression. 172 | if let exprString = ConstExpr.sanitize(expression: string) { 173 | return (.expression, ConstExpr.builder(exprString)) 174 | } 175 | return (.string, string) 176 | } 177 | 178 | private func parse(mapping: YAMLNode) throws -> (ValueType, Any?) { 179 | guard mapping.isMapping else { 180 | return (.undefined, nil) 181 | } 182 | return ObjectExprRegistry.default.eval(fromYaml:mapping) 183 | } 184 | 185 | static private let defaultExpression = Expression("0") 186 | } 187 | -------------------------------------------------------------------------------- /src/Style.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if canImport(UIKit) 3 | import UIKit 4 | public typealias Animator = UIViewPropertyAnimator 5 | #else 6 | public typealias Animator = Any 7 | #endif 8 | 9 | public final class Style { 10 | 11 | public final class Context { 12 | public static let `default` = Context() 13 | #if canImport(UIKit) 14 | /// Whether breakpoints should be ignored or not. 15 | public var skipBreakpoints: Bool = true 16 | /// Optional - The view that is currently being 17 | public weak var view: UIView? 18 | /// The render bounds for the property being evaluated in the next invocation of `rule(_:)`. 19 | public var bounds: CGSize = UIScreen.main.bounds.size 20 | /// User-defined values pushed to the expression evaluation engine. 21 | public var userInfo: [String: CGFloat] = [:] 22 | 23 | public init( 24 | view: UIView? = nil, u 25 | breakpoints: Bool = false, 26 | bounds: CGSize = UIScreen.main.bounds.size 27 | ) { 28 | self.view = view 29 | self.skipBreakpoints = !breakpoints 30 | self.bounds = bounds 31 | } 32 | #endif 33 | 34 | public init() { } 35 | } 36 | 37 | /// Represent a single style definition. 38 | /// e.g. 39 | /// `Style: {foo: 1, bar: 2} # Container/default` 40 | /// `Style/small: {_breakpoint: ${horizontalSizeClass == compact}, foo: 42 } # Container/small` 41 | public final class Container { 42 | /// The style identifier. 43 | public let identifier: String 44 | /// The breakpoint name. 45 | /// Format: `{style}/{brekpoint}: {rules}`. 46 | public let breakpointName: String? 47 | /// The defaul definitions for this `Style`. 48 | var definitions: [String: Rule] = [:] 49 | /// Property animators. 50 | /// Rules that have the `animator-` prefix. 51 | /// e.g. 52 | /// `layer.cornerRadius: 10` 53 | /// `animator-layer.cornerRadius: {_type: animator, curve: easeIn, duration: 1}` 54 | var animators: [String: Animator] = [:] 55 | /// The expression used to evaluate whether this breakpoint should be active or not. 56 | private let breakpointExpression: Expression? 57 | 58 | init( 59 | identifier: String, 60 | breakpointName: String? = nil, 61 | breakpointExpression: Expression? = nil 62 | ) { 63 | self.identifier = identifier 64 | self.breakpointName = breakpointName 65 | self.breakpointExpression = breakpointExpression 66 | } 67 | 68 | public func evaluate(context: Context) -> Bool { 69 | guard 70 | let breakpointExpression = breakpointExpression, 71 | let value = try? breakpointExpression.evaluate() else { 72 | return false 73 | } 74 | return value > 0 75 | } 76 | } 77 | /// The style identifier. 78 | public let identifier: String 79 | /// The defaul definitions for this `Style`. 80 | private let defaultContainer: Container 81 | /// Containers with breakpoints. 82 | private var breakpointContainers: [Container] = [] 83 | 84 | init(identifier: String) { 85 | self.identifier = identifier 86 | self.defaultContainer = Container(identifier: identifier) 87 | } 88 | 89 | /// Adds a new style breakpoint (used for style overrides). 90 | public func addBreakpoint(_ breakpoint: String, rawExpression: String) { 91 | guard breakpointContainers.filter({ $0.identifier != breakpoint}).isEmpty else { 92 | return 93 | } 94 | let expressionString = ConstExpr.sanitize(expression: rawExpression) ?? "0" 95 | let expression = ConstExpr.builder(expressionString) 96 | let container = Container( 97 | identifier: identifier, 98 | breakpointName: breakpoint, 99 | breakpointExpression: expression) 100 | breakpointContainers.append(container) 101 | } 102 | 103 | /// Adds a new property rule. 104 | public func addRule(_ rule: Rule, property: String, breakpoint: String? = nil) { 105 | guard let container = container(forBreakpoint: breakpoint) else { 106 | warn("Cannot find breakpoint \(breakpoint!).") 107 | return 108 | } 109 | container.definitions[property] = rule 110 | } 111 | 112 | /// Adds a new animator to the container. 113 | public func addAnimator(_ animator: Animator, property: String, breakpoint: String? = nil) { 114 | guard let container = container(forBreakpoint: breakpoint) else { 115 | warn("Cannot find breakpoint \(breakpoint!).") 116 | return 117 | } 118 | container.animators[property] = animator 119 | } 120 | 121 | public func property(named propertyName: String, context: Context = Context.default) -> Rule? { 122 | let rule = defaultContainer.definitions[propertyName] 123 | if context.skipBreakpoints || breakpointContainers.isEmpty { 124 | return rule 125 | } 126 | let override = breakpointContainers.lazy.filter { 127 | $0.definitions[propertyName] != nil && $0.evaluate(context: context) 128 | }.first 129 | let overrideProperty = override?.definitions[propertyName] 130 | return overrideProperty ?? rule 131 | } 132 | 133 | public func animator(named name: String, context: Context = Context.default) -> Animator? { 134 | let rule = defaultContainer.animators[name] 135 | if context.skipBreakpoints || breakpointContainers.isEmpty { 136 | return rule 137 | } 138 | let override = breakpointContainers.lazy.filter { 139 | $0.animators[name] != nil && $0.evaluate(context: context) 140 | }.first 141 | return override?.animators[name] ?? rule 142 | } 143 | 144 | public func properties(context: Context = Context.default) -> [String: Rule] { 145 | var rules = defaultContainer.definitions 146 | if context.skipBreakpoints || breakpointContainers.isEmpty { 147 | return rules 148 | } 149 | for container in breakpointContainers { 150 | guard container.evaluate(context: context) else { continue } 151 | for (key, value) in container.definitions { 152 | rules[key] = value 153 | } 154 | } 155 | return rules 156 | } 157 | 158 | private func container(forBreakpoint breakpoint: String? = nil) -> Container? { 159 | guard let breakpoint = breakpoint else { 160 | return defaultContainer 161 | } 162 | let breakpointContainer = breakpointContainers.filter { $0.identifier != breakpoint }.first 163 | return breakpointContainer ?? defaultContainer 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Stylesheet.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public enum ParseError: Error { 4 | /// The filename is not set. 5 | case fileNotSet 6 | /// The file was not found in the bundle. 7 | case fileNotFound(file: String) 8 | /// Illegal stylesheet format. 9 | case malformedStylesheetStructure(message: String?) 10 | /// Illegal stylesheet rule definition. 11 | case malformedRule(message: String) 12 | } 13 | 14 | public final class StylesheetManager { 15 | /// Reserved keywords. 16 | private struct Reserved { 17 | /// Root-level mapping used for cascade imports. 18 | static let importKeyword = "_import" 19 | /// Reserved property used for media queries. 20 | static let breakpointKeywork = "_breakpoint" 21 | /// Property prefix used for property animators. 22 | static let animatorPrefix = "_animator_" 23 | /// Used to define Styles with breakpoints. 24 | /// e.g. 25 | /// `Style: {foo: 1, bar: 2} # Container/default` 26 | /// `Style/small: {_breakpoint: ${horizontalSizeClass == compact}, foo: 42 } # Container/small` 27 | static let breakpointSeparator = "/" 28 | } 29 | /// Shared manager instance. 30 | public static let `default` = StylesheetManager() 31 | /// The style containers. 32 | private var styles: [String: Style] = [:] 33 | /// The reource bundle where the stylesheet is located. 34 | private var bundle: Bundle? 35 | 36 | init() { 37 | // Internal constructor. 38 | } 39 | 40 | // MARK: Public 41 | 42 | /// Returns the desired style. 43 | public func properties( 44 | forStyle style: String, 45 | context: Style.Context = Style.Context.default 46 | ) -> [String: Rule]? { 47 | return styles[style]?.properties(context: context) 48 | } 49 | 50 | /// Returns the rule named `name` of a specified style. 51 | public func property( 52 | style: String, 53 | name: String, 54 | context: Style.Context = Style.Context.default 55 | ) -> Rule? { 56 | return styles[style]?.property(named: name, context: context) 57 | } 58 | 59 | /// Returns the animator for a given property. 60 | /// Animators rule have the `animator-` prefix. 61 | /// e.g. 62 | /// layer.cornerRadius: 10 63 | /// animator-layer.cornerRadius: {_type: animator, curve: easeIn, duration: 1} 64 | public func animator( 65 | style: String, 66 | name: String, 67 | context: Style.Context = Style.Context.default 68 | ) -> Animator? { 69 | return styles[style]?.animator(named: name, context: context) 70 | } 71 | 72 | /// Parse and load the Yaml stylesheet. 73 | public func load(file: String, bundle: Bundle = Bundle.main) throws { 74 | try load(yaml: resolve(file: file, bundle: bundle)) 75 | NotificationCenter.default.post(name: Notification.Name.StylesheetContextDidChange, object: nil) 76 | } 77 | 78 | /// Parses the markup content passed as argument. 79 | public func load(yaml string: String) throws { 80 | let startTime = CFAbsoluteTimeGetCurrent() 81 | 82 | // Parses the top level definitions. 83 | var content: String = string 84 | 85 | // Sanitize the file format. 86 | func validateRootNode(_ string: String) throws -> YAMLNode { 87 | guard let root = try YAMLParser(yaml: string).singleRoot(), root.isMapping else { 88 | throw ParseError.malformedStylesheetStructure(message: "The root node should be a map.") 89 | } 90 | return root 91 | } 92 | 93 | // Resolve all of the yaml imports. 94 | func resolveImports(_ string: String) throws { 95 | if string.isEmpty { 96 | warn("Resolved stylesheet file with empty content.") 97 | return 98 | } 99 | let root = try validateRootNode(string) 100 | for imported in root.mapping![Reserved.importKeyword]?.array() ?? [] { 101 | guard let fileName = imported.string?.replacingOccurrences(of: ".yaml", with: "") else { 102 | continue 103 | } 104 | content += try resolve(file: fileName, bundle: bundle!) 105 | } 106 | } 107 | 108 | // Parse the final stylesheet file. 109 | func parseRoot(_ string: String) throws { 110 | let root = try validateRootNode(string) 111 | for (key, value) in root.mapping ?? [:] { 112 | guard key.string != Reserved.importKeyword else { continue } 113 | guard var defDic = value.mapping, let key = key.string else { 114 | throw ParseError.malformedStylesheetStructure(message:"A style should be a mapping.") 115 | } 116 | // Create the style container. 117 | var styleKey: String = key 118 | var breakpoint: String? = nil 119 | // Tries to parse the breakpoint. 120 | let components = key.components(separatedBy: Reserved.breakpointSeparator) 121 | if components.count == 2 { 122 | styleKey = components[0] 123 | breakpoint = components[1] 124 | } 125 | /// Retrieve the container. 126 | let style = styles[styleKey] ?? Style(identifier: styleKey) 127 | styles[styleKey] = style 128 | /// Adds the breakpoint if necessary. 129 | if let breakpoint = breakpoint, let expr = defDic[Reserved.breakpointKeywork]?.string { 130 | style.addBreakpoint(breakpoint, rawExpression: expr) 131 | } 132 | // In yaml definitions can inherit from others using the <<: *ID expression. e.g. 133 | // myDef: &_myDef 134 | // foo: 1 135 | // myOtherDef: &_myOtherDef 136 | // <<: *_myDef 137 | // bar: 2 138 | if let inherit = defDic["<<"]?.mapping { 139 | for (ik, iv) in inherit { 140 | guard let _ik = ik.string else { 141 | throw ParseError.malformedStylesheetStructure(message: "Invalid key.") 142 | } 143 | style.addRule( 144 | try Rule(key: _ik, value: iv), 145 | property: _ik, 146 | breakpoint: breakpoint) 147 | } 148 | } 149 | // Properties. 150 | for (k, v) in defDic { 151 | guard let _k = k.string, _k != "<<", !_k.hasPrefix(Reserved.animatorPrefix) else { 152 | continue 153 | } 154 | style.addRule( 155 | try Rule(key: _k, value: v), 156 | property: _k, 157 | breakpoint: breakpoint) 158 | } 159 | // Animators. 160 | for (k, v) in defDic { 161 | guard let _k = k.string, _k.hasPrefix(Reserved.animatorPrefix) else { 162 | continue 163 | } 164 | let pk = _k.replacingOccurrences(of: Reserved.animatorPrefix, with: "") 165 | style.addAnimator( 166 | try Rule(key: pk, value: v).animator, 167 | property: pk, 168 | breakpoint: breakpoint) 169 | } 170 | } 171 | } 172 | 173 | try resolveImports(string) 174 | try parseRoot(content) 175 | debugLoadTime("Stylesheet.load", startTime: startTime) 176 | } 177 | 178 | // MARK: Private 179 | 180 | private func resolve(file: String, bundle: Bundle) throws -> String { 181 | guard 182 | let leaf = file.components(separatedBy: "/").last, 183 | let path = bundle.path(forResource: leaf, ofType: "yaml") else { 184 | throw ParseError.fileNotFound(file: file) 185 | } 186 | return try String(contentsOfFile: path, encoding: .utf8) 187 | } 188 | 189 | private func debugLoadTime(_ label: String, startTime: CFAbsoluteTime){ 190 | let timeElapsed = (CFAbsoluteTimeGetCurrent() - startTime) * 1000 191 | print(String(format: "\(label) (%2f) ms.", arguments: [timeElapsed])) 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/StylesheetContext.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public struct StylesheetContext { 4 | /// Shorthand for the shared manager. 5 | static let manager = StylesheetManager.default 6 | /// Shorthand for the Dynamic lookup proxy. 7 | static let lookup = StyleDynamicLookup() 8 | /// Shorthand for the default object expressions registry. 9 | static let objectExpr = ObjectExprRegistry.default 10 | } 11 | 12 | extension Notification.Name { 13 | /// Posted whenever the stylesheet has been reloaded. 14 | static let StylesheetContextDidChange = Notification.Name("io.yas.StylesheetContextDidChange") 15 | } 16 | -------------------------------------------------------------------------------- /src/View.swift: -------------------------------------------------------------------------------- 1 | #if canImport(UIKit) 2 | import UIKit 3 | 4 | public extension UIView { 5 | /// Applies a style definition to this view. 6 | @nonobjc func apply(style: [String: Rule]?) { 7 | guard let style = style else { 8 | return 9 | } 10 | assert(Thread.isMainThread) 11 | for (key, rule) in style { 12 | YASObjcExceptionHandler.try({ [weak self] in 13 | self?.setValue(rule.object, forKeyPath: key) 14 | }, 15 | catchAndRethrow: nil, 16 | finallyBlock: nil) 17 | } 18 | } 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /src/YAS.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | 6 | FOUNDATION_EXPORT double YASVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char YASVersionString[]; 8 | -------------------------------------------------------------------------------- /src/deps/YASObjcExceptionHandler.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface YASObjcExceptionHandler : NSObject 6 | 7 | + (void)tryBlock:(nonnull void (^)(void))tryBlock 8 | catchAndRethrowBlock:(nullable BOOL (^)(_Nonnull id))catchAndRethrowBlock 9 | finallyBlock:(nullable void (^)(void))finallyBlock; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /src/deps/YASObjcExceptionHandler.m: -------------------------------------------------------------------------------- 1 | #import "YASObjcExceptionHandler.h" 2 | 3 | @implementation YASObjcExceptionHandler 4 | 5 | + (void)tryBlock:(void (^)(void))tryBlock 6 | catchAndRethrowBlock:(BOOL (^)(id))catchAndRethrowBlock 7 | finallyBlock:(void (^)(void))finallyBlock { 8 | @try { 9 | tryBlock(); 10 | } @catch (id exception) { 11 | if (catchAndRethrowBlock && catchAndRethrowBlock(exception)) { 12 | @throw; 13 | } 14 | } @finally { 15 | if (finallyBlock) { 16 | finallyBlock(); 17 | } 18 | } 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /src/deps/yaml.h: -------------------------------------------------------------------------------- 1 | //#ifdef RENDER_MOD_STYLESHEET 2 | /** 3 | * @file yaml.h 4 | * @brief Public interface for libyaml. 5 | * 6 | * Include the header file with the code: 7 | * @code 8 | * #include 9 | * @endcode 10 | */ 11 | 12 | #ifndef YAML_H 13 | #define YAML_H 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | /** 24 | * @defgroup export Export Definitions 25 | * @{ 26 | */ 27 | 28 | /** The public API declaration. */ 29 | 30 | #if defined(__MINGW32__) 31 | # define YAML_DECLARE(type) type 32 | #elif defined(WIN32) 33 | # if defined(YAML_DECLARE_STATIC) 34 | # define YAML_DECLARE(type) type 35 | # elif defined(YAML_DECLARE_EXPORT) 36 | # define YAML_DECLARE(type) __declspec(dllexport) type 37 | # else 38 | # define YAML_DECLARE(type) __declspec(dllimport) type 39 | # endif 40 | #else 41 | # define YAML_DECLARE(type) type 42 | #endif 43 | 44 | /** @} */ 45 | 46 | /** 47 | * @defgroup version Version Information 48 | * @{ 49 | */ 50 | 51 | /** 52 | * Get the library version as a string. 53 | * 54 | * @returns The function returns the pointer to a static string of the form 55 | * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version 56 | * number, and @c Z is the patch version number. 57 | */ 58 | 59 | YAML_DECLARE(const char *) 60 | yaml_get_version_string(void); 61 | 62 | /** 63 | * Get the library version numbers. 64 | * 65 | * @param[out] major Major version number. 66 | * @param[out] minor Minor version number. 67 | * @param[out] patch Patch version number. 68 | */ 69 | 70 | YAML_DECLARE(void) 71 | yaml_get_version(int *major, int *minor, int *patch); 72 | 73 | /** @} */ 74 | 75 | /** 76 | * @defgroup basic Basic Types 77 | * @{ 78 | */ 79 | 80 | /** The character type (UTF-8 octet). */ 81 | typedef unsigned char yaml_char_t; 82 | 83 | /** The version directive data. */ 84 | typedef struct yaml_version_directive_s { 85 | /** The major version number. */ 86 | int major; 87 | /** The minor version number. */ 88 | int minor; 89 | } yaml_version_directive_t; 90 | 91 | /** The tag directive data. */ 92 | typedef struct yaml_tag_directive_s { 93 | /** The tag handle. */ 94 | yaml_char_t *handle; 95 | /** The tag prefix. */ 96 | yaml_char_t *prefix; 97 | } yaml_tag_directive_t; 98 | 99 | /** The stream encoding. */ 100 | typedef enum yaml_encoding_e { 101 | /** Let the parser choose the encoding. */ 102 | YAML_ANY_ENCODING, 103 | /** The default UTF-8 encoding. */ 104 | YAML_UTF8_ENCODING, 105 | /** The UTF-16-LE encoding with BOM. */ 106 | YAML_UTF16LE_ENCODING, 107 | /** The UTF-16-BE encoding with BOM. */ 108 | YAML_UTF16BE_ENCODING 109 | } yaml_encoding_t; 110 | 111 | /** Line break types. */ 112 | 113 | typedef enum yaml_break_e { 114 | /** Let the parser choose the break type. */ 115 | YAML_ANY_BREAK, 116 | /** Use CR for line breaks (Mac style). */ 117 | YAML_CR_BREAK, 118 | /** Use LN for line breaks (Unix style). */ 119 | YAML_LN_BREAK, 120 | /** Use CR LN for line breaks (DOS style). */ 121 | YAML_CRLN_BREAK 122 | } yaml_break_t; 123 | 124 | /** Many bad things could happen with the parser and emitter. */ 125 | typedef enum yaml_error_type_e { 126 | /** No error is produced. */ 127 | YAML_NO_ERROR, 128 | 129 | /** Cannot allocate or reallocate a block of memory. */ 130 | YAML_MEMORY_ERROR, 131 | 132 | /** Cannot read or decode the input stream. */ 133 | YAML_READER_ERROR, 134 | /** Cannot scan the input stream. */ 135 | YAML_SCANNER_ERROR, 136 | /** Cannot parse the input stream. */ 137 | YAML_PARSER_ERROR, 138 | /** Cannot compose a YAML document. */ 139 | YAML_COMPOSER_ERROR, 140 | 141 | /** Cannot write to the output stream. */ 142 | YAML_WRITER_ERROR, 143 | /** Cannot emit a YAML stream. */ 144 | YAML_EMITTER_ERROR 145 | } yaml_error_type_t; 146 | 147 | /** The pointer position. */ 148 | typedef struct yaml_mark_s { 149 | /** The position index. */ 150 | size_t index; 151 | 152 | /** The position line. */ 153 | size_t line; 154 | 155 | /** The position column. */ 156 | size_t column; 157 | } yaml_mark_t; 158 | 159 | /** @} */ 160 | 161 | /** 162 | * @defgroup styles YAMLNode Styles 163 | * @{ 164 | */ 165 | 166 | /** Scalar styles. */ 167 | typedef enum yaml_scalar_style_e { 168 | /** Let the emitter choose the style. */ 169 | YAML_ANY_SCALAR_STYLE, 170 | 171 | /** The plain scalar style. */ 172 | YAML_PLAIN_SCALAR_STYLE, 173 | 174 | /** The single-quoted scalar style. */ 175 | YAML_SINGLE_QUOTED_SCALAR_STYLE, 176 | /** The double-quoted scalar style. */ 177 | YAML_DOUBLE_QUOTED_SCALAR_STYLE, 178 | 179 | /** The literal scalar style. */ 180 | YAML_LITERAL_SCALAR_STYLE, 181 | /** The folded scalar style. */ 182 | YAML_FOLDED_SCALAR_STYLE 183 | } yaml_scalar_style_t; 184 | 185 | /** Sequence styles. */ 186 | typedef enum yaml_sequence_style_e { 187 | /** Let the emitter choose the style. */ 188 | YAML_ANY_SEQUENCE_STYLE, 189 | 190 | /** The block sequence style. */ 191 | YAML_BLOCK_SEQUENCE_STYLE, 192 | /** The flow sequence style. */ 193 | YAML_FLOW_SEQUENCE_STYLE 194 | } yaml_sequence_style_t; 195 | 196 | /** Mapping styles. */ 197 | typedef enum yaml_mapping_style_e { 198 | /** Let the emitter choose the style. */ 199 | YAML_ANY_MAPPING_STYLE, 200 | 201 | /** The block mapping style. */ 202 | YAML_BLOCK_MAPPING_STYLE, 203 | /** The flow mapping style. */ 204 | YAML_FLOW_MAPPING_STYLE 205 | /* YAML_FLOW_SET_MAPPING_STYLE */ 206 | } yaml_mapping_style_t; 207 | 208 | /** @} */ 209 | 210 | /** 211 | * @defgroup tokens Tokens 212 | * @{ 213 | */ 214 | 215 | /** Token types. */ 216 | typedef enum yaml_token_type_e { 217 | /** An empty token. */ 218 | YAML_NO_TOKEN, 219 | 220 | /** A STREAM-START token. */ 221 | YAML_STREAM_START_TOKEN, 222 | /** A STREAM-END token. */ 223 | YAML_STREAM_END_TOKEN, 224 | 225 | /** A VERSION-DIRECTIVE token. */ 226 | YAML_VERSION_DIRECTIVE_TOKEN, 227 | /** A TAG-DIRECTIVE token. */ 228 | YAML_TAG_DIRECTIVE_TOKEN, 229 | /** A DOCUMENT-START token. */ 230 | YAML_DOCUMENT_START_TOKEN, 231 | /** A DOCUMENT-END token. */ 232 | YAML_DOCUMENT_END_TOKEN, 233 | 234 | /** A BLOCK-SEQUENCE-START token. */ 235 | YAML_BLOCK_SEQUENCE_START_TOKEN, 236 | /** A BLOCK-SEQUENCE-END token. */ 237 | YAML_BLOCK_MAPPING_START_TOKEN, 238 | /** A BLOCK-END token. */ 239 | YAML_BLOCK_END_TOKEN, 240 | 241 | /** A FLOW-SEQUENCE-START token. */ 242 | YAML_FLOW_SEQUENCE_START_TOKEN, 243 | /** A FLOW-SEQUENCE-END token. */ 244 | YAML_FLOW_SEQUENCE_END_TOKEN, 245 | /** A FLOW-MAPPING-START token. */ 246 | YAML_FLOW_MAPPING_START_TOKEN, 247 | /** A FLOW-MAPPING-END token. */ 248 | YAML_FLOW_MAPPING_END_TOKEN, 249 | 250 | /** A BLOCK-ENTRY token. */ 251 | YAML_BLOCK_ENTRY_TOKEN, 252 | /** A FLOW-ENTRY token. */ 253 | YAML_FLOW_ENTRY_TOKEN, 254 | /** A KEY token. */ 255 | YAML_KEY_TOKEN, 256 | /** A VALUE token. */ 257 | YAML_VALUE_TOKEN, 258 | 259 | /** An ALIAS token. */ 260 | YAML_ALIAS_TOKEN, 261 | /** An ANCHOR token. */ 262 | YAML_ANCHOR_TOKEN, 263 | /** A TAG token. */ 264 | YAML_TAG_TOKEN, 265 | /** A SCALAR token. */ 266 | YAML_SCALAR_TOKEN 267 | } yaml_token_type_t; 268 | 269 | /** The token structure. */ 270 | typedef struct yaml_token_s { 271 | 272 | /** The token type. */ 273 | yaml_token_type_t type; 274 | 275 | /** The token data. */ 276 | union { 277 | 278 | /** The stream start (for @c YAML_STREAM_START_TOKEN). */ 279 | struct { 280 | /** The stream encoding. */ 281 | yaml_encoding_t encoding; 282 | } stream_start; 283 | 284 | /** The alias (for @c YAML_ALIAS_TOKEN). */ 285 | struct { 286 | /** The alias value. */ 287 | yaml_char_t *value; 288 | } alias; 289 | 290 | /** The anchor (for @c YAML_ANCHOR_TOKEN). */ 291 | struct { 292 | /** The anchor value. */ 293 | yaml_char_t *value; 294 | } anchor; 295 | 296 | /** The tag (for @c YAML_TAG_TOKEN). */ 297 | struct { 298 | /** The tag handle. */ 299 | yaml_char_t *handle; 300 | /** The tag suffix. */ 301 | yaml_char_t *suffix; 302 | } tag; 303 | 304 | /** The scalar value (for @c YAML_SCALAR_TOKEN). */ 305 | struct { 306 | /** The scalar value. */ 307 | yaml_char_t *value; 308 | /** The length of the scalar value. */ 309 | size_t length; 310 | /** The scalar style. */ 311 | yaml_scalar_style_t style; 312 | } scalar; 313 | 314 | /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */ 315 | struct { 316 | /** The major version number. */ 317 | int major; 318 | /** The minor version number. */ 319 | int minor; 320 | } version_directive; 321 | 322 | /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */ 323 | struct { 324 | /** The tag handle. */ 325 | yaml_char_t *handle; 326 | /** The tag prefix. */ 327 | yaml_char_t *prefix; 328 | } tag_directive; 329 | 330 | } data; 331 | 332 | /** The beginning of the token. */ 333 | yaml_mark_t start_mark; 334 | /** The end of the token. */ 335 | yaml_mark_t end_mark; 336 | 337 | } yaml_token_t; 338 | 339 | /** 340 | * Free any memory allocated for a token object. 341 | * 342 | * @param[in,out] token A token object. 343 | */ 344 | 345 | YAML_DECLARE(void) 346 | yaml_token_delete(yaml_token_t *token); 347 | 348 | /** @} */ 349 | 350 | /** 351 | * @defgroup events YAMLEvents 352 | * @{ 353 | */ 354 | 355 | /** YAMLEvent types. */ 356 | typedef enum yaml_event_type_e { 357 | /** An empty event. */ 358 | YAML_NO_EVENT, 359 | 360 | /** A STREAM-START event. */ 361 | YAML_STREAM_START_EVENT, 362 | /** A STREAM-END event. */ 363 | YAML_STREAM_END_EVENT, 364 | 365 | /** A DOCUMENT-START event. */ 366 | YAML_DOCUMENT_START_EVENT, 367 | /** A DOCUMENT-END event. */ 368 | YAML_DOCUMENT_END_EVENT, 369 | 370 | /** An ALIAS event. */ 371 | YAML_ALIAS_EVENT, 372 | /** A SCALAR event. */ 373 | YAML_SCALAR_EVENT, 374 | 375 | /** A SEQUENCE-START event. */ 376 | YAML_SEQUENCE_START_EVENT, 377 | /** A SEQUENCE-END event. */ 378 | YAML_SEQUENCE_END_EVENT, 379 | 380 | /** A MAPPING-START event. */ 381 | YAML_MAPPING_START_EVENT, 382 | /** A MAPPING-END event. */ 383 | YAML_MAPPING_END_EVENT 384 | } yaml_event_type_t; 385 | 386 | /** The event structure. */ 387 | typedef struct yaml_event_s { 388 | 389 | /** The event type. */ 390 | yaml_event_type_t type; 391 | 392 | /** The event data. */ 393 | union { 394 | 395 | /** The stream parameters (for @c YAML_STREAM_START_EVENT). */ 396 | struct { 397 | /** The document encoding. */ 398 | yaml_encoding_t encoding; 399 | } stream_start; 400 | 401 | /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */ 402 | struct { 403 | /** The version directive. */ 404 | yaml_version_directive_t *version_directive; 405 | 406 | /** The list of tag directives. */ 407 | struct { 408 | /** The beginning of the tag directives list. */ 409 | yaml_tag_directive_t *start; 410 | /** The end of the tag directives list. */ 411 | yaml_tag_directive_t *end; 412 | } tag_directives; 413 | 414 | /** Is the document indicator implicit? */ 415 | int implicit; 416 | } document_start; 417 | 418 | /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */ 419 | struct { 420 | /** Is the document end indicator implicit? */ 421 | int implicit; 422 | } document_end; 423 | 424 | /** The alias parameters (for @c YAML_ALIAS_EVENT). */ 425 | struct { 426 | /** The anchor. */ 427 | yaml_char_t *anchor; 428 | } alias; 429 | 430 | /** The scalar parameters (for @c YAML_SCALAR_EVENT). */ 431 | struct { 432 | /** The anchor. */ 433 | yaml_char_t *anchor; 434 | /** The tag. */ 435 | yaml_char_t *tag; 436 | /** The scalar value. */ 437 | yaml_char_t *value; 438 | /** The length of the scalar value. */ 439 | size_t length; 440 | /** Is the tag optional for the plain style? */ 441 | int plain_implicit; 442 | /** Is the tag optional for any non-plain style? */ 443 | int quoted_implicit; 444 | /** The scalar style. */ 445 | yaml_scalar_style_t style; 446 | } scalar; 447 | 448 | /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */ 449 | struct { 450 | /** The anchor. */ 451 | yaml_char_t *anchor; 452 | /** The tag. */ 453 | yaml_char_t *tag; 454 | /** Is the tag optional? */ 455 | int implicit; 456 | /** The sequence style. */ 457 | yaml_sequence_style_t style; 458 | } sequence_start; 459 | 460 | /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */ 461 | struct { 462 | /** The anchor. */ 463 | yaml_char_t *anchor; 464 | /** The tag. */ 465 | yaml_char_t *tag; 466 | /** Is the tag optional? */ 467 | int implicit; 468 | /** The mapping style. */ 469 | yaml_mapping_style_t style; 470 | } mapping_start; 471 | 472 | } data; 473 | 474 | /** The beginning of the event. */ 475 | yaml_mark_t start_mark; 476 | /** The end of the event. */ 477 | yaml_mark_t end_mark; 478 | 479 | } yaml_event_t; 480 | 481 | /** 482 | * Create the STREAM-START event. 483 | * 484 | * @param[out] event An empty event object. 485 | * @param[in] encoding The stream encoding. 486 | * 487 | * @returns @c 1 if the function succeeded, @c 0 on error. 488 | */ 489 | 490 | YAML_DECLARE(int) 491 | yaml_stream_start_event_initialize(yaml_event_t *event, 492 | yaml_encoding_t encoding); 493 | 494 | /** 495 | * Create the STREAM-END event. 496 | * 497 | * @param[out] event An empty event object. 498 | * 499 | * @returns @c 1 if the function succeeded, @c 0 on error. 500 | */ 501 | 502 | YAML_DECLARE(int) 503 | yaml_stream_end_event_initialize(yaml_event_t *event); 504 | 505 | /** 506 | * Create the DOCUMENT-START event. 507 | * 508 | * The @a implicit argument is considered as a stylistic parameter and may be 509 | * ignored by the emitter. 510 | * 511 | * @param[out] event An empty event object. 512 | * @param[in] version_directive The %YAML directive value or 513 | * @c NULL. 514 | * @param[in] tag_directives_start The beginning of the %TAG 515 | * directives list. 516 | * @param[in] tag_directives_end The end of the %TAG directives 517 | * list. 518 | * @param[in] implicit If the document start indicator is 519 | * implicit. 520 | * 521 | * @returns @c 1 if the function succeeded, @c 0 on error. 522 | */ 523 | 524 | YAML_DECLARE(int) 525 | yaml_document_start_event_initialize(yaml_event_t *event, 526 | yaml_version_directive_t *version_directive, 527 | yaml_tag_directive_t *tag_directives_start, 528 | yaml_tag_directive_t *tag_directives_end, 529 | int implicit); 530 | 531 | /** 532 | * Create the DOCUMENT-END event. 533 | * 534 | * The @a implicit argument is considered as a stylistic parameter and may be 535 | * ignored by the emitter. 536 | * 537 | * @param[out] event An empty event object. 538 | * @param[in] implicit If the document end indicator is implicit. 539 | * 540 | * @returns @c 1 if the function succeeded, @c 0 on error. 541 | */ 542 | 543 | YAML_DECLARE(int) 544 | yaml_document_end_event_initialize(yaml_event_t *event, int implicit); 545 | 546 | /** 547 | * Create an ALIAS event. 548 | * 549 | * @param[out] event An empty event object. 550 | * @param[in] anchor The anchor value. 551 | * 552 | * @returns @c 1 if the function succeeded, @c 0 on error. 553 | */ 554 | 555 | YAML_DECLARE(int) 556 | yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); 557 | 558 | /** 559 | * Create a SCALAR event. 560 | * 561 | * The @a style argument may be ignored by the emitter. 562 | * 563 | * Either the @a tag attribute or one of the @a plain_implicit and 564 | * @a quoted_implicit flags must be set. 565 | * 566 | * @param[out] event An empty event object. 567 | * @param[in] anchor The scalar anchor or @c NULL. 568 | * @param[in] tag The scalar tag or @c NULL. 569 | * @param[in] value The scalar value. 570 | * @param[in] length The length of the scalar value. 571 | * @param[in] plain_implicit If the tag may be omitted for the plain 572 | * style. 573 | * @param[in] quoted_implicit If the tag may be omitted for any 574 | * non-plain style. 575 | * @param[in] style The scalar style. 576 | * 577 | * @returns @c 1 if the function succeeded, @c 0 on error. 578 | */ 579 | 580 | YAML_DECLARE(int) 581 | yaml_scalar_event_initialize(yaml_event_t *event, 582 | yaml_char_t *anchor, yaml_char_t *tag, 583 | yaml_char_t *value, int length, 584 | int plain_implicit, int quoted_implicit, 585 | yaml_scalar_style_t style); 586 | 587 | /** 588 | * Create a SEQUENCE-START event. 589 | * 590 | * The @a style argument may be ignored by the emitter. 591 | * 592 | * Either the @a tag attribute or the @a implicit flag must be set. 593 | * 594 | * @param[out] event An empty event object. 595 | * @param[in] anchor The sequence anchor or @c NULL. 596 | * @param[in] tag The sequence tag or @c NULL. 597 | * @param[in] implicit If the tag may be omitted. 598 | * @param[in] style The sequence style. 599 | * 600 | * @returns @c 1 if the function succeeded, @c 0 on error. 601 | */ 602 | 603 | YAML_DECLARE(int) 604 | yaml_sequence_start_event_initialize(yaml_event_t *event, 605 | yaml_char_t *anchor, yaml_char_t *tag, int implicit, 606 | yaml_sequence_style_t style); 607 | 608 | /** 609 | * Create a SEQUENCE-END event. 610 | * 611 | * @param[out] event An empty event object. 612 | * 613 | * @returns @c 1 if the function succeeded, @c 0 on error. 614 | */ 615 | 616 | YAML_DECLARE(int) 617 | yaml_sequence_end_event_initialize(yaml_event_t *event); 618 | 619 | /** 620 | * Create a MAPPING-START event. 621 | * 622 | * The @a style argument may be ignored by the emitter. 623 | * 624 | * Either the @a tag attribute or the @a implicit flag must be set. 625 | * 626 | * @param[out] event An empty event object. 627 | * @param[in] anchor The mapping anchor or @c NULL. 628 | * @param[in] tag The mapping tag or @c NULL. 629 | * @param[in] implicit If the tag may be omitted. 630 | * @param[in] style The mapping style. 631 | * 632 | * @returns @c 1 if the function succeeded, @c 0 on error. 633 | */ 634 | 635 | YAML_DECLARE(int) 636 | yaml_mapping_start_event_initialize(yaml_event_t *event, 637 | yaml_char_t *anchor, yaml_char_t *tag, int implicit, 638 | yaml_mapping_style_t style); 639 | 640 | /** 641 | * Create a MAPPING-END event. 642 | * 643 | * @param[out] event An empty event object. 644 | * 645 | * @returns @c 1 if the function succeeded, @c 0 on error. 646 | */ 647 | 648 | YAML_DECLARE(int) 649 | yaml_mapping_end_event_initialize(yaml_event_t *event); 650 | 651 | /** 652 | * Free any memory allocated for an event object. 653 | * 654 | * @param[in,out] event An event object. 655 | */ 656 | 657 | YAML_DECLARE(void) 658 | yaml_event_delete(yaml_event_t *event); 659 | 660 | /** @} */ 661 | 662 | /** 663 | * @defgroup nodes YAMLNodes 664 | * @{ 665 | */ 666 | 667 | /** The tag @c !!null with the only possible value: @c null. */ 668 | #define YAML_NULL_TAG "tag:yaml.org,2002:null" 669 | /** The tag @c !!bool with the values: @c true and @c false. */ 670 | #define YAML_BOOL_TAG "tag:yaml.org,2002:bool" 671 | /** The tag @c !!str for string values. */ 672 | #define YAML_STR_TAG "tag:yaml.org,2002:str" 673 | /** The tag @c !!int for integer values. */ 674 | #define YAML_INT_TAG "tag:yaml.org,2002:int" 675 | /** The tag @c !!float for float values. */ 676 | #define YAML_FLOAT_TAG "tag:yaml.org,2002:float" 677 | /** The tag @c !!timestamp for date and time values. */ 678 | #define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp" 679 | 680 | /** The tag @c !!seq is used to denote sequences. */ 681 | #define YAML_SEQ_TAG "tag:yaml.org,2002:seq" 682 | /** The tag @c !!map is used to denote mapping. */ 683 | #define YAML_MAP_TAG "tag:yaml.org,2002:map" 684 | 685 | /** The default scalar tag is @c !!str. */ 686 | #define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG 687 | /** The default sequence tag is @c !!seq. */ 688 | #define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG 689 | /** The default mapping tag is @c !!map. */ 690 | #define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG 691 | 692 | /** YAMLNode types. */ 693 | typedef enum yaml_node_type_e { 694 | /** An empty node. */ 695 | YAML_NO_NODE, 696 | 697 | /** A scalar node. */ 698 | YAML_SCALAR_NODE, 699 | /** A sequence node. */ 700 | YAML_SEQUENCE_NODE, 701 | /** A mapping node. */ 702 | YAML_MAPPING_NODE 703 | } yaml_node_type_t; 704 | 705 | /** The forward definition of a document node structure. */ 706 | typedef struct yaml_node_s yaml_node_t; 707 | 708 | /** An element of a sequence node. */ 709 | typedef int yaml_node_item_t; 710 | 711 | /** An element of a mapping node. */ 712 | typedef struct yaml_node_pair_s { 713 | /** The key of the element. */ 714 | int key; 715 | /** The value of the element. */ 716 | int value; 717 | } yaml_node_pair_t; 718 | 719 | /** The node structure. */ 720 | struct yaml_node_s { 721 | 722 | /** The node type. */ 723 | yaml_node_type_t type; 724 | 725 | /** The node tag. */ 726 | yaml_char_t *tag; 727 | 728 | /** The node data. */ 729 | union { 730 | 731 | /** The scalar parameters (for @c YAML_SCALAR_NODE). */ 732 | struct { 733 | /** The scalar value. */ 734 | yaml_char_t *value; 735 | /** The length of the scalar value. */ 736 | size_t length; 737 | /** The scalar style. */ 738 | yaml_scalar_style_t style; 739 | } scalar; 740 | 741 | /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */ 742 | struct { 743 | /** The stack of sequence items. */ 744 | struct { 745 | /** The beginning of the stack. */ 746 | yaml_node_item_t *start; 747 | /** The end of the stack. */ 748 | yaml_node_item_t *end; 749 | /** The top of the stack. */ 750 | yaml_node_item_t *top; 751 | } items; 752 | /** The sequence style. */ 753 | yaml_sequence_style_t style; 754 | } sequence; 755 | 756 | /** The mapping parameters (for @c YAML_MAPPING_NODE). */ 757 | struct { 758 | /** The stack of mapping pairs (key, value). */ 759 | struct { 760 | /** The beginning of the stack. */ 761 | yaml_node_pair_t *start; 762 | /** The end of the stack. */ 763 | yaml_node_pair_t *end; 764 | /** The top of the stack. */ 765 | yaml_node_pair_t *top; 766 | } pairs; 767 | /** The mapping style. */ 768 | yaml_mapping_style_t style; 769 | } mapping; 770 | 771 | } data; 772 | 773 | /** The beginning of the node. */ 774 | yaml_mark_t start_mark; 775 | /** The end of the node. */ 776 | yaml_mark_t end_mark; 777 | 778 | }; 779 | 780 | /** The document structure. */ 781 | typedef struct yaml_document_s { 782 | 783 | /** The document nodes. */ 784 | struct { 785 | /** The beginning of the stack. */ 786 | yaml_node_t *start; 787 | /** The end of the stack. */ 788 | yaml_node_t *end; 789 | /** The top of the stack. */ 790 | yaml_node_t *top; 791 | } nodes; 792 | 793 | /** The version directive. */ 794 | yaml_version_directive_t *version_directive; 795 | 796 | /** The list of tag directives. */ 797 | struct { 798 | /** The beginning of the tag directives list. */ 799 | yaml_tag_directive_t *start; 800 | /** The end of the tag directives list. */ 801 | yaml_tag_directive_t *end; 802 | } tag_directives; 803 | 804 | /** Is the document start indicator implicit? */ 805 | int start_implicit; 806 | /** Is the document end indicator implicit? */ 807 | int end_implicit; 808 | 809 | /** The beginning of the document. */ 810 | yaml_mark_t start_mark; 811 | /** The end of the document. */ 812 | yaml_mark_t end_mark; 813 | 814 | } yaml_document_t; 815 | 816 | /** 817 | * Create a YAML document. 818 | * 819 | * @param[out] document An empty document object. 820 | * @param[in] version_directive The %YAML directive value or 821 | * @c NULL. 822 | * @param[in] tag_directives_start The beginning of the %TAG 823 | * directives list. 824 | * @param[in] tag_directives_end The end of the %TAG directives 825 | * list. 826 | * @param[in] start_implicit If the document start indicator is 827 | * implicit. 828 | * @param[in] end_implicit If the document end indicator is 829 | * implicit. 830 | * 831 | * @returns @c 1 if the function succeeded, @c 0 on error. 832 | */ 833 | 834 | YAML_DECLARE(int) 835 | yaml_document_initialize(yaml_document_t *document, 836 | yaml_version_directive_t *version_directive, 837 | yaml_tag_directive_t *tag_directives_start, 838 | yaml_tag_directive_t *tag_directives_end, 839 | int start_implicit, int end_implicit); 840 | 841 | /** 842 | * Delete a YAML document and all its nodes. 843 | * 844 | * @param[in,out] document A document object. 845 | */ 846 | 847 | YAML_DECLARE(void) 848 | yaml_document_delete(yaml_document_t *document); 849 | 850 | /** 851 | * Get a node of a YAML document. 852 | * 853 | * The pointer returned by this function is valid until any of the functions 854 | * modifying the documents are called. 855 | * 856 | * @param[in] document A document object. 857 | * @param[in] index The node id. 858 | * 859 | * @returns the node objct or @c NULL if @c node_id is out of range. 860 | */ 861 | 862 | YAML_DECLARE(yaml_node_t *) 863 | yaml_document_get_node(yaml_document_t *document, int index); 864 | 865 | /** 866 | * Get the root of a YAML document node. 867 | * 868 | * The root object is the first object added to the document. 869 | * 870 | * The pointer returned by this function is valid until any of the functions 871 | * modifying the documents are called. 872 | * 873 | * An empty document produced by the parser signifies the end of a YAML 874 | * stream. 875 | * 876 | * @param[in] document A document object. 877 | * 878 | * @returns the node object or @c NULL if the document is empty. 879 | */ 880 | 881 | YAML_DECLARE(yaml_node_t *) 882 | yaml_document_get_root_node(yaml_document_t *document); 883 | 884 | /** 885 | * Create a SCALAR node and attach it to the document. 886 | * 887 | * The @a style argument may be ignored by the emitter. 888 | * 889 | * @param[in,out] document A document object. 890 | * @param[in] tag The scalar tag. 891 | * @param[in] value The scalar value. 892 | * @param[in] length The length of the scalar value. 893 | * @param[in] style The scalar style. 894 | * 895 | * @returns the node id or @c 0 on error. 896 | */ 897 | 898 | YAML_DECLARE(int) 899 | yaml_document_add_scalar(yaml_document_t *document, 900 | yaml_char_t *tag, yaml_char_t *value, int length, 901 | yaml_scalar_style_t style); 902 | 903 | /** 904 | * Create a SEQUENCE node and attach it to the document. 905 | * 906 | * The @a style argument may be ignored by the emitter. 907 | * 908 | * @param[in,out] document A document object. 909 | * @param[in] tag The sequence tag. 910 | * @param[in] style The sequence style. 911 | * 912 | * @returns the node id or @c 0 on error. 913 | */ 914 | 915 | YAML_DECLARE(int) 916 | yaml_document_add_sequence(yaml_document_t *document, 917 | yaml_char_t *tag, yaml_sequence_style_t style); 918 | 919 | /** 920 | * Create a MAPPING node and attach it to the document. 921 | * 922 | * The @a style argument may be ignored by the emitter. 923 | * 924 | * @param[in,out] document A document object. 925 | * @param[in] tag The sequence tag. 926 | * @param[in] style The sequence style. 927 | * 928 | * @returns the node id or @c 0 on error. 929 | */ 930 | 931 | YAML_DECLARE(int) 932 | yaml_document_add_mapping(yaml_document_t *document, 933 | yaml_char_t *tag, yaml_mapping_style_t style); 934 | 935 | /** 936 | * Add an item to a SEQUENCE node. 937 | * 938 | * @param[in,out] document A document object. 939 | * @param[in] sequence The sequence node id. 940 | * @param[in] item The item node id. 941 | * 942 | * @returns @c 1 if the function succeeded, @c 0 on error. 943 | */ 944 | 945 | YAML_DECLARE(int) 946 | yaml_document_append_sequence_item(yaml_document_t *document, 947 | int sequence, int item); 948 | 949 | /** 950 | * Add a pair of a key and a value to a MAPPING node. 951 | * 952 | * @param[in,out] document A document object. 953 | * @param[in] mapping The mapping node id. 954 | * @param[in] key The key node id. 955 | * @param[in] value The value node id. 956 | * 957 | * @returns @c 1 if the function succeeded, @c 0 on error. 958 | */ 959 | 960 | YAML_DECLARE(int) 961 | yaml_document_append_mapping_pair(yaml_document_t *document, 962 | int mapping, int key, int value); 963 | 964 | /** @} */ 965 | 966 | /** 967 | * @defgroup parser YAMLParser Definitions 968 | * @{ 969 | */ 970 | 971 | /** 972 | * The prototype of a read handler. 973 | * 974 | * The read handler is called when the parser needs to read more bytes from the 975 | * source. The handler should write not more than @a size bytes to the @a 976 | * buffer. The number of written bytes should be set to the @a length variable. 977 | * 978 | * @param[in,out] data A pointer to an application data specified by 979 | * yaml_parser_set_input(). 980 | * @param[out] buffer The buffer to write the data from the source. 981 | * @param[in] size The size of the buffer. 982 | * @param[out] size_read The actual number of bytes read from the source. 983 | * 984 | * @returns On success, the handler should return @c 1. If the handler failed, 985 | * the returned value should be @c 0. On EOF, the handler should set the 986 | * @a size_read to @c 0 and return @c 1. 987 | */ 988 | 989 | typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, 990 | size_t *size_read); 991 | 992 | /** 993 | * This structure holds information about a potential simple key. 994 | */ 995 | 996 | typedef struct yaml_simple_key_s { 997 | /** Is a simple key possible? */ 998 | int possible; 999 | 1000 | /** Is a simple key required? */ 1001 | int required; 1002 | 1003 | /** The number of the token. */ 1004 | size_t token_number; 1005 | 1006 | /** The position mark. */ 1007 | yaml_mark_t mark; 1008 | } yaml_simple_key_t; 1009 | 1010 | /** 1011 | * The states of the parser. 1012 | */ 1013 | typedef enum yaml_parser_state_e { 1014 | /** Expect STREAM-START. */ 1015 | YAML_PARSE_STREAM_START_STATE, 1016 | /** Expect the beginning of an implicit document. */ 1017 | YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, 1018 | /** Expect DOCUMENT-START. */ 1019 | YAML_PARSE_DOCUMENT_START_STATE, 1020 | /** Expect the content of a document. */ 1021 | YAML_PARSE_DOCUMENT_CONTENT_STATE, 1022 | /** Expect DOCUMENT-END. */ 1023 | YAML_PARSE_DOCUMENT_END_STATE, 1024 | /** Expect a block node. */ 1025 | YAML_PARSE_BLOCK_NODE_STATE, 1026 | /** Expect a block node or indentless sequence. */ 1027 | YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, 1028 | /** Expect a flow node. */ 1029 | YAML_PARSE_FLOW_NODE_STATE, 1030 | /** Expect the first entry of a block sequence. */ 1031 | YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, 1032 | /** Expect an entry of a block sequence. */ 1033 | YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, 1034 | /** Expect an entry of an indentless sequence. */ 1035 | YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, 1036 | /** Expect the first key of a block mapping. */ 1037 | YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, 1038 | /** Expect a block mapping key. */ 1039 | YAML_PARSE_BLOCK_MAPPING_KEY_STATE, 1040 | /** Expect a block mapping value. */ 1041 | YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, 1042 | /** Expect the first entry of a flow sequence. */ 1043 | YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, 1044 | /** Expect an entry of a flow sequence. */ 1045 | YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, 1046 | /** Expect a key of an ordered mapping. */ 1047 | YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, 1048 | /** Expect a value of an ordered mapping. */ 1049 | YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, 1050 | /** Expect the and of an ordered mapping entry. */ 1051 | YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, 1052 | /** Expect the first key of a flow mapping. */ 1053 | YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, 1054 | /** Expect a key of a flow mapping. */ 1055 | YAML_PARSE_FLOW_MAPPING_KEY_STATE, 1056 | /** Expect a value of a flow mapping. */ 1057 | YAML_PARSE_FLOW_MAPPING_VALUE_STATE, 1058 | /** Expect an empty value of a flow mapping. */ 1059 | YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, 1060 | /** Expect nothing. */ 1061 | YAML_PARSE_END_STATE 1062 | } yaml_parser_state_t; 1063 | 1064 | /** 1065 | * This structure holds aliases data. 1066 | */ 1067 | 1068 | typedef struct yaml_alias_data_s { 1069 | /** The anchor. */ 1070 | yaml_char_t *anchor; 1071 | /** The node id. */ 1072 | int index; 1073 | /** The anchor mark. */ 1074 | yaml_mark_t mark; 1075 | } yaml_alias_data_t; 1076 | 1077 | /** 1078 | * The parser structure. 1079 | * 1080 | * All members are internal. Manage the structure using the @c yaml_parser_ 1081 | * family of functions. 1082 | */ 1083 | 1084 | typedef struct yaml_parser_s { 1085 | 1086 | /** 1087 | * @name Error handling 1088 | * @{ 1089 | */ 1090 | 1091 | /** Error type. */ 1092 | yaml_error_type_t error; 1093 | /** Error description. */ 1094 | const char *problem; 1095 | /** The byte about which the problem occured. */ 1096 | size_t problem_offset; 1097 | /** The problematic value (@c -1 is none). */ 1098 | int problem_value; 1099 | /** The problem position. */ 1100 | yaml_mark_t problem_mark; 1101 | /** The error context. */ 1102 | const char *context; 1103 | /** The context position. */ 1104 | yaml_mark_t context_mark; 1105 | 1106 | /** 1107 | * @} 1108 | */ 1109 | 1110 | /** 1111 | * @name Reader stuff 1112 | * @{ 1113 | */ 1114 | 1115 | /** Read handler. */ 1116 | yaml_read_handler_t *read_handler; 1117 | 1118 | /** A pointer for passing to the read handler. */ 1119 | void *read_handler_data; 1120 | 1121 | /** Standard (string or file) input data. */ 1122 | union { 1123 | /** String input data. */ 1124 | struct { 1125 | /** The string start pointer. */ 1126 | const unsigned char *start; 1127 | /** The string end pointer. */ 1128 | const unsigned char *end; 1129 | /** The string current position. */ 1130 | const unsigned char *current; 1131 | } string; 1132 | 1133 | /** File input data. */ 1134 | FILE *file; 1135 | } input; 1136 | 1137 | /** EOF flag */ 1138 | int eof; 1139 | 1140 | /** The working buffer. */ 1141 | struct { 1142 | /** The beginning of the buffer. */ 1143 | yaml_char_t *start; 1144 | /** The end of the buffer. */ 1145 | yaml_char_t *end; 1146 | /** The current position of the buffer. */ 1147 | yaml_char_t *pointer; 1148 | /** The last filled position of the buffer. */ 1149 | yaml_char_t *last; 1150 | } buffer; 1151 | 1152 | /* The number of unread characters in the buffer. */ 1153 | size_t unread; 1154 | 1155 | /** The raw buffer. */ 1156 | struct { 1157 | /** The beginning of the buffer. */ 1158 | unsigned char *start; 1159 | /** The end of the buffer. */ 1160 | unsigned char *end; 1161 | /** The current position of the buffer. */ 1162 | unsigned char *pointer; 1163 | /** The last filled position of the buffer. */ 1164 | unsigned char *last; 1165 | } raw_buffer; 1166 | 1167 | /** The input encoding. */ 1168 | yaml_encoding_t encoding; 1169 | 1170 | /** The offset of the current position (in bytes). */ 1171 | size_t offset; 1172 | 1173 | /** The mark of the current position. */ 1174 | yaml_mark_t mark; 1175 | 1176 | /** 1177 | * @} 1178 | */ 1179 | 1180 | /** 1181 | * @name Scanner stuff 1182 | * @{ 1183 | */ 1184 | 1185 | /** Have we started to scan the input stream? */ 1186 | int stream_start_produced; 1187 | 1188 | /** Have we reached the end of the input stream? */ 1189 | int stream_end_produced; 1190 | 1191 | /** The number of unclosed '[' and '{' indicators. */ 1192 | int flow_level; 1193 | 1194 | /** The tokens queue. */ 1195 | struct { 1196 | /** The beginning of the tokens queue. */ 1197 | yaml_token_t *start; 1198 | /** The end of the tokens queue. */ 1199 | yaml_token_t *end; 1200 | /** The head of the tokens queue. */ 1201 | yaml_token_t *head; 1202 | /** The tail of the tokens queue. */ 1203 | yaml_token_t *tail; 1204 | } tokens; 1205 | 1206 | /** The number of tokens fetched from the queue. */ 1207 | size_t tokens_parsed; 1208 | 1209 | /* Does the tokens queue contain a token ready for dequeueing. */ 1210 | int token_available; 1211 | 1212 | /** The indentation levels stack. */ 1213 | struct { 1214 | /** The beginning of the stack. */ 1215 | int *start; 1216 | /** The end of the stack. */ 1217 | int *end; 1218 | /** The top of the stack. */ 1219 | int *top; 1220 | } indents; 1221 | 1222 | /** The current indentation level. */ 1223 | int indent; 1224 | 1225 | /** May a simple key occur at the current position? */ 1226 | int simple_key_allowed; 1227 | 1228 | /** The stack of simple keys. */ 1229 | struct { 1230 | /** The beginning of the stack. */ 1231 | yaml_simple_key_t *start; 1232 | /** The end of the stack. */ 1233 | yaml_simple_key_t *end; 1234 | /** The top of the stack. */ 1235 | yaml_simple_key_t *top; 1236 | } simple_keys; 1237 | 1238 | /** 1239 | * @} 1240 | */ 1241 | 1242 | /** 1243 | * @name YAMLParser stuff 1244 | * @{ 1245 | */ 1246 | 1247 | /** The parser states stack. */ 1248 | struct { 1249 | /** The beginning of the stack. */ 1250 | yaml_parser_state_t *start; 1251 | /** The end of the stack. */ 1252 | yaml_parser_state_t *end; 1253 | /** The top of the stack. */ 1254 | yaml_parser_state_t *top; 1255 | } states; 1256 | 1257 | /** The current parser state. */ 1258 | yaml_parser_state_t state; 1259 | 1260 | /** The stack of marks. */ 1261 | struct { 1262 | /** The beginning of the stack. */ 1263 | yaml_mark_t *start; 1264 | /** The end of the stack. */ 1265 | yaml_mark_t *end; 1266 | /** The top of the stack. */ 1267 | yaml_mark_t *top; 1268 | } marks; 1269 | 1270 | /** The list of TAG directives. */ 1271 | struct { 1272 | /** The beginning of the list. */ 1273 | yaml_tag_directive_t *start; 1274 | /** The end of the list. */ 1275 | yaml_tag_directive_t *end; 1276 | /** The top of the list. */ 1277 | yaml_tag_directive_t *top; 1278 | } tag_directives; 1279 | 1280 | /** 1281 | * @} 1282 | */ 1283 | 1284 | /** 1285 | * @name Dumper stuff 1286 | * @{ 1287 | */ 1288 | 1289 | /** The alias data. */ 1290 | struct { 1291 | /** The beginning of the list. */ 1292 | yaml_alias_data_t *start; 1293 | /** The end of the list. */ 1294 | yaml_alias_data_t *end; 1295 | /** The top of the list. */ 1296 | yaml_alias_data_t *top; 1297 | } aliases; 1298 | 1299 | /** The currently parsed document. */ 1300 | yaml_document_t *document; 1301 | 1302 | /** 1303 | * @} 1304 | */ 1305 | 1306 | } yaml_parser_t; 1307 | 1308 | /** 1309 | * Initialize a parser. 1310 | * 1311 | * This function creates a new parser object. An application is responsible 1312 | * for destroying the object using the yaml_parser_delete() function. 1313 | * 1314 | * @param[out] parser An empty parser object. 1315 | * 1316 | * @returns @c 1 if the function succeeded, @c 0 on error. 1317 | */ 1318 | 1319 | YAML_DECLARE(int) 1320 | yaml_parser_initialize(yaml_parser_t *parser); 1321 | 1322 | /** 1323 | * Destroy a parser. 1324 | * 1325 | * @param[in,out] parser A parser object. 1326 | */ 1327 | 1328 | YAML_DECLARE(void) 1329 | yaml_parser_delete(yaml_parser_t *parser); 1330 | 1331 | /** 1332 | * Set a string input. 1333 | * 1334 | * Note that the @a input pointer must be valid while the @a parser object 1335 | * exists. The application is responsible for destroing @a input after 1336 | * destroying the @a parser. 1337 | * 1338 | * @param[in,out] parser A parser object. 1339 | * @param[in] input A source data. 1340 | * @param[in] size The length of the source data in bytes. 1341 | */ 1342 | 1343 | YAML_DECLARE(void) 1344 | yaml_parser_set_input_string(yaml_parser_t *parser, 1345 | const unsigned char *input, size_t size); 1346 | 1347 | /** 1348 | * Set a file input. 1349 | * 1350 | * @a file should be a file object open for reading. The application is 1351 | * responsible for closing the @a file. 1352 | * 1353 | * @param[in,out] parser A parser object. 1354 | * @param[in] file An open file. 1355 | */ 1356 | 1357 | YAML_DECLARE(void) 1358 | yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); 1359 | 1360 | /** 1361 | * Set a generic input handler. 1362 | * 1363 | * @param[in,out] parser A parser object. 1364 | * @param[in] handler A read handler. 1365 | * @param[in] data Any application data for passing to the read 1366 | * handler. 1367 | */ 1368 | 1369 | YAML_DECLARE(void) 1370 | yaml_parser_set_input(yaml_parser_t *parser, 1371 | yaml_read_handler_t *handler, void *data); 1372 | 1373 | /** 1374 | * Set the source encoding. 1375 | * 1376 | * @param[in,out] parser A parser object. 1377 | * @param[in] encoding The source encoding. 1378 | */ 1379 | 1380 | YAML_DECLARE(void) 1381 | yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); 1382 | 1383 | /** 1384 | * Scan the input stream and produce the next token. 1385 | * 1386 | * Call the function subsequently to produce a sequence of tokens corresponding 1387 | * to the input stream. The initial token has the type 1388 | * @c YAML_STREAM_START_TOKEN while the ending token has the type 1389 | * @c YAML_STREAM_END_TOKEN. 1390 | * 1391 | * An application is responsible for freeing any buffers associated with the 1392 | * produced token object using the @c yaml_token_delete function. 1393 | * 1394 | * An application must not alternate the calls of yaml_parser_scan() with the 1395 | * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break 1396 | * the parser. 1397 | * 1398 | * @param[in,out] parser A parser object. 1399 | * @param[out] token An empty token object. 1400 | * 1401 | * @returns @c 1 if the function succeeded, @c 0 on error. 1402 | */ 1403 | 1404 | YAML_DECLARE(int) 1405 | yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); 1406 | 1407 | /** 1408 | * Parse the input stream and produce the next parsing event. 1409 | * 1410 | * Call the function subsequently to produce a sequence of events corresponding 1411 | * to the input stream. The initial event has the type 1412 | * @c YAML_STREAM_START_EVENT while the ending event has the type 1413 | * @c YAML_STREAM_END_EVENT. 1414 | * 1415 | * An application is responsible for freeing any buffers associated with the 1416 | * produced event object using the yaml_event_delete() function. 1417 | * 1418 | * An application must not alternate the calls of yaml_parser_parse() with the 1419 | * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the 1420 | * parser. 1421 | * 1422 | * @param[in,out] parser A parser object. 1423 | * @param[out] event An empty event object. 1424 | * 1425 | * @returns @c 1 if the function succeeded, @c 0 on error. 1426 | */ 1427 | 1428 | YAML_DECLARE(int) 1429 | yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); 1430 | 1431 | /** 1432 | * Parse the input stream and produce the next YAML document. 1433 | * 1434 | * Call this function subsequently to produce a sequence of documents 1435 | * constituting the input stream. 1436 | * 1437 | * If the produced document has no root node, it means that the document 1438 | * end has been reached. 1439 | * 1440 | * An application is responsible for freeing any data associated with the 1441 | * produced document object using the yaml_document_delete() function. 1442 | * 1443 | * An application must not alternate the calls of yaml_parser_load() with the 1444 | * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break 1445 | * the parser. 1446 | * 1447 | * @param[in,out] parser A parser object. 1448 | * @param[out] document An empty document object. 1449 | * 1450 | * @return @c 1 if the function succeeded, @c 0 on error. 1451 | */ 1452 | 1453 | YAML_DECLARE(int) 1454 | yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); 1455 | 1456 | /** @} */ 1457 | 1458 | /** 1459 | * @defgroup emitter YAMLEmitter Definitions 1460 | * @{ 1461 | */ 1462 | 1463 | /** 1464 | * The prototype of a write handler. 1465 | * 1466 | * The write handler is called when the emitter needs to flush the accumulated 1467 | * characters to the output. The handler should write @a size bytes of the 1468 | * @a buffer to the output. 1469 | * 1470 | * @param[in,out] data A pointer to an application data specified by 1471 | * yaml_emitter_set_output(). 1472 | * @param[in] buffer The buffer with bytes to be written. 1473 | * @param[in] size The size of the buffer. 1474 | * 1475 | * @returns On success, the handler should return @c 1. If the handler failed, 1476 | * the returned value should be @c 0. 1477 | */ 1478 | 1479 | typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size); 1480 | 1481 | /** The emitter states. */ 1482 | typedef enum yaml_emitter_state_e { 1483 | /** Expect STREAM-START. */ 1484 | YAML_EMIT_STREAM_START_STATE, 1485 | /** Expect the first DOCUMENT-START or STREAM-END. */ 1486 | YAML_EMIT_FIRST_DOCUMENT_START_STATE, 1487 | /** Expect DOCUMENT-START or STREAM-END. */ 1488 | YAML_EMIT_DOCUMENT_START_STATE, 1489 | /** Expect the content of a document. */ 1490 | YAML_EMIT_DOCUMENT_CONTENT_STATE, 1491 | /** Expect DOCUMENT-END. */ 1492 | YAML_EMIT_DOCUMENT_END_STATE, 1493 | /** Expect the first item of a flow sequence. */ 1494 | YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, 1495 | /** Expect an item of a flow sequence. */ 1496 | YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, 1497 | /** Expect the first key of a flow mapping. */ 1498 | YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, 1499 | /** Expect a key of a flow mapping. */ 1500 | YAML_EMIT_FLOW_MAPPING_KEY_STATE, 1501 | /** Expect a value for a simple key of a flow mapping. */ 1502 | YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, 1503 | /** Expect a value of a flow mapping. */ 1504 | YAML_EMIT_FLOW_MAPPING_VALUE_STATE, 1505 | /** Expect the first item of a block sequence. */ 1506 | YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, 1507 | /** Expect an item of a block sequence. */ 1508 | YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, 1509 | /** Expect the first key of a block mapping. */ 1510 | YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, 1511 | /** Expect the key of a block mapping. */ 1512 | YAML_EMIT_BLOCK_MAPPING_KEY_STATE, 1513 | /** Expect a value for a simple key of a block mapping. */ 1514 | YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, 1515 | /** Expect a value of a block mapping. */ 1516 | YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, 1517 | /** Expect nothing. */ 1518 | YAML_EMIT_END_STATE 1519 | } yaml_emitter_state_t; 1520 | 1521 | /** 1522 | * The emitter structure. 1523 | * 1524 | * All members are internal. Manage the structure using the @c yaml_emitter_ 1525 | * family of functions. 1526 | */ 1527 | 1528 | typedef struct yaml_emitter_s { 1529 | 1530 | /** 1531 | * @name Error handling 1532 | * @{ 1533 | */ 1534 | 1535 | /** Error type. */ 1536 | yaml_error_type_t error; 1537 | /** Error description. */ 1538 | const char *problem; 1539 | 1540 | /** 1541 | * @} 1542 | */ 1543 | 1544 | /** 1545 | * @name Writer stuff 1546 | * @{ 1547 | */ 1548 | 1549 | /** Write handler. */ 1550 | yaml_write_handler_t *write_handler; 1551 | 1552 | /** A pointer for passing to the white handler. */ 1553 | void *write_handler_data; 1554 | 1555 | /** Standard (string or file) output data. */ 1556 | union { 1557 | /** String output data. */ 1558 | struct { 1559 | /** The buffer pointer. */ 1560 | unsigned char *buffer; 1561 | /** The buffer size. */ 1562 | size_t size; 1563 | /** The number of written bytes. */ 1564 | size_t *size_written; 1565 | } string; 1566 | 1567 | /** File output data. */ 1568 | FILE *file; 1569 | } output; 1570 | 1571 | /** The working buffer. */ 1572 | struct { 1573 | /** The beginning of the buffer. */ 1574 | yaml_char_t *start; 1575 | /** The end of the buffer. */ 1576 | yaml_char_t *end; 1577 | /** The current position of the buffer. */ 1578 | yaml_char_t *pointer; 1579 | /** The last filled position of the buffer. */ 1580 | yaml_char_t *last; 1581 | } buffer; 1582 | 1583 | /** The raw buffer. */ 1584 | struct { 1585 | /** The beginning of the buffer. */ 1586 | unsigned char *start; 1587 | /** The end of the buffer. */ 1588 | unsigned char *end; 1589 | /** The current position of the buffer. */ 1590 | unsigned char *pointer; 1591 | /** The last filled position of the buffer. */ 1592 | unsigned char *last; 1593 | } raw_buffer; 1594 | 1595 | /** The stream encoding. */ 1596 | yaml_encoding_t encoding; 1597 | 1598 | /** 1599 | * @} 1600 | */ 1601 | 1602 | /** 1603 | * @name YAMLEmitter stuff 1604 | * @{ 1605 | */ 1606 | 1607 | /** If the output is in the canonical style? */ 1608 | int canonical; 1609 | /** The number of indentation spaces. */ 1610 | int best_indent; 1611 | /** The preferred width of the output lines. */ 1612 | int best_width; 1613 | /** Allow unescaped non-ASCII characters? */ 1614 | int unicode; 1615 | /** The preferred line break. */ 1616 | yaml_break_t line_break; 1617 | 1618 | /** The stack of states. */ 1619 | struct { 1620 | /** The beginning of the stack. */ 1621 | yaml_emitter_state_t *start; 1622 | /** The end of the stack. */ 1623 | yaml_emitter_state_t *end; 1624 | /** The top of the stack. */ 1625 | yaml_emitter_state_t *top; 1626 | } states; 1627 | 1628 | /** The current emitter state. */ 1629 | yaml_emitter_state_t state; 1630 | 1631 | /** The event queue. */ 1632 | struct { 1633 | /** The beginning of the event queue. */ 1634 | yaml_event_t *start; 1635 | /** The end of the event queue. */ 1636 | yaml_event_t *end; 1637 | /** The head of the event queue. */ 1638 | yaml_event_t *head; 1639 | /** The tail of the event queue. */ 1640 | yaml_event_t *tail; 1641 | } events; 1642 | 1643 | /** The stack of indentation levels. */ 1644 | struct { 1645 | /** The beginning of the stack. */ 1646 | int *start; 1647 | /** The end of the stack. */ 1648 | int *end; 1649 | /** The top of the stack. */ 1650 | int *top; 1651 | } indents; 1652 | 1653 | /** The list of tag directives. */ 1654 | struct { 1655 | /** The beginning of the list. */ 1656 | yaml_tag_directive_t *start; 1657 | /** The end of the list. */ 1658 | yaml_tag_directive_t *end; 1659 | /** The top of the list. */ 1660 | yaml_tag_directive_t *top; 1661 | } tag_directives; 1662 | 1663 | /** The current indentation level. */ 1664 | int indent; 1665 | 1666 | /** The current flow level. */ 1667 | int flow_level; 1668 | 1669 | /** Is it the document root context? */ 1670 | int root_context; 1671 | /** Is it a sequence context? */ 1672 | int sequence_context; 1673 | /** Is it a mapping context? */ 1674 | int mapping_context; 1675 | /** Is it a simple mapping key context? */ 1676 | int simple_key_context; 1677 | 1678 | /** The current line. */ 1679 | int line; 1680 | /** The current column. */ 1681 | int column; 1682 | /** If the last character was a whitespace? */ 1683 | int whitespace; 1684 | /** If the last character was an indentation character (' ', '-', '?', ':')? */ 1685 | int indention; 1686 | /** If an explicit document end is required? */ 1687 | int open_ended; 1688 | 1689 | /** Anchor analysis. */ 1690 | struct { 1691 | /** The anchor value. */ 1692 | yaml_char_t *anchor; 1693 | /** The anchor length. */ 1694 | size_t anchor_length; 1695 | /** Is it an alias? */ 1696 | int alias; 1697 | } anchor_data; 1698 | 1699 | /** YAMLTag analysis. */ 1700 | struct { 1701 | /** The tag handle. */ 1702 | yaml_char_t *handle; 1703 | /** The tag handle length. */ 1704 | size_t handle_length; 1705 | /** The tag suffix. */ 1706 | yaml_char_t *suffix; 1707 | /** The tag suffix length. */ 1708 | size_t suffix_length; 1709 | } tag_data; 1710 | 1711 | /** Scalar analysis. */ 1712 | struct { 1713 | /** The scalar value. */ 1714 | yaml_char_t *value; 1715 | /** The scalar length. */ 1716 | size_t length; 1717 | /** Does the scalar contain line breaks? */ 1718 | int multiline; 1719 | /** Can the scalar be expessed in the flow plain style? */ 1720 | int flow_plain_allowed; 1721 | /** Can the scalar be expressed in the block plain style? */ 1722 | int block_plain_allowed; 1723 | /** Can the scalar be expressed in the single quoted style? */ 1724 | int single_quoted_allowed; 1725 | /** Can the scalar be expressed in the literal or folded styles? */ 1726 | int block_allowed; 1727 | /** The output style. */ 1728 | yaml_scalar_style_t style; 1729 | } scalar_data; 1730 | 1731 | /** 1732 | * @} 1733 | */ 1734 | 1735 | /** 1736 | * @name Dumper stuff 1737 | * @{ 1738 | */ 1739 | 1740 | /** If the stream was already opened? */ 1741 | int opened; 1742 | /** If the stream was already closed? */ 1743 | int closed; 1744 | 1745 | /** The information associated with the document nodes. */ 1746 | struct { 1747 | /** The number of references. */ 1748 | int references; 1749 | /** The anchor id. */ 1750 | int anchor; 1751 | /** If the node has been emitted? */ 1752 | int serialized; 1753 | } *anchors; 1754 | 1755 | /** The last assigned anchor id. */ 1756 | int last_anchor_id; 1757 | 1758 | /** The currently emitted document. */ 1759 | yaml_document_t *document; 1760 | 1761 | /** 1762 | * @} 1763 | */ 1764 | 1765 | } yaml_emitter_t; 1766 | 1767 | /** 1768 | * Initialize an emitter. 1769 | * 1770 | * This function creates a new emitter object. An application is responsible 1771 | * for destroying the object using the yaml_emitter_delete() function. 1772 | * 1773 | * @param[out] emitter An empty parser object. 1774 | * 1775 | * @returns @c 1 if the function succeeded, @c 0 on error. 1776 | */ 1777 | 1778 | YAML_DECLARE(int) 1779 | yaml_emitter_initialize(yaml_emitter_t *emitter); 1780 | 1781 | /** 1782 | * Destroy an emitter. 1783 | * 1784 | * @param[in,out] emitter An emitter object. 1785 | */ 1786 | 1787 | YAML_DECLARE(void) 1788 | yaml_emitter_delete(yaml_emitter_t *emitter); 1789 | 1790 | /** 1791 | * Set a string output. 1792 | * 1793 | * The emitter will write the output characters to the @a output buffer of the 1794 | * size @a size. The emitter will set @a size_written to the number of written 1795 | * bytes. If the buffer is smaller than required, the emitter produces the 1796 | * YAML_WRITE_ERROR error. 1797 | * 1798 | * @param[in,out] emitter An emitter object. 1799 | * @param[in] output An output buffer. 1800 | * @param[in] size The buffer size. 1801 | * @param[in] size_written The pointer to save the number of written 1802 | * bytes. 1803 | */ 1804 | 1805 | YAML_DECLARE(void) 1806 | yaml_emitter_set_output_string(yaml_emitter_t *emitter, 1807 | unsigned char *output, size_t size, size_t *size_written); 1808 | 1809 | /** 1810 | * Set a file output. 1811 | * 1812 | * @a file should be a file object open for writing. The application is 1813 | * responsible for closing the @a file. 1814 | * 1815 | * @param[in,out] emitter An emitter object. 1816 | * @param[in] file An open file. 1817 | */ 1818 | 1819 | YAML_DECLARE(void) 1820 | yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file); 1821 | 1822 | /** 1823 | * Set a generic output handler. 1824 | * 1825 | * @param[in,out] emitter An emitter object. 1826 | * @param[in] handler A write handler. 1827 | * @param[in] data Any application data for passing to the write 1828 | * handler. 1829 | */ 1830 | 1831 | YAML_DECLARE(void) 1832 | yaml_emitter_set_output(yaml_emitter_t *emitter, 1833 | yaml_write_handler_t *handler, void *data); 1834 | 1835 | /** 1836 | * Set the output encoding. 1837 | * 1838 | * @param[in,out] emitter An emitter object. 1839 | * @param[in] encoding The output encoding. 1840 | */ 1841 | 1842 | YAML_DECLARE(void) 1843 | yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding); 1844 | 1845 | /** 1846 | * Set if the output should be in the "canonical" format as in the YAML 1847 | * specification. 1848 | * 1849 | * @param[in,out] emitter An emitter object. 1850 | * @param[in] canonical If the output is canonical. 1851 | */ 1852 | 1853 | YAML_DECLARE(void) 1854 | yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical); 1855 | 1856 | /** 1857 | * Set the intendation increment. 1858 | * 1859 | * @param[in,out] emitter An emitter object. 1860 | * @param[in] indent The indentation increment (1 < . < 10). 1861 | */ 1862 | 1863 | YAML_DECLARE(void) 1864 | yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent); 1865 | 1866 | /** 1867 | * Set the preferred line width. @c -1 means unlimited. 1868 | * 1869 | * @param[in,out] emitter An emitter object. 1870 | * @param[in] width The preferred line width. 1871 | */ 1872 | 1873 | YAML_DECLARE(void) 1874 | yaml_emitter_set_width(yaml_emitter_t *emitter, int width); 1875 | 1876 | /** 1877 | * Set if unescaped non-ASCII characters are allowed. 1878 | * 1879 | * @param[in,out] emitter An emitter object. 1880 | * @param[in] unicode If unescaped Unicode characters are allowed. 1881 | */ 1882 | 1883 | YAML_DECLARE(void) 1884 | yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode); 1885 | 1886 | /** 1887 | * Set the preferred line break. 1888 | * 1889 | * @param[in,out] emitter An emitter object. 1890 | * @param[in] line_break The preferred line break. 1891 | */ 1892 | 1893 | YAML_DECLARE(void) 1894 | yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); 1895 | 1896 | /** 1897 | * Emit an event. 1898 | * 1899 | * The event object may be generated using the yaml_parser_parse() function. 1900 | * The emitter takes the responsibility for the event object and destroys its 1901 | * content after it is emitted. The event object is destroyed even if the 1902 | * function fails. 1903 | * 1904 | * @param[in,out] emitter An emitter object. 1905 | * @param[in,out] event An event object. 1906 | * 1907 | * @returns @c 1 if the function succeeded, @c 0 on error. 1908 | */ 1909 | 1910 | YAML_DECLARE(int) 1911 | yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); 1912 | 1913 | /** 1914 | * Start a YAML stream. 1915 | * 1916 | * This function should be used before yaml_emitter_dump() is called. 1917 | * 1918 | * @param[in,out] emitter An emitter object. 1919 | * 1920 | * @returns @c 1 if the function succeeded, @c 0 on error. 1921 | */ 1922 | 1923 | YAML_DECLARE(int) 1924 | yaml_emitter_open(yaml_emitter_t *emitter); 1925 | 1926 | /** 1927 | * Finish a YAML stream. 1928 | * 1929 | * This function should be used after yaml_emitter_dump() is called. 1930 | * 1931 | * @param[in,out] emitter An emitter object. 1932 | * 1933 | * @returns @c 1 if the function succeeded, @c 0 on error. 1934 | */ 1935 | 1936 | YAML_DECLARE(int) 1937 | yaml_emitter_close(yaml_emitter_t *emitter); 1938 | 1939 | /** 1940 | * Emit a YAML document. 1941 | * 1942 | * The documen object may be generated using the yaml_parser_load() function 1943 | * or the yaml_document_initialize() function. The emitter takes the 1944 | * responsibility for the document object and destoys its content after 1945 | * it is emitted. The document object is destroyedeven if the function fails. 1946 | * 1947 | * @param[in,out] emitter An emitter object. 1948 | * @param[in,out] document A document object. 1949 | * 1950 | * @returns @c 1 if the function succeeded, @c 0 on error. 1951 | */ 1952 | 1953 | YAML_DECLARE(int) 1954 | yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); 1955 | 1956 | /** 1957 | * Flush the accumulated characters to the output. 1958 | * 1959 | * @param[in,out] emitter An emitter object. 1960 | * 1961 | * @returns @c 1 if the function succeeded, @c 0 on error. 1962 | */ 1963 | 1964 | YAML_DECLARE(int) 1965 | yaml_emitter_flush(yaml_emitter_t *emitter); 1966 | 1967 | /** @} */ 1968 | 1969 | #ifdef __cplusplus 1970 | } 1971 | #endif 1972 | 1973 | #endif /* #ifndef YAML_H */ 1974 | //#endif /* #ifdef RENDER_MOD_STYLESHEET */ 1975 | -------------------------------------------------------------------------------- /src/helpers/UIKit+ConstExpr.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if canImport(UIKit) 3 | import UIKit 4 | #endif 5 | 6 | #if canImport(UIKit) 7 | let defaultUIKitConstExpr: [String: Double] = [ 8 | // Idiom. 9 | "iPhoneSE": Double(Screen.Device.iPhoneSE.rawValue), 10 | "iPhone8": Double(Screen.Device.iPhone8.rawValue), 11 | "iPhone8Plus": Double(Screen.Device.iPhone8Plus.rawValue), 12 | "iPhoneX": Double(Screen.Device.iPhoneX.rawValue), 13 | "iPhoneXMax": Double(Screen.Device.iPhoneXMax.rawValue), 14 | "iPad": Double(Screen.Device.iPad.rawValue), 15 | "tv": Double(Screen.Device.tv.rawValue), 16 | // Bounds. 17 | "iPhoneSE.height": Double(568), 18 | "iPhone8.height": Double(667), 19 | "iPhone8Plus.height": Double(736), 20 | "iPhoneX.height": Double(812), 21 | "iPhoneXSMax.height": Double(896), 22 | "iPhoneSE.width": Double(320), 23 | "iPhone8.width": Double(375), 24 | "iPhone8Plus.width": Double(414), 25 | "iPhoneX.width": Double(375), 26 | "iPhoneXSMax.width": Double(414), 27 | // Orientation and Size Classes. 28 | "portrait": Double(Screen.Orientation.portrait.rawValue), 29 | "landscape": Double(Screen.Orientation.landscape.rawValue), 30 | "compact": Double(Screen.SizeClass.compact.rawValue), 31 | "regular": Double(Screen.SizeClass.regular.rawValue), 32 | "unspecified": Double(Screen.SizeClass.unspecified.rawValue), 33 | // Yoga. 34 | "inherit": Double(0), 35 | "ltr": Double(1), 36 | "rtl": Double(2), 37 | "auto": Double(0), 38 | "flexStart": Double(1), 39 | "center": Double(2), 40 | "flexEnd": Double(3), 41 | "stretch": Double(4), 42 | "baseline": Double(5), 43 | "spaceBetween": Double(6), 44 | "spaceAround": Double(7), 45 | "flex": Double(0), 46 | "none": Double(1), 47 | "column": Double(0), 48 | "columnReverse": Double(1), 49 | "row": Double(2), 50 | "rowReverse": Double(3), 51 | "visible": Double(0), 52 | "hidden": Double(1), 53 | "absolute": Double(2), 54 | "noWrap": Double(0), 55 | "wrap": Double(1), 56 | "wrapReverse": Double(2), 57 | ] 58 | 59 | let defaultUIKitSymbols: [Expression.Symbol: Expression.SymbolEvaluator] = [ 60 | .variable("idiom"): { _ in 61 | Double(Screen.Device.current().rawValue) }, 62 | .variable("orientation"): { _ in 63 | Double(Screen.Orientation.current().rawValue) }, 64 | .variable("verticalSizeClass"): { _ in 65 | Double(Screen.SizeClass.verticalSizeClass().rawValue) }, 66 | .variable("horizontalSizeClass"): { _ in 67 | Double(Screen.SizeClass.horizontalSizeClass().rawValue) }, 68 | .variable("screenSize.height"): { _ in 69 | Double(Screen.default.state().screenSize.height) }, 70 | .variable("screenSize.width"): { _ in 71 | Double(Screen.default.state().screenSize.width) } 72 | ] 73 | 74 | extension NSTextAlignment: EnumRepresentable { 75 | public static func expressionConstants() -> [String : Double] { 76 | let namespace = "NSTextAlignment" 77 | return [ 78 | "\(namespace).left": Double(NSTextAlignment.left.rawValue), 79 | "\(namespace).center": Double(NSTextAlignment.center.rawValue), 80 | "\(namespace).right": Double(NSTextAlignment.right.rawValue), 81 | "\(namespace).justified": Double(NSTextAlignment.justified.rawValue), 82 | "\(namespace).natural": Double(NSTextAlignment.natural.rawValue)] 83 | } 84 | } 85 | 86 | extension NSLineBreakMode: EnumRepresentable { 87 | public static func expressionConstants() -> [String : Double] { 88 | let namespace = "NSLineBreakMode" 89 | return [ 90 | "\(namespace).byWordWrapping": Double(NSLineBreakMode.byWordWrapping.rawValue), 91 | "\(namespace).byCharWrapping": Double(NSLineBreakMode.byCharWrapping.rawValue), 92 | "\(namespace).byClipping": Double(NSLineBreakMode.byClipping.rawValue), 93 | "\(namespace).byTruncatingHead": Double(NSLineBreakMode.byTruncatingHead.rawValue), 94 | "\(namespace).byTruncatingMiddle": Double(NSLineBreakMode.byTruncatingMiddle.rawValue)] 95 | } 96 | } 97 | 98 | extension UIImage.Orientation: EnumRepresentable { 99 | public static func expressionConstants() -> [String : Double] { 100 | let namespace = "UIImageOrientation" 101 | return [ 102 | "\(namespace).up": Double(UIImage.Orientation.up.rawValue), 103 | "\(namespace).down": Double(UIImage.Orientation.down.rawValue), 104 | "\(namespace).left": Double(UIImage.Orientation.left.rawValue), 105 | "\(namespace).right": Double(UIImage.Orientation.right.rawValue), 106 | "\(namespace).upMirrored": Double(UIImage.Orientation.upMirrored.rawValue), 107 | "\(namespace).downMirrored": Double(UIImage.Orientation.downMirrored.rawValue), 108 | "\(namespace).leftMirrored": Double(UIImage.Orientation.leftMirrored.rawValue), 109 | "\(namespace).rightMirrored": Double(UIImage.Orientation.rightMirrored.rawValue)] 110 | } 111 | } 112 | 113 | extension UIImage.ResizingMode: EnumRepresentable { 114 | public static func expressionConstants() -> [String : Double] { 115 | let namespace = "UIImageResizingMode" 116 | return [ 117 | "\(namespace).title": Double(UIImage.ResizingMode.tile.rawValue), 118 | "\(namespace).stretch": Double(UIImage.ResizingMode.stretch.rawValue)] 119 | } 120 | } 121 | 122 | extension UIView.ContentMode: EnumRepresentable { 123 | public static func expressionConstants() -> [String : Double] { 124 | let namespace = "UIViewContentMode" 125 | return [ 126 | "\(namespace).scaleToFill": Double(UIView.ContentMode.scaleToFill.rawValue), 127 | "\(namespace).scaleAspectFit": Double(UIView.ContentMode.scaleAspectFit.rawValue), 128 | "\(namespace).scaleAspectFill": Double(UIView.ContentMode.scaleAspectFill.rawValue), 129 | "\(namespace).redraw": Double(UIView.ContentMode.redraw.rawValue), 130 | "\(namespace).center": Double(UIView.ContentMode.center.rawValue), 131 | "\(namespace).top": Double(UIView.ContentMode.top.rawValue), 132 | "\(namespace).bottom": Double(UIView.ContentMode.bottom.rawValue), 133 | "\(namespace).left": Double(UIView.ContentMode.left.rawValue), 134 | "\(namespace).right": Double(UIView.ContentMode.right.rawValue), 135 | "\(namespace).topLeft": Double(UIView.ContentMode.topLeft.rawValue), 136 | "\(namespace).topRight": Double(UIView.ContentMode.topRight.rawValue), 137 | "\(namespace).bottomLeft": Double(UIView.ContentMode.bottomLeft.rawValue), 138 | "\(namespace).bottomRight": Double(UIView.ContentMode.bottomRight.rawValue)] 139 | } 140 | } 141 | 142 | // MARK: - Screen 143 | 144 | public class Screen { 145 | /// Default singletion screen state factory. 146 | static let `default` = Screen() 147 | 148 | public enum Device: Int, Codable { 149 | /// Applicable for iPhone5, 5S, 5C and SE. 150 | case iPhoneSE 151 | /// Applicable for iPhone 6, 6S, 7 and 8. 152 | case iPhone8 153 | /// Applicable for iPhone 6+, 6S+, 7+ and 8+. 154 | case iPhone8Plus 155 | /// Applicable for iPhone X and XR, 156 | case iPhoneX 157 | /// Applicable for iPhone X Max. 158 | case iPhoneXMax 159 | /// Applicable for any iPad. 160 | case iPad 161 | /// Applicable for Apple TV. 162 | case tv 163 | /// Any other unsupported interface idiom. 164 | case undefined 165 | 166 | /// The interface idiom for the current device screen. 167 | static func current() -> Device { 168 | let idiom = UIDevice().userInterfaceIdiom 169 | switch idiom { 170 | case .phone: 171 | switch UIScreen.main.nativeBounds.height { 172 | case 568: return .iPhoneSE 173 | case 667: return .iPhone8 174 | case 736: return .iPhone8Plus 175 | case 812: return .iPhoneX 176 | case 896: return .iPhoneXMax 177 | default: return .undefined 178 | } 179 | case .pad: return .iPad 180 | case .tv: return .tv 181 | default: return .undefined 182 | } 183 | } 184 | } 185 | 186 | public enum Orientation: Int, Codable { 187 | case portrait 188 | case landscape 189 | 190 | /// Queries the physical orientation of the device. 191 | static func current() -> Orientation { 192 | return isPortrait() ? .portrait : landscape 193 | } 194 | /// Returns `true` if the phone is portrait, `false` otherwise. 195 | private static func isPortrait() -> Bool { 196 | let orientation = UIDevice.current.orientation 197 | switch orientation { 198 | case .portrait, .portraitUpsideDown: return true 199 | case .faceUp: 200 | // Check the interface orientation 201 | let interfaceOrientation = UIApplication.shared.statusBarOrientation 202 | switch interfaceOrientation{ 203 | case .portrait, .portraitUpsideDown: return true 204 | default: return false 205 | } 206 | default: return false 207 | } 208 | } 209 | /// Returns `true` if the phone is landscape, `false` otherwise. 210 | private static func isLandscape() -> Bool { 211 | return !isPortrait() 212 | } 213 | } 214 | 215 | public enum SizeClass: Int, Codable { 216 | case unspecified 217 | /// Indicates a regular size class. 218 | case regular 219 | /// Indicates a compact size class. 220 | case compact 221 | 222 | /// The device's horizontal size class. 223 | public static func horizontalSizeClass(for view: UIView? = nil) -> SizeClass { 224 | switch (view?.traitCollection ?? UIScreen.main.traitCollection).horizontalSizeClass { 225 | case .regular: return .regular 226 | case .compact: return .compact 227 | case .unspecified: return .unspecified 228 | @unknown default: 229 | return .unspecified 230 | } 231 | } 232 | 233 | /// The device's vertical size class. 234 | public static func verticalSizeClass(for view: UIView? = nil) -> SizeClass { 235 | switch (view?.traitCollection ?? UIScreen.main.traitCollection).verticalSizeClass { 236 | case .regular: return .regular 237 | case .compact: return .compact 238 | case .unspecified: return .unspecified 239 | @unknown default: 240 | return .unspecified 241 | } 242 | } 243 | } 244 | 245 | public struct State: Codable { 246 | /// The user interface idiom based on the screen size. 247 | public let idiom: Device 248 | /// The physical orientation of the device. 249 | public let orientation: Orientation 250 | /// The horizontal size class of the trait collection. 251 | public let horizontalSizeClass: SizeClass 252 | /// The vertical size class of the trait collection. 253 | public let verticalSizeClass: SizeClass 254 | /// The width and the height of the physical screen. 255 | public let screenSize: CGSize 256 | /// The width and the height of the canvas view for this context. 257 | public let canvasSize: CGSize 258 | /// The width and the height for the size passed as argument for this last render pass. 259 | public let renderSize: CGSize 260 | /// The safe area of a view reflects the area not covered by navigation bars, tab bars, 261 | /// toolbars, and other ancestors that obscure a view controller`s view. 262 | public let safeAreaSize: CGSize 263 | public let safeAreaInsets: Insets 264 | 265 | /// Edge inset values are applied to a rectangle to shrink or expand the area represented by 266 | /// that rectangle. 267 | public struct Insets: Codable { 268 | /// The inset on the top of an object. 269 | public let top: CGFloat 270 | /// The inset on the left of an object. 271 | public let left: CGFloat 272 | /// The inset on the bottom of an object. 273 | public let bottom: CGFloat 274 | /// The inset on the right of an object. 275 | public let right: CGFloat 276 | 277 | public var uiEdgeInsets: UIEdgeInsets { 278 | return UIEdgeInsets(top: top, left: left, bottom: bottom, right: right) 279 | } 280 | 281 | public static func from(edgeInsets: UIEdgeInsets) -> Insets { 282 | return Insets( 283 | top: edgeInsets.top, 284 | left: edgeInsets.left, 285 | bottom: edgeInsets.bottom, 286 | right: edgeInsets.right) 287 | } 288 | } 289 | } 290 | 291 | /// The canvas view in which the component will be rendered in. 292 | private var viewProvider: () -> UIView? 293 | /// The width and the height for the size passed as argument for this last render pass. 294 | public var bounds: CGSize = UIScreen.main.nativeBounds.size 295 | 296 | init(viewProvider: @escaping () -> UIView? = { nil }) { 297 | self.viewProvider = viewProvider 298 | } 299 | 300 | /// Returns the information about the screen at this very moment. 301 | public func state() -> State { 302 | let native = UIScreen.main.nativeBounds.size 303 | // Compute the Safe Area (if applicable). 304 | var safeAreaSize = native 305 | var safeAreaInsets = State.Insets(top: 0, left: 0, bottom: 0, right: 0) 306 | if #available(iOS 11.0, *) { 307 | let defaultView = UIApplication.shared.keyWindow?.rootViewController?.view 308 | if let view = viewProvider() ?? defaultView { 309 | safeAreaInsets = State.Insets.from(edgeInsets: view.safeAreaInsets) 310 | safeAreaSize.width -= safeAreaInsets.left + safeAreaInsets.right 311 | safeAreaSize.height -= safeAreaInsets.top + safeAreaInsets.bottom 312 | } 313 | } 314 | return State( 315 | idiom: Device.current(), 316 | orientation: Orientation.current(), 317 | horizontalSizeClass: SizeClass.horizontalSizeClass(for: viewProvider()), 318 | verticalSizeClass: SizeClass.verticalSizeClass(for: viewProvider()), 319 | screenSize: native, 320 | canvasSize: viewProvider()?.bounds.size ?? native, 321 | renderSize: bounds, 322 | safeAreaSize: safeAreaSize, 323 | safeAreaInsets: safeAreaInsets) 324 | } 325 | } 326 | #endif 327 | -------------------------------------------------------------------------------- /src/helpers/UIKit+Helpers.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if canImport(UIKit) 3 | import UIKit 4 | #endif 5 | 6 | /// Warning message related to stylesheet parsing and rules evaluation. 7 | func warn(_ message: String) { 8 | print("warning \(#function): \(message)") 9 | } 10 | 11 | #if canImport(UIKit) 12 | public extension UIColor { 13 | /// Parse a color from a haxadecimal string. 14 | convenience init?(hex: String) { 15 | var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines) 16 | hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "") 17 | var rgb: UInt32 = 0 18 | var r: CGFloat = 0.0 19 | var g: CGFloat = 0.0 20 | var b: CGFloat = 0.0 21 | var a: CGFloat = 1.0 22 | let length = hexSanitized.count 23 | guard Scanner(string: hexSanitized).scanHexInt32(&rgb) else { return nil } 24 | if length == 6 { 25 | r = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 26 | g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 27 | b = CGFloat(rgb & 0x0000FF) / 255.0 28 | 29 | } else if length == 8 { 30 | r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 31 | g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 32 | b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 33 | a = CGFloat(rgb & 0x000000FF) / 255.0 34 | } else { 35 | return nil 36 | } 37 | self.init(red: r, green: g, blue: b, alpha: a) 38 | } 39 | 40 | func lighter(by percentage: CGFloat = 30.0) -> UIColor? { 41 | return self.adjust(by: abs(percentage) ) 42 | } 43 | 44 | func darker(by percentage: CGFloat = 30.0) -> UIColor? { 45 | return self.adjust(by: -1 * abs(percentage) ) 46 | } 47 | 48 | func adjust(by percentage: CGFloat = 30.0) -> UIColor? { 49 | var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 50 | if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) { 51 | return UIColor( 52 | red: min(red + percentage/100, 1.0), 53 | green: min(green + percentage/100, 1.0), 54 | blue: min(blue + percentage/100, 1.0), 55 | alpha: alpha) 56 | } else { 57 | return nil 58 | } 59 | } 60 | } 61 | 62 | /// Fonts and its attributes. 63 | public class TextStyle: NSObject { 64 | /// The typeface. 65 | private let internalFont: UIFont 66 | /// The font letter spacing. 67 | private let kern: CGFloat 68 | /// Whether this font support dybamic font size. 69 | private var supportDynamicType: Bool 70 | /// The font color. 71 | public var color: UIColor 72 | /// Publicly exposed font (subject to font scaling if appliocable). 73 | public var font: UIFont { 74 | guard supportDynamicType else { 75 | return internalFont 76 | } 77 | if #available(iOS 11.0, *) { 78 | return UIFontMetrics.default.scaledFont(for: internalFont) 79 | } else { 80 | return internalFont 81 | } 82 | } 83 | 84 | public init( 85 | font: UIFont = UIFont.systemFont(ofSize: 10), 86 | kern: CGFloat = 1, 87 | supportDynamicType: Bool = false, 88 | color: UIColor = .black 89 | ) { 90 | self.internalFont = font 91 | self.kern = kern 92 | self.supportDynamicType = supportDynamicType 93 | self.color = color 94 | } 95 | 96 | /// Returns a dictionary of attributes for `NSAttributedString`. 97 | public var attributes: [NSAttributedString.Key: Any] { 98 | return [ 99 | NSAttributedString.Key.font: font, 100 | NSAttributedString.Key.foregroundColor: color, 101 | NSAttributedString.Key.kern: kern 102 | ] 103 | } 104 | /// Overrides the `NSForegroundColorAttributeName` attribute. 105 | public func withColor(_ override: UIColor) -> TextStyle { 106 | return TextStyle( 107 | font: internalFont, 108 | kern: kern, 109 | supportDynamicType: supportDynamicType, 110 | color: override) 111 | } 112 | /// Returns an attributed string with the current font descriptor attributes. 113 | public func asAttributedString(_ string: String) -> NSAttributedString { 114 | return NSAttributedString(string: string, attributes: attributes) 115 | } 116 | } 117 | 118 | extension UIImageView { 119 | /// Configure this image view to work with the icon passed as argument. 120 | /// - parameter icon: The icon name, see *Icons.generated.swift*. 121 | /// - parameter size: The optional icon size (with the assumption that the icon is squared). 122 | /// - parameter color: Tint the image with the desired color. 123 | @discardableResult 124 | func withIcon(_ icon: String, size: CGFloat? = nil, color: UIColor? = nil) -> UIImageView { 125 | guard let icon = UIImage(named: icon)?.withRenderingMode(.alwaysTemplate) else { return self } 126 | image = icon 127 | if let size = size { frame.size = CGSize(width: size, height: size) } 128 | if let color = color { tintColor = color } 129 | return self 130 | } 131 | } 132 | 133 | public extension UIImage { 134 | /// Tint the image with the desired color. 135 | func withTintColor(_ color: UIColor) -> UIImage { 136 | UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) 137 | let context: CGContext = UIGraphicsGetCurrentContext()! 138 | context.translateBy(x: 0, y: self.size.height) 139 | context.scaleBy(x: 1.0, y: -1.0) 140 | context.setBlendMode(CGBlendMode.normal) 141 | let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) 142 | context.clip(to: rect, mask: self.cgImage!) 143 | color.setFill() 144 | context.fill(rect) 145 | let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! 146 | UIGraphicsEndImageContext() 147 | return newImage 148 | } 149 | 150 | /// Resize an image. 151 | func byResizingToTargetHeight(_ targetHeight: CGFloat) -> UIImage { 152 | let size = self.size 153 | let heightRatio = targetHeight / size.height 154 | let newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) 155 | let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) 156 | UIGraphicsBeginImageContextWithOptions(newSize, false, 0) 157 | self.draw(in: rect) 158 | let newImage = UIGraphicsGetImageFromCurrentImageContext() 159 | UIGraphicsEndImageContext() 160 | return newImage! 161 | } 162 | } 163 | #endif 164 | -------------------------------------------------------------------------------- /src/helpers/UIKit+ObjectExpr.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | #if canImport(UIKit) 3 | import UIKit 4 | #endif 5 | 6 | #if canImport(UIKit) 7 | struct UIKitObjectExpr { 8 | 9 | class Font: ObjectExprBase { 10 | static let fontWeights = [ 11 | "ultralight": CGFloat(-0.800000011920929), 12 | "thin": CGFloat(-0.600000023841858), 13 | "light": CGFloat(-0.400000005960464), 14 | "medium": CGFloat(0.230000004172325), 15 | "regular": CGFloat(0), 16 | "semibold": CGFloat(0.300000011920929), 17 | "bold": CGFloat(0.400000005960464), 18 | "heavy": CGFloat(0.560000002384186), 19 | "black": CGFloat(0.620000004768372)] 20 | 21 | @objc dynamic var name: String? = nil 22 | @objc dynamic var size: CGFloat = 10 23 | @objc dynamic var weight: String = "regular" 24 | 25 | override func eval() -> Any? { 26 | if let fontName = name { 27 | return UIFont(name: fontName, size: size) 28 | } else { 29 | let weights = UIKitObjectExpr.Font.fontWeights 30 | let fontWeight = UIFont.Weight(rawValue: weights[weight] ?? 0) 31 | return UIFont.systemFont(ofSize: size, weight: fontWeight) 32 | } 33 | } 34 | } 35 | 36 | class Color: ObjectExprBase{ 37 | @objc dynamic var hex: String = "000" 38 | @objc dynamic var darken: CGFloat = 0 39 | @objc dynamic var lighten: CGFloat = 0 40 | @objc dynamic var alpha: CGFloat = 1 41 | 42 | override func eval() -> Any? { 43 | var color = UIColor(hex: hex) 44 | if darken > 0 { 45 | color = color?.darker(by: darken) 46 | } else if lighten > 0 { 47 | color = color?.lighter(by: lighten) 48 | } 49 | if alpha < 1 { 50 | color = color?.withAlphaComponent(alpha) 51 | } 52 | return color 53 | } 54 | } 55 | 56 | class Animator: ObjectExprBase { 57 | @objc dynamic var duration: TimeInterval = 0 58 | @objc dynamic var curve: String = "linear" 59 | @objc dynamic var damping: CGFloat = CGFloat.nan 60 | 61 | override func eval() -> Any? { 62 | var animationCurve: UIView.AnimationCurve = .linear 63 | switch curve { 64 | case "easeInOut": animationCurve = .easeInOut 65 | case "easeIn" : animationCurve = .easeIn 66 | case "easeOut": animationCurve = .easeOut 67 | case "linear": animationCurve = .linear 68 | default: break 69 | } 70 | if damping.isNormal { 71 | return UIViewPropertyAnimator( 72 | duration: duration, 73 | dampingRatio: damping, 74 | animations: nil) 75 | } else { 76 | return UIViewPropertyAnimator( 77 | duration: duration, 78 | curve: animationCurve, 79 | animations:nil) 80 | } 81 | } 82 | } 83 | 84 | class Text: ObjectExprBase { 85 | @objc dynamic var name: String? = nil 86 | @objc dynamic var size: CGFloat = 10 87 | @objc dynamic var kern: CGFloat = 1 88 | @objc dynamic var weight: String = "regular" 89 | @objc dynamic var supportDynamicType: Bool = true 90 | @objc dynamic var hex: String = "000" 91 | 92 | override func eval() -> Any? { 93 | let uiColor = UIColor(hex: hex) ?? UIColor.black 94 | var font = UIFont.systemFont(ofSize: size) 95 | if let fontName = name { 96 | font = UIFont(name: fontName, size: size)! 97 | } else { 98 | let weights = UIKitObjectExpr.Font.fontWeights 99 | let fontWeight = UIFont.Weight(rawValue: weights[weight] ?? 0) 100 | font = UIFont.systemFont(ofSize: size, weight: fontWeight) 101 | } 102 | return TextStyle( 103 | font: font, 104 | kern: kern, 105 | supportDynamicType: supportDynamicType, 106 | color: uiColor) 107 | } 108 | } 109 | } 110 | 111 | // MARK: - Rule Extensions 112 | 113 | public extension Rule { 114 | /// Returns this rule evaluated as a float. 115 | /// - note: The default value is 0. 116 | var cgFloat: CGFloat { 117 | return (nsNumber as? CGFloat) ?? 0 118 | } 119 | /// Returns this rule evaluated as a `UIFont`. 120 | var font: UIFont { 121 | return cast(type: .object, default: UIFont.init()) 122 | } 123 | 124 | /// Returns this rule evaluated as a `UIColor`. 125 | /// - note: The default value is `UIColor.black`. 126 | var color: UIColor { 127 | return cast(type: .object, default: UIColor.init()) 128 | } 129 | 130 | /// Returns this rule as a `UIViewPropertyAnimator`. 131 | var animator: UIViewPropertyAnimator { 132 | return cast(type: .object, default: UIViewPropertyAnimator()) 133 | } 134 | 135 | /// Returns this rule evaluated as a `NSAttributedStringBuilder`. 136 | var textStyle: TextStyle { 137 | return cast(type: .object, default: TextStyle()) 138 | } 139 | } 140 | 141 | #endif 142 | 143 | // MARK: - Register Defaults 144 | 145 | func objectExprRegisterDefaults(_ registry: ObjectExprRegistry) { 146 | #if canImport(UIKit) 147 | registry.export(ObjectExprFactory( 148 | type: UIKitObjectExpr.Font.self, 149 | name: "font", 150 | builder: { return UIKitObjectExpr.Font() })) 151 | registry.export(ObjectExprFactory( 152 | type: UIKitObjectExpr.Color.self, 153 | name: "color", 154 | builder: { return UIKitObjectExpr.Color() })) 155 | registry.export(ObjectExprFactory( 156 | type: UIKitObjectExpr.Animator.self, 157 | name: "animator", 158 | builder: { return UIKitObjectExpr.Animator() })) 159 | registry.export(ObjectExprFactory( 160 | type: UIKitObjectExpr.Text.self, 161 | name: "text", 162 | builder: { return UIKitObjectExpr.Text() })) 163 | #endif 164 | } 165 | -------------------------------------------------------------------------------- /test/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/Test.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import UIKit 3 | @testable import YAS 4 | 5 | class StylesheetTests: XCTestCase { 6 | 7 | let test: String = "Test" 8 | var parser: StylesheetManager = StylesheetManager() 9 | 10 | override func setUp() { 11 | parser = StylesheetManager() 12 | try! parser.load(yaml: standardDefs) 13 | } 14 | 15 | func testCGFloat() { 16 | XCTAssert(parser.property(style: test, name: "cgFloat")?.cgFloat == 42.0) 17 | } 18 | 19 | func testBool() { 20 | XCTAssert(parser.property(style: test, name: "bool")?.bool == true) 21 | } 22 | 23 | func testInt() { 24 | XCTAssert(parser.property(style: test, name: "integer")?.integer == 42) 25 | } 26 | 27 | func testCGFloatExpression() { 28 | XCTAssert(parser.property(style: test, name: "cgFloatExpr")?.cgFloat == 42.0) 29 | } 30 | 31 | func testBoolExpression() { 32 | XCTAssert(parser.property(style: test, name: "boolExpr")?.bool == true) 33 | } 34 | 35 | func testIntExpression() { 36 | XCTAssert(parser.property(style: test, name: "integerExpr")?.integer == 42) 37 | } 38 | 39 | func testConstExpression() { 40 | XCTAssert(parser.property(style: test, name: "const")?.cgFloat == 320) 41 | } 42 | 43 | func testColor() { 44 | let value = parser.property(style: test, name: "color")?.color 45 | XCTAssert(value!.cgColor.components![0] == 1) 46 | XCTAssert(value!.cgColor.components![1] == 0) 47 | XCTAssert(value!.cgColor.components![2] == 0) 48 | } 49 | 50 | func testFont() { 51 | let value = parser.property(style: test, name: "font")?.font 52 | XCTAssert(value!.pointSize == 42.0) 53 | } 54 | 55 | func testFontWeight() { 56 | let value = parser.property(style: test, name: "fontWeight")?.font 57 | XCTAssert(value!.pointSize == 12.0) 58 | } 59 | 60 | func testAttributedString() { 61 | let value = parser.property(style: test, name: "textStyle")?.textStyle 62 | XCTAssert(value!.font.pointSize == 42) 63 | XCTAssert(value!.font.fontName == "ArialMT") 64 | XCTAssert(value!.color.cgColor.components![0] == 1) 65 | XCTAssert(value!.color.cgColor.components![1] == 0) 66 | } 67 | 68 | func testEnum() { 69 | XCTAssert(parser.property(style: test, name: "enum")?.enum(NSTextAlignment.self) == .right) 70 | } 71 | 72 | func testApplyStyleseetToView() { 73 | try! StylesheetContext.manager.load(yaml: viewDefs) 74 | let view = UIView() 75 | view.apply(style: StylesheetContext.manager.properties(forStyle: "View")) 76 | let value = view.backgroundColor 77 | XCTAssert(value!.cgColor.components![0] == 1) 78 | XCTAssert(value!.cgColor.components![1] == 0) 79 | XCTAssert(value!.cgColor.components![2] == 0) 80 | XCTAssert(view.layer.borderWidth == 1) 81 | } 82 | 83 | func testRefValues() { 84 | XCTAssert(parser.property(style: test, name: "cgFloat")?.cgFloat == 42.0) 85 | XCTAssert(parser.property(style: test, name: "refValue")?.cgFloat == 42.0) 86 | } 87 | 88 | func testInheritance() { 89 | XCTAssert(parser.property(style: "Foo", name: "foo")?.cgFloat == 1) 90 | XCTAssert(parser.property(style: "Bar", name: "foo")?.cgFloat == 1) 91 | XCTAssert(parser.property(style: "Bar", name: "bar")?.cgFloat == 2) 92 | } 93 | 94 | func testTransition() { 95 | XCTAssert(parser.property(style: test, name: "animator1")?.animator.duration == 1) 96 | } 97 | 98 | func testStyleDynamicLookup() { 99 | try! StylesheetContext.manager.load(yaml: viewDefs) 100 | let view = UIView() 101 | view.apply(style: StylesheetContext.lookup.View.style) 102 | XCTAssert(view.layer.borderWidth == 1) 103 | } 104 | 105 | func testRuleDynamicLookup() { 106 | try! StylesheetContext.manager.load(yaml: viewDefs) 107 | XCTAssert(StylesheetContext.lookup.View.margin.cgFloat == 10.0) 108 | XCTAssert(StylesheetContext.lookup.View.someText.string == "Aaa") 109 | } 110 | } 111 | 112 | let standardDefs = """ 113 | Test: 114 | cgFloat: &_cgFloat 42 115 | refValue: *_cgFloat 116 | bool: true 117 | integer: 42 118 | enum: ${NSTextAlignment.right} 119 | cgFloatExpr: ${41+1} 120 | boolExpr: ${1 == 1 && true} 121 | integerExpr: ${41+1} 122 | const: ${iPhoneSE.width} 123 | color: {_type: color, hex: ff0000} 124 | font: {_type: font, name: Arial, size: 42} 125 | fontWeight: {_type: font, weight: bold, size: 12} 126 | animator1: {_type: animator, curve: easeIn, duration: 1} 127 | fontName: &_fontName Arial 128 | textStyle: {_type: text, name: *_fontName, size: 42, kern: 2, hex: ff0000} 129 | Foo: &_Foo 130 | foo: 1 131 | Bar: 132 | <<: *_Foo 133 | bar: 2 134 | """ 135 | 136 | let fooDefs = """ 137 | Foo: 138 | bar: 42 139 | baz: ${41+1} 140 | bax: true 141 | """ 142 | 143 | let viewDefs = """ 144 | View: 145 | backgroundColor: {_type: color, hex: ff0000} 146 | layer.borderWidth: 1 147 | flexDirection: ${row} 148 | margin: 10 149 | width_percentage: 100 150 | customNonApplicableProperty: 42 151 | someText: "Aaa" 152 | """ 153 | 154 | let breakpointDefs = """ 155 | Test: 156 | margin: 10 157 | padding: 4 158 | Test/aBreakpoint: 159 | _breakpoint: ${ 1 } 160 | margin: 20 161 | Test/aSkippedBreakpoint: 162 | _breakpoint: ${ 0 } 163 | margin: 0 164 | """ 165 | //#endif 166 | --------------------------------------------------------------------------------