Linkify SSB refs

main
cel 5 years ago
parent 57c8c1d88a
commit a1c15a7270

@ -26,12 +26,26 @@
#define strncasecmp _strnicmp
#endif
static int
ismentionchar(char c)
{
return isalnum(c) || c == '_' || c == '-' || c == '+' || c == '/' || c == '=';
}
static int
ishashtagend(char c)
{
return isspace(c) || c == '(' || c == ')' || c == '[' || c == ']' ||
c == ',' || c == '.' || c == '"';
}
int
sd_autolink_issafe(const uint8_t *link, size_t link_len)
{
static const size_t valid_uris_count = 8;
static const size_t valid_uris_count = 12;
static const char *valid_uris[] = {
"§",
"@", "&", "%", "#",
"gemini://", "gopher://",
"/", "http://", "https://", "ftp://", "mailto:"
};
@ -329,3 +343,46 @@ sd_autolink__zet(
return link_end;
}
size_t
sd_autolink__ssb(
size_t *rewind_p,
struct buf *link,
uint8_t *data,
size_t max_rewind,
size_t size,
unsigned int flags)
{
size_t link_end = 1, rewind = 0, domain_len;
char sigil = data[0];
if (sigil == '#') {
while (link_end < size && isdigit(data[link_end]))
link_end++;
if (link_end < size && (isspace(data[link_end]) ||
ispunct(data[link_end])))
return 0;
while (link_end < size && !ishashtagend(data[link_end]))
link_end++;
} else {
if (sigil != '%' && sigil != '@' && sigil != '&')
return 0;
while (link_end < size && (ismentionchar(data[link_end]) || data[link_end] == '.'))
link_end++;
if (ispunct(data[link_end-1]))
link_end--;
if (link_end < 2)
return 0;
}
bufput(link, data - rewind, link_end + rewind);
*rewind_p = rewind;
return link_end;
}

@ -46,6 +46,10 @@ size_t
sd_autolink__zet(size_t *rewind_p, struct buf *link,
uint8_t *data, size_t offset, size_t size, unsigned int flags);
size_t
sd_autolink__ssb(size_t *rewind_p, struct buf *link,
uint8_t *data, size_t offset, size_t size, unsigned int flags);
#ifdef __cplusplus
}
#endif

