sc-docs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/.gitignore +4 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +48 -0
  5. data/LICENSE +21 -0
  6. data/README.md +59 -0
  7. data/bin/sc-docs +5 -0
  8. data/lib/sc_docs.rb +3 -0
  9. data/lib/sc_docs/cli.rb +54 -0
  10. data/lib/sc_docs/docs/Buildfile +8 -0
  11. data/lib/sc_docs/docs/README +8 -0
  12. data/lib/sc_docs/docs/apps/docs/Buildfile +15 -0
  13. data/lib/sc_docs/docs/apps/docs/controllers/classes.js +27 -0
  14. data/lib/sc_docs/docs/apps/docs/controllers/search_controller.js +62 -0
  15. data/lib/sc_docs/docs/apps/docs/controllers/selected_class.js +143 -0
  16. data/lib/sc_docs/docs/apps/docs/core.js +148 -0
  17. data/lib/sc_docs/docs/apps/docs/main.js +41 -0
  18. data/lib/sc_docs/docs/apps/docs/models/class.js +63 -0
  19. data/lib/sc_docs/docs/apps/docs/models/entity.js +29 -0
  20. data/lib/sc_docs/docs/apps/docs/models/method.js +79 -0
  21. data/lib/sc_docs/docs/apps/docs/models/property.js +48 -0
  22. data/lib/sc_docs/docs/apps/docs/resources/images/method_icon.png +0 -0
  23. data/lib/sc_docs/docs/apps/docs/resources/images/property_icon.png +0 -0
  24. data/lib/sc_docs/docs/apps/docs/resources/loading.rhtml +9 -0
  25. data/lib/sc_docs/docs/apps/docs/resources/main_page.css +156 -0
  26. data/lib/sc_docs/docs/apps/docs/resources/main_page.js +91 -0
  27. data/lib/sc_docs/docs/apps/docs/resources/templates/details.handlebars +81 -0
  28. data/lib/sc_docs/docs/apps/docs/resources/templates/extensions/signature.js +0 -0
  29. data/lib/sc_docs/docs/apps/docs/system/jquery_ui.js +62 -0
  30. data/lib/sc_docs/docs/apps/docs/system/showdown.js +1297 -0
  31. data/lib/sc_docs/docs/apps/docs/theme.js +29 -0
  32. data/lib/sc_docs/docs/apps/docs/views/detail_list.js +24 -0
  33. data/lib/sc_docs/docs/apps/docs/views/master_list.js +35 -0
  34. data/lib/sc_docs/docs/apps/docs/views/methods_collection.js +80 -0
  35. data/lib/sc_docs/docs/apps/docs/views/properties_collection.js +9 -0
  36. data/lib/sc_docs/generator.rb +145 -0
  37. data/lib/sc_docs/server.rb +21 -0
  38. data/lib/sc_docs/templates/docs.sproutcore.com/allclasses.tmpl +31 -0
  39. data/lib/sc_docs/templates/docs.sproutcore.com/allfiles.tmpl +66 -0
  40. data/lib/sc_docs/templates/docs.sproutcore.com/class.tmpl +437 -0
  41. data/lib/sc_docs/templates/docs.sproutcore.com/index.tmpl +52 -0
  42. data/lib/sc_docs/templates/docs.sproutcore.com/output/css/api.css +619 -0
  43. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/apidocs.jpg +0 -0
  44. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/apidocs.png +0 -0
  45. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/clearinput.png +0 -0
  46. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/cross.png +0 -0
  47. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/ddiagonal.png +0 -0
  48. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/diagonal.png +0 -0
  49. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/docbullet.jpg +0 -0
  50. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/docbullet.png +0 -0
  51. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/glow.png +0 -0
  52. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/logo.png +0 -0
  53. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/pixels.png +0 -0
  54. data/lib/sc_docs/templates/docs.sproutcore.com/output/img/search.png +0 -0
  55. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/api.js +134 -0
  56. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/jquery-bbq.js +18 -0
  57. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/lib/jquery-1.5.1.min.js +16 -0
  58. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/lib/modernizr-1.7.min.js +2 -0
  59. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/plugin.js +1 -0
  60. data/lib/sc_docs/templates/docs.sproutcore.com/output/js/script.js +5 -0
  61. data/lib/sc_docs/templates/docs.sproutcore.com/publish.js +200 -0
  62. data/lib/sc_docs/templates/docs.sproutcore.com/static/default.css +300 -0
  63. data/lib/sc_docs/templates/docs.sproutcore.com/static/header.html +19 -0
  64. data/lib/sc_docs/templates/docs.sproutcore.com/static/index.html +19 -0
  65. data/lib/sc_docs/templates/docs.sproutcore.com/symbol.tmpl +35 -0
  66. data/lib/sc_docs/templates/sc_fixture/publish.js +632 -0
  67. data/lib/sc_docs/version.rb +4 -0
  68. data/sc_docs.gemspec +27 -0
  69. data/vendor/jsdoc/README.txt +109 -0
  70. data/vendor/jsdoc/app/frame.js +33 -0
  71. data/vendor/jsdoc/app/frame/Chain.js +102 -0
  72. data/vendor/jsdoc/app/frame/Dumper.js +144 -0
  73. data/vendor/jsdoc/app/frame/Hash.js +84 -0
  74. data/vendor/jsdoc/app/frame/Link.js +173 -0
  75. data/vendor/jsdoc/app/frame/Namespace.js +10 -0
  76. data/vendor/jsdoc/app/frame/Opt.js +134 -0
  77. data/vendor/jsdoc/app/frame/Reflection.js +26 -0
  78. data/vendor/jsdoc/app/frame/String.js +93 -0
  79. data/vendor/jsdoc/app/frame/Testrun.js +129 -0
  80. data/vendor/jsdoc/app/handlers/FOODOC.js +26 -0
  81. data/vendor/jsdoc/app/handlers/XMLDOC.js +26 -0
  82. data/vendor/jsdoc/app/handlers/XMLDOC/DomReader.js +159 -0
  83. data/vendor/jsdoc/app/handlers/XMLDOC/XMLDoc.js +16 -0
  84. data/vendor/jsdoc/app/handlers/XMLDOC/XMLParse.js +292 -0
  85. data/vendor/jsdoc/app/lib/JSDOC.js +106 -0
  86. data/vendor/jsdoc/app/lib/JSDOC/DocComment.js +204 -0
  87. data/vendor/jsdoc/app/lib/JSDOC/DocTag.js +294 -0
  88. data/vendor/jsdoc/app/lib/JSDOC/JsDoc.js +140 -0
  89. data/vendor/jsdoc/app/lib/JSDOC/JsPlate.js +109 -0
  90. data/vendor/jsdoc/app/lib/JSDOC/Lang.js +144 -0
  91. data/vendor/jsdoc/app/lib/JSDOC/Parser.js +146 -0
  92. data/vendor/jsdoc/app/lib/JSDOC/PluginManager.js +33 -0
  93. data/vendor/jsdoc/app/lib/JSDOC/Symbol.js +644 -0
  94. data/vendor/jsdoc/app/lib/JSDOC/SymbolSet.js +243 -0
  95. data/vendor/jsdoc/app/lib/JSDOC/TextStream.js +41 -0
  96. data/vendor/jsdoc/app/lib/JSDOC/Token.js +18 -0
  97. data/vendor/jsdoc/app/lib/JSDOC/TokenReader.js +332 -0
  98. data/vendor/jsdoc/app/lib/JSDOC/TokenStream.js +133 -0
  99. data/vendor/jsdoc/app/lib/JSDOC/Util.js +32 -0
  100. data/vendor/jsdoc/app/lib/JSDOC/Walker.js +507 -0
  101. data/vendor/jsdoc/app/main.js +111 -0
  102. data/vendor/jsdoc/app/plugins/commentSrcJson.js +20 -0
  103. data/vendor/jsdoc/app/plugins/frameworkPrototype.js +16 -0
  104. data/vendor/jsdoc/app/plugins/functionCall.js +10 -0
  105. data/vendor/jsdoc/app/plugins/publishSrcHilite.js +62 -0
  106. data/vendor/jsdoc/app/plugins/symbolLink.js +10 -0
  107. data/vendor/jsdoc/app/plugins/tagParamConfig.js +31 -0
  108. data/vendor/jsdoc/app/plugins/tagSynonyms.js +43 -0
  109. data/vendor/jsdoc/app/run.js +297 -0
  110. data/vendor/jsdoc/app/t/TestDoc.js +144 -0
  111. data/vendor/jsdoc/app/t/runner.js +13 -0
  112. data/vendor/jsdoc/app/test.js +342 -0
  113. data/vendor/jsdoc/app/test/addon.js +24 -0
  114. data/vendor/jsdoc/app/test/anon_inner.js +14 -0
  115. data/vendor/jsdoc/app/test/augments.js +31 -0
  116. data/vendor/jsdoc/app/test/augments2.js +26 -0
  117. data/vendor/jsdoc/app/test/borrows.js +46 -0
  118. data/vendor/jsdoc/app/test/borrows2.js +23 -0
  119. data/vendor/jsdoc/app/test/config.js +22 -0
  120. data/vendor/jsdoc/app/test/constructs.js +18 -0
  121. data/vendor/jsdoc/app/test/encoding.js +10 -0
  122. data/vendor/jsdoc/app/test/encoding_other.js +12 -0
  123. data/vendor/jsdoc/app/test/event.js +54 -0
  124. data/vendor/jsdoc/app/test/exports.js +14 -0
  125. data/vendor/jsdoc/app/test/functions_anon.js +39 -0
  126. data/vendor/jsdoc/app/test/functions_nested.js +33 -0
  127. data/vendor/jsdoc/app/test/global.js +13 -0
  128. data/vendor/jsdoc/app/test/globals.js +25 -0
  129. data/vendor/jsdoc/app/test/ignore.js +10 -0
  130. data/vendor/jsdoc/app/test/inner.js +16 -0
  131. data/vendor/jsdoc/app/test/jsdoc_test.js +477 -0
  132. data/vendor/jsdoc/app/test/lend.js +33 -0
  133. data/vendor/jsdoc/app/test/memberof.js +19 -0
  134. data/vendor/jsdoc/app/test/memberof2.js +38 -0
  135. data/vendor/jsdoc/app/test/memberof3.js +33 -0
  136. data/vendor/jsdoc/app/test/memberof_constructor.js +17 -0
  137. data/vendor/jsdoc/app/test/module.js +17 -0
  138. data/vendor/jsdoc/app/test/multi_methods.js +25 -0
  139. data/vendor/jsdoc/app/test/name.js +19 -0
  140. data/vendor/jsdoc/app/test/namespace_nested.js +23 -0
  141. data/vendor/jsdoc/app/test/nocode.js +13 -0
  142. data/vendor/jsdoc/app/test/oblit_anon.js +20 -0
  143. data/vendor/jsdoc/app/test/overview.js +20 -0
  144. data/vendor/jsdoc/app/test/param_inline.js +37 -0
  145. data/vendor/jsdoc/app/test/params_optional.js +8 -0
  146. data/vendor/jsdoc/app/test/prototype.js +17 -0
  147. data/vendor/jsdoc/app/test/prototype_nested.js +9 -0
  148. data/vendor/jsdoc/app/test/prototype_oblit.js +13 -0
  149. data/vendor/jsdoc/app/test/prototype_oblit_constructor.js +24 -0
  150. data/vendor/jsdoc/app/test/public.js +10 -0
  151. data/vendor/jsdoc/app/test/scripts/code.js +5 -0
  152. data/vendor/jsdoc/app/test/scripts/notcode.txt +5 -0
  153. data/vendor/jsdoc/app/test/shared.js +42 -0
  154. data/vendor/jsdoc/app/test/shared2.js +2 -0
  155. data/vendor/jsdoc/app/test/shortcuts.js +22 -0
  156. data/vendor/jsdoc/app/test/static_this.js +13 -0
  157. data/vendor/jsdoc/app/test/synonyms.js +31 -0
  158. data/vendor/jsdoc/app/test/tosource.js +23 -0
  159. data/vendor/jsdoc/app/test/variable_redefine.js +14 -0
  160. data/vendor/jsdoc/changes.txt +127 -0
  161. data/vendor/jsdoc/conf/sample.conf +31 -0
  162. metadata +240 -0
