Advertisement
ronerez

Katex SwiftUI Example

Apr 25th, 2025
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 5.04 KB | Source Code | 0 0
  1. import SwiftUI
  2. import WebKit
  3.  
  4. struct FieldsView: View {
  5.     let fieldDef = """
  6.    <p>A field \\((F, +, \\cdot)\\) is a set \\(F\\) together with two binary operations: addition \\((+)\\) and multiplication \\((\\cdot)\\), satisfying the following axioms:</p>
  7.  
  8.    <ol>
  9.        <li><strong>(F1)</strong> \\((F, +)\\) is an abelian group:
  10.            <ul>
  11.                <li>Closure: \\(a + b \\in F\\)</li>
  12.                <li>Associativity: \\[(a + b) + c = a + (b + c)\\]</li>
  13.                <li>Commutativity: \\(a + b = b + a\\)</li>
  14.                <li>Identity: \\(\\exists 0_F \\in F\\) such that \\(a + 0_F = a\\)</li>
  15.                <li>Inverse: \\(\\exists -a \\in F\\) such that \\(a + (-a) = 0_F\\)</li>
  16.            </ul>
  17.        </li>
  18.        <li><strong>(F2)</strong> \\((F \\setminus \\{0_F\\}, \\cdot)\\) is an abelian group:
  19.            <ul>
  20.                <li>Closure: \\(a \\cdot b \\in F\\)</li>
  21.                <li>Associativity: \\((a \\cdot b) \\cdot c = a \\cdot (b \\cdot c)\\)</li>
  22.                <li>Commutativity: \\(a \\cdot b = b \\cdot a\\)</li>
  23.                <li>Identity: \\(\\exists 1_F \\in F\\) such that \\(a \\cdot 1_F = a\\)</li>
  24.            </ul>
  25.        </li>
  26.        <li><strong>(F3)</strong> Distributivity: \\(a \\cdot (b + c) = a \\cdot b + a \\cdot c\\)</li>
  27.        <li><strong>(F4)</strong> No zero divisors: if \\(a \\cdot b = 0_F\\), then \\(a = 0_F\\) or \\(b = 0_F\\)</li>
  28.    </ol>
  29.    """
  30.  
  31.     var body: some View {
  32.         ScrollView {
  33.             VStack(alignment: .leading, spacing: 16) {
  34.                 Text("Field Definition")
  35.                     .font(.title2)
  36.                     .bold()
  37.                 HTMLWebView(
  38.                     text: fieldDef,
  39.                     fontSize: 16,
  40.                     borderColor: .blue,
  41.                     height: 500
  42.                 )
  43.             }
  44.             .padding()
  45.         }
  46.     }
  47. }
  48.  
  49.  
  50.  
  51. // MARK: - Simple WKWebView Wrapper
  52. struct WebView: UIViewRepresentable {
  53.     let html: String
  54.    
  55.     func makeUIView(context: Context) -> WKWebView {
  56.         let webView = WKWebView()
  57.         webView.scrollView.isScrollEnabled = false
  58.         webView.isOpaque = false
  59.         webView.backgroundColor = .clear
  60.         return webView
  61.     }
  62.    
  63.     func updateUIView(_ uiView: WKWebView, context: Context) {
  64.         uiView.loadHTMLString(html, baseURL: nil)
  65.     }
  66. }
  67.  
  68. // MARK: - HTMLWebView with KaTeX Support
  69. struct HTMLWebView: View {
  70.     let text: String
  71.     let fontSize: Int
  72.     let borderColor: Color
  73.     let borderWidth: CGFloat
  74.     let cornerRadius: CGFloat
  75.     let height: CGFloat
  76.     let paragraphAlignment: String // e.g., "left", "center", "right", "justify"
  77.    
  78.     // Custom Initializer with Default Parameters
  79.     init(
  80.         text: String,
  81.         fontSize: Int = 16,
  82.         borderColor: Color = .blue,
  83.         borderWidth: CGFloat = 2,
  84.         cornerRadius: CGFloat = 10,
  85.         height: CGFloat = 200,
  86.         paragraphAlignment: String = "left"
  87.     ) {
  88.         self.text = text
  89.         self.fontSize = fontSize
  90.         self.borderColor = borderColor
  91.         self.borderWidth = borderWidth
  92.         self.cornerRadius = cornerRadius
  93.         self.height = height
  94.         self.paragraphAlignment = paragraphAlignment
  95.     }
  96.    
  97.     var body: some View {
  98.         let htmlContent = composeHTML(text: text)
  99.        
  100.         return VStack {
  101.             WebView(html: htmlContent)
  102.         }
  103.         .frame(height: height)
  104.         .overlay(
  105.             RoundedRectangle(cornerRadius: cornerRadius)
  106.                 .stroke(borderColor, lineWidth: borderWidth)
  107.         )
  108.     }
  109.    
  110.     private func composeHTML(text: String) -> String {
  111.         """
  112.        <!DOCTYPE html>
  113.        <html>
  114.        <head>
  115.            <meta name="viewport" content="width=device-width, initial-scale=1.0">
  116.            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">
  117.             <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
  118.             <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"
  119.                 onload="renderMathInElement(document.body, {
  120.                    delimiters: [
  121.                        {left: '\\\\(', right: '\\\\)', display: false},
  122.                        {left: '\\\\[', right: '\\\\]', display: true}
  123.                    ]
  124.                });">
  125.             </script>
  126.             <style>
  127.                 body {
  128.                     font-family: -apple-system, sans-serif;
  129.                     font-size: \(fontSize)px;
  130.                     margin: 12px;
  131.                     color: #000;
  132.                     background-color: transparent;
  133.                 }
  134.                 p {
  135.                     text-align: \(paragraphAlignment);
  136.                 }
  137.                 .katex {
  138.                     font-size: \(fontSize)px;
  139.                 }
  140.             </style>
  141.         </head>
  142.         <body>
  143.             \(text)
  144.         </body>
  145.         </html>
  146.         """
  147.    }
  148. }
  149.  
  150.  
  151.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement