packages feed

cmark 0.3.1 → 0.3.2

raw patch · 9 files changed

+107/−90 lines, 9 filesdep +bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring

API changes (from Hackage documentation)

Files

CMark.hsc view
@@ -26,13 +26,15 @@  import Foreign import Foreign.C.Types-import Foreign.C.String (CString, withCString)+import Foreign.C.String (CString) import qualified System.IO.Unsafe as Unsafe import GHC.Generics (Generic) import Data.Data (Data) import Data.Typeable (Typeable)-import Data.Text (Text, empty, unpack)+import Data.Text (Text, empty) import qualified Data.Text.Foreign as TF+import qualified Data.ByteString as B+import Data.Text.Encoding (encodeUtf8) import Control.Applicative ((<$>), (<*>))  #include <cmark.h>@@ -55,14 +57,14 @@ -- | Convert CommonMark formatted text to a structured 'Node' tree, -- which can be transformed or rendered using Haskell code. commonmarkToNode :: [CMarkOption] -> Text -> Node-commonmarkToNode opts s = io $ do+commonmarkToNode opts s = Unsafe.unsafePerformIO $ do   nptr <- TF.withCStringLen s $! \(ptr, len) ->              c_cmark_parse_document ptr len (combineOptions opts)   fptr <- newForeignPtr c_cmark_node_free nptr   withForeignPtr fptr toNode  nodeToCommonmark :: [CMarkOption] -> Int -> Node -> Text-nodeToCommonmark opts width node = io $ do+nodeToCommonmark opts width node = Unsafe.unsafePerformIO $ do   nptr <- fromNode node   fptr <- newForeignPtr c_cmark_node_free nptr   withForeignPtr fptr $ \ptr -> do@@ -73,14 +75,15 @@               -> [CMarkOption]               -> Text               -> Text-commonmarkToX renderer opts s = io $ TF.withCStringLen s $ \(ptr, len) -> do-  let opts' = combineOptions opts-  nptr <- c_cmark_parse_document ptr len opts'-  fptr <- newForeignPtr c_cmark_node_free nptr-  withForeignPtr fptr $ \p -> do-    str <- renderer p opts'-    t <- TF.peekCStringLen $! (str, c_strlen str)-    return t+commonmarkToX renderer opts s = Unsafe.unsafePerformIO $+  TF.withCStringLen s $ \(ptr, len) -> do+    let opts' = combineOptions opts+    nptr <- c_cmark_parse_document ptr len opts'+    fptr <- newForeignPtr c_cmark_node_free nptr+    withForeignPtr fptr $ \p -> do+      str <- renderer p opts'+      t <- TF.peekCStringLen $! (str, c_strlen str)+      return t  type NodePtr = Ptr () @@ -263,12 +266,12 @@             BLOCK_QUOTE -> c_cmark_node_new (#const CMARK_NODE_BLOCK_QUOTE)             HTML literal -> do                      n <- c_cmark_node_new (#const CMARK_NODE_HTML)-                     c_cmark_node_set_literal n (fromtext literal)+                     c_cmark_node_set_literal n =<< fromtext literal                      return n             CODE_BLOCK info literal -> do                      n <- c_cmark_node_new (#const CMARK_NODE_CODE_BLOCK)-                     c_cmark_node_set_literal n (fromtext literal)-                     c_cmark_node_set_fence_info n (fromtext info)+                     c_cmark_node_set_literal n =<< fromtext literal+                     c_cmark_node_set_fence_info n =<< fromtext info                      return n             LIST attr   -> do                      n <- c_cmark_node_new (#const CMARK_NODE_LIST)@@ -290,41 +293,38 @@             STRONG      -> c_cmark_node_new (#const CMARK_NODE_STRONG)             LINK url title -> do                      n <- c_cmark_node_new (#const CMARK_NODE_LINK)-                     c_cmark_node_set_url n (fromtext url)-                     c_cmark_node_set_title n (fromtext title)+                     c_cmark_node_set_url n =<< fromtext url+                     c_cmark_node_set_title n =<< fromtext title                      return n             IMAGE url title -> do                      n <- c_cmark_node_new (#const CMARK_NODE_IMAGE)-                     c_cmark_node_set_url n (fromtext url)-                     c_cmark_node_set_title n (fromtext title)+                     c_cmark_node_set_url n =<< fromtext url+                     c_cmark_node_set_title n =<< fromtext title                      return n             TEXT literal -> do                      n <- c_cmark_node_new (#const CMARK_NODE_TEXT)-                     c_cmark_node_set_literal n (fromtext literal)+                     c_cmark_node_set_literal n =<< fromtext literal                      return n             CODE literal -> do                      n <- c_cmark_node_new (#const CMARK_NODE_CODE)-                     c_cmark_node_set_literal n (fromtext literal)+                     c_cmark_node_set_literal n =<< fromtext literal                      return n             INLINE_HTML literal -> do                      n <- c_cmark_node_new (#const CMARK_NODE_INLINE_HTML)-                     c_cmark_node_set_literal n (fromtext literal)+                     c_cmark_node_set_literal n =<< fromtext literal                      return n             SOFTBREAK   -> c_cmark_node_new (#const CMARK_NODE_SOFTBREAK)             LINEBREAK   -> c_cmark_node_new (#const CMARK_NODE_LINEBREAK)   mapM_ (\child -> fromNode child >>= c_cmark_node_append_child node) children   return node -io :: IO a -> a-io = Unsafe.unsafePerformIO- totext :: CString -> IO Text totext str   | str == nullPtr = return empty   | otherwise      = TF.peekCStringLen (str, c_strlen str) -fromtext :: Text -> CString-fromtext t = io $! withCString (unpack t) return+fromtext :: Text -> IO CString+fromtext t = B.useAsCString (encodeUtf8 t) return  foreign import ccall "string.h strlen"     c_strlen :: CString -> Int
README.md view
@@ -3,8 +3,8 @@  This package provides Haskell bindings for [libcmark], the reference parser for [CommonMark], a fully specified variant of Markdown.-It includes sources for [libcmark] (as of commit f40e098, implementing-version 0.18 of the spec) and does not require prior installation of+It includes sources for [libcmark] (version 0.19.0, implementing+version 0.19 of the spec) and does not require prior installation of the C library.  cmark provides the following advantages over existing Markdown
cbits/cmark_version.h view
@@ -1,7 +1,7 @@ #ifndef CMARK_VERSION_H #define CMARK_VERSION_H -#define CMARK_VERSION ((0 << 16) | (18 << 8)  | 1)-#define CMARK_VERSION_STRING "0.18.1"+#define CMARK_VERSION ((0 << 16) | (19 << 8)  | 0)+#define CMARK_VERSION_STRING "0.19.0"  #endif
cbits/commonmark.c view
@@ -49,35 +49,35 @@  static inline bool needs_escaping(escaping escape,-	       int32_t c,-	       unsigned char next_c,-	       struct render_state *state)+               int32_t c,+               unsigned char next_c,+               struct render_state *state) { 	if (escape == NORMAL) { 		return (c == '*' || c == '_' || c == '[' || c == ']' ||-			c == '<' || c == '>' || c == '\\' || c == '`' ||-			(c == '&' && isalpha(next_c)) ||-			(c == '!' && next_c == '[') ||-			(state->begin_line &&-			 (c == '-' || c == '+' || c == '#' || c == '=')) ||-			(c == '#' && (isspace(next_c) || next_c == '\0')) ||-			((c == '.' || c == ')') &&-			 isdigit(state->buffer->ptr[state->buffer->size - 1])));+		        c == '<' || c == '>' || c == '\\' || c == '`' ||+		        (c == '&' && isalpha(next_c)) ||+		        (c == '!' && next_c == '[') ||+		        (state->begin_line &&+		         (c == '-' || c == '+' || c == '#' || c == '=')) ||+		        (c == '#' && (isspace(next_c) || next_c == '\0')) ||+		        ((c == '.' || c == ')') &&+		         isdigit(state->buffer->ptr[state->buffer->size - 1]))); 	} else if (escape == TITLE) { 		return (c == '`' || c == '<' || c == '>' || c == '"' ||-			c == '\\');+		        c == '\\'); 	} else if (escape == URL) { 		return (c == '`' || c == '<' || c == '>' || isspace(c) ||-			c == '\\' || c == ')' || c == '(');+		        c == '\\' || c == ')' || c == '('); 	} else { 		return false; 	} }  static inline void out(struct render_state *state,-		       cmark_chunk str,-		       bool wrap,-		       escaping escape)+                       cmark_chunk str,+                       bool wrap,+                       escaping escape) { 	unsigned char* source = str.data; 	int length = str.len;@@ -100,7 +100,7 @@ 			cmark_strbuf_putc(state->buffer, '\n'); 			if (state->need_cr > 1) { 				cmark_strbuf_put(state->buffer, state->prefix->ptr,-						 state->prefix->size);+				                 state->prefix->size); 			} 		} 		state->column = 0;@@ -111,12 +111,15 @@ 	while (i < length) { 		if (state->begin_line) { 			cmark_strbuf_put(state->buffer, state->prefix->ptr,-					 state->prefix->size);+			                 state->prefix->size); 			// note: this assumes prefix is ascii: 			state->column = state->prefix->size; 		}  		len = utf8proc_iterate(source + i, length - i, &c);+		if (len == -1) { // error condition+			return;  // return without rendering rest of string+		} 		nextc = source[i + len]; 		if (c == 32 && wrap) { 			if (!state->begin_line) {@@ -124,7 +127,7 @@ 				state->column += 1; 				state->begin_line = false; 				state->last_breakable = state->buffer->size --					1;+				                        1; 				// skip following spaces 				while (source[i + 1] == ' ') { 					i++;@@ -167,7 +170,7 @@ 			// add newline, prefix, and remainder 			cmark_strbuf_putc(state->buffer, '\n'); 			cmark_strbuf_put(state->buffer, state->prefix->ptr,-					 state->prefix->size);+			                 state->prefix->size); 			cmark_strbuf_put(state->buffer, remainder.data, remainder.len); 			state->column = state->prefix->size + remainder.len; 			cmark_chunk_free(&remainder);@@ -254,8 +257,8 @@ 	} 	cmark_consolidate_text_nodes(node); 	return (strncmp(url,-			(char*)node->as.literal.data,-			node->as.literal.len) == 0);+	                (char*)node->as.literal.data,+	                node->as.literal.len) == 0); }  // if node is a block node, returns node.@@ -265,7 +268,7 @@ { 	while (node && 	       (node->type < CMARK_NODE_FIRST_BLOCK ||-		node->type > CMARK_NODE_LAST_BLOCK)) {+	        node->type > CMARK_NODE_LAST_BLOCK)) { 		node = node->parent; 	} 	return node;@@ -284,7 +287,7 @@ 	bool entering = (ev_type == CMARK_EVENT_ENTER); 	const char *info; 	const char *title;-	char listmarker[64];+	cmark_strbuf listmarker = GH_BUF_INIT; 	char *emph_delim; 	int marker_width; @@ -293,14 +296,14 @@ 	// a following list. 	if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && 	      entering)) {-			tmp = get_containing_block(node);-			state->in_tight_list_item =-				(tmp->type == CMARK_NODE_ITEM &&-				 cmark_node_get_list_tight(tmp->parent)) ||-				(tmp &&-				 tmp->parent &&-				 tmp->parent->type == CMARK_NODE_ITEM &&-				 cmark_node_get_list_tight(tmp->parent->parent));+		tmp = get_containing_block(node);+		state->in_tight_list_item =+		    (tmp->type == CMARK_NODE_ITEM &&+		     cmark_node_get_list_tight(tmp->parent)) ||+		    (tmp &&+		     tmp->parent &&+		     tmp->parent->type == CMARK_NODE_ITEM &&+		     cmark_node_get_list_tight(tmp->parent->parent)); 	}  	switch (node->type) {@@ -316,7 +319,7 @@ 			cmark_strbuf_puts(state->prefix, "> "); 		} else { 			cmark_strbuf_truncate(state->prefix,-					      state->prefix->size - 2);+			                      state->prefix->size - 2); 			blankline(state); 		} 		break;@@ -347,11 +350,12 @@ 			// we ensure a width of at least 4 so 			// we get nice transition from single digits 			// to double-			snprintf(listmarker, 63, "%d%s%s", list_number,-				 list_delim == CMARK_PAREN_DELIM ?-				 ")" : ".",-				 list_number < 10 ? "  " : " ");-			marker_width = strlen(listmarker);+			cmark_strbuf_printf(&listmarker,+			                    "%d%s%s", list_number,+			                    list_delim == CMARK_PAREN_DELIM ?+			                    ")" : ".",+			                    list_number < 10 ? "  " : " ");+			marker_width = listmarker.size; 		} 		if (entering) { 			if (cmark_node_get_list_type(node->parent) ==@@ -359,17 +363,18 @@ 				lit(state, "* ", false); 				cmark_strbuf_puts(state->prefix, "  "); 			} else {-				lit(state, listmarker, false);-				for (i=marker_width; i--;) {+				lit(state, (char *)listmarker.ptr, false);+				for (i = marker_width; i--;) { 					cmark_strbuf_putc(state->prefix, ' '); 				} 			} 		} else { 			cmark_strbuf_truncate(state->prefix,-					      state->prefix->size --					      marker_width);+			                      state->prefix->size -+			                      marker_width); 			cr(state); 		}+		cmark_strbuf_free(&listmarker); 		break;  	case CMARK_NODE_HEADER:@@ -403,7 +408,7 @@ 			cmark_strbuf_puts(state->prefix, "    "); 			out(state, node->as.code.literal, false, LITERAL); 			cmark_strbuf_truncate(state->prefix,-					      state->prefix->size - 4);+			                      state->prefix->size - 4); 		} else { 			numticks = longest_backtick_sequence(code) + 1; 			if (numticks < 3) {@@ -512,7 +517,7 @@ 			if (entering) { 				lit(state, "<", false); 				if (strncmp(cmark_node_get_url(node),-					    "mailto:", 7) == 0) {+				            "mailto:", 7) == 0) { 					lit(state, 					    (char *)cmark_node_get_url(node) + 7, 					    false);@@ -577,9 +582,10 @@ 	if (CMARK_OPT_HARDBREAKS & options) { 		width = 0; 	}-	struct render_state state =-		{ options, &commonmark, &prefix, 0, width,-		  0, 0, true, false, false};+	struct render_state state = {+		options, &commonmark, &prefix, 0, width,+		0, 0, true, false, false+	}; 	cmark_node *cur; 	cmark_event_type ev_type; 	cmark_iter *iter = cmark_iter_new(root);
cbits/inlines.c view
@@ -301,8 +301,10 @@ 	                   !utf8proc_is_space(after_char) && 	                   !utf8proc_is_punctuation(after_char)); 	if (c == '_') {-		*can_open = left_flanking && !right_flanking;-		*can_close = right_flanking && !left_flanking;+		*can_open = left_flanking &&+			(!right_flanking || utf8proc_is_punctuation(before_char));+		*can_close = right_flanking &&+			(!left_flanking || utf8proc_is_punctuation(after_char)); 	} else if (c == '\'' || c == '"') { 		*can_open = left_flanking && !right_flanking; 		*can_close = right_flanking;@@ -636,7 +638,7 @@ 	}  	cmark_strbuf_unescape(&buf);-	return cmark_strbuf_detach(&buf);+	return buf.size == 0 ? NULL : cmark_strbuf_detach(&buf); }  unsigned char *cmark_clean_title(cmark_chunk *title)@@ -660,7 +662,7 @@ 	}  	cmark_strbuf_unescape(&buf);-	return cmark_strbuf_detach(&buf);+	return buf.size == 0 ? NULL : cmark_strbuf_detach(&buf); }  // Parse an autolink or HTML tag.
cbits/man.c view
@@ -20,6 +20,9 @@  	while (i < length) { 		len = utf8proc_iterate(source + i, length - i, &c);+		if (len == -1) { // error condition+			return;  // return without rendering anything+		} 		switch(c) { 		case 46: 			if (beginLine) {
cbits/utf8.c view
@@ -172,8 +172,7 @@ 	case 3: 		uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) <<  6) 		     + (str[2] & 0x3F);-		if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) ||-		    (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1;+		if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000)) uc = -1; 		break; 	case 4: 		uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12)@@ -182,7 +181,7 @@ 		break; 	} -	if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE))+	if (uc < 0) 		return -1;  	*dst = uc;
changelog view
@@ -1,3 +1,11 @@+cmark 0.3.2 (28 Apr 2015)++  * Updated libcmark C sources to 0.19.0.+  * Fixes to avoid warning for earlier ghc versions.+  * Refactored, removing the `io` convenience function.+  * Removed unnecessary `unsafePerformIO` on `fromtext`.+  * `fromtext`: use `ByteString.useAsCString` + explicit `encodeUtf8`.+ cmark 0.3.1 (29 Mar 2015)    * Added nodeToCommonmark.
cmark.cabal view
@@ -1,14 +1,13 @@ name:                cmark-version:             0.3.1+version:             0.3.2 synopsis:            Fast, accurate CommonMark (Markdown) parser and renderer description:   This package provides Haskell bindings for   <https://github.com/jgm/cmark libcmark>, the reference   parser for <http://commonmark.org CommonMark>, a fully   specified variant of Markdown. It includes sources for-  libcmark (as of commit f40e098, implementing version 0.18-  of the CommonMark spec) and does not require prior-  installation of the C library.+  libcmark (0.19.0) and does not require prior installation of the+  C library.   .   cmark provides the following advantages over existing   Markdown libraries for Haskell:@@ -118,7 +117,7 @@  library   exposed-modules:     CMark-  build-depends:       base >=4.5 && < 4.9, text+  build-depends:       base >=4.5 && < 4.9, text, bytestring   if impl(ghc < 7.6)     build-depends:     ghc-prim >= 0.2   default-language:    Haskell2010