bhf 0.4.7 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -45,6 +45,7 @@ header
45
45
  float: left
46
46
  font-weight: bold
47
47
  margin-right: 20px
48
+ margin-bottom: 10px
48
49
  &.active
49
50
  a
50
51
  +text-shadow(#fff, -1)
@@ -743,48 +744,31 @@ input[type="submit"].alt_button,
743
744
  width: 100%
744
745
  height: 100%
745
746
  .hour, .separator, .minutes
746
- color: #535B6F
747
- background: #fff
748
- width: 50px
749
- font-size: 32px
750
747
  position: absolute
751
- top: 10px
752
- text-align: center
753
- padding: 2px
754
748
  .hour,
755
749
  .minutes
756
- +box-shadow(0, 0, 1, #2F4D7B)
757
- +text-shadow(#ccc)
758
- margin-top: 8px
759
- border: none
760
750
  left: 15px
751
+ font-size: 26px
752
+ height: 48px
753
+ width: 40px
754
+ font-weight: bold
755
+ color: $g3
756
+ text-align: center
757
+ @extend .default_input
761
758
  .separator
762
- background: transparent
763
- border: 0px
764
759
  width: 10px
760
+ font-size: 34px
765
761
  left: 76px
766
762
  .minutes
767
763
  left: 95px
768
764
  .ok
769
- +box-shadow(0, 0, 1, #2F4D7B)
770
- +text-shadow(#ccc)
771
- color: #535B6F
772
- background: #fff
773
765
  position: absolute
774
- border: none
775
766
  cursor: pointer
776
- top: 73px
767
+ top: 46px
777
768
  left: 15px
778
769
  width: 134px
779
- padding: 4px 0
780
- font-size: 16px
781
- &:hover,
782
- &:focus,
783
- &:active
784
- background-color: #2F4D7B
785
- color: #fff
786
- +text-shadow(#000)
787
- +box-shadow(0, 0, 1, #fff)
770
+ @extend .alt_button
771
+ font-size: 20px !important
788
772
  .days
789
773
  .day
790
774
  float: left
@@ -804,10 +788,12 @@ input[type="submit"].alt_button,
804
788
  background-color: #fff
805
789
  color: #2F4D7B
806
790
  +text-shadow(#ccc)
791
+ +border-radius(2)
807
792
 
808
793
  .otherMonth
809
794
  color: #aaa
810
795
  .selected
796
+ +border-radius(2)
811
797
  background-color: #2F4D7B
812
798
  color: #fff
813
799
  +text-shadow(#000)
@@ -896,29 +882,22 @@ input[type="submit"].alt_button,
896
882
 
897
883
 
898
884
 
899
- #wmd-button-bar
900
- width: 100%
901
- background: $w1
902
- padding: 0 10px 4px 0
903
- margin: 0 -6px 4px -6px
904
- @extend .default_input
905
- #wmd-input
906
- height: 400px
907
- width: 100%
885
+
908
886
 
909
- #wmd-preview,
910
- #wmd-output
887
+ .wmd-preview,
888
+ .wmd-output
911
889
  @extend .default_input
890
+ width: 500px
912
891
  margin: 0 -6px 0 -6px
913
892
  background-color: #F5F5F5
914
- padding: 3px 5px
893
+ padding: 3px 5px 2px 5px
915
894
  margin-bottom: 10px
916
895
  line-height: 22px
917
896
 
918
897
  .wmd-panel
919
898
  width: 700px !important
920
899
 
921
- #wmd-preview
900
+ .wmd-preview
922
901
  img
923
902
  display: block
924
903
  ul,
@@ -935,6 +914,7 @@ input[type="submit"].alt_button,
935
914
  font-weight: bold
936
915
 
937
916
  .preview_switch
917
+ padding-right: 6px
938
918
  span
939
919
  float: right
940
920
  margin-left: 10px
@@ -942,7 +922,7 @@ input[type="submit"].alt_button,
942
922
  &.active
943
923
  color: $b2
944
924
 
945
- #wmd-output
925
+ .wmd-output
946
926
  font-size: 12px
947
927
  line-height: 16px
948
928
  background: $g3
@@ -951,14 +931,16 @@ input[type="submit"].alt_button,
951
931
  font-family: Monaco,Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Courier New",Courier,monospace
952
932
  white-space: pre-wrap
953
933
 
954
- #wmd-button-row
955
- position: relative
956
- margin-left: 5px
957
- margin-right: 5px
934
+ .wmd-button-row
935
+ width: 500px
936
+ background: $w1
937
+ padding: 6px 5px 1px 5px
938
+ @extend .default_input
939
+ margin-left: -6px
958
940
  margin-bottom: 5px
959
- margin-top: 10px
960
- padding: 0px
961
- height: 20px
941
+ .wmd-input
942
+ height: 400px
943
+ width: 100%
962
944
 
963
945
 
964
946
  .wmd-spacer
@@ -975,67 +957,54 @@ input[type="submit"].alt_button,
975
957
  height: 20px
976
958
  margin-left: 5px
977
959
  margin-right: 5px
978
- position: absolute
960
+ position: relative
979
961
  background-image: url(wmd-buttons.png)
980
962
  background-repeat: no-repeat
981
- background-position: 0px 0px
982
- display: inline-block
963
+ display: inline-block
964
+ list-style: none
965
+ border: 1px solid transparent
966
+ &:hover
967
+ border-color: $g2
968
+
969
+
970
+ .wmd-spacer
971
+ width: 1px
972
+ height: 20px
973
+ margin-left: 7px
974
+ margin-right: 7px
975
+ position: relative
976
+ background-color: $g2
977
+ display: inline-block
983
978
  list-style: none
984
- > a
985
- width: 20px
986
- height: 20px
987
- margin-left: 5px
988
- margin-right: 5px
989
- position: absolute
990
- display: inline-block
991
979
 
992
980
  // TODO: style this properly
993
981
 
994
- #wmd-button-bar
995
- #wmd-bold-button
996
- left: 0px
997
- background-position: 0px 0
998
- #wmd-italic-button
999
- left: 25px
982
+ .wmd-button-row
983
+ .wmd-bold-button
984
+ background-position: 0px 0px
985
+ .wmd-italic-button
1000
986
  background-position: -20px 0
1001
- #wmd-spacer1
1002
- left: 50px
1003
- #wmd-link-button
1004
- left: 75px
987
+ .wmd-link-button
1005
988
  background-position: -40px 0
1006
- #wmd-quote-button
1007
- left: 100px
989
+ .wmd-quote-button
1008
990
  background-position: -60px 0
1009
- #wmd-code-button
1010
- left: 125px
991
+ .wmd-code-button
1011
992
  background-position: -80px 0
1012
- #wmd-image-button
1013
- left: 150px
993
+ .wmd-image-button
1014
994
  background-position: -100px 0
1015
- #wmd-spacer2
1016
- left: 175px
1017
- #wmd-olist-button
1018
- left: 200px
995
+ .wmd-olist-button
1019
996
  background-position: -120px 0
1020
- #wmd-ulist-button
1021
- left: 225px
997
+ .wmd-ulist-button
1022
998
  background-position: -140px 0
1023
- #wmd-heading-button
1024
- left: 250px
999
+ .wmd-heading-button
1025
1000
  background-position: -160px 0
1026
- #wmd-hr-button
1027
- left: 275px
1001
+ .wmd-hr-button
1028
1002
  background-position: -180px 0
1029
- #wmd-spacer3
1030
- left: 300px
1031
- #wmd-undo-button
1032
- left: 325px
1003
+ .wmd-undo-button
1033
1004
  background-position: -200px 0
1034
- #wmd-redo-button
1035
- left: 350px
1005
+ .wmd-redo-button
1036
1006
  background-position: -220px 0
1037
- #wmd-help-button
1038
- right: 0px
1007
+ .wmd-help-button
1039
1008
  background-position: -240px 0
1040
1009
 
1041
1010
  .wmd-prompt-background
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bhf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000Z
12
+ date: 2012-02-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &70185416394600 !ruby/object:Gem::Requirement
16
+ requirement: &70333944386280 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.1.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70185416394600
24
+ version_requirements: *70333944386280
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: kaminari
27
- requirement: &70185416393640 !ruby/object:Gem::Requirement
27
+ requirement: &70333944385280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.12.4
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70185416393640
35
+ version_requirements: *70333944385280
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: haml-rails
38
- requirement: &70185416392780 !ruby/object:Gem::Requirement
38
+ requirement: &70333944372920 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.3.4
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70185416392780
46
+ version_requirements: *70333944372920
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sass-rails
49
- requirement: &70185416392040 !ruby/object:Gem::Requirement
49
+ requirement: &70333944368040 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 3.1.4
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70185416392040
57
+ version_requirements: *70333944368040
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: mootools-rails
60
- requirement: &70185416390720 !ruby/object:Gem::Requirement
60
+ requirement: &70333944366560 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0.4'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70185416390720
68
+ version_requirements: *70333944366560
69
69
  description: Gets you there on time
70
70
  email: anton.pawlik@gmail.com
71
71
  executables: []
@@ -176,8 +176,8 @@ files:
176
176
  - vendor/assets/javascripts/bhf/classes/Picker.js
177
177
  - vendor/assets/javascripts/bhf/classes/Picker_Attach.js
178
178
  - vendor/assets/javascripts/bhf/classes/Picker_Date.js
179
- - vendor/assets/javascripts/bhf/includes/showdown.js
180
- - vendor/assets/javascripts/bhf/includes/wmd.js
179
+ - vendor/assets/javascripts/bhf/classes/showdown.js
180
+ - vendor/assets/javascripts/bhf/classes/wmd.js
181
181
  - vendor/assets/javascripts/bhf/mootools-more-1.4.0.1.js
182
182
  - vendor/assets/stylesheets/bhf/MooEditable.css.scss
183
183
  - vendor/assets/stylesheets/bhf/application.css.sass
@@ -1,1330 +0,0 @@
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
- // The full source distribution is at:
10
- //
11
- // A A L
12
- // T C A
13
- // T K B
14
- //
15
- // <http://www.attacklab.net/>
16
- //
17
-
18
- //
19
- // Wherever possible, Showdown is a straight, line-by-line port
20
- // of the Perl version of Markdown.
21
- //
22
- // This is not a normal parser design; it's basically just a
23
- // series of string substitutions. It's hard to read and
24
- // maintain this way, but keeping Showdown close to the original
25
- // design makes it easier to port new features.
26
- //
27
- // More importantly, Showdown behaves like markdown.pl in most
28
- // edge cases. So web applications can do client-side preview
29
- // in Javascript, and then build identical HTML on the server.
30
- //
31
- // This port needs the new RegExp functionality of ECMA 262,
32
- // 3rd Edition (i.e. Javascript 1.5). Most modern web browsers
33
- // should do fine. Even with the new regular expression features,
34
- // We do a lot of work to emulate Perl's regex functionality.
35
- // The tricky changes in this file mostly have the "attacklab:"
36
- // label. Major or self-explanatory changes don't.
37
- //
38
- // Smart diff tools like Araxis Merge will be able to match up
39
- // this file with markdown.pl in a useful way. A little tweaking
40
- // helps: in a copy of markdown.pl, replace "#" with "//" and
41
- // replace "$text" with "text". Be sure to ignore whitespace
42
- // and line endings.
43
- //
44
-
45
-
46
- //
47
- // Showdown usage:
48
- //
49
- // var text = "Markdown *rocks*.";
50
- //
51
- // var converter = new Attacklab.showdown.converter();
52
- // var html = converter.makeHtml(text);
53
- //
54
- // alert(html);
55
- //
56
- // Note: move the sample code to the bottom of this
57
- // file before uncommenting it.
58
- //
59
-
60
-
61
- //
62
- // Attacklab namespace
63
- //
64
- var Attacklab = Attacklab || {}
65
-
66
- //
67
- // Showdown namespace
68
- //
69
- Attacklab.showdown = Attacklab.showdown || {}
70
-
71
- //
72
- // converter
73
- //
74
- // Wraps all "globals" so that the only thing
75
- // exposed is makeHtml().
76
- //
77
- Attacklab.showdown.converter = function() {
78
-
79
-
80
- // g_urls and g_titles allow arbitrary user-entered strings as keys. This
81
- // caused an exception (and hence stopped the rendering) when the user entered
82
- // e.g. [push] or [__proto__]. Adding a prefix to the actual key prevents this
83
- // (since no builtin property starts with "s_"). See
84
- // http://meta.stackoverflow.com/questions/64655/strange-wmd-bug
85
- // (granted, switching from Array() to Object() alone would have left only __proto__
86
- // to be a problem)
87
- var SaveHash = function () {
88
- this.set = function (key, value) {
89
- this["s_" + key] = value;
90
- }
91
- this.get = function (key) {
92
- return this["s_" + key];
93
- }
94
- }
95
-
96
- //
97
- // Globals:
98
- //
99
-
100
- // Global hashes, used by various utility routines
101
- var g_urls;
102
- var g_titles;
103
- var g_html_blocks;
104
-
105
- // Used to track when we're inside an ordered or unordered list
106
- // (see _ProcessListItems() for details):
107
- var g_list_level = 0;
108
-
109
-
110
- this.makeHtml = function(text) {
111
- //
112
- // Main function. The order in which other subs are called here is
113
- // essential. Link and image substitutions need to happen before
114
- // _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
115
- // and <img> tags get encoded.
116
- //
117
-
118
- // Clear the global hashes. If we don't clear these, you get conflicts
119
- // from other articles when generating a page which contains more than
120
- // one article (e.g. an index page that shows the N most recent
121
- // articles):
122
- g_urls = new SaveHash();
123
- g_titles = new SaveHash();
124
- g_html_blocks = new Array();
125
-
126
- // attacklab: Replace ~ with ~T
127
- // This lets us use tilde as an escape char to avoid md5 hashes
128
- // The choice of character is arbitray; anything that isn't
129
- // magic in Markdown will work.
130
- text = text.replace(/~/g,"~T");
131
-
132
- // attacklab: Replace $ with ~D
133
- // RegExp interprets $ as a special character
134
- // when it's in a replacement string
135
- text = text.replace(/\$/g,"~D");
136
-
137
- // Standardize line endings
138
- text = text.replace(/\r\n/g,"\n"); // DOS to Unix
139
- text = text.replace(/\r/g,"\n"); // Mac to Unix
140
-
141
- // Make sure text begins and ends with a couple of newlines:
142
- text = "\n\n" + text + "\n\n";
143
-
144
- // Convert all tabs to spaces.
145
- text = _Detab(text);
146
-
147
- // Strip any lines consisting only of spaces and tabs.
148
- // This makes subsequent regexen easier to write, because we can
149
- // match consecutive blank lines with /\n+/ instead of something
150
- // contorted like /[ \t]*\n+/ .
151
- text = text.replace(/^[ \t]+$/mg,"");
152
-
153
- // Turn block-level HTML blocks into hash entries
154
- text = _HashHTMLBlocks(text);
155
-
156
- // Strip link definitions, store in hashes.
157
- text = _StripLinkDefinitions(text);
158
-
159
- text = _RunBlockGamut(text);
160
-
161
- text = _UnescapeSpecialChars(text);
162
-
163
- // attacklab: Restore dollar signs
164
- text = text.replace(/~D/g,"$$");
165
-
166
- // attacklab: Restore tildes
167
- text = text.replace(/~T/g,"~");
168
-
169
- return text;
170
- }
171
-
172
- var _StripLinkDefinitions = function(text) {
173
- //
174
- // Strips link definitions from text, stores the URLs and titles in
175
- // hash references.
176
- //
177
-
178
- // Link defs are in the form: ^[id]: url "optional title"
179
-
180
- /*
181
- var text = text.replace(/
182
- ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1
183
- [ \t]*
184
- \n? // maybe *one* newline
185
- [ \t]*
186
- <?(\S+?)>? // url = $2
187
- (?=\s|$) // lookahead for whitespace instead of the lookbehind removed below
188
- [ \t]*
189
- \n? // maybe one newline
190
- [ \t]*
191
- ( // (potential) title = $3
192
- (\n*) // any lines skipped = $4 attacklab: lookbehind removed
193
- [ \t]+
194
- ["(]
195
- (.+?) // title = $5
196
- [")]
197
- [ \t]*
198
- )? // title is optional
199
- (?:\n+|$)
200
- /gm,
201
- function(){...});
202
- */
203
- var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?(?=\s|$)[ \t]*\n?[ \t]*((\n*)["(](.+?)[")][ \t]*)?(?:\n+)/gm,
204
- function (wholeMatch,m1,m2,m3,m4,m5) {
205
- m1 = m1.toLowerCase();
206
- g_urls.set(m1, _EncodeAmpsAndAngles(m2)); // Link IDs are case-insensitive
207
- if (m4) {
208
- // Oops, found blank lines, so it's not a title.
209
- // Put back the parenthetical statement we stole.
210
- return m3;
211
- } else if (m5) {
212
- g_titles.set(m1, m5.replace(/"/g,"&quot;"));
213
- }
214
-
215
- // Completely remove the definition from the text
216
- return "";
217
- }
218
- );
219
-
220
- return text;
221
- }
222
-
223
- var _HashHTMLBlocks = function(text) {
224
-
225
- // Hashify HTML blocks:
226
- // We only want to do this for block-level HTML tags, such as headers,
227
- // lists, and tables. That's because we still want to wrap <p>s around
228
- // "paragraphs" that are wrapped in non-block-level tags, such as anchors,
229
- // phrase emphasis, and spans. The list of tags we're looking for is
230
- // hard-coded:
231
- var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del"
232
- var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math"
233
-
234
- // First, look for nested blocks, e.g.:
235
- // <div>
236
- // <div>
237
- // tags for inner block must be indented.
238
- // </div>
239
- // </div>
240
- //
241
- // The outermost tags must start at the left margin for this to match, and
242
- // the inner nested divs must be indented.
243
- // We need to do this before the next, more liberal match, because the next
244
- // match will start at the first `<div>` and stop at the first `</div>`.
245
-
246
- // attacklab: This regex can be expensive when it fails.
247
- /*
248
- var text = text.replace(/
249
- ( // save in $1
250
- ^ // start of line (with /m)
251
- <($block_tags_a) // start tag = $2
252
- \b // word break
253
- // attacklab: hack around khtml/pcre bug...
254
- [^\r]*?\n // any number of lines, minimally matching
255
- </\2> // the matching end tag
256
- [ \t]* // trailing spaces/tabs
257
- (?=\n+) // followed by a newline
258
- ) // attacklab: there are sentinel newlines at end of document
259
- /gm,function(){...}};
260
- */
261
- 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);
262
-
263
- //
264
- // Now match more liberally, simply from `\n<tag>` to `</tag>\n`
265
- //
266
-
267
- /*
268
- var text = text.replace(/
269
- ( // save in $1
270
- ^ // start of line (with /m)
271
- <($block_tags_b) // start tag = $2
272
- \b // word break
273
- // attacklab: hack around khtml/pcre bug...
274
- [^\r]*? // any number of lines, minimally matching
275
- .*</\2> // the matching end tag
276
- [ \t]* // trailing spaces/tabs
277
- (?=\n+) // followed by a newline
278
- ) // attacklab: there are sentinel newlines at end of document
279
- /gm,function(){...}};
280
- */
281
- 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);
282
-
283
- // Special case just for <hr />. It was easier to make a special case than
284
- // to make the other regex more complicated.
285
-
286
- /*
287
- text = text.replace(/
288
- \n // Starting after a blank line
289
- [ ]{0,3}
290
- ( // save in $1
291
- (<(hr) // start tag = $2
292
- \b // word break
293
- ([^<>])*? //
294
- \/?>) // the matching end tag
295
- [ \t]*
296
- (?=\n{2,}) // followed by a blank line
297
- )
298
- /g,hashElement);
299
- */
300
- text = text.replace(/\n[ ]{0,3}((<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
301
-
302
- // Special case for standalone HTML comments:
303
-
304
- /*
305
- text = text.replace(/
306
- \n\n // Starting after a blank line
307
- [ ]{0,3} // attacklab: g_tab_width - 1
308
- ( // save in $1
309
- <!
310
- (--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--) // see http://www.w3.org/TR/html-markup/syntax.html#comments
311
- >
312
- [ \t]*
313
- (?=\n{2,}) // followed by a blank line
314
- )
315
- /g,hashElement);
316
- */
317
- text = text.replace(/\n\n[ ]{0,3}(<!(--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>[ \t]*(?=\n{2,}))/g, hashElement);
318
-
319
- // PHP and ASP-style processor instructions (<?...?> and <%...%>)
320
-
321
- /*
322
- text = text.replace(/
323
- (?:
324
- \n\n // Starting after a blank line
325
- )
326
- ( // save in $1
327
- [ ]{0,3} // attacklab: g_tab_width - 1
328
- (?:
329
- <([?%]) // $2
330
- [^\r]*?
331
- \2>
332
- )
333
- [ \t]*
334
- (?=\n{2,}) // followed by a blank line
335
- )
336
- /g,hashElement);
337
- */
338
- text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
339
-
340
- return text;
341
- }
342
-
343
- var hashElement = function(wholeMatch,m1) {
344
- var blockText = m1;
345
-
346
- // Undo double lines
347
- blockText = blockText.replace(/^\n+/,"");
348
-
349
- // strip trailing blank lines
350
- blockText = blockText.replace(/\n+$/g,"");
351
-
352
- // Replace the element text with a marker ("~KxK" where x is its key)
353
- blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
354
-
355
- return blockText;
356
- };
357
-
358
- var _RunBlockGamut = function(text, doNotUnhash) {
359
- //
360
- // These are all the transformations that form block-level
361
- // tags like paragraphs, headers, and list items.
362
- //
363
- text = _DoHeaders(text);
364
-
365
- // Do Horizontal Rules:
366
- var key = hashBlock("<hr />");
367
- text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
368
- text = text.replace(/^[ ]{0,2}([ ]?-[ ]?){3,}[ \t]*$/gm,key);
369
- text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm,key);
370
-
371
- text = _DoLists(text);
372
- text = _DoCodeBlocks(text);
373
- text = _DoBlockQuotes(text);
374
-
375
- // We already ran _HashHTMLBlocks() before, in Markdown(), but that
376
- // was to escape raw HTML in the original Markdown source. This time,
377
- // we're escaping the markup we've just created, so that we don't wrap
378
- // <p> tags around block-level tags.
379
- text = _HashHTMLBlocks(text);
380
- text = _FormParagraphs(text, doNotUnhash);
381
-
382
- return text;
383
- }
384
-
385
-
386
- var _RunSpanGamut = function(text) {
387
- //
388
- // These are all the transformations that occur *within* block-level
389
- // tags like paragraphs, headers, and list items.
390
- //
391
-
392
- text = _DoCodeSpans(text);
393
- text = _EscapeSpecialCharsWithinTagAttributes(text);
394
- text = _EncodeBackslashEscapes(text);
395
-
396
- // Process anchor and image tags. Images must come first,
397
- // because ![foo][f] looks like an anchor.
398
- text = _DoImages(text);
399
- text = _DoAnchors(text);
400
-
401
- // Make links out of things like `<http://example.com/>`
402
- // Must come after _DoAnchors(), because you can use < and >
403
- // delimiters in inline links like [this](<url>).
404
- text = _DoAutoLinks(text);
405
- text = _EncodeAmpsAndAngles(text);
406
- text = _DoItalicsAndBold(text);
407
-
408
- // Do hard breaks:
409
- text = text.replace(/ +\n/g," <br />\n");
410
-
411
- return text;
412
- }
413
-
414
- var _EscapeSpecialCharsWithinTagAttributes = function(text) {
415
- //
416
- // Within tags -- meaning between < and > -- encode [\ ` * _] so they
417
- // don't conflict with their use in Markdown for code, italics and strong.
418
- //
419
-
420
- // Build a regex to find HTML tags and comments. See Friedl's
421
- // "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
422
-
423
- // SE: changed the comment part of the regex
424
-
425
- var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--(?:|(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>)/gi;
426
-
427
- text = text.replace(regex, function(wholeMatch) {
428
- var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
429
- tag = escapeCharacters(tag,"\\`*_");
430
- return tag;
431
- });
432
-
433
- return text;
434
- }
435
-
436
- var _DoAnchors = function(text) {
437
- //
438
- // Turn Markdown link shortcuts into XHTML <a> tags.
439
- //
440
- //
441
- // First, handle reference-style links: [link text] [id]
442
- //
443
-
444
- /*
445
- text = text.replace(/
446
- ( // wrap whole match in $1
447
- \[
448
- (
449
- (?:
450
- \[[^\]]*\] // allow brackets nested one level
451
- |
452
- [^\[] // or anything else
453
- )*
454
- )
455
- \]
456
-
457
- [ ]? // one optional space
458
- (?:\n[ ]*)? // one optional newline followed by spaces
459
-
460
- \[
461
- (.*?) // id = $3
462
- \]
463
- )()()()() // pad remaining backreferences
464
- /g,_DoAnchors_callback);
465
- */
466
- text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
467
-
468
- //
469
- // Next, inline-style links: [link text](url "optional title")
470
- //
471
-
472
- /*
473
- text = text.replace(/
474
- ( // wrap whole match in $1
475
- \[
476
- (
477
- (?:
478
- \[[^\]]*\] // allow brackets nested one level
479
- |
480
- [^\[\]] // or anything else
481
- )*
482
- )
483
- \]
484
- \( // literal paren
485
- [ \t]*
486
- () // no id, so leave $3 empty
487
- <?( // href = $4
488
- (?:
489
- \([^)]*\) // allow one level of (correctly nested) parens (think MSDN)
490
- |
491
- [^()]
492
- )*?
493
- )>?
494
- [ \t]*
495
- ( // $5
496
- (['"]) // quote char = $6
497
- (.*?) // Title = $7
498
- \6 // matching quote
499
- [ \t]* // ignore any spaces/tabs between closing quote and )
500
- )? // title is optional
501
- \)
502
- )
503
- /g,writeAnchorTag);
504
- */
505
-
506
- text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?((?:\([^)]*\)|[^()])*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
507
-
508
- //
509
- // Last, handle reference-style shortcuts: [link text]
510
- // These must come last in case you've also got [link test][1]
511
- // or [link test](/foo)
512
- //
513
-
514
- /*
515
- text = text.replace(/
516
- ( // wrap whole match in $1
517
- \[
518
- ([^\[\]]+) // link text = $2; can't contain '[' or ']'
519
- \]
520
- )()()()()() // pad rest of backreferences
521
- /g, writeAnchorTag);
522
- */
523
- text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
524
-
525
- return text;
526
- }
527
-
528
- var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
529
- if (m7 == undefined) m7 = "";
530
- var whole_match = m1;
531
- var link_text = m2;
532
- var link_id = m3.toLowerCase();
533
- var url = m4;
534
- var title = m7;
535
-
536
- if (url == "") {
537
- if (link_id == "") {
538
- // lower-case and turn embedded newlines into spaces
539
- link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
540
- }
541
- url = "#"+link_id;
542
-
543
- if (g_urls.get(link_id) != undefined) {
544
- url = g_urls.get(link_id);
545
- if (g_titles.get(link_id) != undefined) {
546
- title = g_titles.get(link_id);
547
- }
548
- }
549
- else {
550
- if (whole_match.search(/\(\s*\)$/m)>-1) {
551
- // Special case for explicit empty url
552
- url = "";
553
- } else {
554
- return whole_match;
555
- }
556
- }
557
- }
558
-
559
- url = escapeCharacters(url,"*_");
560
- var result = "<a href=\"" + url + "\"";
561
-
562
- if (title != "") {
563
- title = title.replace(/"/g,"&quot;");
564
- title = escapeCharacters(title,"*_");
565
- result += " title=\"" + title + "\"";
566
- }
567
-
568
- result += ">" + link_text + "</a>";
569
-
570
- return result;
571
- }
572
-
573
-
574
- var _DoImages = function(text) {
575
- //
576
- // Turn Markdown image shortcuts into <img> tags.
577
- //
578
-
579
- //
580
- // First, handle reference-style labeled images: ![alt text][id]
581
- //
582
-
583
- /*
584
- text = text.replace(/
585
- ( // wrap whole match in $1
586
- !\[
587
- (.*?) // alt text = $2
588
- \]
589
-
590
- [ ]? // one optional space
591
- (?:\n[ ]*)? // one optional newline followed by spaces
592
-
593
- \[
594
- (.*?) // id = $3
595
- \]
596
- )()()()() // pad rest of backreferences
597
- /g,writeImageTag);
598
- */
599
- text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
600
-
601
- //
602
- // Next, handle inline images: ![alt text](url "optional title")
603
- // Don't forget: encode * and _
604
-
605
- /*
606
- text = text.replace(/
607
- ( // wrap whole match in $1
608
- !\[
609
- (.*?) // alt text = $2
610
- \]
611
- \s? // One optional whitespace character
612
- \( // literal paren
613
- [ \t]*
614
- () // no id, so leave $3 empty
615
- <?(\S+?)>? // src url = $4
616
- [ \t]*
617
- ( // $5
618
- (['"]) // quote char = $6
619
- (.*?) // title = $7
620
- \6 // matching quote
621
- [ \t]*
622
- )? // title is optional
623
- \)
624
- )
625
- /g,writeImageTag);
626
- */
627
- text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
628
-
629
- return text;
630
- }
631
-
632
- var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
633
- var whole_match = m1;
634
- var alt_text = m2;
635
- var link_id = m3.toLowerCase();
636
- var url = m4;
637
- var title = m7;
638
-
639
- if (!title) title = "";
640
-
641
- if (url == "") {
642
- if (link_id == "") {
643
- // lower-case and turn embedded newlines into spaces
644
- link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
645
- }
646
- url = "#"+link_id;
647
-
648
- if (g_urls.get(link_id) != undefined) {
649
- url = g_urls.get(link_id);
650
- if (g_titles.get(link_id) != undefined) {
651
- title = g_titles.get(link_id);
652
- }
653
- }
654
- else {
655
- return whole_match;
656
- }
657
- }
658
-
659
- alt_text = alt_text.replace(/"/g,"&quot;");
660
- url = escapeCharacters(url,"*_");
661
- var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
662
-
663
- // attacklab: Markdown.pl adds empty title attributes to images.
664
- // Replicate this bug.
665
-
666
- //if (title != "") {
667
- title = title.replace(/"/g,"&quot;");
668
- title = escapeCharacters(title,"*_");
669
- result += " title=\"" + title + "\"";
670
- //}
671
-
672
- result += " />";
673
-
674
- return result;
675
- }
676
-
677
-
678
- var _DoHeaders = function(text) {
679
-
680
- // Setext-style headers:
681
- // Header 1
682
- // ========
683
- //
684
- // Header 2
685
- // --------
686
- //
687
- text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
688
- function(wholeMatch,m1){return "<h1>" + _RunSpanGamut(m1) + "</h1>\n\n";});
689
-
690
- text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
691
- function(matchFound,m1){return "<h2>" + _RunSpanGamut(m1) + "</h2>\n\n";});
692
-
693
- // atx-style headers:
694
- // # Header 1
695
- // ## Header 2
696
- // ## Header 2 with closing hashes ##
697
- // ...
698
- // ###### Header 6
699
- //
700
-
701
- /*
702
- text = text.replace(/
703
- ^(\#{1,6}) // $1 = string of #'s
704
- [ \t]*
705
- (.+?) // $2 = Header text
706
- [ \t]*
707
- \#* // optional closing #'s (not counted)
708
- \n+
709
- /gm, function() {...});
710
- */
711
-
712
- text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
713
- function(wholeMatch,m1,m2) {
714
- var h_level = m1.length;
715
- return "<h" + h_level + ">" + _RunSpanGamut(m2) + "</h" + h_level + ">\n\n";
716
- });
717
-
718
- return text;
719
- }
720
-
721
- // This declaration keeps Dojo compressor from outputting garbage:
722
- var _ProcessListItems;
723
-
724
- var _DoLists = function(text) {
725
- //
726
- // Form HTML ordered (numbered) and unordered (bulleted) lists.
727
- //
728
-
729
- // attacklab: add sentinel to hack around khtml/safari bug:
730
- // http://bugs.webkit.org/show_bug.cgi?id=11231
731
- text += "~0";
732
-
733
- // Re-usable pattern to match any entirel ul or ol list:
734
-
735
- /*
736
- var whole_list = /
737
- ( // $1 = whole list
738
- ( // $2
739
- [ ]{0,3} // attacklab: g_tab_width - 1
740
- ([*+-]|\d+[.]) // $3 = first list item marker
741
- [ \t]+
742
- )
743
- [^\r]+?
744
- ( // $4
745
- ~0 // sentinel for workaround; should be $
746
- |
747
- \n{2,}
748
- (?=\S)
749
- (?! // Negative lookahead for another list item marker
750
- [ \t]*
751
- (?:[*+-]|\d+[.])[ \t]+
752
- )
753
- )
754
- )/g
755
- */
756
- var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
757
-
758
- if (g_list_level) {
759
- text = text.replace(whole_list,function(wholeMatch,m1,m2) {
760
- var list = m1;
761
- var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
762
-
763
- var result = _ProcessListItems(list, list_type);
764
-
765
- // Trim any trailing whitespace, to put the closing `</$list_type>`
766
- // up on the preceding line, to get it past the current stupid
767
- // HTML block parser. This is a hack to work around the terrible
768
- // hack that is the HTML block parser.
769
- result = result.replace(/\s+$/,"");
770
- result = "<"+list_type+">" + result + "</"+list_type+">\n";
771
- return result;
772
- });
773
- } else {
774
- whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
775
- text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
776
- var runup = m1;
777
- var list = m2;
778
-
779
- var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
780
- var result = _ProcessListItems(list, list_type);
781
- result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
782
- return result;
783
- });
784
- }
785
-
786
- // attacklab: strip sentinel
787
- text = text.replace(/~0/,"");
788
-
789
- return text;
790
- }
791
-
792
- var _listItemMarkers = { ol: "\\d+[.]", ul: "[*+-]" };
793
-
794
- _ProcessListItems = function(list_str, list_type) {
795
- //
796
- // Process the contents of a single ordered or unordered list, splitting it
797
- // into individual list items.
798
- //
799
- // list_type is either "ul" or "ol".
800
-
801
- // The $g_list_level global keeps track of when we're inside a list.
802
- // Each time we enter a list, we increment it; when we leave a list,
803
- // we decrement. If it's zero, we're not in a list anymore.
804
- //
805
- // We do this because when we're not inside a list, we want to treat
806
- // something like this:
807
- //
808
- // I recommend upgrading to version
809
- // 8. Oops, now this line is treated
810
- // as a sub-list.
811
- //
812
- // As a single paragraph, despite the fact that the second line starts
813
- // with a digit-period-space sequence.
814
- //
815
- // Whereas when we're inside a list (or sub-list), that line will be
816
- // treated as the start of a sub-list. What a kludge, huh? This is
817
- // an aspect of Markdown's syntax that's hard to parse perfectly
818
- // without resorting to mind-reading. Perhaps the solution is to
819
- // change the syntax rules such that sub-lists must start with a
820
- // starting cardinal number; e.g. "1." or "a.".
821
-
822
- g_list_level++;
823
-
824
- // trim trailing blank lines:
825
- list_str = list_str.replace(/\n{2,}$/,"\n");
826
-
827
- // attacklab: add sentinel to emulate \z
828
- list_str += "~0";
829
-
830
- // In the original attacklab WMD, list_type was not given to this function, and anything
831
- // that matched /[*+-]|\d+[.]/ would just create the next <li>, causing this mismatch:
832
- //
833
- // Markdown rendered by WMD rendered by MarkdownSharp
834
- // ------------------------------------------------------------------
835
- // 1. first 1. first 1. first
836
- // 2. second 2. second 2. second
837
- // - third 3. third * third
838
- //
839
- // We changed this to behave identical to MarkdownSharp. This is the constructed RegEx,
840
- // with {MARKER} being one of \d+[.] or [*+-], depending on list_type:
841
- /*
842
- list_str = list_str.replace(/
843
- (^[ \t]*) // leading whitespace = $1
844
- ({MARKER}) [ \t]+ // list marker = $2
845
- ([^\r]+? // list item text = $3
846
- (\n+))
847
- (?= (~0 | \2 ({MARKER}) [ \t]+))
848
- /gm, function(){...});
849
- */
850
-
851
- var marker = _listItemMarkers[list_type];
852
- var re = new RegExp("(^[ \\t]*)(" + marker + ")[ \\t]+([^\\r]+?(\\n+))(?=(~0|\\1(" + marker + ")[ \\t]+))", "gm");
853
- var last_item_had_a_double_newline = false;
854
- list_str = list_str.replace(re,
855
- function(wholeMatch,m1,m2,m3){
856
- var item = m3;
857
- var leading_space = m1;
858
- var ends_with_double_newline = /\n\n$/.test(item);
859
- var contains_double_newline = ends_with_double_newline || item.search(/\n{2,}/)>-1;
860
-
861
- if (contains_double_newline || last_item_had_a_double_newline) {
862
- item = _RunBlockGamut(_Outdent(item), /* doNotUnhash = */ true);
863
- }
864
- else {
865
- // Recursion for sub-lists:
866
- item = _DoLists(_Outdent(item));
867
- item = item.replace(/\n$/,""); // chomp(item)
868
- item = _RunSpanGamut(item);
869
- }
870
- last_item_had_a_double_newline = ends_with_double_newline;
871
- return "<li>" + item + "</li>\n";
872
- }
873
- );
874
-
875
- // attacklab: strip sentinel
876
- list_str = list_str.replace(/~0/g,"");
877
-
878
- g_list_level--;
879
- return list_str;
880
- }
881
-
882
-
883
- var _DoCodeBlocks = function(text) {
884
- //
885
- // Process Markdown `<pre><code>` blocks.
886
- //
887
-
888
- /*
889
- text = text.replace(text,
890
- /(?:\n\n|^)
891
- ( // $1 = the code block -- one or more lines, starting with a space/tab
892
- (?:
893
- (?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
894
- .*\n+
895
- )+
896
- )
897
- (\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
898
- /g,function(){...});
899
- */
900
-
901
- // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
902
- text += "~0";
903
-
904
- text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
905
- function(wholeMatch,m1,m2) {
906
- var codeblock = m1;
907
- var nextChar = m2;
908
-
909
- codeblock = _EncodeCode( _Outdent(codeblock));
910
- codeblock = _Detab(codeblock);
911
- codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
912
- codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
913
-
914
- codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
915
-
916
- return "\n\n" + codeblock + "\n\n" + nextChar;
917
- }
918
- );
919
-
920
- // attacklab: strip sentinel
921
- text = text.replace(/~0/,"");
922
-
923
- return text;
924
- }
925
-
926
- var hashBlock = function(text) {
927
- text = text.replace(/(^\n+|\n+$)/g,"");
928
- return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
929
- }
930
-
931
-
932
- var _DoCodeSpans = function(text) {
933
- //
934
- // * Backtick quotes are used for <code></code> spans.
935
- //
936
- // * You can use multiple backticks as the delimiters if you want to
937
- // include literal backticks in the code span. So, this input:
938
- //
939
- // Just type ``foo `bar` baz`` at the prompt.
940
- //
941
- // Will translate to:
942
- //
943
- // <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
944
- //
945
- // There's no arbitrary limit to the number of backticks you
946
- // can use as delimters. If you need three consecutive backticks
947
- // in your code, use four for delimiters, etc.
948
- //
949
- // * You can use spaces to get literal backticks at the edges:
950
- //
951
- // ... type `` `bar` `` ...
952
- //
953
- // Turns to:
954
- //
955
- // ... type <code>`bar`</code> ...
956
- //
957
-
958
- /*
959
- text = text.replace(/
960
- (^|[^\\]) // Character before opening ` can't be a backslash
961
- (`+) // $2 = Opening run of `
962
- ( // $3 = The code block
963
- [^\r]*?
964
- [^`] // attacklab: work around lack of lookbehind
965
- )
966
- \2 // Matching closer
967
- (?!`)
968
- /gm, function(){...});
969
- */
970
-
971
- text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
972
- function(wholeMatch,m1,m2,m3,m4) {
973
- var c = m3;
974
- c = c.replace(/^([ \t]*)/g,""); // leading whitespace
975
- c = c.replace(/[ \t]*$/g,""); // trailing whitespace
976
- c = _EncodeCode(c);
977
- return m1+"<code>"+c+"</code>";
978
- });
979
-
980
- return text;
981
- }
982
-
983
-
984
- var _EncodeCode = function(text) {
985
- //
986
- // Encode/escape certain characters inside Markdown code runs.
987
- // The point is that in code, these characters are literals,
988
- // and lose their special Markdown meanings.
989
- //
990
- // Encode all ampersands; HTML entities are not
991
- // entities within a Markdown code span.
992
- text = text.replace(/&/g,"&amp;");
993
-
994
- // Do the angle bracket song and dance:
995
- text = text.replace(/</g,"&lt;");
996
- text = text.replace(/>/g,"&gt;");
997
-
998
- // Now, escape characters that are magic in Markdown:
999
- text = escapeCharacters(text,"\*_{}[]\\",false);
1000
-
1001
- // jj the line above breaks this:
1002
- //---
1003
-
1004
- //* Item
1005
-
1006
- // 1. Subitem
1007
-
1008
- // special char: *
1009
- //---
1010
-
1011
- return text;
1012
- }
1013
-
1014
-
1015
- var _DoItalicsAndBold = function(text) {
1016
-
1017
- // <strong> must go first:
1018
- text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\1/g,
1019
- "<strong>$2</strong>");
1020
-
1021
- text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
1022
- "<em>$2</em>");
1023
-
1024
- return text;
1025
- }
1026
-
1027
-
1028
- var _DoBlockQuotes = function(text) {
1029
-
1030
- /*
1031
- text = text.replace(/
1032
- ( // Wrap whole match in $1
1033
- (
1034
- ^[ \t]*>[ \t]? // '>' at the start of a line
1035
- .+\n // rest of the first line
1036
- (.+\n)* // subsequent consecutive lines
1037
- \n* // blanks
1038
- )+
1039
- )
1040
- /gm, function(){...});
1041
- */
1042
-
1043
- text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
1044
- function(wholeMatch,m1) {
1045
- var bq = m1;
1046
-
1047
- // attacklab: hack around Konqueror 3.5.4 bug:
1048
- // "----------bug".replace(/^-/g,"") == "bug"
1049
-
1050
- bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0"); // trim one level of quoting
1051
-
1052
- // attacklab: clean up hack
1053
- bq = bq.replace(/~0/g,"");
1054
-
1055
- bq = bq.replace(/^[ \t]+$/gm,""); // trim whitespace-only lines
1056
- bq = _RunBlockGamut(bq); // recurse
1057
-
1058
- bq = bq.replace(/(^|\n)/g,"$1 ");
1059
- // These leading spaces screw with <pre> content, so we need to fix that:
1060
- bq = bq.replace(
1061
- /(\s*<pre>[^\r]+?<\/pre>)/gm,
1062
- function(wholeMatch,m1) {
1063
- var pre = m1;
1064
- // attacklab: hack around Konqueror 3.5.4 bug:
1065
- pre = pre.replace(/^ /mg,"~0");
1066
- pre = pre.replace(/~0/g,"");
1067
- return pre;
1068
- });
1069
-
1070
- return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
1071
- });
1072
- return text;
1073
- }
1074
-
1075
-
1076
- var _FormParagraphs = function(text, doNotUnhash) {
1077
- //
1078
- // Params:
1079
- // $text - string to process with html <p> tags
1080
- //
1081
-
1082
- // Strip leading and trailing lines:
1083
- text = text.replace(/^\n+/g,"");
1084
- text = text.replace(/\n+$/g,"");
1085
-
1086
- var grafs = text.split(/\n{2,}/g);
1087
- var grafsOut = new Array();
1088
-
1089
- //
1090
- // Wrap <p> tags.
1091
- //
1092
- var end = grafs.length;
1093
- for (var i=0; i<end; i++) {
1094
- var str = grafs[i];
1095
-
1096
- // if this is an HTML marker, copy it
1097
- if (str.search(/~K(\d+)K/g) >= 0) {
1098
- grafsOut.push(str);
1099
- }
1100
- else if (str.search(/\S/) >= 0) {
1101
- str = _RunSpanGamut(str);
1102
- str = str.replace(/^([ \t]*)/g,"<p>");
1103
- str += "</p>"
1104
- grafsOut.push(str);
1105
- }
1106
-
1107
- }
1108
- //
1109
- // Unhashify HTML blocks
1110
- //
1111
- if (!doNotUnhash) {
1112
- end = grafsOut.length;
1113
- for (var i=0; i<end; i++) {
1114
- // if this is a marker for an html block...
1115
- while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
1116
- var blockText = g_html_blocks[RegExp.$1];
1117
- blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
1118
- grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
1119
- }
1120
- }
1121
- }
1122
- return grafsOut.join("\n\n");
1123
- }
1124
-
1125
-
1126
- var _EncodeAmpsAndAngles = function(text) {
1127
- // Smart processing for ampersands and angle brackets that need to be encoded.
1128
-
1129
- // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
1130
- // http://bumppo.net/projects/amputator/
1131
- text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
1132
-
1133
- // Encode naked <'s
1134
- text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
1135
-
1136
- return text;
1137
- }
1138
-
1139
-
1140
- var _EncodeBackslashEscapes = function(text) {
1141
- //
1142
- // Parameter: String.
1143
- // Returns: The string, with after processing the following backslash
1144
- // escape sequences.
1145
- //
1146
-
1147
- // attacklab: The polite way to do this is with the new
1148
- // escapeCharacters() function:
1149
- //
1150
- // text = escapeCharacters(text,"\\",true);
1151
- // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
1152
- //
1153
- // ...but we're sidestepping its use of the (slow) RegExp constructor
1154
- // as an optimization for Firefox. This function gets called a LOT.
1155
-
1156
- text = text.replace(/\\(\\)/g,escapeCharacters_callback);
1157
- text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
1158
- return text;
1159
- }
1160
-
1161
-
1162
- var _DoAutoLinks = function(text) {
1163
-
1164
- text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
1165
-
1166
- // Email addresses: <address@domain.foo>
1167
-
1168
- /*
1169
- text = text.replace(/
1170
- <
1171
- (?:mailto:)?
1172
- (
1173
- [-.\w]+
1174
- \@
1175
- [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
1176
- )
1177
- >
1178
- /gi, _DoAutoLinks_callback());
1179
- */
1180
- text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
1181
- function(wholeMatch,m1) {
1182
- return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
1183
- }
1184
- );
1185
-
1186
- return text;
1187
- }
1188
-
1189
-
1190
- var _EncodeEmailAddress = function(addr) {
1191
- //
1192
- // Input: an email address, e.g. "foo@example.com"
1193
- //
1194
- // Output: the email address as a mailto link, with each character
1195
- // of the address encoded as either a decimal or hex entity, in
1196
- // the hopes of foiling most address harvesting spam bots. E.g.:
1197
- //
1198
- // <a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
1199
- // x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
1200
- // &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
1201
- //
1202
- // Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
1203
- // mailing list: <http://tinyurl.com/yu7ue>
1204
- //
1205
-
1206
- // attacklab: why can't javascript speak hex?
1207
- function char2hex(ch) {
1208
- var hexDigits = '0123456789ABCDEF';
1209
- var dec = ch.charCodeAt(0);
1210
- return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
1211
- }
1212
-
1213
- var encode = [
1214
- function(ch){return "&#"+ch.charCodeAt(0)+";";},
1215
- function(ch){return "&#x"+char2hex(ch)+";";},
1216
- function(ch){return ch;}
1217
- ];
1218
-
1219
- addr = "mailto:" + addr;
1220
-
1221
- addr = addr.replace(/./g, function(ch) {
1222
- if (ch == "@") {
1223
- // this *must* be encoded. I insist.
1224
- ch = encode[Math.floor(Math.random()*2)](ch);
1225
- } else if (ch !=":") {
1226
- // leave ':' alone (to spot mailto: later)
1227
- var r = Math.random();
1228
- // roughly 10% raw, 45% hex, 45% dec
1229
- ch = (
1230
- r > .9 ? encode[2](ch) :
1231
- r > .45 ? encode[1](ch) :
1232
- encode[0](ch)
1233
- );
1234
- }
1235
- return ch;
1236
- });
1237
-
1238
- addr = "<a href=\"" + addr + "\">" + addr + "</a>";
1239
- addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
1240
-
1241
- return addr;
1242
- }
1243
-
1244
-
1245
- var _UnescapeSpecialChars = function(text) {
1246
- //
1247
- // Swap back in all the special characters we've hidden.
1248
- //
1249
- text = text.replace(/~E(\d+)E/g,
1250
- function(wholeMatch,m1) {
1251
- var charCodeToReplace = parseInt(m1);
1252
- return String.fromCharCode(charCodeToReplace);
1253
- }
1254
- );
1255
- return text;
1256
- }
1257
-
1258
-
1259
- var _Outdent = function(text) {
1260
- //
1261
- // Remove one level of line-leading tabs or spaces
1262
- //
1263
-
1264
- // attacklab: hack around Konqueror 3.5.4 bug:
1265
- // "----------bug".replace(/^-/g,"") == "bug"
1266
-
1267
- text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
1268
-
1269
- // attacklab: clean up hack
1270
- text = text.replace(/~0/g,"")
1271
-
1272
- return text;
1273
- }
1274
-
1275
- var _Detab = function (text) {
1276
- if (!/\t/.test(text))
1277
- return text;
1278
-
1279
- var spaces = [" ", " ", " ", " "],
1280
- skew = 0,
1281
- v;
1282
-
1283
- return text.replace(/[\n\t]/g, function (match, offset) {
1284
- if (match === "\n") {
1285
- skew = offset + 1;
1286
- return match;
1287
- }
1288
- v = (offset - skew) % 4;
1289
- skew = offset + 1;
1290
- return spaces[v];
1291
- });
1292
- }
1293
-
1294
- //
1295
- // attacklab: Utility functions
1296
- //
1297
-
1298
-
1299
- var escapeCharacters = function(text, charsToEscape, afterBackslash) {
1300
- // First we have to escape the escape characters so that
1301
- // we can build a character class out of them
1302
- var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
1303
-
1304
- if (afterBackslash) {
1305
- regexString = "\\\\" + regexString;
1306
- }
1307
-
1308
- var regex = new RegExp(regexString,"g");
1309
- text = text.replace(regex,escapeCharacters_callback);
1310
-
1311
- return text;
1312
- }
1313
-
1314
-
1315
- var escapeCharacters_callback = function(wholeMatch,m1) {
1316
- var charCodeToEscape = m1.charCodeAt(0);
1317
- return "~E"+charCodeToEscape+"E";
1318
- }
1319
-
1320
- } // end of Attacklab.showdown.converter
1321
-
1322
-
1323
- // Version 0.9 used the Showdown namespace instead of Attacklab.showdown
1324
- // The old namespace is deprecated, but we'll support it for now:
1325
- var Showdown = Attacklab.showdown;
1326
-
1327
- // If anyone's interested, tell the world that this file's been loaded
1328
- if (Attacklab.fileLoaded) {
1329
- Attacklab.fileLoaded("showdown.js");
1330
- }