0001    // The MIT License
0002    //
0003    // Copyright (c) 2015 Gwendal Roué
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    extension StandardLibrary {
0024    
0025        /**
0026        StandardLibrary.Logger is a tool intended for debugging templates.
0027    
0028        It logs the rendering of variable and section tags such as `{{name}}` and
0029        `{{#name}}...{{/name}}`.
0030    
0031        To activate logging, add a Logger to the base context of a template:
0032    
0033            let template = try! Template(string: "{{name}} died at {{age}}.")
0034    
0035            // Logs all tag renderings with NSLog():
0036            let logger = StandardLibrary.Logger()
0037            template.extendBaseContext(Box(logger))
0038    
0039            // Render
0040            let data = ["name": "Freddy Mercury", "age": 45]
0041            let rendering = try! template.render(Box(data))
0042    
0043            // In NSLog:
0044            // {{name}} at line 1 did render "Freddy Mercury" as "Freddy Mercury"
0045            // {{age}} at line 1 did render 45 as "45"
0046        */
0047        public final class Logger : MustacheBoxable {
0048    
0049            /**
0050            Returns a Logger.
0051    
0052            - parameter log: A closure that takes a String. Default one logs that
0053                             string with NSLog().
0054            - returns: a Logger
0055            */
0056            public init(log: ((String) -> Void)? = nil) {
0057                if let log = log {
0058                    self.log = log
0059                } else {
0060                    self.log = { print($0) }
0061                }
0062            }
0063    
0064            /**
0065            Logger adopts the `MustacheBoxable` protocol so that it can feed
0066            Mustache templates.
0067    
0068            You should not directly call the `mustacheBox` property. Always use the
0069            `Box()` function instead:
0070    
0071                localizer.mustacheBox   // Valid, but discouraged
0072                Box(localizer)          // Preferred
0073            */
0074            public var mustacheBox: MustacheBox {
0075                return MustacheBox(
0076                    willRender: { (tag, box) in
0077                        if tag.type == .Section {
0078                            self.log("\(self.indentationPrefix)\(tag) will render \(box.valueDescription)")
0079                            self.indentationLevel += 1
0080                        }
0081                        return box
0082                    },
0083                    didRender: { (tag, box, string) in
0084                        if tag.type == .Section {
0085                            self.indentationLevel -= 1
0086                        }
0087                        if let string = string {
0088                            self.log("\(self.indentationPrefix)\(tag) did render \(box.valueDescription) as \(string.debugDescription)")
0089                        }
0090                    }
0091                )
0092            }
0093    
0094            var indentationPrefix
Logger.swift:78
                        self.log("\(self.indentationPrefix)\(tag) will render \(box.valueDescription)")
Logger.swift:88
                        self.log("\(self.indentationPrefix)\(tag) did render \(box.valueDescription) as \(string.debugDescription)")
: String { 0095 return String(count: indentationLevel * 2, repeatedValue: " " as Character) 0096 } 0097 0098 private let log
Logger.swift:58
                self.log = log
Logger.swift:60
                self.log = { print($0) }
Logger.swift:78
                        self.log("\(self.indentationPrefix)\(tag) will render \(box.valueDescription)")
Logger.swift:88
                        self.log("\(self.indentationPrefix)\(tag) did render \(box.valueDescription) as \(string.debugDescription)")
: (String) -> Void 0099 private var indentationLevel
Logger.swift:79
                        self.indentationLevel += 1
Logger.swift:85
                        self.indentationLevel -= 1
Logger.swift:95
            return String(count: indentationLevel * 2, repeatedValue: " " as Character)
: Int = 0 0100 } 0101 } 0102