Skip to content

Commit dc9e63a

Browse files
committed
Merge branch 'release/1.14.0'
2 parents e9cee5e + 1aed94a commit dc9e63a

15 files changed

Lines changed: 349 additions & 28 deletions

File tree

Aztec.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@
223223
F99D5CF321B989FF0089314A /* StringRangeMultibyteConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F99D5CF221B989FF0089314A /* StringRangeMultibyteConversionTests.swift */; };
224224
FF0714021EFD78AF00E50713 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FF0714001EFD78AF00E50713 /* Media.xcassets */; };
225225
FF17B2D2227A589F0022AECE /* LIElementConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF17B2D1227A589F0022AECE /* LIElementConverter.swift */; };
226+
FF1F56A123955EF600E93A30 /* ColorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF1F56A023955EF600E93A30 /* ColorProvider.swift */; };
227+
FF1F56A3239562B900E93A30 /* html_colors.json in Resources */ = {isa = PBXBuildFile; fileRef = FF1F56A2239562B900E93A30 /* html_colors.json */; };
226228
FF20D6401EDC389A00294B78 /* ShortcodeAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF20D63D1EDC389A00294B78 /* ShortcodeAttribute.swift */; };
227229
FF20D6411EDC389A00294B78 /* HTMLProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF20D63E1EDC389A00294B78 /* HTMLProcessor.swift */; };
228230
FF20D6421EDC389A00294B78 /* Processor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF20D63F1EDC389A00294B78 /* Processor.swift */; };
@@ -499,6 +501,8 @@
499501
F99D5CF221B989FF0089314A /* StringRangeMultibyteConversionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringRangeMultibyteConversionTests.swift; sourceTree = "<group>"; };
500502
FF0714001EFD78AF00E50713 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
501503
FF17B2D1227A589F0022AECE /* LIElementConverter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LIElementConverter.swift; sourceTree = "<group>"; };
504+
FF1F56A023955EF600E93A30 /* ColorProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorProvider.swift; sourceTree = "<group>"; };
505+
FF1F56A2239562B900E93A30 /* html_colors.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = html_colors.json; sourceTree = "<group>"; };
502506
FF20D63D1EDC389A00294B78 /* ShortcodeAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcodeAttribute.swift; sourceTree = "<group>"; };
503507
FF20D63E1EDC389A00294B78 /* HTMLProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLProcessor.swift; sourceTree = "<group>"; };
504508
FF20D63F1EDC389A00294B78 /* Processor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Processor.swift; sourceTree = "<group>"; };
@@ -810,6 +814,7 @@
810814
B5A99D831EBA073D00DED081 /* HTMLStorage.swift */,
811815
F9982CF521877663001E606B /* TextViewPasteboardDelegate.swift */,
812816
FF7EAEC3234D253B007A26E0 /* FontProvider.swift */,
817+
FF1F56A023955EF600E93A30 /* ColorProvider.swift */,
813818
);
814819
path = TextKit;
815820
sourceTree = "<group>";
@@ -1337,6 +1342,7 @@
13371342
isa = PBXGroup;
13381343
children = (
13391344
FF0714001EFD78AF00E50713 /* Media.xcassets */,
1345+
FF1F56A2239562B900E93A30 /* html_colors.json */,
13401346
);
13411347
path = Assets;
13421348
sourceTree = "<group>";
@@ -1486,6 +1492,7 @@
14861492
isa = PBXResourcesBuildPhase;
14871493
buildActionMask = 2147483647;
14881494
files = (
1495+
FF1F56A3239562B900E93A30 /* html_colors.json in Resources */,
14891496
FF0714021EFD78AF00E50713 /* Media.xcassets in Resources */,
14901497
);
14911498
runOnlyForDeploymentPostprocessing = 0;
@@ -1540,6 +1547,7 @@
15401547
FFD3C1732344DCA900AE8DA0 /* ForegroundColorElementAttributeConverter.swift in Sources */,
15411548
F1656FDE2152A6A6009C7E3A /* CiteStringAttributeConverter.swift in Sources */,
15421549
599F254B1D8BC9A1002871D6 /* String+RangeConversion.swift in Sources */,
1550+
FF1F56A123955EF600E93A30 /* ColorProvider.swift in Sources */,
15431551
599F25481D8BC9A1002871D6 /* Metrics.swift in Sources */,
15441552
914CD9E72200B2D200DDD5C9 /* BoldFormatter.swift in Sources */,
15451553
F1BDDDE72060403B000714E1 /* FigureFormatter.swift in Sources */,

