╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ markdown.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯
821 } 822 823 fn isAutolinkBoundary(c: u8) bool { 824 return switch (c) { 825 ' ', '\n', '*', '_', '~', '(' => true, 826 else => false, 827 }; 828 } 829 830 // the length of a bare `http://` or `https://` link at the start of `s` 831 fn bareAutolink(s: []const u8) ?usize { 832 const prefix_len: usize = if (std.ascii.startsWithIgnoreCase(s, "https://")) 8 else if (std.ascii.startsWithIgnoreCase(s, "http://")) 7 else return null; 833 var end = prefix_len; 834 while (end < s.len and !isSpace(s[end]) and s[end] != '<') end += 1; 835 var unmatched_closes = @as(isize, @intCast(std.mem.count(u8, s[0..end], ")"))) - @as(isize, @intCast(std.mem.count(u8, s[0..end], "("))); 836 // trailing punctuation is left out, as is an unbalanced closing paren 837 while (end > prefix_len) : (end -= 1) { 838 const c = s[end - 1]; 839 if (c == ')' and unmatched_closes > 0) { 840 unmatched_closes -= 1; 841 } else if (std.mem.indexOfScalar(u8, "?!.,:;*_~'\"", c) == null) break; 842 } 843 return if (end > prefix_len) end else null; 844 } 845