         case span
         case a
 
-        func openTag(with attributes: String? = nil) -> String {
-            if let attributes = attributes {
-                return "<\(self.rawValue) \(attributes)>"
-            } else {
-                return "<\(self.rawValue)>"
+        func openTag(with attributes: String...) -> String {
+            var attributesString = ""
+            for attribute in attributes {
+                if attribute.isEmpty { continue }
+
+                attributesString += " " + attribute
             }
+            return "<\(self.rawValue)\(attributesString)>"
         }
 
         func closeTag() -> String {
             return "</\(self.rawValue)>"
         }
     }
+
+    private var hasParsedLinks: Bool = false
+    private var usedTagName: Name { return self.hasParsedLinks ? Name.a : self.defaultName }
+
+    // MARK: - Properties
 
     let defaultName: Name
     var attributes: [NSAttributedStringKey: Any]
     let ignoreParagraphStyles: Bool
 
+    init(defaultName: Name, attributes: [NSAttributedStringKey: Any], ignoreParagraphStyles: Bool) {
+        self.defaultName = defaultName
+        self.attributes = attributes
+        self.ignoreParagraphStyles = ignoreParagraphStyles
+    }
+
     mutating func addAttributes(_ attributes: [NSAttributedStringKey: Any]?) {
         attributes?.forEach { (key, value) in
             self.attributes[key] = value
         }
     }
 
-    func makeOpenTag() -> String {
-        guard !self.attributes.isEmpty else { return self.defaultName.openTag() }
+    mutating func parseOpenTag() -> String {
+        guard !self.attributes.isEmpty else { return self.usedTagName.openTag() }
 
         var styles: [String: String] = [:]
         var cocoaStyles: [String: String] = [:]

    ]

    func makeCloseTag() -> String {
        let containsStyle = self.attributes.contains(where: { HTMLTag.styleAttributes.contains($0.key) })
        let containsLinks = self.attributes.contains(where: { $0.key == .link })

        if containsLinks {
            var closeTag = ""
            closeTag += Name.a.closeTag()
            if containsStyle {
                closeTag += self.defaultName.closeTag()
            }
            return closeTag
        } else {
            return self.defaultName.closeTag()
        }
    }

    // MARK: - Private

                                                    } else {
                                                        guard let range = Range(nsrange, in: attributedString.string) else { return }

                                                        var tag = HTMLTag(defaultName: .span, attributes: attributes, ignoreParagraphStyles: true)
                                                        paragraphContent += tag.parseOpenTag()
                                                        paragraphContent += String(attributedString.string[range]).htmlEscaped
                                                        paragraphContent += tag.makeCloseTag()
                                                    }
            })

            html += paragraphTag.parseOpenTag() + paragraphContent + paragraphTag.makeCloseTag()
        }

        return html
