Class: BlueCloth
- Inherits:
-
Object
- Object
- BlueCloth
- Defined in:
- lib/bluecloth.rb,
ext/bluecloth.c
Overview
Bluecloth is a Ruby implementation of Markdown, a text-to-HTML conversion tool.
Authors
-
Michael Granger <[email protected]>
Contributors
-
Martin Chase <[email protected]> - Peer review, helpful suggestions
-
Florian Gross <[email protected]> - Filter options, suggestions
This product includes software developed by David Loren Parsons <www.pell.portland.or.us/~orc>.
Version
2.1.0
Revision
$Revision: 34dd000f535c $
License
Copyright © 2004-2011, Michael Granger All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of the author/s, nor the names of the project’s contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Constant Summary collapse
- VERSION =
Release Version
'2.2.0'
- REVISION =
Version control revision
%q$Revision: 34dd000f535c $
- DEFAULT_OPTIONS =
The defaults for all supported options.
{ :alphalists => true, :auto_links => false, :definition_lists => false, :divquotes => false, :escape_html => false, :expand_tabs => true, :header_labels => false, :mdtest_1_compat => false, :pandoc_headers => false, :pseudoprotocols => false, :relaxed => false, :remove_images => false, :remove_links => false, :safe_links => false, :smartypants => true, :strict_mode => true, :strikethrough => true, :superscript => false, :tables => false, :tagtext_mode => false, :xml_cdata => false, :footnotes => false, }.freeze
- INSPECT_TEXT_LENGTH =
The number of characters of the original markdown source to include in the output of #inspect
50
- MKD_NOLINKS =
Do not process ‘[]’ and remove A tags from the output.
INT2FIX(MKD_NOLINKS)
- MKD_NOIMAGE =
Do not process ‘![]’ and remove IMG tags from the output.
INT2FIX(MKD_NOIMAGE)
- MKD_NOPANTS =
Do not do Smartypants-style mangling of quotes, dashes, or ellipses.
INT2FIX(MKD_NOPANTS)
- MKD_NOHTML =
Escape all opening angle brackets in the input text instead of allowing block-level HTML
INT2FIX(MKD_NOHTML)
- MKD_STRICT =
disable SUPERSCRIPT, RELAXED_EMPHASIS
INT2FIX(MKD_STRICT)
- MKD_TAGTEXT =
process text inside an html tag; no <em>, no <bold>, no html or [] expansion
INT2FIX(MKD_TAGTEXT)
- MKD_NO_EXT =
don’t allow pseudo-protocols
INT2FIX(MKD_NO_EXT)
- MKD_CDATA =
Generate code for xml ![CDATA]
INT2FIX(MKD_CDATA)
- MKD_NOSUPERSCRIPT =
Don’t use superscript extension
INT2FIX(MKD_NOSUPERSCRIPT)
- MKD_NORELAXED =
Relaxed emphasis – emphasis happens everywhere
INT2FIX(MKD_NORELAXED)
- MKD_NOTABLES =
disallow tables
INT2FIX(MKD_NOTABLES)
- MKD_NOSTRIKETHROUGH =
forbid ~~strikethrough~~
INT2FIX(MKD_NOSTRIKETHROUGH)
- MKD_TOC =
do table-of-contents processing
INT2FIX(MKD_TOC)
- MKD_1_COMPAT =
MarkdownTest 1.0 Compatibility Mode
INT2FIX(MKD_1_COMPAT)
- MKD_EMBED =
MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
INT2FIX(MKD_EMBED)
- MKD_AUTOLINK =
Create links for inline URIs
INT2FIX(MKD_AUTOLINK)
- MKD_SAFELINK =
Be paranoid about link protocols
INT2FIX(MKD_SAFELINK)
- MKD_NOHEADER =
don’t process header blocks
INT2FIX(MKD_NOHEADER)
- MKD_TABSTOP =
Expand tabs to 4 spaces
INT2FIX(MKD_TABSTOP)
- MKD_NODIVQUOTE =
Forbid ‘>%class%’ blocks
INT2FIX(MKD_NODIVQUOTE)
- MKD_NOALPHALIST =
Forbid alphabetic lists
INT2FIX(MKD_NOALPHALIST)
- MKD_NODLIST =
Forbid definition lists
INT2FIX(MKD_NODLIST)
- MKD_EXTRA_FOOTNOTE =
Markdown-extra Footnotes
INT2FIX(MKD_EXTRA_FOOTNOTE)
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
The options hash that describes the options in effect when the object was created.
-
#text ⇒ Object
readonly
The original Markdown text the object was constructed with.
Class Method Summary collapse
-
.discount_version ⇒ String
Return the version string of the Discount library BlueCloth was built on.
-
.flags_from_opthash(opthash = {}) ⇒ Object
Convert the specified
opthash
into a flags bitmask. -
.opthash_from_flags(flags = 0) ⇒ Object
Returns a Hash that reflects the settings from the specified
flags
Integer.
Instance Method Summary collapse
-
#header ⇒ Hash
(also: #pandoc_header)
Return the hash of Pandoc-style headers from the parsed document.
-
#new(string = '', options = DEFAULT_OPTIONS) ⇒ Object
constructor
Create a new BlueCloth object that will process the given
string
. -
#inspect ⇒ Object
Return a human-readable representation of the object suitable for debugging.
-
#to_html ⇒ String
Transform the document into HTML.
Constructor Details
#new(string = '', options = DEFAULT_OPTIONS) ⇒ Object
Create a new BlueCloth object that will process the given string
. The options
argument is a Hash that can be used to control the generated markup, and to enable/disable extensions. The supported options are:
- :remove_links
-
Ignore links in Markdown, and escape A tags in the output. Defaults to
false
. - :remove_images
-
Ignore images in Markdown, and escape IMG tags in the output. Defaults to
false
. - :smartypants
-
Do Smartypants-style mangling of quotes, dashes, or ellipses. Defaults to
true
. - :pseudoprotocols
-
Support Discount’s pseudo-protocol links. Defaults to
false
. - :pandoc_headers
-
Support the extraction of Pandoc headers, which can be fetched as a Hash via the #header method. Defaults to
false
. - :header_labels
-
Generate ID attributes for all headers. Defaults to
false
. - :escape_html
-
Escape all HTML in the input string. Defaults to
false
. - :strict_mode
-
Disables Discount’s relaxed emphasis (ignores underscores in the middle of words) and superscript notation. Defaults to
true
.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'ext/bluecloth.c', line 184
static VALUE
bluecloth_initialize( int argc, VALUE *argv, VALUE self ) {
if ( !bluecloth_check_ptr(self) ) {
MMIOT *document;
VALUE text, optflags, fullhash, opthash = Qnil;
int flags = 0;
VALUE utf8text = Qnil;
rb_scan_args( argc, argv, "02", &text, &opthash );
/* Default empty string and options */
if ( argc == 0 ) {
text = rb_str_new( "", 0 );
}
/* One arg could be either the text or the opthash, so shift the args if appropriate */
else if ( argc == 1 && (TYPE(text) == T_HASH || TYPE(text) == T_FIXNUM) ) {
opthash = text;
text = rb_str_new( "", 0 );
}
else {
text = rb_obj_dup( rb_obj_as_string(text) );
}
/* Merge the options hash with the defaults and turn it into a flags int */
if ( NIL_P(opthash) ) opthash = rb_hash_new();
optflags = rb_funcall( bluecloth_cBlueCloth, rb_intern("flags_from_opthash"), 1, opthash );
fullhash = rb_funcall( bluecloth_cBlueCloth, rb_intern("opthash_from_flags"), 1, optflags );
flags = NUM2INT( optflags );
#ifdef M17N_SUPPORTED
bluecloth_debug( "Bytes before utf8ification: %s",
RSTRING_PTR(rb_funcall(text, rb_intern("dump"), 0, Qnil)) );
utf8text = rb_str_export_to_enc( rb_str_dup(text), rb_utf8_encoding() );
DATA_PTR( self ) = document = bluecloth_alloc( utf8text, flags );
#else
DATA_PTR( self ) = document = bluecloth_alloc( text, flags );
#endif /* M17N_SUPPORTED */
if ( !mkd_compile(document, flags) )
rb_raise( rb_eRuntimeError, "Failed to compile markdown" );
OBJ_FREEZE( text );
rb_iv_set( self, "@text", text );
OBJ_FREEZE( fullhash );
rb_iv_set( self, "@options", fullhash );
OBJ_INFECT( self, text );
}
return self;
}
|
Instance Attribute Details
#options ⇒ Object (readonly)
The options hash that describes the options in effect when the object was created
#text ⇒ Object (readonly)
The original Markdown text the object was constructed with
Class Method Details
.discount_version ⇒ String
Return the version string of the Discount library BlueCloth was built on.
146 147 148 149 |
# File 'ext/bluecloth.c', line 146 static VALUE bluecloth_s_discount_version( VALUE klass ) { return rb_str_new2( markdown_version ); } |
.flags_from_opthash(opthash = {}) ⇒ Object
Convert the specified opthash
into a flags bitmask. If it’s already a Fixnum (e.g., if someone passed in an ORed flags argument instead of an opthash), just return it as-is.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/bluecloth.rb', line 103 def self::flags_from_opthash( opthash={} ) return opthash if opthash.is_a?( Integer ) # Support BlueCloth1-style options if opthash == :filter_html || opthash == [:filter_html] opthash = { :escape_html => true } elsif opthash == :filter_styles opthash = {} elsif !opthash.is_a?( Hash ) raise ArgumentError, "option %p not supported" % [ opthash ] end flags = 0 if opthash[:remove_links] then flags |= MKD_NOLINKS; end if opthash[:remove_images] then flags |= MKD_NOIMAGE; end if ! opthash[:smartypants] then flags |= MKD_NOPANTS; end if opthash[:escape_html] then flags |= MKD_NOHTML; end if opthash[:strict_mode] then flags |= MKD_STRICT; end if opthash[:tagtext_mode] then flags |= MKD_TAGTEXT; end if ! opthash[:pseudoprotocols] then flags |= MKD_NO_EXT; end if opthash[:xml_cdata] then flags |= MKD_CDATA; end if ! opthash[:superscript] then flags |= MKD_NOSUPERSCRIPT; end if ! opthash[:relaxed] then flags |= MKD_NORELAXED; end if ! opthash[:tables] then flags |= MKD_NOTABLES; end if ! opthash[:strikethrough] then flags |= MKD_NOSTRIKETHROUGH; end if opthash[:header_labels] then flags |= MKD_TOC; end if opthash[:mdtest_1_compat] then flags |= MKD_1_COMPAT; end if opthash[:auto_links] then flags |= MKD_AUTOLINK; end if opthash[:safe_links] then flags |= MKD_SAFELINK; end if ! opthash[:pandoc_headers] then flags |= MKD_NOHEADER; end if opthash[:expand_tabs] then flags |= MKD_TABSTOP; end if ! opthash[:divquotes] then flags |= MKD_NODIVQUOTE; end if ! opthash[:alphalists] then flags |= MKD_NOALPHALIST; end if ! opthash[:definition_lists] then flags |= MKD_NODLIST; end if opthash[:footnotes] then flags |= MKD_EXTRA_FOOTNOTE; end return flags end |
.opthash_from_flags(flags = 0) ⇒ Object
Returns a Hash that reflects the settings from the specified flags
Integer.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/bluecloth.rb', line 145 def self::opthash_from_flags( flags=0 ) flags = flags.to_i opthash = {} if ( flags & MKD_NOLINKS ).nonzero? then opthash[:remove_links] = true; end if ( flags & MKD_NOIMAGE ).nonzero? then opthash[:remove_images] = true; end if !( flags & MKD_NOPANTS ).nonzero? then opthash[:smartypants] = true; end if ( flags & MKD_NOHTML ).nonzero? then opthash[:escape_html] = true; end if ( flags & MKD_STRICT ).nonzero? then opthash[:strict_mode] = true; end if ( flags & MKD_TAGTEXT ).nonzero? then opthash[:tagtext_mode] = true; end if !( flags & MKD_NO_EXT ).nonzero? then opthash[:pseudoprotocols] = true; end if ( flags & MKD_CDATA ).nonzero? then opthash[:xml_cdata] = true; end if !( flags & MKD_NOSUPERSCRIPT ).nonzero? then opthash[:superscript] = true; end if !( flags & MKD_NORELAXED ).nonzero? then opthash[:relaxed] = true; end if !( flags & MKD_NOTABLES ).nonzero? then opthash[:tables] = true; end if !( flags & MKD_NOSTRIKETHROUGH ).nonzero? then opthash[:strikethrough] = true; end if ( flags & MKD_TOC ).nonzero? then opthash[:header_labels] = true; end if ( flags & MKD_1_COMPAT ).nonzero? then opthash[:mdtest_1_compat] = true; end if ( flags & MKD_AUTOLINK ).nonzero? then opthash[:auto_links] = true; end if ( flags & MKD_SAFELINK ).nonzero? then opthash[:safe_links] = true; end if !( flags & MKD_NOHEADER ).nonzero? then opthash[:pandoc_headers] = true; end if ( flags & MKD_TABSTOP ).nonzero? then opthash[:expand_tabs] = true; end if !( flags & MKD_NODIVQUOTE ).nonzero? then opthash[:divquotes] = true; end if !( flags & MKD_NOALPHALIST ).nonzero? then opthash[:alphalists] = true; end if !( flags & MKD_NODLIST ).nonzero? then opthash[:definition_lists] = true; end if ( flags & MKD_EXTRA_FOOTNOTE ).nonzero? then opthash[:footnotes] = true; end return opthash end |
Instance Method Details
#header ⇒ Hash Also known as: pandoc_header
Return the hash of Pandoc-style headers from the parsed document. If there were no headers, or the BlueCloth object was not constructed with the :pandoc_headers option enabled, an empty Hash is returned.
markdown = "%title My Essay\n%author Me\n%date Today\n\nSome stuff..."
bc = BlueCloth.new( markdown, :pandoc_headers => true )
# =>
bc.header
# =>
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'ext/bluecloth.c', line 296
static VALUE
bluecloth_header( VALUE self ) {
MMIOT *document = bluecloth_get_ptr( self );
char *field;
VALUE fieldstring, headers = rb_hash_new();
bluecloth_debug( "Fetching pandoc headers for document %p", document );
if ( (field = mkd_doc_title(document)) ) {
fieldstring = rb_str_new2( field );
OBJ_INFECT( fieldstring, self );
rb_hash_aset( headers, ID2SYM(rb_intern("title")), fieldstring );
}
if ( (field = mkd_doc_author(document)) ) {
fieldstring = rb_str_new2( field );
OBJ_INFECT( fieldstring, self );
rb_hash_aset( headers, ID2SYM(rb_intern("author")), fieldstring );
}
if ( (field = mkd_doc_date(document)) ) {
fieldstring = rb_str_new2( field );
OBJ_INFECT( fieldstring, self );
rb_hash_aset( headers, ID2SYM(rb_intern("date")), fieldstring );
}
return headers;
}
|
#inspect ⇒ Object
Return a human-readable representation of the object suitable for debugging.
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/bluecloth.rb', line 181 def inspect return "#<%s:0x%x text: %p; options: %p>" % [ self.class.name, self.object_id / 2, self.text.length > INSPECT_TEXT_LENGTH ? self.text[ 0, INSPECT_TEXT_LENGTH - 5] + '[...]' : self.text, self., ] end |
#to_html ⇒ String
Transform the document into HTML.
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'ext/bluecloth.c', line 246
static VALUE
bluecloth_to_html( VALUE self ) {
MMIOT *document = bluecloth_get_ptr( self );
char *output;
int length;
VALUE result = Qnil;
bluecloth_debug( "Compiling document %p", document );
if ( (length = mkd_document( document, &output )) != EOF ) {
#ifdef M17N_SUPPORTED
VALUE orig_encoding = rb_obj_encoding( rb_iv_get(self, "@text") );
VALUE utf8_result = rb_enc_str_new( output, strlen(output), rb_utf8_encoding() );
result = rb_str_encode( utf8_result, orig_encoding, 0, Qnil );
bluecloth_debug( "Bytes after un-utf8ification (if necessary): %s",
RSTRING_PTR(rb_funcall(result, rb_intern("dump"), 0, Qnil)) );
#else
result = rb_str_new2( output );
#endif /* M17N_SUPPORTED */
OBJ_INFECT( result, self );
return result;
} else {
return Qnil;
}
}
|