test
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

reorganize, improve parser

12Me21 b144f987 77676007

+3 -106
-102
facet.js
··· 5 5 // 2: list of "windows" {start:Number, end:Number, spans:Span[]} - do not overlap (like facets) 6 6 // 3: list of facets {index:ByteRange, features:Feature[]} 7 7 8 - export class MarkupParser { 9 - constructor(big_regex, process_match) { 10 - this.process_match = process_match 11 - this.big_regex = big_regex 12 - } 13 - text_to_spans(text) { 14 - let spans = [] 15 - for (let match of String(text).matchAll(this.big_regex)) { 16 - let span = this.process_match(match) 17 - if (span) { 18 - span.start = match.index 19 - span.end = match.index+match[0].length 20 - spans.push(span) 21 - } 22 - } 23 - return spans 24 - } 25 - } 26 - 27 - let r = String.raw 28 - let whitespace = r`\s\u00AD\u2060\u200A\u200B\u200C\u200D\u20e2` 29 - let url = r`[-\w/%&=#+~@$*'!?,.;:]*` 30 - let url_final = r`[-\w/%&=#+~@$*']` 31 - let big_regex = RegExp([ 32 - r`\b(?<link>https?://${url}${url_final}([(]${url}[)](${url}${url_final})?)?)(?:\[(?<link_text>.*?)\])?`, 33 - r`(?<=^|\s)[##](?<hashtag>(?!\uFE0F)[^${whitespace}]*[^\p{P}${whitespace}])`, // note: must filter out #123 34 - r`(?<=^|\s|[(])@(?<mention>[-a-zA-Z0-9]+([.][-a-zA-Z0-9]+)+)\b`, 35 - ].join("|"), 'gu') 36 - function process_match(match) { 37 - let g = match.groups 38 - if (g.mention!=null) { 39 - return { 40 - strip: [0, 0], 41 - feature: { 42 - $type: 'app.bsky.richtext.facet#mention', 43 - did: g.mention, // hack, DID must be resolved afterwards 44 - }, 45 - } 46 - } 47 - if (g.link!=null) { 48 - if (g.link_text) { 49 - return { 50 - strip: [g.link.length+1, 1], 51 - feature: { 52 - $type: 'app.bsky.richtext.facet#link', 53 - uri: g.link, 54 - }, 55 - } 56 - } else { 57 - return { 58 - strip: [0, 0], 59 - feature: { 60 - $type: 'app.bsky.richtext.facet#link', 61 - uri: g.link, 62 - }, 63 - } 64 - } 65 - } 66 - if (g.hashtag!=null && !/^#\d+$/.test(g.hashtag)) { 67 - return { 68 - strip: [0,0], 69 - feature: { 70 - $type: 'app.bsky.richtext.facet#tag', 71 - tag: g.hashtag, 72 - }, 73 - } 74 - } 75 - } 76 - export let markup1 = new MarkupParser(big_regex, process_match) 77 - 78 - export function markup_italic(text) { 79 - let spans = [] 80 - for (let m of text.matchAll(/[/].*?[/]/g)) { 81 - spans.push({ 82 - start: m.index, 83 - end: m.index+m[0].length, 84 - strip: [1,1], 85 - feature: { 86 - $type: "com.example.richtext.facet#markup", 87 - style: "italic" 88 - }, 89 - }) 90 - } 91 - return spans 92 - } 93 - 94 - export function markup_bold(text) { 95 - let spans = [] 96 - for (let m of text.matchAll(/[*][*].*?[*][*]/g)) { 97 - spans.push({ 98 - start: m.index, 99 - end: m.index+m[0].length, 100 - strip: [2,2], 101 - feature: { 102 - $type: "com.example.richtext.facet#markup", 103 - style: "bold" 104 - }, 105 - }) 106 - } 107 - return spans 108 - } 109 - 110 8 // the strip field is used internally to process things. 111 9 // SOME Features have support for doing it on the client side (this way we can leave the extra syntax chars in the post text, for clients which dont recognize those Features), so we write their strip values to the output 112 10 // while other Features (i.e. the builtin ones) don't, so we want to pre-apply their strip before outputting
+3 -4
test3.html
··· 12 12 </style> 13 13 14 14 <script type=module> 15 - import {MarkedText, markup_italic, markup1, markup_bold} from './facet.js' 15 + import {MarkedText} from './facet.js' 16 16 import {index_to_byteindex, byteindex_to_index} from './byteindex.js' 17 + import {markup_main} from './markup.js' 17 18 import {HTML} from './template.js' 18 19 19 20 function *post_to_segments(post) { ··· 117 118 118 119 let text = new MarkedText(inputtext) 119 120 text.spans = [ 120 - ...markup_italic(text.text), 121 - ...markup1.text_to_spans(text.text), 122 - ...markup_bold(text.text), 121 + ...markup_main(text.text), 123 122 ] 124 123 125 124 text.make_windows()