You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.2 KiB
C

#include "model/status.h"
// Submodules
#include "collections/array.h"
#include "util/format.h"
// Model
#include "model/account.h"
#include "model/emoji.h"
// Standard Library
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
char* status_render_source( struct status* s, const char* default_server )
{
if( s->content ) {
goto done;
}
if( !s->source ) {
s->content = strdup("");
goto done;
}
char account_server[50]; {
struct account* status_account = account_from_id(s->account_id);
strncpy( account_server, status_account->server, 50 );
account_free(status_account);
}
char* result = NULL;
size_t size = 0;
FILE* f = open_memstream(&result,&size);
for( char* i = s->source; *i; ++i ) {
// Handle URLs
if( ( 0 == strncmp( i, "https://", 8 ) ) || ( 0 == strncmp( i, "http://", 7 ) ) ) {
char* start = i;
while( *i && !index(" ,\r\n\t",*i) ) ++i;
char* url = strndup( start, i - start );
printf( "link, count = %d, url = '%s'\n", (int)(i - start), url );
fprintf( f, "<a href='%s' rel='ugc'>%s</a>", url, url );
printf( "<a href='%s' rel='ugc'>%s</a>", url, url );
free(url);
} else if( isalpha(i[1]) && *i == '#' ) {
i += 1;
char* start = i;
while( *i && ( isalpha(*i) || *i == '_' || *i == '-' ) ) ++i;
char* tag = strndup( start, i - start );
printf( "tag = %s\n", tag );
fprintf( f, "<a class=\"hashtag\" data-tag=\"%s\" href=\"https://%s/tag/%s\" rel=\"tag ugc\">#%s</a>",
tag, default_server, tag, tag
);
status_add_tag( s, tag );
free(tag);
} else if( isalpha(i[1]) && *i == '@' ) {
char* start = i;
while( *i && !index(" ,\r\n",*i) ) ++i;
char* handle = strndup( start, i - start );
/*
if( strstr( handle, "mostr.pub" ) ) {
fprintf( f, "<a href='https://mostr.pub/%s'>@%.4s@nostr</a>", handle, handle );
} else {
*/
struct account* user = account_from_webfinger( &handle[1], default_server );
if( user ) {
status_add_mention( s, user->id );
fprintf( f,
"<span class='h-card'>"
"<a class='u-url mention' href='%s' rel='ugc'>"
"@<span>%s</span>"
"</a>"
"</span>",
user->account_url, user->handle
);
account_free(user);
} else {
fprintf( f, "%s", handle );
}
//}
free(handle);
} else if( *i == ':' ) {
// Emoji
++i;
char* start = i;
while( *i && !index(" ,:",*i) ) ++i;
char* shortcode = strndup( start, i - start );
if( !*shortcode ) {
fprintf( f, ":" );
} else {
// Check if shortcode is already present in status
for( int i = 0; i < s->emoji.count; ++i ) {
struct emoji* e = s->emoji.items[i];
if( 0 == strcmp( e->shortcode, shortcode ) ) { goto already_has_emoji; }
}
struct emoji* e = emoji_from_shortcode( shortcode );
if( e ) {
array_append( &s->emoji, sizeof(e), &e );
}
already_has_emoji:
fprintf( f, ":%s", shortcode );
}
free(shortcode);
} else if( *i == '\n' ) {
fprintf( f, "<br/>" );
continue;
} else if( *i == '\r' ) {
// Ignore
}
if( !*i ) {
printf( "break\n" );
break;
}
fputc( *i, f );
}
fputc( '\0', f );
fclose(f);
s->content = result;
done:
status_save(s);
return s->content;
}