From 5ab45be3c7a2934da880b397d7a637e19326d4ca Mon Sep 17 00:00:00 2001 From: Ali <> Date: Thu, 2 Nov 2023 20:19:24 +0400 Subject: [PATCH] Implement code highlight colors --- ...SendMessageActionSheetControllerNode.swift | 4 +- submodules/Display/Source/TextNode.swift | 14 ++++-- .../Sources/ChatInputTextNode.swift | 21 +++++++- .../ChatMessageAttachedContentNode.swift | 4 +- .../Sources/ChatMessageReplyInfoNode.swift | 1 + .../ChatMessageTextBubbleContentNode.swift | 26 ++++++++-- .../MessageInlineBlockBackgroundView.swift | 49 ++++++++++++------- .../Sources/ChatTextInputPanelNode.swift | 11 ++++- .../Sources/ChatTextInputAttributes.swift | 18 +++++-- .../Sources/StringWithAppliedEntities.swift | 11 +++-- third-party/libprisma/Sources/Highlight.h | 37 +++++++------- 11 files changed, 141 insertions(+), 55 deletions(-) diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift index 0efd6a7a4f..ac9a4cb3cb 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageActionSheetControllerNode.swift @@ -289,7 +289,9 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, quote: ChatInputTextView.Theme.Quote( background: mainColor.withMultipliedAlpha(0.1), foreground: mainColor, - lineStyle: mappedLineStyle + lineStyle: mappedLineStyle, + codeBackground: mainColor.withMultipliedAlpha(0.1), + codeForeground: mainColor ) ) } diff --git a/submodules/Display/Source/TextNode.swift b/submodules/Display/Source/TextNode.swift index a31009bd8e..c5e17b65e9 100644 --- a/submodules/Display/Source/TextNode.swift +++ b/submodules/Display/Source/TextNode.swift @@ -78,13 +78,15 @@ public final class TextNodeBlockQuoteData: NSObject { public let color: UIColor public let secondaryColor: UIColor? public let tertiaryColor: UIColor? + public let backgroundColor: UIColor - public init(kind: Kind, title: NSAttributedString?, color: UIColor, secondaryColor: UIColor?, tertiaryColor: UIColor?) { + public init(kind: Kind, title: NSAttributedString?, color: UIColor, secondaryColor: UIColor?, tertiaryColor: UIColor?, backgroundColor: UIColor) { self.kind = kind self.title = title self.color = color self.secondaryColor = secondaryColor self.tertiaryColor = tertiaryColor + self.backgroundColor = backgroundColor super.init() } @@ -162,13 +164,15 @@ private final class TextNodeBlockQuote { let tintColor: UIColor let secondaryTintColor: UIColor? let tertiaryTintColor: UIColor? + let backgroundColor: UIColor - init(frame: CGRect, data: TextNodeBlockQuoteData, tintColor: UIColor, secondaryTintColor: UIColor?, tertiaryTintColor: UIColor?) { + init(frame: CGRect, data: TextNodeBlockQuoteData, tintColor: UIColor, secondaryTintColor: UIColor?, tertiaryTintColor: UIColor?, backgroundColor: UIColor) { self.frame = frame self.data = data self.tintColor = tintColor self.secondaryTintColor = secondaryTintColor self.tertiaryTintColor = tertiaryTintColor + self.backgroundColor = backgroundColor } } @@ -1554,7 +1558,7 @@ open class TextNode: ASDisplayNode { } if let blockQuote = segment.blockQuote, let tintColor = segment.tintColor { - blockQuotes.append(TextNodeBlockQuote(frame: CGRect(origin: CGPoint(x: 0.0, y: blockMinY - 2.0), size: CGSize(width: blockWidth, height: blockMaxY - (blockMinY - 2.0) + 4.0)), data: blockQuote, tintColor: tintColor, secondaryTintColor: segment.secondaryTintColor, tertiaryTintColor: segment.tertiaryTintColor)) + blockQuotes.append(TextNodeBlockQuote(frame: CGRect(origin: CGPoint(x: 0.0, y: blockMinY - 2.0), size: CGSize(width: blockWidth, height: blockMaxY - (blockMinY - 2.0) + 4.0)), data: blockQuote, tintColor: tintColor, secondaryTintColor: segment.secondaryTintColor, tertiaryTintColor: segment.tertiaryTintColor, backgroundColor: blockQuote.backgroundColor)) } } @@ -2223,7 +2227,7 @@ open class TextNode: ASDisplayNode { blockFrame.size.width += 4.0 blockFrame.origin.x -= 2.0 - context.setFillColor(blockQuote.tintColor.withMultipliedAlpha(0.1).cgColor) + context.setFillColor(blockQuote.backgroundColor.cgColor) context.addPath(UIBezierPath(roundedRect: blockFrame, cornerRadius: radius).cgPath) context.fillPath() @@ -2315,7 +2319,9 @@ open class TextNode: ASDisplayNode { } } else { context.setFillColor(blockQuote.tintColor.cgColor) + context.setBlendMode(.copy) context.fill(lineFrame) + context.setBlendMode(.normal) } context.resetClip() diff --git a/submodules/TelegramUI/Components/Chat/ChatInputTextNode/Sources/ChatInputTextNode.swift b/submodules/TelegramUI/Components/Chat/ChatInputTextNode/Sources/ChatInputTextNode.swift index c4bf235e6b..976d187e5b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatInputTextNode/Sources/ChatInputTextNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatInputTextNode/Sources/ChatInputTextNode.swift @@ -278,15 +278,21 @@ public final class ChatInputTextView: ChatInputTextViewImpl, NSLayoutManagerDele public let background: UIColor public let foreground: UIColor public let lineStyle: LineStyle + public let codeBackground: UIColor + public let codeForeground: UIColor public init( background: UIColor, foreground: UIColor, - lineStyle: LineStyle + lineStyle: LineStyle, + codeBackground: UIColor, + codeForeground: UIColor ) { self.background = background self.foreground = foreground self.lineStyle = lineStyle + self.codeBackground = codeBackground + self.codeForeground = codeForeground } public static func ==(lhs: Quote, rhs: Quote) -> Bool { @@ -299,6 +305,12 @@ public final class ChatInputTextView: ChatInputTextViewImpl, NSLayoutManagerDele if lhs.lineStyle != rhs.lineStyle { return false } + if !lhs.codeBackground.isEqual(rhs.codeBackground) { + return false + } + if !lhs.codeForeground.isEqual(rhs.codeForeground) { + return false + } return true } } @@ -830,6 +842,7 @@ private final class QuoteBackgroundView: UIView { var primaryColor: UIColor var secondaryColor: UIColor? var tertiaryColor: UIColor? + let backgroundColor: UIColor? switch value.kind { case .quote: @@ -846,10 +859,13 @@ private final class QuoteBackgroundView: UIView { secondaryColor = secondaryColorValue tertiaryColor = tertiaryColorValue } + + backgroundColor = nil case .code: self.iconView.isHidden = true - primaryColor = .gray + primaryColor = theme.codeForeground + backgroundColor = theme.codeBackground } self.backgroundView.update( @@ -858,6 +874,7 @@ private final class QuoteBackgroundView: UIView { primaryColor: primaryColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, + backgroundColor: backgroundColor, pattern: nil, animation: .None ) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index 67455efa73..63e599cd45 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -869,13 +869,13 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { if let current = self.backgroundView { backgroundView = current animation.animator.updateFrame(layer: backgroundView.layer, frame: backgroundFrame, completion: nil) - backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: animation) + backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, backgroundColor: nil, pattern: nil, animation: animation) } else { backgroundView = MessageInlineBlockBackgroundView() self.backgroundView = backgroundView backgroundView.frame = backgroundFrame self.transformContainer.view.insertSubview(backgroundView, at: 0) - backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, pattern: nil, animation: .None) + backgroundView.update(size: backgroundFrame.size, isTransparent: false, primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, backgroundColor: nil, pattern: nil, animation: .None) } } else { if let backgroundView = self.backgroundView { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift index 29878e0883..19eba9f9d5 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageReplyInfoNode/Sources/ChatMessageReplyInfoNode.swift @@ -809,6 +809,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode { primaryColor: mainColor, secondaryColor: secondaryColor, thirdColor: tertiaryColor, + backgroundColor: nil, pattern: pattern, animation: animation ) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift index 2075a5907d..100fff36e7 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTextBubbleContentNode/Sources/ChatMessageTextBubbleContentNode.swift @@ -392,6 +392,9 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { var tertiaryColor: UIColor? = nil let nameColors = author?.nameColor.flatMap { item.context.peerNameColors.get($0, dark: item.presentationData.theme.theme.overallDarkAppearance) } + let codeBlockTitleColor: UIColor + let codeBlockAccentColor: UIColor + let codeBlockBackgroundColor: UIColor if !incoming { mainColor = messageTheme.accentTextColor if let _ = nameColors?.secondary { @@ -400,6 +403,16 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { if let _ = nameColors?.tertiary { tertiaryColor = .clear } + + if item.presentationData.theme.theme.overallDarkAppearance { + codeBlockTitleColor = .white + codeBlockAccentColor = UIColor(white: 1.0, alpha: 0.5) + codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.65) + } else { + codeBlockTitleColor = mainColor + codeBlockAccentColor = mainColor + codeBlockBackgroundColor = mainColor.withMultipliedAlpha(0.1) + } } else { let authorNameColor = nameColors?.main secondaryColor = nameColors?.secondary @@ -410,10 +423,17 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } else { mainColor = messageTheme.accentTextColor } + + codeBlockTitleColor = mainColor + codeBlockAccentColor = mainColor + + if item.presentationData.theme.theme.overallDarkAppearance { + codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.65) + } else { + codeBlockBackgroundColor = UIColor(white: 0.0, alpha: 0.05) + } } - let codeBlockColor = messageTheme.secondaryTextColor - codeHighlightSpecs = extractMessageSyntaxHighlightSpecs(text: rawText, entities: entities) if !codeHighlightSpecs.isEmpty { @@ -426,7 +446,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } } - attributedText = stringWithAppliedEntities(rawText, entities: entities, baseColor: messageTheme.primaryTextColor, linkColor: messageTheme.linkTextColor, baseQuoteTintColor: mainColor, baseQuoteSecondaryTintColor: secondaryColor, baseQuoteTertiaryTintColor: tertiaryColor, baseCodeBlockColor: codeBlockColor, baseFont: textFont, linkFont: textFont, boldFont: item.presentationData.messageBoldFont, italicFont: item.presentationData.messageItalicFont, boldItalicFont: item.presentationData.messageBoldItalicFont, fixedFont: item.presentationData.messageFixedFont, blockQuoteFont: item.presentationData.messageBlockQuoteFont, underlineLinks: underlineLinks, message: item.message, adjustQuoteFontSize: true, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight) + attributedText = stringWithAppliedEntities(rawText, entities: entities, baseColor: messageTheme.primaryTextColor, linkColor: messageTheme.linkTextColor, baseQuoteTintColor: mainColor, baseQuoteSecondaryTintColor: secondaryColor, baseQuoteTertiaryTintColor: tertiaryColor, codeBlockTitleColor: codeBlockTitleColor, codeBlockAccentColor: codeBlockAccentColor, codeBlockBackgroundColor: codeBlockBackgroundColor, baseFont: textFont, linkFont: textFont, boldFont: item.presentationData.messageBoldFont, italicFont: item.presentationData.messageItalicFont, boldItalicFont: item.presentationData.messageBoldItalicFont, fixedFont: item.presentationData.messageFixedFont, blockQuoteFont: item.presentationData.messageBlockQuoteFont, underlineLinks: underlineLinks, message: item.message, adjustQuoteFontSize: true, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight) } else if !rawText.isEmpty { attributedText = NSAttributedString(string: rawText, font: textFont, textColor: messageTheme.primaryTextColor) } else { diff --git a/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift b/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift index feb93a93e1..14f5bb3d83 100644 --- a/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift +++ b/submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView/Sources/MessageInlineBlockBackgroundView.swift @@ -28,15 +28,15 @@ private func addRoundedRectPath(context: CGContext, rect: CGRect, radius: CGFloa context.restoreGState() } -private func generateBackgroundTemplateImage(addStripe: Bool, isTransparent: Bool) -> UIImage { +private func generateBackgroundTemplateImage(addStripe: Bool, backgroundAlpha: CGFloat) -> UIImage { return generateImage(CGSize(width: radius * 2.0 + 4.0, height: radius * 2.0 + 8.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) addRoundedRectPath(context: context, rect: CGRect(origin: CGPoint(), size: size), radius: radius) context.clip() - context.setFillColor(UIColor.white.withMultipliedAlpha(0.1).cgColor) - if !isTransparent { + if backgroundAlpha != 0.0 { + context.setFillColor(UIColor.white.withMultipliedAlpha(backgroundAlpha).cgColor) context.fill(CGRect(origin: CGPoint(), size: size)) } @@ -71,19 +71,23 @@ private func generateProgressTemplateImage() -> UIImage { } private let backgroundSolidTemplateImage: UIImage = { - return generateBackgroundTemplateImage(addStripe: true, isTransparent: false) + return generateBackgroundTemplateImage(addStripe: true, backgroundAlpha: 0.1) }() private let backgroundDashTemplateImage: UIImage = { - return generateBackgroundTemplateImage(addStripe: false, isTransparent: false) + return generateBackgroundTemplateImage(addStripe: false, backgroundAlpha: 0.1) }() private let transparentBackgroundSolidTemplateImage: UIImage = { - return generateBackgroundTemplateImage(addStripe: true, isTransparent: true) + return generateBackgroundTemplateImage(addStripe: true, backgroundAlpha: 0.0) }() private let transparentBackgroundDashTemplateImage: UIImage = { - return generateBackgroundTemplateImage(addStripe: false, isTransparent: true) + return generateBackgroundTemplateImage(addStripe: false, backgroundAlpha: 0.0) +}() + +private let solidBackgroundTemplateImage: UIImage = { + return generateBackgroundTemplateImage(addStripe: false, backgroundAlpha: 1.0) }() private func generateDashBackgroundTemplateImage() -> UIImage { @@ -450,6 +454,7 @@ public final class MessageInlineBlockBackgroundView: UIView { var primaryColor: UIColor var secondaryColor: UIColor? var thirdColor: UIColor? + var backgroundColor: UIColor? var pattern: Pattern? var displayProgress: Bool @@ -459,6 +464,7 @@ public final class MessageInlineBlockBackgroundView: UIView { primaryColor: UIColor, secondaryColor: UIColor?, thirdColor: UIColor?, + backgroundColor: UIColor?, pattern: Pattern?, displayProgress: Bool ) { @@ -467,6 +473,7 @@ public final class MessageInlineBlockBackgroundView: UIView { self.primaryColor = primaryColor self.secondaryColor = secondaryColor self.thirdColor = thirdColor + self.backgroundColor = backgroundColor self.pattern = pattern self.displayProgress = displayProgress } @@ -484,6 +491,7 @@ public final class MessageInlineBlockBackgroundView: UIView { primaryColor: params.primaryColor, secondaryColor: params.secondaryColor, thirdColor: params.thirdColor, + backgroundColor: params.backgroundColor, pattern: params.pattern, animation: .None ) @@ -595,6 +603,7 @@ public final class MessageInlineBlockBackgroundView: UIView { primaryColor: UIColor, secondaryColor: UIColor?, thirdColor: UIColor?, + backgroundColor: UIColor?, pattern: Pattern?, animation: ListViewItemUpdateAnimation ) { @@ -604,6 +613,7 @@ public final class MessageInlineBlockBackgroundView: UIView { primaryColor: primaryColor, secondaryColor: secondaryColor, thirdColor: thirdColor, + backgroundColor: backgroundColor, pattern: pattern, displayProgress: self.displayProgress ) @@ -618,20 +628,25 @@ public final class MessageInlineBlockBackgroundView: UIView { patternContentLayer.layerTintColor = primaryColor.cgColor } - if params.isTransparent { - if params.secondaryColor != nil { - self.backgroundView.image = transparentBackgroundDashTemplateImage - } else { - self.backgroundView.image = transparentBackgroundSolidTemplateImage - } + if let backgroundColor = params.backgroundColor { + self.backgroundView.image = solidBackgroundTemplateImage + self.backgroundView.tintColor = backgroundColor } else { - if params.secondaryColor != nil { - self.backgroundView.image = backgroundDashTemplateImage + if params.isTransparent { + if params.secondaryColor != nil { + self.backgroundView.image = transparentBackgroundDashTemplateImage + } else { + self.backgroundView.image = transparentBackgroundSolidTemplateImage + } } else { - self.backgroundView.image = backgroundSolidTemplateImage + if params.secondaryColor != nil { + self.backgroundView.image = backgroundDashTemplateImage + } else { + self.backgroundView.image = backgroundSolidTemplateImage + } } + self.backgroundView.tintColor = params.primaryColor } - self.backgroundView.tintColor = params.primaryColor } if previousParams?.pattern != params.pattern { diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index ed10c8204b..8008e9fe63 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -500,12 +500,21 @@ private func makeTextInputTheme(context: AccountContext, interfaceState: ChatPre lineStyle = .solid(color: interfaceState.theme.list.itemAccentColor) authorNameColor = interfaceState.theme.list.itemAccentColor } + + let codeBackgroundColor: UIColor + if interfaceState.theme.overallDarkAppearance { + codeBackgroundColor = UIColor(white: 1.0, alpha: 0.05) + } else { + codeBackgroundColor = UIColor(white: 0.0, alpha: 0.05) + } return ChatInputTextView.Theme( quote: ChatInputTextView.Theme.Quote( background: authorNameColor.withMultipliedAlpha(interfaceState.theme.overallDarkAppearance ? 0.2 : 0.1), foreground: authorNameColor, - lineStyle: lineStyle + lineStyle: lineStyle, + codeBackground: codeBackgroundColor, + codeForeground: authorNameColor ) ) } diff --git a/submodules/TextFormat/Sources/ChatTextInputAttributes.swift b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift index a836f1cb22..b165172c2c 100644 --- a/submodules/TextFormat/Sources/ChatTextInputAttributes.swift +++ b/submodules/TextFormat/Sources/ChatTextInputAttributes.swift @@ -148,8 +148,13 @@ public func textAttributedStringForStateText(_ stateText: NSAttributedString, fo } else if key == ChatTextInputAttributes.customEmoji { result.addAttribute(key, value: value, range: range) result.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.clear, range: range) - } else if key == ChatTextInputAttributes.block { - fontAttributes.insert(.blockQuote) + } else if key == ChatTextInputAttributes.block, let value = value as? ChatTextInputTextQuoteAttribute { + switch value.kind { + case .quote: + fontAttributes.insert(.blockQuote) + case .code: + fontAttributes.insert(.monospace) + } result.addAttribute(key, value: value, range: range) } } @@ -742,8 +747,13 @@ public func refreshChatTextInputAttributes(textView: UITextView, primaryTextColo } else if key == ChatTextInputAttributes.customEmoji, let value = value as? ChatTextInputTextCustomEmojiAttribute { textView.textStorage.addAttribute(key, value: value, range: range) textView.textStorage.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.clear, range: range) - } else if key == ChatTextInputAttributes.block { - fontAttributes.insert(.blockQuote) + } else if key == ChatTextInputAttributes.block, let value = value as? ChatTextInputTextQuoteAttribute { + switch value.kind { + case .quote: + fontAttributes.insert(.blockQuote) + case .code: + fontAttributes.insert(.monospace) + } textView.textStorage.addAttribute(key, value: value, range: range) } } diff --git a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift index 03321b3641..63b88620a2 100644 --- a/submodules/TextFormat/Sources/StringWithAppliedEntities.swift +++ b/submodules/TextFormat/Sources/StringWithAppliedEntities.swift @@ -61,7 +61,7 @@ public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [M private let syntaxHighlighter = Syntaxer() -public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, baseCodeBlockColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil) -> NSAttributedString { +public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil) -> NSAttributedString { let baseQuoteTintColor = baseQuoteTintColor ?? baseColor var nsString: NSString? @@ -210,16 +210,19 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti string.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.Code), value: nsString!.substring(with: range), range: range) case let .Pre(language): addFontAttributes(range, .monospace) + addFontAttributes(range, .blockQuote) if nsString == nil { nsString = text as NSString } - if let baseCodeBlockColor { - string.addAttribute(NSAttributedString.Key(rawValue: "Attribute__Blockquote"), value: TextNodeBlockQuoteData(kind: .code(language: language), title: nil, color: baseCodeBlockColor, secondaryColor: nil, tertiaryColor: nil), range: range) + if let codeBlockTitleColor, let codeBlockAccentColor, let codeBlockBackgroundColor { + string.addAttribute(NSAttributedString.Key(rawValue: "Attribute__Blockquote"), value: TextNodeBlockQuoteData(kind: .code(language: language), title: language.flatMap { + NSAttributedString(string: $0.capitalized, font: boldFont.withSize(round(boldFont.pointSize * 0.8235294117647058)), textColor: codeBlockTitleColor) + }, color: codeBlockAccentColor, secondaryColor: nil, tertiaryColor: nil, backgroundColor: codeBlockBackgroundColor), range: range) } case .BlockQuote: addFontAttributes(range, .blockQuote) - string.addAttribute(NSAttributedString.Key(rawValue: "Attribute__Blockquote"), value: TextNodeBlockQuoteData(kind: .quote, title: nil, color: baseQuoteTintColor, secondaryColor: baseQuoteSecondaryTintColor, tertiaryColor: baseQuoteTertiaryTintColor), range: range) + string.addAttribute(NSAttributedString.Key(rawValue: "Attribute__Blockquote"), value: TextNodeBlockQuoteData(kind: .quote, title: nil, color: baseQuoteTintColor, secondaryColor: baseQuoteSecondaryTintColor, tertiaryColor: baseQuoteTertiaryTintColor, backgroundColor: baseQuoteTintColor.withMultipliedAlpha(0.1)), range: range) case .BankCard: string.addAttribute(NSAttributedString.Key.foregroundColor, value: linkColor, range: range) if underlineLinks && underlineAllLinks { diff --git a/third-party/libprisma/Sources/Highlight.h b/third-party/libprisma/Sources/Highlight.h index a1130e069a..f545b92de2 100644 --- a/third-party/libprisma/Sources/Highlight.h +++ b/third-party/libprisma/Sources/Highlight.h @@ -49,25 +49,28 @@ public: std::string_view match(bool& success, size_t& pos, std::string_view text) const { - boost::cmatch m; - - auto flags = boost::regex_constants::match_not_dot_newline; - auto match = boost::regex_search(text.data() + pos, text.data() + text.size(), m, m_regex, flags); - if (match) - { - success = true; - pos += m.position(); - - if (m_lookbehind && m[1].matched) + try { + boost::cmatch m; + + auto flags = boost::regex_constants::match_not_dot_newline; + auto match = boost::regex_search(text.data() + pos, text.data() + text.size(), m, m_regex, flags); + if (match) { - // change the match to remove the text matched by the Prism lookbehind group - auto lookbehindLength = m[1].length(); - pos += lookbehindLength; - - return text.substr(pos, m[0].length() - lookbehindLength); + success = true; + pos += m.position(); + + if (m_lookbehind && m[1].matched) + { + // change the match to remove the text matched by the Prism lookbehind group + auto lookbehindLength = m[1].length(); + pos += lookbehindLength; + + return text.substr(pos, m[0].length() - lookbehindLength); + } + + return text.substr(pos, m[0].length()); } - - return text.substr(pos, m[0].length()); + } catch(...) { } return {};