ContentParsing.swift (3395B)
1 // 2 // ContentParsing.swift 3 // damus 4 // 5 // Created by William Casarin on 2023-07-22. 6 // 7 8 import Foundation 9 10 enum NoteContent { 11 case note(NostrEvent) 12 case content(String, TagsSequence?) 13 14 init(note: NostrEvent, keypair: Keypair) { 15 if note.known_kind == .dm { 16 self = .content(note.get_content(keypair), note.tags) 17 } else { 18 self = .note(note) 19 } 20 } 21 } 22 23 func parsed_blocks_finish(bs: inout note_blocks, tags: TagsSequence?) -> Blocks { 24 var out: [Block] = [] 25 26 var i = 0 27 while (i < bs.num_blocks) { 28 let block = bs.blocks[i] 29 30 if let converted = Block(block, tags: tags) { 31 out.append(converted) 32 } 33 34 i += 1 35 } 36 37 let words = Int(bs.words) 38 blocks_free(&bs) 39 40 return Blocks(words: words, blocks: out) 41 42 } 43 44 func parse_note_content(content: NoteContent) -> Blocks { 45 var bs = note_blocks() 46 bs.num_blocks = 0; 47 48 blocks_init(&bs) 49 50 switch content { 51 case .content(let s, let tags): 52 return s.withCString { cptr in 53 damus_parse_content(&bs, cptr) 54 return parsed_blocks_finish(bs: &bs, tags: tags) 55 } 56 case .note(let note): 57 damus_parse_content(&bs, note.content_raw) 58 return parsed_blocks_finish(bs: &bs, tags: note.tags) 59 } 60 } 61 62 func interpret_event_refs_ndb(blocks: [Block], tags: TagsSequence) -> [EventRef] { 63 if tags.count == 0 { 64 return [] 65 } 66 67 /// build a set of indices for each event mention 68 let mention_indices = build_mention_indices(blocks, type: .e) 69 70 /// simpler case with no mentions 71 if mention_indices.count == 0 { 72 return interp_event_refs_without_mentions_ndb(tags.note.referenced_noterefs) 73 } 74 75 return interp_event_refs_with_mentions_ndb(tags: tags, mention_indices: mention_indices) 76 } 77 78 func interp_event_refs_without_mentions_ndb(_ ev_tags: References<NoteRef>) -> [EventRef] { 79 var evrefs: [EventRef] = [] 80 var first: Bool = true 81 var root_id: NoteRef? = nil 82 var any_marker: Bool = false 83 84 for ref in ev_tags { 85 if let marker = ref.marker { 86 any_marker = true 87 switch marker { 88 case .root: root_id = ref 89 case .reply: evrefs.append(.reply(ref)) 90 case .mention: evrefs.append(.mention(.noteref(ref))) 91 } 92 } else { 93 if !any_marker && first { 94 root_id = ref 95 first = false 96 } else if !any_marker { 97 evrefs.append(.reply(ref)) 98 } 99 } 100 } 101 102 if let root_id { 103 if evrefs.count == 0 { 104 return [.reply_to_root(root_id)] 105 } else { 106 evrefs.insert(.thread_id(root_id), at: 0) 107 } 108 } 109 110 return evrefs 111 } 112 113 func interp_event_refs_with_mentions_ndb(tags: TagsSequence, mention_indices: Set<Int>) -> [EventRef] { 114 var mentions: [EventRef] = [] 115 var ev_refs: [NoteRef] = [] 116 var i: Int = 0 117 118 for tag in tags { 119 if let note_id = NoteRef.from_tag(tag: tag) { 120 if mention_indices.contains(i) { 121 mentions.append(.mention(.noteref(note_id, index: i))) 122 } else { 123 ev_refs.append(note_id) 124 } 125 } 126 i += 1 127 } 128 129 var replies = interp_event_refs_without_mentions(ev_refs) 130 replies.append(contentsOf: mentions) 131 return replies 132 }