예제 #1
0
SERD_API
SerdStatus
serd_writer_set_prefix(SerdWriter*     writer,
                       const SerdNode* name,
                       const SerdNode* uri)
{
	if (!serd_env_set_prefix(writer->env, name, uri)) {
		if (writer->syntax != SERD_NTRIPLES) {
			if (writer->context.graph.type || writer->context.subject.type) {
				sink(" .\n\n", 4, writer);
				reset_context(writer, false);
			}
			sink("@prefix ", 8, writer);
			sink(name->buf, name->n_bytes, writer);
			sink(": <", 3, writer);
			write_uri(writer, uri->buf, uri->n_bytes);
			sink("> .\n", 4, writer);
		}
		writer->indent = 0;
		return reset_context(writer, false);
	}
	return SERD_ERR_UNKNOWN;
}
예제 #2
0
파일: text2html.c 프로젝트: sba1/simplemail
char *text2html(unsigned char *buffer, int buffer_len, int flags, const char *fonttag)
{
	unsigned char *saved_buffer = buffer;
	string str;

	if (string_initialize(&str,1024))
	{
		char buf[512];
		int last_color = 0; /* the color of the current line */
		int eval_color = 2; /* recheck the color */
		int initial_color = 1;
		int level = 0;
		int line = 0; /* the type of the line */

		if (flags & TEXT2HTML_BODY_TAG)
		{
			sm_snprintf(buf,sizeof(buf),"<BODY BGCOLOR=\"#%06x\" TEXT=\"#%06x\" LINK=\"#%06x\">",user.config.read_background,user.config.read_text,user.config.read_link);
			string_append(&str,buf);
		}
		string_append(&str,fonttag); /* accepts NULL pointer */

		/* check for >0, otherwise we'll be in an endless loop if buffer_len becomes <0 */
		while (buffer_len > 0)
		{
			if (eval_color)
			{
				int new_level = 0;
				int buffer2_len = buffer_len;
				unsigned char *buffer2 = buffer;
				int new_color = 0;

				/* Determine the citation level. Afterwards, buffer2 will point to the end of the citation symbols. */
				while (buffer2_len)
				{
					unsigned char c = *buffer2;
					if (c == '>')
					{
						new_level++;
						if (new_color == 1) new_color = 2;
						else new_color = 1;
					} else
					{
						if (c != ' ') break;
						if (c == ' ' && !new_level) break;
					}
					buffer2_len--;
					buffer2++;
				}

				if (user.config.read_graphical_quote_bar)
				{
					/* When graphical quote bar is enabled we skip all quotation symbols */
					buffer = buffer2;
					buffer_len = buffer2_len;

					if (level != new_level)
					{
						const char *begin_quote_string = "<TABLE BGCOLOR=\"#%06x\" WIDTH=\"100%%\" STYLE=\"border-left: 3px solid #%06x; border-right: 3px solid #%06x;\"><TD><FONT COLOR=\"#%06x\">";
						const char *end_quote_string = "</FONT></TD></TABLE>";

						/* If new level is larger */
						for (;level < new_level; level++)
						{
							unsigned int color = level%2?user.config.read_quoted:user.config.read_old_quoted;
							sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_quoted_background,color,color,color);
							string_append(&str,buf);
						}

						/* If new level is lower */
						for (;level > new_level; level--)
							string_append(&str,end_quote_string);
					}
				} else
				{
					if (last_color != new_color)
					{
						const char *begin_quote_string = "<FONT COLOR=\"#%x\">";
						const char *end_quote_string = "</FONT>";

						if (!initial_color) string_append(&str,end_quote_string);
						if (new_color == 1)
						{
							sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_quoted);
							string_append(&str,buf);
						}
						else if (new_color == 2)
						{
							sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_old_quoted);
							string_append(&str,buf);
						}
						last_color = new_color;
						if (new_color) initial_color = 0;
						else initial_color = 1;
					}
				}
				eval_color = 0;
			}

			if (!mystrnicmp("http:",(char*)buffer,5)) write_uri(&buffer, &buffer_len, &str);
			else if (!mystrnicmp("mailto:",(char*)buffer,7)) write_uri(&buffer, &buffer_len, &str);
			else if (!mystrnicmp("ftp:",(char*)buffer,4)) write_uri(&buffer, &buffer_len, &str);
			else if (!mystrnicmp("https:",(char*)buffer,6)) write_uri(&buffer, &buffer_len, &str);
			else
			{
				unsigned char c;

				c = *buffer;

				if ((c == '@') && (buffer > saved_buffer))
				{
					/* A @ has been encountered, check if this belongs to an email adresse by traversing back
           * within the string */

					unsigned char *buffer2 = buffer - 1;
					unsigned char *buffer3;
					unsigned char c2;
					int buffer2_len = buffer_len + 1;
					char *address;

					while ((c2 = *buffer2) && buffer2 > saved_buffer)
					{
						static const char noaliaschars[] = {
							" ()<>@,;:\\\"[]\n\r"};

						if (strchr(noaliaschars,c2))
						{
							buffer2++;
							break;
						}
						buffer2_len++;
						buffer2--;
					}

					if ((buffer3 = (unsigned char*)parse_addr_spec((char*)buffer2, &address)))
					{
						int email_len;

						/* crop the string to the beginning of the email address */
						string_crop(&str,0,str.len - (buffer - buffer2));

						buffer_len += buffer - buffer2;
						buffer -= buffer - buffer2;
						email_len = buffer3 - buffer;
						buffer_len -= email_len;

						buffer = buffer3;

						sm_snprintf(buf,sizeof(buf),"<A HREF=\"mailto:%s\"%s>",address, user.config.read_link_underlined?"":" STYLE=\"TEXT-DECORATION: none\"");
						string_append(&str,buf);
						write_unicode(address,&str);
						string_append(&str,"</A>");
						free(address);
						continue;
					}
				}

		  	if (user.config.read_smilies)
		  	{
		  		unsigned int i;
		  		int smily_used = 0;
			  	/* No look into the smily table, this is slow and needs to be improved */
		  		for (i=0;i<sizeof(smily)/sizeof(struct smily);i++)
		  		{
		  			if (!strncmp(smily[i].ascii,(char*)buffer,strlen(smily[i].ascii)))
		  			{
		  				buffer += strlen(smily[i].ascii);
		  				buffer_len -= strlen(smily[i].ascii);
		  				sm_snprintf(buf,sizeof(buf),"<IMG SRC=\"PROGDIR:Images/%s\" VALIGN=\"middle\" ALT=\"%s\">",smily[i].gfx,smily[i].ascii);
		  				string_append(&str,buf);
		  				smily_used = 1;
		  			}
		  		}
		  		if (smily_used) continue;
		  	}

				if (!strncmp("\n<sb>",(char*)buffer,5))
				{
					if (line) string_append(&str,"<BR></TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>");
					line = 1;
					buffer += 5;
					buffer_len -= 5;

					string_append(&str,"<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR><TD VALIGN=\"middle\" WIDTH=\"50%\"><HR></TD><TD>");
					continue;
				}

				if (!strncmp("\n<tsb>",(char*)buffer,6))
				{
					if (line) string_append(&str,"<BR></TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>");
					line = 2;
					buffer += 6;
					buffer_len -= 6;

					string_append(&str,"<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR><TD VALIGN=\"middle\" WIDTH=\"50%\"><HR></TD><TD>");
					continue;
				}

				if (c < 128)
				{
					buffer++;
					buffer_len--;
					if (c== '<') string_append(&str,"&lt;");
					else if (c== '>') string_append(&str,"&gt;");
					else if (c== '&') string_append(&str,"&amp;");
					else if (c == 10)
					{
						eval_color = 1;
						string_append(&str,"<BR>\n");
						if (line)
						{
							string_append(&str,"</TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>");
							line = 0;
						}
					} else
					{
						if (c == 32) {
							if (*buffer == 32 || (flags & TEXT2HTML_NOWRAP)) string_append(&str,"&nbsp;");
							else string_append(&str," ");
						} else {
						  if (c)
						  {
						  	string_append_part(&str,(char*)&c,1);
						  }
						}
					}
				} else
				{
					unsigned int unicode;
					int len = 0;
					/* check if it really could be a utf8 char */
					if (utf8islegal((utf8*)buffer, (utf8*)(buffer+buffer_len)))
					{
						len = utf8tochar((utf8*)buffer, &unicode, user.config.default_codeset);
					}
					if ((len == 0) || (len > buffer_len))
					{
						/* something wrong with that utf8 sequence */
						unicode = '?';
						len = 1;
					}
					buffer_len -= len;
					buffer += len;

					if (unicode == 0) unicode = '_';
					sm_snprintf(buf,sizeof(buf),"&#%d;",unicode);
					string_append(&str,buf);
				}
			}
		}

		if (fonttag) string_append(&str,"</FONT>");

		if (flags & TEXT2HTML_ENDBODY_TAG) string_append(&str,"</BODY>");

		SM_DEBUGF(20,("%s\n",str.str));

		return str.str;
	}
	return NULL;
}
예제 #3
0
static bool
write_node(SerdWriter*        writer,
           const SerdNode*    node,
           const SerdNode*    datatype,
           const SerdNode*    lang,
           Field              field,
           SerdStatementFlags flags)
{
	SerdChunk uri_prefix;
	SerdChunk uri_suffix;
	bool      has_scheme;
	switch (node->type) {
	case SERD_BLANK:
		if (writer->syntax != SERD_NTRIPLES
		    && ((field == FIELD_SUBJECT && (flags & SERD_ANON_S_BEGIN))
		        || (field == FIELD_OBJECT && (flags & SERD_ANON_O_BEGIN)))) {
			++writer->indent;
			write_sep(writer, SEP_ANON_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && (field == FIELD_SUBJECT && (flags & SERD_LIST_S_BEGIN))) {
			assert(writer->list_depth == 0);
			copy_node(&writer->list_subj, node);
			++writer->list_depth;
			++writer->indent;
			write_sep(writer, SEP_LIST_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && (field == FIELD_OBJECT && (flags & SERD_LIST_O_BEGIN))) {
			++writer->indent;
			++writer->list_depth;
			write_sep(writer, SEP_LIST_BEGIN);
		} else if (writer->syntax != SERD_NTRIPLES
		           && ((field == FIELD_SUBJECT && (flags & SERD_EMPTY_S))
		               || (field == FIELD_OBJECT && (flags & SERD_EMPTY_O)))) {
			sink("[]", 2, writer);
		} else {
			sink("_:", 2, writer);
			if (writer->bprefix && !strncmp((const char*)node->buf,
			                                (const char*)writer->bprefix,
			                                writer->bprefix_len)) {
				sink(node->buf + writer->bprefix_len,
				     node->n_bytes - writer->bprefix_len,
				     writer);
			} else {
				sink(node->buf, node->n_bytes, writer);
			}
		}
		break;
	case SERD_CURIE:
		switch (writer->syntax) {
		case SERD_NTRIPLES:
			if (serd_env_expand(writer->env, node, &uri_prefix, &uri_suffix)) {
				w_err(writer, SERD_ERR_BAD_CURIE,
				      "undefined namespace prefix `%s'\n", node->buf);
				return false;
			}
			sink("<", 1, writer);
			write_uri(writer, uri_prefix.buf, uri_prefix.len);
			write_uri(writer, uri_suffix.buf, uri_suffix.len);
			sink(">", 1, writer);
			break;
		case SERD_TURTLE:
			write_lname(writer, node->buf, node->n_bytes);
		}
		break;
	case SERD_LITERAL:
		if (writer->syntax == SERD_TURTLE && datatype && datatype->buf) {
			const char* type_uri = (const char*)datatype->buf;
			if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) && (
				    !strcmp(type_uri + sizeof(NS_XSD) - 1, "boolean") ||
				    !strcmp(type_uri + sizeof(NS_XSD) - 1, "integer"))) {
				sink(node->buf, node->n_bytes, writer);
				break;
			} else if (!strcmp(type_uri + sizeof(NS_XSD) - 1, "decimal") &&
			           strchr((const char*)node->buf, '.') &&
			           node->buf[node->n_bytes - 1] != '.') {
				/* xsd:decimal literals without trailing digits, e.g. "5.", can
				   not be written bare in Turtle.  We could add a 0 which is
				   prettier, but changes the text and breaks round tripping.
				*/
				sink(node->buf, node->n_bytes, writer);
				break;
			}
		}
		if (writer->syntax != SERD_NTRIPLES
		    && (node->flags & (SERD_HAS_NEWLINE|SERD_HAS_QUOTE))) {
			sink("\"\"\"", 3, writer);
			write_text(writer, WRITE_LONG_STRING, node->buf, node->n_bytes);
			sink("\"\"\"", 3, writer);
		} else {
			sink("\"", 1, writer);
			write_text(writer, WRITE_STRING, node->buf, node->n_bytes);
			sink("\"", 1, writer);
		}
		if (lang && lang->buf) {
			sink("@", 1, writer);
			sink(lang->buf, lang->n_bytes, writer);
		} else if (datatype && datatype->buf) {
			sink("^^", 2, writer);
			write_node(writer, datatype, NULL, NULL, FIELD_NONE, flags);
		}
		break;
	case SERD_URI:
		has_scheme = serd_uri_string_has_scheme(node->buf);
		if (field == FIELD_PREDICATE && (writer->syntax == SERD_TURTLE)
		    && !strcmp((const char*)node->buf, NS_RDF "type")) {
			sink("a", 1, writer);
			break;
		} else if ((writer->syntax == SERD_TURTLE)
		           && !strcmp((const char*)node->buf, NS_RDF "nil")) {
			sink("()", 2, writer);
			break;
		} else if (has_scheme && (writer->style & SERD_STYLE_CURIED)) {
			SerdNode  prefix;
			SerdChunk suffix;
			if (serd_env_qualify(writer->env, node, &prefix, &suffix)) {
				write_uri(writer, prefix.buf, prefix.n_bytes);
				sink(":", 1, writer);
				write_uri(writer, suffix.buf, suffix.len);
				break;
			}
		}
		sink("<", 1, writer);
		if (writer->style & SERD_STYLE_RESOLVED) {
			SerdURI in_base_uri, uri, abs_uri;
			serd_env_get_base_uri(writer->env, &in_base_uri);
			serd_uri_parse(node->buf, &uri);
			serd_uri_resolve(&uri, &in_base_uri, &abs_uri);
			bool rooted = uri_is_under(&writer->base_uri, &writer->root_uri);
			SerdURI* root = rooted ? &writer->root_uri : & writer->base_uri;
			if (!uri_is_under(&abs_uri, root) ||
			    writer->syntax == SERD_NTRIPLES) {
				serd_uri_serialise(&abs_uri, uri_sink, writer);
			} else {
				serd_uri_serialise_relative(
					&uri, &writer->base_uri, root, uri_sink, writer);
			}
		} else {
			write_uri(writer, node->buf, node->n_bytes);
		}
		sink(">", 1, writer);
	default:
		break;
	}
	writer->last_sep = SEP_NONE;
	return true;
}
예제 #4
0
static size_t
uri_sink(const void* buf, size_t len, void* stream)
{
	return write_uri((SerdWriter*)stream, (const uint8_t*)buf, len);
}