@@ -0,0 +1,91 @@
1
+ // ==========================================================================
2
+ // Project: SproutCore - JavaScript Application Framework
3
+ // Copyright: ©2008-2011 Apple Inc. All rights reserved.
4
+ // License: Licensed under MIT license (see license.js)
5
+ // ==========================================================================
6
+ /*globals Docs */
7
+
8
+ // This page describes the main user interface for your application.
9
+ Docs.mainPage = SC.Page.design({
10
+
11
+ // The main pane is made visible on screen as soon as your app is loaded.
12
+ // Add childViews to this pane for views to display immediately on page
13
+ // load.
14
+ mainPane: SC.MainPane.design({
15
+ layerId: 'mainPane',
16
+ childViews: 'sidebar detailView'.w(),
17
+
18
+ sidebar: SC.View.design({
19
+ layout: { top:0, left:0, bottom:0, width:190 },
20
+ childViews: 'search classList'.w(),
21
+
22
+ search: SC.View.design({
23
+ layout: { top:0, left:0, height:35, width:190 },
24
+ classNames: 'search'.w(),
25
+ childViews: 'searchTextField'.w(),
26
+
27
+ searchTextField: SC.TextFieldView.design({
28
+ hint: 'Search For Symbol',
29
+ valueBinding: 'Docs.searchController.searchQuery'
30
+ })
31
+ }),
32
+
33
+ classList: SC.ScrollView.design({
34
+ layout: { top:35, left:0, bottom:0, width:190 },
35
+
36
+ contentView: Docs.MasterListView.design({
37
+ contentBinding: 'Docs.classesController.arrangedObjects',
38
+ selectionBinding: 'Docs.classesController.selection',
39
+ showAlternatingRows: YES,
40
+ contentValueKey: 'displayName'
41
+ })
42
+ })
43
+ }),
44
+
45
+ detailView: SC.View.design({
46
+ layout: { top:0, left:190, bottom:0, right:0 },
47
+ childViews: 'toolbar workspace'.w(),
48
+
49
+ toolbar: SC.View.design({
50
+ layout: { top:0, left:0, right:0, height:50 },
51
+ classNames: 'class-header'.w(),
52
+ childViews: 'className'.w(),
53
+
54
+ className: SC.LabelView.design({
55
+ layout: { centerY:0, left:10, right:0, height:27 },
56
+ classNames: 'class-name'.w(),
57
+ valueBinding: 'Docs.selectedClassController.name',
58
+ controlSize: SC.LARGE_CONTROL_SIZE
59
+ })
60
+ }),
61
+
62
+ workspace: SC.View.design({
63
+ layout: { top:50, left:0, bottom:0, right:0 },
64
+ classNames: 'workspace'.w(),
65
+ childViews: 'symbolList classDetails'.w(),
66
+
67
+ symbolList: SC.ScrollView.design({
68
+ layout: { top:0, left:0, bottom:0, width:190 },
69
+ contentView: Docs.DetailListView.design({
70
+ classNames: 'symbol-list'.w(),
71
+ contentBinding: 'Docs.selectedClassController.symbols',
72
+ selectionBinding: 'Docs.selectedClassController.symbolSelection',
73
+ contentValueKey: 'name',
74
+ contentIconKey: 'icon',
75
+
76
+ exampleView: SC.ListItemView.extend({
77
+ hasContentIcon: YES
78
+ })
79
+ })
80
+ }),
81
+
82
+ classDetails: SC.TemplateView.design({
83
+ classNames: 'class-detail'.w(),
84
+ isTextSelectable: YES,
85
+ contentBinding: 'Docs.selectedClassController.content',
86
+ templateName: 'details'
87
+ })
88
+ })
89
+ })
90
+ })
91
+ });
@@ -0,0 +1,81 @@
1
+ <div id="class-details">
2
+ {{#if content.extendsFrom}}
3
+ <div class="extends">
4
+ <span class="name">Extends:</span>
5
+ <span class="value">{{extends content.extendsFrom}}</span>
6
+ </div>
7
+ {{/if}}
8
+ {{#if content.since}}
9
+ <div class="since">
10
+ <span class="name">Since:</span>
11
+ <span class="value">{{content.since}}</span>
12
+ </div>
13
+ {{/if}}
14
+ </div>
15
+
16
+ <div id="class-info">
17
+
18
+ {{#if content.formattedOverview}}
19
+ <h2> Overview </h2>
20
+ <div class="overview">
21
+ {{{content.formattedOverview}}}
22
+ </div>
23
+ {{/if}}
24
+
25
+ {{#if content.hasProperties}}
26
+ <h2> Properties </h2>
27
+ {{#collection Docs.PropertiesCollectionView itemClassNames="symbol"}}
28
+
29
+ <div {{bindAttr name="content.name"}}>
30
+ <div class="header">
31
+ {{content.name}}
32
+ </div>
33
+
34
+ <div class="subtitles">
35
+ {{#if content.propertyType}}
36
+ <span class="type">
37
+ <span class="name">Type: </span>
38
+ <span class="data-type" {{bindAttr name="content.propertyType"}}>
39
+ {{content.propertyType}}
40
+ </span>
41
+ </span>
42
+ {{/if}}
43
+ {{#if content.default}}
44
+ <span class="default">
45
+ <span class="name">Default</span>:
46
+ <span class="value">{{content.default}}</span>
47
+ </span>
48
+ {{/if}}
49
+ </div>
50
+
51
+ <div class="overview">
52
+ {{content.formattedOverview}}
53
+ </div>
54
+ </div>
55
+
56
+ <hr>
57
+
58
+ {{/collection}}
59
+ {{/if}}
60
+
61
+ {{#if content.hasMethods}}
62
+ <h2> Methods </h2>
63
+ {{#collection Docs.MethodsCollectionView itemClassNames="symbol"}}
64
+
65
+ <div {{bindAttr name="content.name"}}>
66
+ <div class="header">
67
+ {{signature content}}
68
+ </div>
69
+
70
+ <div class="overview">
71
+ {{content.formattedOverview}}
72
+ </div>
73
+
74
+ {{returns content}}
75
+ </div>
76
+
77
+ <hr>
78
+
79
+ {{/collection}}
80
+ {{/if}}
81
+ </div>
@@ -0,0 +1,62 @@
1
+ /*!
2
+ * jQuery UI 1.8.11
3
+ *
4
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI
9
+ */
10
+ (function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.11",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,
11
+ NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,
12
+ "position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");
13
+ if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,
14
+ "border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,
15
+ d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
16
+ c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
17
+ b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
18
+ ;/*
19
+ * jQuery UI Effects 1.8.11
20
+ *
21
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
22
+ * Dual licensed under the MIT or GPL Version 2 licenses.
23
+ * http://jquery.org/license
24
+ *
25
+ * http://docs.jquery.com/UI/Effects/
26
+ */
27
+ jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1],
28
+ 16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
29
+ a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d=
30
+ a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
31
+ "borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
32
+ 0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
33
+ 211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,
34
+ d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0];
35
+ h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,
36
+ a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.11",save:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.data("ec.storage."+a[b],c[0].style[a[b]])},restore:function(c,a){for(var b=0;b<a.length;b++)a[b]!==null&&c.css(a[b],c.data("ec.storage."+a[b]))},setMode:function(c,a){if(a=="toggle")a=c.is(":hidden")?"show":"hide";return a},getBaseline:function(c,
37
+ a){var b;switch(c[0]){case "top":b=0;break;case "middle":b=0.5;break;case "bottom":b=1;break;default:b=c[0]/a.height}switch(c[1]){case "left":c=0;break;case "center":c=0.5;break;case "right":c=1;break;default:c=c[1]/a.width}return{x:c,y:b}},createWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent();var a={width:c.outerWidth(true),height:c.outerHeight(true),"float":c.css("float")},b=f("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",
38
+ border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);
39
+ return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments);
40
+ else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),
41
+ b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,
42
+ a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,
43
+ a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==
44
+ e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=
45
+ g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g))+b},easeOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*a)*Math.sin((a*e-c)*2*Math.PI/g)+d+b},easeInOutElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e/2)==2)return b+d;g||(g=e*0.3*1.5);if(h<Math.abs(d)){h=d;c=g/4}else c=g/(2*Math.PI)*Math.asin(d/
46
+ h);if(a<1)return-0.5*h*Math.pow(2,10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)+b;return h*Math.pow(2,-10*(a-=1))*Math.sin((a*e-c)*2*Math.PI/g)*0.5+d+b},easeInBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*(a/=e)*a*((g+1)*a-g)+b},easeOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;return d*((a=a/e-1)*a*((g+1)*a+g)+1)+b},easeInOutBack:function(c,a,b,d,e,g){if(g==j)g=1.70158;if((a/=e/2)<1)return d/2*a*a*(((g*=1.525)+1)*a-g)+b;return d/2*((a-=2)*a*(((g*=1.525)+1)*a+g)+2)+b},easeInBounce:function(c,
47
+ a,b,d,e){return d-f.easing.easeOutBounce(c,e-a,0,d,e)+b},easeOutBounce:function(c,a,b,d,e){return(a/=e)<1/2.75?d*7.5625*a*a+b:a<2/2.75?d*(7.5625*(a-=1.5/2.75)*a+0.75)+b:a<2.5/2.75?d*(7.5625*(a-=2.25/2.75)*a+0.9375)+b:d*(7.5625*(a-=2.625/2.75)*a+0.984375)+b},easeInOutBounce:function(c,a,b,d,e){if(a<e/2)return f.easing.easeInBounce(c,a*2,0,d,e)*0.5+b;return f.easing.easeOutBounce(c,a*2-e,0,d,e)*0.5+d*0.5+b}})}(jQuery);
48
+ ;/*
49
+ * jQuery UI Effects Highlight 1.8.11
50
+ *
51
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
52
+ * Dual licensed under the MIT or GPL Version 2 licenses.
53
+ * http://jquery.org/license
54
+ *
55
+ * http://docs.jquery.com/UI/Effects/Highlight
56
+ *
57
+ * Depends:
58
+ * jquery.effects.core.js
59
+ */
60
+ (function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&&
61
+ this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery);
62
+ ;
@@ -0,0 +1,1297 @@
1
+ //
2
+ // showdown.js -- A javascript port of Markdown.
3
+ //
4
+ // Copyright (c) 2007 John Fraser.
5
+ //
6
+ // Original Markdown Copyright (c) 2004-2005 John Gruber
7
+ // <http://daringfireball.net/projects/markdown/>
8
+ //
9
+ // Redistributable under a BSD-style open source license.
10
+ // See license.txt for more information.
11
+ //
12
+ // The full source distribution is at:
13
+ //
14
+ // A A L
15
+ // T C A
16
+ // T K B
17
+ //
18
+ // <http://www.attacklab.net/>
19
+ //
20
+
21
+ //
22
+ // Wherever possible, Showdown is a straight, line-by-line port
23
+ // of the Perl version of Markdown.
24
+ //
25
+ // This is not a normal parser design; it's basically just a
26
+ // series of string substitutions. It's hard to read and
27
+ // maintain this way, but keeping Showdown close to the original
28
+ // design makes it easier to port new features.
29
+ //
30
+ // More importantly, Showdown behaves like markdown.pl in most
31
+ // edge cases. So web applications can do client-side preview
32
+ // in Javascript, and then build identical HTML on the server.
33
+ //
34
+ // This port needs the new RegExp functionality of ECMA 262,
35
+ // 3rd Edition (i.e. Javascript 1.5). Most modern web browsers
36
+ // should do fine. Even with the new regular expression features,
37
+ // We do a lot of work to emulate Perl's regex functionality.
38
+ // The tricky changes in this file mostly have the "attacklab:"
39
+ // label. Major or self-explanatory changes don't.
40
+ //
41
+ // Smart diff tools like Araxis Merge will be able to match up
42
+ // this file with markdown.pl in a useful way. A little tweaking
43
+ // helps: in a copy of markdown.pl, replace "#" with "//" and
44
+ // replace "$text" with "text". Be sure to ignore whitespace
45
+ // and line endings.
46
+ //
47
+
48
+
49
+ //
50
+ // Showdown usage:
51
+ //
52
+ // var text = "Markdown *rocks*.";
53
+ //
54
+ // var converter = new Showdown.converter();
55
+ // var html = converter.makeHtml(text);
56
+ //
57
+ // alert(html);
58
+ //
59
+ // Note: move the sample code to the bottom of this
60
+ // file before uncommenting it.
61
+ //
62
+
63
+
64
+ //
65
+ // Showdown namespace
66
+ //
67
+ var Showdown = {};
68
+
69
+ //
70
+ // converter
71
+ //
72
+ // Wraps all "globals" so that the only thing
73
+ // exposed is makeHtml().
74
+ //
75
+ Showdown.converter = function() {
76
+
77
+ //
78
+ // Globals:
79
+ //
80
+
81
+ // Global hashes, used by various utility routines
82
+ var g_urls;
83
+ var g_titles;
84
+ var g_html_blocks;
85
+
86
+ // Used to track when we're inside an ordered or unordered list
87
+ // (see _ProcessListItems() for details):
88
+ var g_list_level = 0;
89
+
90
+
91
+ this.makeHtml = function(text) {
92
+ //
93
+ // Main function. The order in which other subs are called here is
94
+ // essential. Link and image substitutions need to happen before
95
+ // _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
96
+ // and <img> tags get encoded.
97
+ //
98
+
99
+ // Clear the global hashes. If we don't clear these, you get conflicts
100
+ // from other articles when generating a page which contains more than
101
+ // one article (e.g. an index page that shows the N most recent
102
+ // articles):
103
+ g_urls = new Array();
104
+ g_titles = new Array();
105
+ g_html_blocks = new Array();
106
+
107
+ // attacklab: Replace ~ with ~T
108
+ // This lets us use tilde as an escape char to avoid md5 hashes
109
+ // The choice of character is arbitray; anything that isn't
110
+ // magic in Markdown will work.
111
+ text = text.replace(/~/g,"~T");
112
+
113
+ // attacklab: Replace $ with ~D
114
+ // RegExp interprets $ as a special character
115
+ // when it's in a replacement string
116
+ text = text.replace(/\$/g,"~D");
117
+
118
+ // Standardize line endings
119
+ text = text.replace(/\r\n/g,"\n"); // DOS to Unix
120
+ text = text.replace(/\r/g,"\n"); // Mac to Unix
121
+
122
+ // Make sure text begins and ends with a couple of newlines:
123
+ text = "\n\n" + text + "\n\n";
124
+
125
+ // Convert all tabs to spaces.
126
+ text = _Detab(text);
127
+
128
+ // Strip any lines consisting only of spaces and tabs.
129
+ // This makes subsequent regexen easier to write, because we can
130
+ // match consecutive blank lines with /\n+/ instead of something
131
+ // contorted like /[ \t]*\n+/ .
132
+ text = text.replace(/^[ \t]+$/mg,"");
133
+
134
+ // Turn block-level HTML blocks into hash entries
135
+ text = _HashHTMLBlocks(text);
136
+
137
+ // Strip link definitions, store in hashes.
138
+ text = _StripLinkDefinitions(text);
139
+
140
+ text = _RunBlockGamut(text);
141
+
142
+ text = _UnescapeSpecialChars(text);
143
+
144
+ // attacklab: Restore dollar signs
145
+ text = text.replace(/~D/g,"$$");
146
+
147
+ // attacklab: Restore tildes
148
+ text = text.replace(/~T/g,"~");
149
+
150
+ return text;
151
+ }
152
+
153
+
154
+ var _StripLinkDefinitions = function(text) {
155
+ //
156
+ // Strips link definitions from text, stores the URLs and titles in
157
+ // hash references.
158
+ //
159
+
160
+ // Link defs are in the form: ^[id]: url "optional title"
161
+
162
+ /*
163
+ var text = text.replace(/
164
+ ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1
165
+ [ \t]*
166
+ \n? // maybe *one* newline
167
+ [ \t]*
168
+ <?(\S+?)>? // url = $2
169
+ [ \t]*
170
+ \n? // maybe one newline
171
+ [ \t]*
172
+ (?:
173
+ (\n*) // any lines skipped = $3 attacklab: lookbehind removed
174
+ ["(]
175
+ (.+?) // title = $4
176
+ [")]
177
+ [ \t]*
178
+ )? // title is optional
179
+ (?:\n+|$)
180
+ /gm,
181
+ function(){...});
182
+ */
183
+ var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
184
+ function (wholeMatch,m1,m2,m3,m4) {
185
+ m1 = m1.toLowerCase();
186
+ g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive
187
+ if (m3) {
188
+ // Oops, found blank lines, so it's not a title.
189
+ // Put back the parenthetical statement we stole.
190
+ return m3+m4;
191
+ } else if (m4) {
192
+ g_titles[m1] = m4.replace(/"/g,"&quot;");
193
+ }
194
+
195
+ // Completely remove the definition from the text
196
+ return "";
197
+ }
198
+ );
199
+
200
+ return text;
201
+ }
202
+
203
+
204
+ var _HashHTMLBlocks = function(text) {
205
+ // attacklab: Double up blank lines to reduce lookaround
206
+ text = text.replace(/\n/g,"\n\n");
207
+
208
+ // Hashify HTML blocks:
209
+ // We only want to do this for block-level HTML tags, such as headers,
210
+ // lists, and tables. That's because we still want to wrap <p>s around
211
+ // "paragraphs" that are wrapped in non-block-level tags, such as anchors,
212
+ // phrase emphasis, and spans. The list of tags we're looking for is
213
+ // hard-coded:
214
+ var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del"
215
+ var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math"
216
+
217
+ // First, look for nested blocks, e.g.:
218
+ // <div>
219
+ // <div>
220
+ // tags for inner block must be indented.
221
+ // </div>
222
+ // </div>
223
+ //
224
+ // The outermost tags must start at the left margin for this to match, and
225
+ // the inner nested divs must be indented.
226
+ // We need to do this before the next, more liberal match, because the next
227
+ // match will start at the first `<div>` and stop at the first `</div>`.
228
+
229
+ // attacklab: This regex can be expensive when it fails.
230
+ /*
231
+ var text = text.replace(/
232
+ ( // save in $1
233
+ ^ // start of line (with /m)
234
+ <($block_tags_a) // start tag = $2
235
+ \b // word break
236
+ // attacklab: hack around khtml/pcre bug...
237
+ [^\r]*?\n // any number of lines, minimally matching
238
+ </\2> // the matching end tag
239
+ [ \t]* // trailing spaces/tabs
240
+ (?=\n+) // followed by a newline
241
+ ) // attacklab: there are sentinel newlines at end of document
242
+ /gm,function(){...}};
243
+ */
244
+ text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
245
+
246
+ //
247
+ // Now match more liberally, simply from `\n<tag>` to `</tag>\n`
248
+ //
249
+
250
+ /*
251
+ var text = text.replace(/
252
+ ( // save in $1
253
+ ^ // start of line (with /m)
254
+ <($block_tags_b) // start tag = $2
255
+ \b // word break
256
+ // attacklab: hack around khtml/pcre bug...
257
+ [^\r]*? // any number of lines, minimally matching
258
+ .*</\2> // the matching end tag
259
+ [ \t]* // trailing spaces/tabs
260
+ (?=\n+) // followed by a newline
261
+ ) // attacklab: there are sentinel newlines at end of document
262
+ /gm,function(){...}};
263
+ */
264
+ text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
265
+
266
+ // Special case just for <hr />. It was easier to make a special case than
267
+ // to make the other regex more complicated.
268
+
269
+ /*
270
+ text = text.replace(/
271
+ ( // save in $1
272
+ \n\n // Starting after a blank line
273
+ [ ]{0,3}
274
+ (<(hr) // start tag = $2
275
+ \b // word break
276
+ ([^<>])*? //
277
+ \/?>) // the matching end tag
278
+ [ \t]*
279
+ (?=\n{2,}) // followed by a blank line
280
+ )
281
+ /g,hashElement);
282
+ */
283
+ text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
284
+
285
+ // Special case for standalone HTML comments:
286
+
287
+ /*
288
+ text = text.replace(/
289
+ ( // save in $1
290
+ \n\n // Starting after a blank line
291
+ [ ]{0,3} // attacklab: g_tab_width - 1
292
+ <!
293
+ (--[^\r]*?--\s*)+
294
+ >
295
+ [ \t]*
296
+ (?=\n{2,}) // followed by a blank line
297
+ )
298
+ /g,hashElement);
299
+ */
300
+ text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
301
+
302
+ // PHP and ASP-style processor instructions (<?...?> and <%...%>)
303
+
304
+ /*
305
+ text = text.replace(/
306
+ (?:
307
+ \n\n // Starting after a blank line
308
+ )
309
+ ( // save in $1
310
+ [ ]{0,3} // attacklab: g_tab_width - 1
311
+ (?:
312
+ <([?%]) // $2
313
+ [^\r]*?
314
+ \2>
315
+ )
316
+ [ \t]*
317
+ (?=\n{2,}) // followed by a blank line
318
+ )
319
+ /g,hashElement);
320
+ */
321
+ text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
322
+
323
+ // attacklab: Undo double lines (see comment at top of this function)
324
+ text = text.replace(/\n\n/g,"\n");
325
+ return text;
326
+ }
327
+
328
+ var hashElement = function(wholeMatch,m1) {
329
+ var blockText = m1;
330
+
331
+ // Undo double lines
332
+ blockText = blockText.replace(/\n\n/g,"\n");
333
+ blockText = blockText.replace(/^\n/,"");
334
+
335
+ // strip trailing blank lines
336
+ blockText = blockText.replace(/\n+$/g,"");
337
+
338
+ // Replace the element text with a marker ("~KxK" where x is its key)
339
+ blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
340
+
341
+ return blockText;
342
+ };
343
+
344
+ var _RunBlockGamut = function(text) {
345
+ //
346
+ // These are all the transformations that form block-level
347
+ // tags like paragraphs, headers, and list items.
348
+ //
349
+ text = _DoHeaders(text);
350
+
351
+ // Do Horizontal Rules:
352
+ var key = hashBlock("<hr />");
353
+ text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
354
+ text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
355
+ text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
356
+
357
+ text = _DoLists(text);
358
+ text = _DoCodeBlocks(text);
359
+ text = _DoBlockQuotes(text);
360
+
361
+ // We already ran _HashHTMLBlocks() before, in Markdown(), but that
362
+ // was to escape raw HTML in the original Markdown source. This time,
363
+ // we're escaping the markup we've just created, so that we don't wrap
364
+ // <p> tags around block-level tags.
365
+ text = _HashHTMLBlocks(text);
366
+ text = _FormParagraphs(text);
367
+
368
+ return text;
369
+ }
370
+
371
+
372
+ var _RunSpanGamut = function(text) {
373
+ //
374
+ // These are all the transformations that occur *within* block-level
375
+ // tags like paragraphs, headers, and list items.
376
+ //
377
+
378
+ text = _DoCodeSpans(text);
379
+ text = _EscapeSpecialCharsWithinTagAttributes(text);
380
+ text = _EncodeBackslashEscapes(text);
381
+
382
+ // Process anchor and image tags. Images must come first,
383
+ // because ![foo][f] looks like an anchor.
384
+ text = _DoImages(text);
385
+ text = _DoAnchors(text);
386
+
387
+ // Make links out of things like `<http://example.com/>`
388
+ // Must come after _DoAnchors(), because you can use < and >
389
+ // delimiters in inline links like [this](<url>).
390
+ text = _DoAutoLinks(text);
391
+ text = _EncodeAmpsAndAngles(text);
392
+ text = _DoItalicsAndBold(text);
393
+
394
+ // Do hard breaks:
395
+ text = text.replace(/ +\n/g," <br />\n");
396
+
397
+ return text;
398
+ }
399
+
400
+ var _EscapeSpecialCharsWithinTagAttributes = function(text) {
401
+ //
402
+ // Within tags -- meaning between < and > -- encode [\ ` * _] so they
403
+ // don't conflict with their use in Markdown for code, italics and strong.
404
+ //
405
+
406
+ // Build a regex to find HTML tags and comments. See Friedl's
407
+ // "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
408
+ var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
409
+
410
+ text = text.replace(regex, function(wholeMatch) {
411
+ var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
412
+ tag = escapeCharacters(tag,"\\`*_");
413
+ return tag;
414
+ });
415
+
416
+ return text;
417
+ }
418
+
419
+ var _DoAnchors = function(text) {
420
+ //
421
+ // Turn Markdown link shortcuts into XHTML <a> tags.
422
+ //
423
+ //
424
+ // First, handle reference-style links: [link text] [id]
425
+ //
426
+
427
+ /*
428
+ text = text.replace(/
429
+ ( // wrap whole match in $1
430
+ \[
431
+ (
432
+ (?:
433
+ \[[^\]]*\] // allow brackets nested one level
434
+ |
435
+ [^\[] // or anything else
436
+ )*
437
+ )
438
+ \]
439
+
440
+ [ ]? // one optional space
441
+ (?:\n[ ]*)? // one optional newline followed by spaces
442
+
443
+ \[
444
+ (.*?) // id = $3
445
+ \]
446
+ )()()()() // pad remaining backreferences
447
+ /g,_DoAnchors_callback);
448
+ */
449
+ text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
450
+
451
+ //
452
+ // Next, inline-style links: [link text](url "optional title")
453
+ //
454
+
455
+ /*
456
+ text = text.replace(/
457
+ ( // wrap whole match in $1
458
+ \[
459
+ (
460
+ (?:
461
+ \[[^\]]*\] // allow brackets nested one level
462
+ |
463
+ [^\[\]] // or anything else
464
+ )
465
+ )
466
+ \]
467
+ \( // literal paren
468
+ [ \t]*
469
+ () // no id, so leave $3 empty
470
+ <?(.*?)>? // href = $4
471
+ [ \t]*
472
+ ( // $5
473
+ (['"]) // quote char = $6
474
+ (.*?) // Title = $7
475
+ \6 // matching quote
476
+ [ \t]* // ignore any spaces/tabs between closing quote and )
477
+ )? // title is optional
478
+ \)
479
+ )
480
+ /g,writeAnchorTag);
481
+ */
482
+ text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
483
+
484
+ //
485
+ // Last, handle reference-style shortcuts: [link text]
486
+ // These must come last in case you've also got [link test][1]
487
+ // or [link test](/foo)
488
+ //
489
+
490
+ /*
491
+ text = text.replace(/
492
+ ( // wrap whole match in $1
493
+ \[
494
+ ([^\[\]]+) // link text = $2; can't contain '[' or ']'
495
+ \]
496
+ )()()()()() // pad rest of backreferences
497
+ /g, writeAnchorTag);
498
+ */
499
+ text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
500
+
501
+ return text;
502
+ }
503
+
504
+ var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
505
+ if (m7 == undefined) m7 = "";
506
+ var whole_match = m1;
507
+ var link_text = m2;
508
+ var link_id = m3.toLowerCase();
509
+ var url = m4;
510
+ var title = m7;
511
+
512
+ if (url == "") {
513
+ if (link_id == "") {
514
+ // lower-case and turn embedded newlines into spaces
515
+ link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
516
+ }
517
+ url = "#"+link_id;
518
+
519
+ if (g_urls[link_id] != undefined) {
520
+ url = g_urls[link_id];
521
+ if (g_titles[link_id] != undefined) {
522
+ title = g_titles[link_id];
523
+ }
524
+ }
525
+ else {
526
+ if (whole_match.search(/\(\s*\)$/m)>-1) {
527
+ // Special case for explicit empty url
528
+ url = "";
529
+ } else {
530
+ return whole_match;
531
+ }
532
+ }
533
+ }
534
+
535
+ url = escapeCharacters(url,"*_");
536
+ var result = "<a href=\"" + url + "\"";
537
+
538
+ if (title != "") {
539
+ title = title.replace(/"/g,"&quot;");
540
+ title = escapeCharacters(title,"*_");
541
+ result += " title=\"" + title + "\"";
542
+ }
543
+
544
+ result += ">" + link_text + "</a>";
545
+
546
+ return result;
547
+ }
548
+
549
+
550
+ var _DoImages = function(text) {
551
+ //
552
+ // Turn Markdown image shortcuts into <img> tags.
553
+ //
554
+
555
+ //
556
+ // First, handle reference-style labeled images: ![alt text][id]
557
+ //
558
+
559
+ /*
560
+ text = text.replace(/
561
+ ( // wrap whole match in $1
562
+ !\[
563
+ (.*?) // alt text = $2
564
+ \]
565
+
566
+ [ ]? // one optional space
567
+ (?:\n[ ]*)? // one optional newline followed by spaces
568
+
569
+ \[
570
+ (.*?) // id = $3
571
+ \]
572
+ )()()()() // pad rest of backreferences
573
+ /g,writeImageTag);
574
+ */
575
+ text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
576
+
577
+ //
578
+ // Next, handle inline images: ![alt text](url "optional title")
579
+ // Don't forget: encode * and _
580
+
581
+ /*
582
+ text = text.replace(/
583
+ ( // wrap whole match in $1
584
+ !\[
585
+ (.*?) // alt text = $2
586
+ \]
587
+ \s? // One optional whitespace character
588
+ \( // literal paren
589
+ [ \t]*
590
+ () // no id, so leave $3 empty
591
+ <?(\S+?)>? // src url = $4
592
+ [ \t]*
593
+ ( // $5
594
+ (['"]) // quote char = $6
595
+ (.*?) // title = $7
596
+ \6 // matching quote
597
+ [ \t]*
598
+ )? // title is optional
599
+ \)
600
+ )
601
+ /g,writeImageTag);
602
+ */
603
+ text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
604
+
605
+ return text;
606
+ }
607
+
608
+ var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
609
+ var whole_match = m1;
610
+ var alt_text = m2;
611
+ var link_id = m3.toLowerCase();
612
+ var url = m4;
613
+ var title = m7;
614
+
615
+ if (!title) title = "";
616
+
617
+ if (url == "") {
618
+ if (link_id == "") {
619
+ // lower-case and turn embedded newlines into spaces
620
+ link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
621
+ }
622
+ url = "#"+link_id;
623
+
624
+ if (g_urls[link_id] != undefined) {
625
+ url = g_urls[link_id];
626
+ if (g_titles[link_id] != undefined) {
627
+ title = g_titles[link_id];
628
+ }
629
+ }
630
+ else {
631
+ return whole_match;
632
+ }
633
+ }
634
+
635
+ alt_text = alt_text.replace(/"/g,"&quot;");
636
+ url = escapeCharacters(url,"*_");
637
+ var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
638
+
639
+ // attacklab: Markdown.pl adds empty title attributes to images.
640
+ // Replicate this bug.
641
+
642
+ //if (title != "") {
643
+ title = title.replace(/"/g,"&quot;");
644
+ title = escapeCharacters(title,"*_");
645
+ result += " title=\"" + title + "\"";
646
+ //}
647
+
648
+ result += " />";
649
+
650
+ return result;
651
+ }
652
+
653
+
654
+ var _DoHeaders = function(text) {
655
+
656
+ // Setext-style headers:
657
+ // Header 1
658
+ // ========
659
+ //
660
+ // Header 2
661
+ // --------
662
+ //
663
+ text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
664
+ function(wholeMatch,m1){return hashBlock("<h1>" + _RunSpanGamut(m1) + "</h1>");});
665
+
666
+ text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
667
+ function(matchFound,m1){return hashBlock("<h2>" + _RunSpanGamut(m1) + "</h2>");});
668
+
669
+ // atx-style headers:
670
+ // # Header 1
671
+ // ## Header 2
672
+ // ## Header 2 with closing hashes ##
673
+ // ...
674
+ // ###### Header 6
675
+ //
676
+
677
+ /*
678
+ text = text.replace(/
679
+ ^(\#{1,6}) // $1 = string of #'s
680
+ [ \t]*
681
+ (.+?) // $2 = Header text
682
+ [ \t]*
683
+ \#* // optional closing #'s (not counted)
684
+ \n+
685
+ /gm, function() {...});
686
+ */
687
+
688
+ text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
689
+ function(wholeMatch,m1,m2) {
690
+ var h_level = m1.length;
691
+ return hashBlock("<h" + h_level + ">" + _RunSpanGamut(m2) + "</h" + h_level + ">");
692
+ });
693
+
694
+ return text;
695
+ }
696
+
697
+ // This declaration keeps Dojo compressor from outputting garbage:
698
+ var _ProcessListItems;
699
+
700
+ var _DoLists = function(text) {
701
+ //
702
+ // Form HTML ordered (numbered) and unordered (bulleted) lists.
703
+ //
704
+
705
+ // attacklab: add sentinel to hack around khtml/safari bug:
706
+ // http://bugs.webkit.org/show_bug.cgi?id=11231
707
+ text += "~0";
708
+
709
+ // Re-usable pattern to match any entirel ul or ol list:
710
+
711
+ /*
712
+ var whole_list = /
713
+ ( // $1 = whole list
714
+ ( // $2
715
+ [ ]{0,3} // attacklab: g_tab_width - 1
716
+ ([*+-]|\d+[.]) // $3 = first list item marker
717
+ [ \t]+
718
+ )
719
+ [^\r]+?
720
+ ( // $4
721
+ ~0 // sentinel for workaround; should be $
722
+ |
723
+ \n{2,}
724
+ (?=\S)
725
+ (?! // Negative lookahead for another list item marker
726
+ [ \t]*
727
+ (?:[*+-]|\d+[.])[ \t]+
728
+ )
729
+ )
730
+ )/g
731
+ */
732
+ var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
733
+
734
+ if (g_list_level) {
735
+ text = text.replace(whole_list,function(wholeMatch,m1,m2) {
736
+ var list = m1;
737
+ var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
738
+
739
+ // Turn double returns into triple returns, so that we can make a
740
+ // paragraph for the last item in a list, if necessary:
741
+ list = list.replace(/\n{2,}/g,"\n\n\n");;
742
+ var result = _ProcessListItems(list);
743
+
744
+ // Trim any trailing whitespace, to put the closing `</$list_type>`
745
+ // up on the preceding line, to get it past the current stupid
746
+ // HTML block parser. This is a hack to work around the terrible
747
+ // hack that is the HTML block parser.
748
+ result = result.replace(/\s+$/,"");
749
+ result = "<"+list_type+">" + result + "</"+list_type+">\n";
750
+ return result;
751
+ });
752
+ } else {
753
+ whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
754
+ text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
755
+ var runup = m1;
756
+ var list = m2;
757
+
758
+ var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
759
+ // Turn double returns into triple returns, so that we can make a
760
+ // paragraph for the last item in a list, if necessary:
761
+ var list = list.replace(/\n{2,}/g,"\n\n\n");;
762
+ var result = _ProcessListItems(list);
763
+ result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
764
+ return result;
765
+ });
766
+ }
767
+
768
+ // attacklab: strip sentinel
769
+ text = text.replace(/~0/,"");
770
+
771
+ return text;
772
+ }
773
+
774
+ _ProcessListItems = function(list_str) {
775
+ //
776
+ // Process the contents of a single ordered or unordered list, splitting it
777
+ // into individual list items.
778
+ //
779
+ // The $g_list_level global keeps track of when we're inside a list.
780
+ // Each time we enter a list, we increment it; when we leave a list,
781
+ // we decrement. If it's zero, we're not in a list anymore.
782
+ //
783
+ // We do this because when we're not inside a list, we want to treat
784
+ // something like this:
785
+ //
786
+ // I recommend upgrading to version
787
+ // 8. Oops, now this line is treated
788
+ // as a sub-list.
789
+ //
790
+ // As a single paragraph, despite the fact that the second line starts
791
+ // with a digit-period-space sequence.
792
+ //
793
+ // Whereas when we're inside a list (or sub-list), that line will be
794
+ // treated as the start of a sub-list. What a kludge, huh? This is
795
+ // an aspect of Markdown's syntax that's hard to parse perfectly
796
+ // without resorting to mind-reading. Perhaps the solution is to
797
+ // change the syntax rules such that sub-lists must start with a
798
+ // starting cardinal number; e.g. "1." or "a.".
799
+
800
+ g_list_level++;
801
+
802
+ // trim trailing blank lines:
803
+ list_str = list_str.replace(/\n{2,}$/,"\n");
804
+
805
+ // attacklab: add sentinel to emulate \z
806
+ list_str += "~0";
807
+
808
+ /*
809
+ list_str = list_str.replace(/
810
+ (\n)? // leading line = $1
811
+ (^[ \t]*) // leading whitespace = $2
812
+ ([*+-]|\d+[.]) [ \t]+ // list marker = $3
813
+ ([^\r]+? // list item text = $4
814
+ (\n{1,2}))
815
+ (?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
816
+ /gm, function(){...});
817
+ */
818
+ list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
819
+ function(wholeMatch,m1,m2,m3,m4){
820
+ var item = m4;
821
+ var leading_line = m1;
822
+ var leading_space = m2;
823
+
824
+ if (leading_line || (item.search(/\n{2,}/)>-1)) {
825
+ item = _RunBlockGamut(_Outdent(item));
826
+ }
827
+ else {
828
+ // Recursion for sub-lists:
829
+ item = _DoLists(_Outdent(item));
830
+ item = item.replace(/\n$/,""); // chomp(item)
831
+ item = _RunSpanGamut(item);
832
+ }
833
+
834
+ return "<li>" + item + "</li>\n";
835
+ }
836
+ );
837
+
838
+ // attacklab: strip sentinel
839
+ list_str = list_str.replace(/~0/g,"");
840
+
841
+ g_list_level--;
842
+ return list_str;
843
+ }
844
+
845
+
846
+ var _DoCodeBlocks = function(text) {
847
+ //
848
+ // Process Markdown `<pre><code>` blocks.
849
+ //
850
+
851
+ /*
852
+ text = text.replace(text,
853
+ /(?:\n\n|^)
854
+ ( // $1 = the code block -- one or more lines, starting with a space/tab
855
+ (?:
856
+ (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
857
+ .*\n+
858
+ )+
859
+ )
860
+ (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
861
+ /g,function(){...});
862
+ */
863
+
864
+ // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
865
+ text += "~0";
866
+
867
+ text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
868
+ function(wholeMatch,m1,m2) {
869
+ var codeblock = m1;
870
+ var nextChar = m2;
871
+
872
+ codeblock = _EncodeCode( _Outdent(codeblock));
873
+ codeblock = _Detab(codeblock);
874
+ codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
875
+ codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
876
+
877
+ codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
878
+
879
+ return hashBlock(codeblock) + nextChar;
880
+ }
881
+ );
882
+
883
+ // attacklab: strip sentinel
884
+ text = text.replace(/~0/,"");
885
+
886
+ return text;
887
+ }
888
+
889
+ var hashBlock = function(text) {
890
+ text = text.replace(/(^\n+|\n+$)/g,"");
891
+ return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
892
+ }
893
+
894
+
895
+ var _DoCodeSpans = function(text) {
896
+ //
897
+ // * Backtick quotes are used for <code></code> spans.
898
+ //
899
+ // * You can use multiple backticks as the delimiters if you want to
900
+ // include literal backticks in the code span. So, this input:
901
+ //
902
+ // Just type ``foo `bar` baz`` at the prompt.
903
+ //
904
+ // Will translate to:
905
+ //
906
+ // <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
907
+ //
908
+ // There's no arbitrary limit to the number of backticks you
909
+ // can use as delimters. If you need three consecutive backticks
910
+ // in your code, use four for delimiters, etc.
911
+ //
912
+ // * You can use spaces to get literal backticks at the edges:
913
+ //
914
+ // ... type `` `bar` `` ...
915
+ //
916
+ // Turns to:
917
+ //
918
+ // ... type <code>`bar`</code> ...
919
+ //
920
+
921
+ /*
922
+ text = text.replace(/
923
+ (^|[^\\]) // Character before opening ` can't be a backslash
924
+ (`+) // $2 = Opening run of `
925
+ ( // $3 = The code block
926
+ [^\r]*?
927
+ [^`] // attacklab: work around lack of lookbehind
928
+ )
929
+ \2 // Matching closer
930
+ (?!`)
931
+ /gm, function(){...});
932
+ */
933
+
934
+ text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
935
+ function(wholeMatch,m1,m2,m3,m4) {
936
+ var c = m3;
937
+ c = c.replace(/^([ \t]*)/g,""); // leading whitespace
938
+ c = c.replace(/[ \t]*$/g,""); // trailing whitespace
939
+ c = _EncodeCode(c);
940
+ return m1+"<code>"+c+"</code>";
941
+ });
942
+
943
+ return text;
944
+ }
945
+
946
+
947
+ var _EncodeCode = function(text) {
948
+ //
949
+ // Encode/escape certain characters inside Markdown code runs.
950
+ // The point is that in code, these characters are literals,
951
+ // and lose their special Markdown meanings.
952
+ //
953
+ // Encode all ampersands; HTML entities are not
954
+ // entities within a Markdown code span.
955
+ text = text.replace(/&/g,"&amp;");
956
+
957
+ // Do the angle bracket song and dance:
958
+ text = text.replace(/</g,"&lt;");
959
+ text = text.replace(/>/g,"&gt;");
960
+
961
+ // Now, escape characters that are magic in Markdown:
962
+ text = escapeCharacters(text,"\*_{}[]\\",false);
963
+
964
+ // jj the line above breaks this:
965
+ //---
966
+
967
+ //* Item
968
+
969
+ // 1. Subitem
970
+
971
+ // special char: *
972
+ //---
973
+
974
+ return text;
975
+ }
976
+
977
+
978
+ var _DoItalicsAndBold = function(text) {
979
+
980
+ // <strong> must go first:
981
+ text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
982
+ "<strong>$2</strong>");
983
+
984
+ text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
985
+ "<em>$2</em>");
986
+
987
+ return text;
988
+ }
989
+
990
+
991
+ var _DoBlockQuotes = function(text) {
992
+
993
+ /*
994
+ text = text.replace(/
995
+ ( // Wrap whole match in $1
996
+ (
997
+ ^[ \t]*>[ \t]? // '>' at the start of a line
998
+ .+\n // rest of the first line
999
+ (.+\n)* // subsequent consecutive lines
1000
+ \n* // blanks
1001
+ )+
1002
+ )
1003
+ /gm, function(){...});
1004
+ */
1005
+
1006
+ text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
1007
+ function(wholeMatch,m1) {
1008
+ var bq = m1;
1009
+
1010
+ // attacklab: hack around Konqueror 3.5.4 bug:
1011
+ // "----------bug".replace(/^-/g,"") == "bug"
1012
+
1013
+ bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0"); // trim one level of quoting
1014
+
1015
+ // attacklab: clean up hack
1016
+ bq = bq.replace(/~0/g,"");
1017
+
1018
+ bq = bq.replace(/^[ \t]+$/gm,""); // trim whitespace-only lines
1019
+ bq = _RunBlockGamut(bq); // recurse
1020
+
1021
+ bq = bq.replace(/(^|\n)/g,"$1 ");
1022
+ // These leading spaces screw with <pre> content, so we need to fix that:
1023
+ bq = bq.replace(
1024
+ /(\s*<pre>[^\r]+?<\/pre>)/gm,
1025
+ function(wholeMatch,m1) {
1026
+ var pre = m1;
1027
+ // attacklab: hack around Konqueror 3.5.4 bug:
1028
+ pre = pre.replace(/^ /mg,"~0");
1029
+ pre = pre.replace(/~0/g,"");
1030
+ return pre;
1031
+ });
1032
+
1033
+ return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
1034
+ });
1035
+ return text;
1036
+ }
1037
+
1038
+
1039
+ var _FormParagraphs = function(text) {
1040
+ //
1041
+ // Params:
1042
+ // $text - string to process with html <p> tags
1043
+ //
1044
+
1045
+ // Strip leading and trailing lines:
1046
+ text = text.replace(/^\n+/g,"");
1047
+ text = text.replace(/\n+$/g,"");
1048
+
1049
+ var grafs = text.split(/\n{2,}/g);
1050
+ var grafsOut = new Array();
1051
+
1052
+ //
1053
+ // Wrap <p> tags.
1054
+ //
1055
+ var end = grafs.length;
1056
+ for (var i=0; i<end; i++) {
1057
+ var str = grafs[i];
1058
+
1059
+ // if this is an HTML marker, copy it
1060
+ if (str.search(/~K(\d+)K/g) >= 0) {
1061
+ grafsOut.push(str);
1062
+ }
1063
+ else if (str.search(/\S/) >= 0) {
1064
+ str = _RunSpanGamut(str);
1065
+ str = str.replace(/^([ \t]*)/g,"<p>");
1066
+ str += "</p>"
1067
+ grafsOut.push(str);
1068
+ }
1069
+
1070
+ }
1071
+
1072
+ //
1073
+ // Unhashify HTML blocks
1074
+ //
1075
+ end = grafsOut.length;
1076
+ for (var i=0; i<end; i++) {
1077
+ // if this is a marker for an html block...
1078
+ while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
1079
+ var blockText = g_html_blocks[RegExp.$1];
1080
+ blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
1081
+ grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
1082
+ }
1083
+ }
1084
+
1085
+ return grafsOut.join("\n\n");
1086
+ }
1087
+
1088
+
1089
+ var _EncodeAmpsAndAngles = function(text) {
1090
+ // Smart processing for ampersands and angle brackets that need to be encoded.
1091
+
1092
+ // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
1093
+ // http://bumppo.net/projects/amputator/
1094
+ text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
1095
+
1096
+ // Encode naked <'s
1097
+ text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
1098
+
1099
+ return text;
1100
+ }
1101
+
1102
+
1103
+ var _EncodeBackslashEscapes = function(text) {
1104
+ //
1105
+ // Parameter: String.
1106
+ // Returns: The string, with after processing the following backslash
1107
+ // escape sequences.
1108
+ //
1109
+
1110
+ // attacklab: The polite way to do this is with the new
1111
+ // escapeCharacters() function:
1112
+ //
1113
+ // text = escapeCharacters(text,"\\",true);
1114
+ // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
1115
+ //
1116
+ // ...but we're sidestepping its use of the (slow) RegExp constructor
1117
+ // as an optimization for Firefox. This function gets called a LOT.
1118
+
1119
+ text = text.replace(/\\(\\)/g,escapeCharacters_callback);
1120
+ text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
1121
+ return text;
1122
+ }
1123
+
1124
+
1125
+ var _DoAutoLinks = function(text) {
1126
+
1127
+ text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
1128
+
1129
+ // Email addresses: <address@domain.foo>
1130
+
1131
+ /*
1132
+ text = text.replace(/
1133
+ <
1134
+ (?:mailto:)?
1135
+ (
1136
+ [-.\w]+
1137
+ \@
1138
+ [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
1139
+ )
1140
+ >
1141
+ /gi, _DoAutoLinks_callback());
1142
+ */
1143
+ text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
1144
+ function(wholeMatch,m1) {
1145
+ return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
1146
+ }
1147
+ );
1148
+
1149
+ return text;
1150
+ }
1151
+
1152
+
1153
+ var _EncodeEmailAddress = function(addr) {
1154
+ //
1155
+ // Input: an email address, e.g. "foo@example.com"
1156
+ //
1157
+ // Output: the email address as a mailto link, with each character
1158
+ // of the address encoded as either a decimal or hex entity, in
1159
+ // the hopes of foiling most address harvesting spam bots. E.g.:
1160
+ //
1161
+ // <a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
1162
+ // x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
1163
+ // &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
1164
+ //
1165
+ // Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
1166
+ // mailing list: <http://tinyurl.com/yu7ue>
1167
+ //
1168
+
1169
+ // attacklab: why can't javascript speak hex?
1170
+ function char2hex(ch) {
1171
+ var hexDigits = '0123456789ABCDEF';
1172
+ var dec = ch.charCodeAt(0);
1173
+ return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
1174
+ }
1175
+
1176
+ var encode = [
1177
+ function(ch){return "&#"+ch.charCodeAt(0)+";";},
1178
+ function(ch){return "&#x"+char2hex(ch)+";";},
1179
+ function(ch){return ch;}
1180
+ ];
1181
+
1182
+ addr = "mailto:" + addr;
1183
+
1184
+ addr = addr.replace(/./g, function(ch) {
1185
+ if (ch == "@") {
1186
+ // this *must* be encoded. I insist.
1187
+ ch = encode[Math.floor(Math.random()*2)](ch);
1188
+ } else if (ch !=":") {
1189
+ // leave ':' alone (to spot mailto: later)
1190
+ var r = Math.random();
1191
+ // roughly 10% raw, 45% hex, 45% dec
1192
+ ch = (
1193
+ r > .9 ? encode[2](ch) :
1194
+ r > .45 ? encode[1](ch) :
1195
+ encode[0](ch)
1196
+ );
1197
+ }
1198
+ return ch;
1199
+ });
1200
+
1201
+ addr = "<a href=\"" + addr + "\">" + addr + "</a>";
1202
+ addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
1203
+
1204
+ return addr;
1205
+ }
1206
+
1207
+
1208
+ var _UnescapeSpecialChars = function(text) {
1209
+ //
1210
+ // Swap back in all the special characters we've hidden.
1211
+ //
1212
+ text = text.replace(/~E(\d+)E/g,
1213
+ function(wholeMatch,m1) {
1214
+ var charCodeToReplace = parseInt(m1);
1215
+ return String.fromCharCode(charCodeToReplace);
1216
+ }
1217
+ );
1218
+ return text;
1219
+ }
1220
+
1221
+
1222
+ var _Outdent = function(text) {
1223
+ //
1224
+ // Remove one level of line-leading tabs or spaces
1225
+ //
1226
+
1227
+ // attacklab: hack around Konqueror 3.5.4 bug:
1228
+ // "----------bug".replace(/^-/g,"") == "bug"
1229
+
1230
+ text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
1231
+
1232
+ // attacklab: clean up hack
1233
+ text = text.replace(/~0/g,"")
1234
+
1235
+ return text;
1236
+ }
1237
+
1238
+ var _Detab = function(text) {
1239
+ // attacklab: Detab's completely rewritten for speed.
1240
+ // In perl we could fix it by anchoring the regexp with \G.
1241
+ // In javascript we're less fortunate.
1242
+
1243
+ // expand first n-1 tabs
1244
+ text = text.replace(/\t(?=\t)/g," "); // attacklab: g_tab_width
1245
+
1246
+ // replace the nth with two sentinels
1247
+ text = text.replace(/\t/g,"~A~B");
1248
+
1249
+ // use the sentinel to anchor our regex so it doesn't explode
1250
+ text = text.replace(/~B(.+?)~A/g,
1251
+ function(wholeMatch,m1,m2) {
1252
+ var leadingText = m1;
1253
+ var numSpaces = 4 - leadingText.length % 4; // attacklab: g_tab_width
1254
+
1255
+ // there *must* be a better way to do this:
1256
+ for (var i=0; i<numSpaces; i++) leadingText+=" ";
1257
+
1258
+ return leadingText;
1259
+ }
1260
+ );
1261
+
1262
+ // clean up sentinels
1263
+ text = text.replace(/~A/g," "); // attacklab: g_tab_width
1264
+ text = text.replace(/~B/g,"");
1265
+
1266
+ return text;
1267
+ }
1268
+
1269
+
1270
+ //
1271
+ // attacklab: Utility functions
1272
+ //
1273
+
1274
+
1275
+ var escapeCharacters = function(text, charsToEscape, afterBackslash) {
1276
+ // First we have to escape the escape characters so that
1277
+ // we can build a character class out of them
1278
+ var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
1279
+
1280
+ if (afterBackslash) {
1281
+ regexString = "\\\\" + regexString;
1282
+ }
1283
+
1284
+ var regex = new RegExp(regexString,"g");
1285
+ text = text.replace(regex,escapeCharacters_callback);
1286
+
1287
+ return text;
1288
+ }
1289
+
1290
+
1291
+ var escapeCharacters_callback = function(wholeMatch,m1) {
1292
+ var charCodeToEscape = m1.charCodeAt(0);
1293
+ return "~E"+charCodeToEscape+"E";
1294
+ }
1295
+
1296
+ } // end of Showdown.converter
1297
+