Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
public enum EnrichedMarkdown {}
public enum EnrichedMarkdown {
// Namespace for the EnrichedMarkdown library.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import SwiftUI
import UIKit

public struct EnrichedMarkdownText: View {
private let markdown: String

@Environment(\.markdownStyleConfig) private var styleConfig

public init(_ markdown: String) {
self.markdown = markdown
}

public var body: some View {
MarkdownTextViewRepresentable(
attributedText: MarkdownRenderer.render(markdown, config: styleConfig)
)
.fixedSize(horizontal: false, vertical: true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import SwiftUI
import UIKit

struct MarkdownTextViewRepresentable: UIViewRepresentable {
let attributedText: NSAttributedString

func makeUIView(context: Context) -> MarkdownTextView {
MarkdownTextView()
}

func updateUIView(_ textView: MarkdownTextView, context: Context) {
textView.setMarkdownAttributedText(attributedText)
}

@available(iOS 16.0, *)
func sizeThatFits(_ proposal: ProposedViewSize, uiView: MarkdownTextView, context: Context) -> CGSize? {
let width = proposal.width ?? UIScreen.main.bounds.width
let size = uiView.sizeThatFits(CGSize(width: width, height: .greatestFiniteMagnitude))
return CGSize(width: width, height: size.height)
}
}

final class MarkdownTextView: UITextView {
override var intrinsicContentSize: CGSize {
let width = bounds.width > 0 ? bounds.width : UIView.noIntrinsicMetric
guard width != UIView.noIntrinsicMetric else {
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
}
let size = sizeThatFits(CGSize(width: width, height: .greatestFiniteMagnitude))
return CGSize(width: UIView.noIntrinsicMetric, height: size.height)
}

init() {
super.init(frame: .zero, textContainer: nil)
configure()
}

@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func configure() {
isEditable = false
isScrollEnabled = false
backgroundColor = .clear
textContainerInset = .zero
textContainer.lineFragmentPadding = 0
setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
}

func setMarkdownAttributedText(_ attributedText: NSAttributedString) {
guard !(self.attributedText?.isEqual(to: attributedText) ?? false) else { return }
self.attributedText = attributedText
invalidateIntrinsicContentSize()
}
}