Aztec/Assets/html_colors.json

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
{
2+
"aliceblue": "#f0f8ff",
3+
"antiquewhite": "#faebd7",
4+
"aqua": "#00ffff",
5+
"aquamarine": "#7fffd4",
6+
"azure": "#f0ffff",
7+
"beige": "#f5f5dc",
8+
"bisque": "#ffe4c4",
9+
"black": "#000000",
10+
"blanchedalmond": "#ffebcd",
11+
"blue": "#0000ff",
12+
"blueviolet": "#8a2be2",
13+
"brown": "#a52a2a",
14+
"burlywood": "#deb887",
15+
"cadetblue": "#5f9ea0",
16+
"chartreuse": "#7fff00",
17+
"chocolate": "#d2691e",
18+
"coral": "#ff7f50",
19+
"cornflowerblue": "#6495ed",
20+
"cornsilk": "#fff8dc",
21+
"crimson": "#dc143c",
22+
"cyan": "#00ffff",
23+
"darkblue": "#00008b",
24+
"darkcyan": "#008b8b",
25+
"darkgoldenrod": "#b8860b",
26+
"darkgray": "#a9a9a9",
27+
"darkgreen": "#006400",
28+
"darkgrey": "#a9a9a9",
29+
"darkkhaki": "#bdb76b",
30+
"darkmagenta": "#8b008b",
31+
"darkolivegreen": "#556b2f",
32+
"darkorange": "#ff8c00",
33+
"darkorchid": "#9932cc",
34+
"darkred": "#8b0000",
35+
"darksalmon": "#e9967a",
36+
"darkseagreen": "#8fbc8f",
37+
"darkslateblue": "#483d8b",
38+
"darkslategray": "#2f4f4f",
39+
"darkslategrey": "#2f4f4f",
40+
"darkturquoise": "#00ced1",
41+
"darkviolet": "#9400d3",
42+
"deeppink": "#ff1493",
43+
"deepskyblue": "#00bfff",
44+
"dimgray": "#696969",
45+
"dimgrey": "#696969",
46+
"dodgerblue": "#1e90ff",
47+
"firebrick": "#b22222",
48+
"floralwhite": "#fffaf0",
49+
"forestgreen": "#228b22",
50+
"fuchsia": "#ff00ff",
51+
"gainsboro": "#dcdcdc",
52+
"ghostwhite": "#f8f8ff",
53+
"goldenrod": "#daa520",
54+
"gold": "#ffd700",
55+
"gray": "#808080",
56+
"green": "#008000",
57+
"greenyellow": "#adff2f",
58+
"grey": "#808080",
59+
"honeydew": "#f0fff0",
60+
"hotpink": "#ff69b4",
61+
"indianred": "#cd5c5c",
62+
"indigo": "#4b0082",
63+
"ivory": "#fffff0",
64+
"khaki": "#f0e68c",
65+
"lavenderblush": "#fff0f5",
66+
"lavender": "#e6e6fa",
67+
"lawngreen": "#7cfc00",
68+
"lemonchiffon": "#fffacd",
69+
"lightblue": "#add8e6",
70+
"lightcoral": "#f08080",
71+
"lightcyan": "#e0ffff",
72+
"lightgoldenrodyellow": "#fafad2",
73+
"lightgray": "#d3d3d3",
74+
"lightgreen": "#90ee90",
75+
"lightgrey": "#d3d3d3",
76+
"lightpink": "#ffb6c1",
77+
"lightsalmon": "#ffa07a",
78+
"lightseagreen": "#20b2aa",
79+
"lightskyblue": "#87cefa",
80+
"lightslategray": "#778899",
81+
"lightslategrey": "#778899",
82+
"lightsteelblue": "#b0c4de",
83+
"lightyellow": "#ffffe0",
84+
"lime": "#00ff00",
85+
"limegreen": "#32cd32",
86+
"linen": "#faf0e6",
87+
"magenta": "#ff00ff",
88+
"maroon": "#800000",
89+
"mediumaquamarine": "#66cdaa",
90+
"mediumblue": "#0000cd",
91+
"mediumorchid": "#ba55d3",
92+
"mediumpurple": "#9370db",
93+
"mediumseagreen": "#3cb371",
94+
"mediumslateblue": "#7b68ee",
95+
"mediumspringgreen": "#00fa9a",
96+
"mediumturquoise": "#48d1cc",
97+
"mediumvioletred": "#c71585",
98+
"midnightblue": "#191970",
99+
"mintcream": "#f5fffa",
100+
"mistyrose": "#ffe4e1",
101+
"moccasin": "#ffe4b5",
102+
"navajowhite": "#ffdead",
103+
"navy": "#000080",
104+
"oldlace": "#fdf5e6",
105+
"olive": "#808000",
106+
"olivedrab": "#6b8e23",
107+
"orange": "#ffa500",
108+
"orangered": "#ff4500",
109+
"orchid": "#da70d6",
110+
"palegoldenrod": "#eee8aa",
111+
"palegreen": "#98fb98",
112+
"paleturquoise": "#afeeee",
113+
"palevioletred": "#db7093",
114+
"papayawhip": "#ffefd5",
115+
"peachpuff": "#ffdab9",
116+
"peru": "#cd853f",
117+
"pink": "#ffc0cb",
118+
"plum": "#dda0dd",
119+
"powderblue": "#b0e0e6",
120+
"purple": "#800080",
121+
"rebeccapurple": "#663399",
122+
"red": "#ff0000",
123+
"rosybrown": "#bc8f8f",
124+
"royalblue": "#4169e1",
125+
"saddlebrown": "#8b4513",
126+
"salmon": "#fa8072",
127+
"sandybrown": "#f4a460",
128+
"seagreen": "#2e8b57",
129+
"seashell": "#fff5ee",
130+
"sienna": "#a0522d",
131+
"silver": "#c0c0c0",
132+
"skyblue": "#87ceeb",
133+
"slateblue": "#6a5acd",
134+
"slategray": "#708090",
135+
"slategrey": "#708090",
136+
"snow": "#fffafa",
137+
"springgreen": "#00ff7f",
138+
"steelblue": "#4682b4",
139+
"tan": "#d2b48c",
140+
"teal": "#008080",
141+
"thistle": "#d8bfd8",
142+
"tomato": "#ff6347",
143+
"turquoise": "#40e0d0",
144+
"violet": "#ee82ee",
145+
"wheat": "#f5deb3",
146+
"white": "#ffffff",
147+
"whitesmoke": "#f5f5f5",
148+
"yellow": "#ffff00",
149+
"yellowgreen": "#9acd32"
150+
}