@ -71,7 +71,9 @@ static size_t char_entity(struct buf *ob, struct sd_markdown *rndr, uint8_t *dat
static size_t char_langle_tag(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_at(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_ssb(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_autolink_zet(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
static size_t char_superscript(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
@ -86,8 +88,9 @@ enum markdown_char_t {
MD_CHAR_ESCAPE,
MD_CHAR_ENTITITY,
MD_CHAR_AUTOLINK_URL,
MD_CHAR_AUTOLINK_EMAIL,
MD_CHAR_AUTOLINK_AT,
MD_CHAR_AUTOLINK_WWW,
MD_CHAR_AUTOLINK_SSB,
MD_CHAR_AUTOLINK_ZET,
MD_CHAR_SUPERSCRIPT,
};
@ -102,8 +105,9 @@ static char_trigger markdown_char_ptrs[] = {
&char_escape,
&char_entity,
&char_autolink_url,
&char_autolink_email,
&char_autolink_at,
&char_autolink_www,
&char_autolink_ssb,
&char_autolink_zet,
&char_superscript,
};
@ -817,6 +821,17 @@ char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, siz
return link_len;
}
static size_t
char_autolink_at(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
{
size_t link_len;
link_len = char_autolink_ssb(ob, rndr, data, offset, size);
if (link_len) return link_len;
return char_autolink_email(ob, rndr, data, offset, size);
}
static size_t
char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
{
@ -837,6 +852,26 @@ char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_
return link_len;
}
static size_t
char_autolink_ssb(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
{
struct buf *link;
size_t link_len, rewind;
if (!rndr->cb.autolink || rndr->in_link_body)
return 0;
link = rndr_newbuf(rndr, BUFFER_SPAN);
if ((link_len = sd_autolink__ssb(&rewind, link, data, offset, size, 0)) > 0) {
ob->size -= rewind;
rndr->cb.autolink(ob, link, MKDA_SSB, rndr->opaque);
}
rndr_popbuf(rndr, BUFFER_SPAN);
return link_len;
}
static size_t
char_autolink_zet(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
{
@ -2457,8 +2492,11 @@ sd_markdown_new(
if (extensions & MKDEXT_AUTOLINK) {
md->active_char[':'] = MD_CHAR_AUTOLINK_URL;
md->active_char['@'] = MD_CHAR_AUTOLINK_EMAIL;
md->active_char['@'] = MD_CHAR_AUTOLINK_AT;
md->active_char['w'] = MD_CHAR_AUTOLINK_WWW;
md->active_char['%'] = MD_CHAR_AUTOLINK_SSB;
md->active_char['&'] = MD_CHAR_AUTOLINK_SSB;
md->active_char['#'] = MD_CHAR_AUTOLINK_SSB;
md->active_char[194] = MD_CHAR_AUTOLINK_ZET;
}

@ -40,7 +40,8 @@ enum mkd_autolink {
MKDA_NOT_AUTOLINK, /* used internally when it is not an autolink*/
MKDA_NORMAL, /* normal http/http/ftp/mailto/etc link */
MKDA_EMAIL, /* e-mail link without explit mailto: */
MKDA_ZET, /* zet link */
MKDA_SSB, /* ssb link */
MKDA_ZET, /* zet link */
};
enum mkd_tableflags {

@ -27,6 +27,9 @@
static const size_t sigil_size = sizeof("§")-1;
static const int id_length = 16;
static const char ssb_ref_base[] = "http://localhost:8027/";
static const char ssb_channel_base[] = "http://localhost:8027/channel/";
static const int max_cols = 40;
static char server_hostname[256];
@ -473,7 +476,14 @@ md_rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, co
if (!strncmp((char *)link->data, "§", sigil_size))
houdini_escape_href(ob, link->data + sigil_size,
link->size - sigil_size);
else
if (link->data[0] == '#') {
BUFPUTSL(ob, ssb_channel_base);
houdini_escape_href(ob, link->data + 1, link->size - 1);
} else if (link->data[0] == '#' || link->data[0] == '@'
|| link->data[0] == '&' || link->data[0] == '%') {
BUFPUTSL(ob, ssb_ref_base);
houdini_escape_href(ob, link->data, link->size);
} else
houdini_escape_href(ob, link->data, link->size);
}
@ -495,12 +505,13 @@ md_rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, co
return 1;
}
static void put_link_truncated(struct buf *ob, const struct buf *link) {
if (link->size < max_cols) {
return houdini_escape_html0(ob, link->data, link->size, 0);
static void put_link_truncated(struct buf *ob, const struct buf *link, int max_length) {
if (link->size > max_length) {
houdini_escape_html0(ob, link->data, max_length, 0);
BUFPUTSL(ob, "");
} else {
houdini_escape_html0(ob, link->data, link->size, 0);
}
houdini_escape_html0(ob, link->data, max_cols, 0);
BUFPUTSL(ob, "");
}
static int
@ -521,7 +532,15 @@ md_rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type,
BUFPUTSL(ob, "mailto:");
if (type == MKDA_ZET)
houdini_escape_href(ob, link->data + sigil_size, link->size - sigil_size);
else
else if (type == MKDA_SSB) {
if (link->data[0] == '#') {
BUFPUTSL(ob, ssb_channel_base);
houdini_escape_href(ob, link->data + 1, link->size - 1);
} else {
BUFPUTSL(ob, ssb_ref_base);
houdini_escape_href(ob, link->data, link->size);
}
} else
houdini_escape_href(ob, link->data, link->size);
if (type == MKDA_ZET) {
@ -548,8 +567,10 @@ md_rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type,
*/
if (bufprefix(link, "mailto:") == 0) {
houdini_escape_html0(ob, link->data + 7, link->size - 7, 0);
} else if (link->data[0] == '&' || link->data[0] == '@' || link->data[0] == '%') {
put_link_truncated(ob, link, 8);
} else {
put_link_truncated(ob, link);
put_link_truncated(ob, link, max_cols);
}
BUFPUTSL(ob, "</a>");

Loading…
Cancel
Save