<commit_before>//
// Xcore
// Copyright © 2015 Xcore
// MIT license, see LICENSE file for details
//

import UIKit

extension UIFont {
    public enum Trait {
        case normal
        case italic
        case monospaced
    }

    static func system(
        size: CGFloat,
        weight: Weight = .regular,
        trait: Trait = .normal
    ) -> UIFont {
        switch trait {
            case .normal:
                return systemFont(ofSize: size, weight: weight)
            case .italic:
                return italicSystemFont(ofSize: size)
            case .monospaced:
                return monospacedSystemFont(ofSize: size, weight: weight)
        }
    }
}

extension UIFont {
    /// Returns a font matching the given font descriptor.
    ///
    /// - Parameter traits: The new symbolic traits.
    /// - Returns: The new font matching the given font descriptor.
    public func traits(_ traits: UIFontDescriptor.SymbolicTraits...) -> UIFont? {
        fontDescriptor.withSymbolicTraits(.init(traits)).map {
            UIFont(descriptor: $0, size: 0)
        }
    }

    func bold() -> UIFont? {
        traits(.traitBold)
    }

    func italic() -> UIFont? {
        traits(.traitItalic)
    }

    func monospaced() -> UIFont? {
        traits(.traitMonoSpace)
    }
}

extension UIFont {
    var monospacedDigitFont: UIFont {
        let featureSettings = [[
            UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
            UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
        ]]
        let attributes = [UIFontDescriptor.AttributeName.featureSettings: featureSettings]
        let oldDescriptor = fontDescriptor
        let newDescriptor = oldDescriptor.addingAttributes(attributes)
        return UIFont(descriptor: newDescriptor, size: 0)
    }
}

extension UIFont {
    public static func printAvailableFontNames() {
        for family in familyNames {
            let count = fontNames(forFamilyName: family).count
            print("▿ \(family) (\(count) \(count == 1 ? "font" : "fonts"))")

            for name in fontNames(forFamilyName: family) {
                print("  - \(name)")
            }
        }
    }<commit_msg>Added support for custom weight<commit_after>//
// Xcore
// Copyright © 2015 Xcore
// MIT license, see LICENSE file for details
//

import UIKit

extension UIFont {
    public enum Trait {
        case normal
        case italic
        case monospaced
    }

    static func system(
        size: CGFloat,
        weight: Weight = .regular,
        trait: Trait = .normal
    ) -> UIFont {
        switch trait {
            case .normal:
                return systemFont(ofSize: size, weight: weight)
            case .italic:
                return italicSystemFont(ofSize: size)
            case .monospaced:
                return monospacedSystemFont(ofSize: size, weight: weight)
        }
    }
}

extension UIFont {
    /// Returns a font matching the given symbolic traits.
    ///
    /// - Parameter traits: The new symbolic traits.
    /// - Returns: The new font matching the given symbolic traits.
    public func withTraits(_ traits: UIFontDescriptor.SymbolicTraits...) -> UIFont? {
        fontDescriptor.withSymbolicTraits(.init(traits)).map {
            UIFont(descriptor: $0, size: 0)
        }
    }

    /// Returns a font object that is the same as the font, but has the specified
    /// weight.
    ///
    /// - Parameter weight: The desired weight of the new font object.
    /// - Returns: A font object of the specified weight.
    public func withWeight(_ weight: Weight) -> UIFont {
        var attributes = fontDescriptor.fontAttributes
        var traits = (attributes[.traits] as? [UIFontDescriptor.TraitKey: Any]) ?? [:]
        traits[.weight] = weight

        attributes[.name] = nil // Needed for custom fonts as the name can be tied to specific weight.
        attributes[.family] = familyName
        attributes[.traits] = traits

        let descriptor = UIFontDescriptor(fontAttributes: attributes)
        return UIFont(descriptor: descriptor, size: 0)
    }

    func bold() -> UIFont? {
        withTraits(.traitBold)
    }

    func italic() -> UIFont? {
        withTraits(.traitItalic)
    }

    func monospaced() -> UIFont? {
        withTraits(.traitMonoSpace)
    }
}

extension UIFont {
    var monospacedDigitFont: UIFont {
        let featureSettings = [[
            UIFontDescriptor.FeatureKey.featureIdentifier: kNumberSpacingType,
            UIFontDescriptor.FeatureKey.typeIdentifier: kMonospacedNumbersSelector
        ]]
        let attributes = [UIFontDescriptor.AttributeName.featureSettings: featureSettings]
        let oldDescriptor = fontDescriptor
        let newDescriptor = oldDescriptor.addingAttributes(attributes)
        return UIFont(descriptor: newDescriptor, size: 0)
    }
}

extension UIFont {
    public static func printAvailableFontNames() {
        for family in familyNames {
            let count = fontNames(forFamilyName: family).count
            print("▿ \(family) (\(count) \(count == 1 ? "font" : "fonts"))")

            for name in fontNames(forFamilyName: family) {
                print("  - \(name)")
            }
        }
    }
{'fraction_non_alphanumeric': 0.09645444147922226, 'fraction_numerical': 0.003240564239420511, 'mean_word_length': 2.115795724465558, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '826740', 'n_tokens_mistral': 1484, 'n_tokens_neox': 1432, 'n_words': 405}