Aztec/Classes/Converters/AttributesToStringAttributes/Implementations/ForegroundColorElementAttributeConverter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ForegroundColorElementAttributesConverter: ElementAttributeConverter {
1111

1212
guard let cssColor = attribute.firstCSSAttribute(ofType: .foregroundColor),
1313
let colorValue = cssColor.value,
14-
let color = UIColor(hexString: colorValue) else {
14+
let color = ColorProvider.shared.color(named: colorValue) ?? UIColor(hexString: colorValue) else {
1515
return attributes
1616
}
1717

Aztec/Classes/Extensions/NSAttributedString+Lists.swift

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,41 @@ extension NSAttributedString {
6868
return resultRange
6969
}
7070

71+
/// Returns the number of items of a list at the given location.
72+
///
73+
/// - Parameters:
74+
/// - list: The list.
75+
/// - location: The location of the item.
76+
///
77+
/// - Returns: Returns the total number of items within the list or NSNotFound if no list is available at location.
78+
///
79+
func numberOfItems(in list: TextList, at location: Int) -> Int {
80+
guard
81+
let paragraphStyle = attribute(.paragraphStyle, at: location, effectiveRange: nil) as? ParagraphStyle
82+
else {
83+
return NSNotFound
84+
}
85+
let listDepth = paragraphStyle.lists.count
86+
guard let rangeOfList = range(of:list, at: location) else {
87+
return NSNotFound
88+
}
89+
var numberInList = 0
90+
let paragraphRanges = self.paragraphRanges(intersecting: rangeOfList)
91+
for (_, enclosingRange) in paragraphRanges {
92+
if let paragraphStyle = attribute(.paragraphStyle, at: enclosingRange.location, effectiveRange: nil) as? ParagraphStyle,
93+
listDepth == paragraphStyle.lists.count {
94+
numberInList += 1
95+
}
96+
}
97+
return numberInList
98+
}
7199
/// Returns the index of the item at the given location within the list.
72100
///
73101
/// - Parameters:
74102
/// - list: The list.
75103
/// - location: The location of the item.
76104
///
77-
/// - Returns: Returns the index within the list.
105+
/// - Returns: Returns the index within the list or NSNotFound is no list is available at location.
78106
///
79107
func itemNumber(in list: TextList, at location: Int) -> Int {
80108
guard
@@ -86,7 +114,7 @@ extension NSAttributedString {
86114
guard let rangeOfList = range(of:list, at: location) else {
87115
return NSNotFound
88116
}
89-
var numberInList = 1
117+
var numberInList = 0
90118
let paragraphRanges = self.paragraphRanges(intersecting: rangeOfList)
91119

92120
for (_, enclosingRange) in paragraphRanges {

Aztec/Classes/Formatters/Implementations/CodeFormatter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class CodeFormatter: AttributeFormatter {
1212

1313
// MARK: - Init
1414

15-
init(monospaceFont: UIFont = FontProvider.shared.monospaceFont, backgroundColor: UIColor = UIColor.lightGray) {
15+
init(monospaceFont: UIFont = FontProvider.shared.monospaceFont, backgroundColor: UIColor = ColorProvider.shared.codeBackgroungColor) {
1616
self.monospaceFont = monospaceFont
1717
self.backgroundColor = backgroundColor
1818
self.htmlRepresentationKey = .codeHtmlRepresentation

Aztec/Classes/Libxml2/DOM/Data/AttributeType.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ extension AttributeType {
3636
public static let src = AttributeType("src")
3737
public static let style = AttributeType("style")
3838
public static let target = AttributeType("target")
39+
public static let reversed = AttributeType("reversed")
40+
public static let start = AttributeType("start")
3941
}

Aztec/Classes/NSAttributedString/Conversions/AttributedStringParser.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,15 @@ private extension AttributedStringParser {
765765
listElement = element.toElementNode()
766766
} else {
767767
listElement = ElementNode(type: listType)
768+
if list.style == .ordered {
769+
if list.reversed {
770+
listElement.updateAttribute(named: "reversed", value: .none)
771+
}
772+
773+
if let start = list.start {
774+
listElement.updateAttribute(named: "start", value: .string("\(start)"))
775+
}
776+
}
768777
}
769778

770779
return listElement
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import Foundation
2+
import UIKit
3+
4+
/// A class that provides colors to the formatter in TextKit.
5+
/// By default only the standard html colors are provided, but new color can be added by using the `add(namedColors:)` method.
6+
public class ColorProvider {
7+
8+
9+
private init() {
10+
11+
}
12+
13+
public static var shared = ColorProvider()
14+
15+
private lazy var htmlColors: [String: UIColor] = {
16+
guard let colorDataURL = Bundle.aztecBundle.url(forResource: "html_colors", withExtension: "json"),
17+
let data = try? Data(contentsOf: colorDataURL),
18+
let object = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
19+
let colorDict = object as? [String: String] else {
20+
return [String:UIColor]()
21+
}
22+
23+
return colorDict.compactMapValues { UIColor(hexString: $0) }
24+
}()
25+
26+
private var extraColors = [String:UIColor]()
27+
28+
/// Adds extra named colors to be used by the `color(named:)` method.
29+
/// If there is a name collision, the value in the added dictionary will overwrite the current color.
30+
/// - Parameter namedColors: a dictionary of colors keyed by name
31+
public func add(namedColors: [String: UIColor]) {
32+
extraColors.merge(namedColors) { (base, other) -> UIColor in
33+
return other
34+
}
35+
}
36+
37+
/// Returns a color designated by name or nil if the name is not available
38+
/// By default the the color available are the ones defined in the HTML specification: https://www.w3schools.com/colors/colors_names.asp
39+
/// - Parameter name: the name of the color
40+
public func color(named name: String) -> UIColor? {
41+
if let color = htmlColors[name.lowercased()] {
42+
return color
43+
}
44+
45+
return extraColors[name]
46+
}
47+
48+
public lazy var codeBackgroungColor: UIColor = {
49+
if #available(iOS 13.0, *) {
50+
return .secondarySystemBackground
51+
} else {
52+
return .lightGray
53+
}
54+
}()
55+
}

Aztec/Classes/TextKit/LayoutManager.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,16 @@ private extension LayoutManager {
210210

211211
let glyphRange = self.glyphRange(forCharacterRange: enclosingRange, actualCharacterRange: nil)
212212
let markerRect = rectForItem(range: glyphRange, origin: origin, paragraphStyle: paragraphStyle)
213-
let markerNumber = textStorage.itemNumber(in: list, at: enclosingRange.location)
214-
213+
var markerNumber = textStorage.itemNumber(in: list, at: enclosingRange.location)
214+
var start = list.start ?? 1
215+
if list.reversed {
216+
markerNumber = -markerNumber
217+
if list.start == nil {
218+
start = textStorage.numberOfItems(in: list, at: enclosingRange.location)
219+
}
220+
}
221+
markerNumber += start
222+
215223
drawItem(number: markerNumber, in: markerRect, from: list, using: paragraphStyle, at: enclosingRange.location)
216224
}
217225
}

0 commit comments

Comments
 (0)