...
1
-
...
2
|
...
3
|
...
4
|
...
5
|
...
6
|
...
7
|
...
8
|
...
9
|
..
10
|
..
11
|
..
12
|
..
13
|
..
14
|
..
15
|
..
16
|
..
17
|
..
18
|
..
19
|
..
20
-
..
21
..
22
-
..
23
|
..
24
|
..
25
|
..
26
|
..
27
|
..
28
|
..
29
|
..
30
|
..
31
|
..
32
|
..
33
|
..
34
-
..
35
..
36
..
37
..
38
..
39
-
..
40
|
..
41
|
..
42
|
..
43
|
..
44
|
..
45
|
-
..
46
||
..
47
||
..
48
||
..
49
||
..
50
||
..
51
||
..
52
||
..
53
||
..
54
||
..
55
||
..
56
||
..
57
|
-
..
58
|
..
59
|
-
..
60
||
..
61
||
..
62
||
..
63
||
..
64
||
..
65
||
..
66
||
..
67
||
..
68
||
..
69
||
..
70
||
..
71
||
..
72
||
..
73
||
..
74
||
..
75
||
..
76
||
..
77
||
..
78
||
..
79
||
..
80
|
-
..
81
|
..
82
|
..
83
|
-
..
84
||
..
85
||
..
86
||
..
87
||
..
88
||
..
89
||
..
90
||
..
91
||
..
92
||
..
93
||
..
94
||
..
95
||
..
96
||
..
97
||
..
98
||
..
99
||
.
100
||
.
101
||
.
102
||
.
103
||
.
104
||
.
105
||
.
106
|
-
.
107
|
.
108
|
.
109
|
-
.
110
||
.
111
||
.
112
||
.
113
||
-
.
114
|||
.
115
|||
.
116
|||
.
117
|||
.
118
|||
.
119
|||
.
120
|||
.
121
|||
.
122
|||
.
123
|||
.
124
|||
.
125
|||
.
126
|||
.
127
|||
.
128
|||
.
129
|||
.
130
|||
.
131
|||
.
132
|||
.
133
|||
.
134
|||
.
135
|||
.
136
|||
.
137
|||
.
138
|||
.
139
|||
.
140
|||
.
141
|||
.
142
|||
.
143
|||
.
144
|||
.
145
|||
.
146
|||
.
147
|||
.
148
|||
.
149
|||
.
150
|||
.
151
|||
.
152
|||
.
153
|||
.
154
|||
.
155
|||
.
156
||
-
.
157
||
.
158
||
.
159
||
-
.
160
|||
.
161
|||
.
162
|||
.
163
|||
.
164
|||
.
165
|||
.
166
|||
.
167
|||
.
168
|||
.
169
|||
.
170
|||
.
171
|||
.
172
|||
.
173
|||
.
174
|||
.
175
|||
.
176
|||
.
177
|||
.
178
|||
.
179
|||
.
180
|||
.
181
|||
.
182
|||
.
183
|||
.
184
|||
.
185
|||
.
186
|||
.
187
|||
.
188
|||
.
189
|||
.
190
|||
.
191
|||
.
192
|||
.
193
|||
.
194
|||
.
195
||
-
.
196
||
.
197
||
.
198
||
.
199
||
.
200
||
.
201
|
-
.
202
|
.
203
|
-
.
204
||
.
205
||
.
206
||
.
207
||
.
208
||
.
209
||
.
210
||
.
211
||
.
212
||
.
213
||
.
214
||
.
215
||
.
216
||
.
217
||
.
218
||
.
219
||
.
220
||
.
221
||
.
222
||
.
223
||
.
224
||
.
225
||
.
226
||
.
227
||
.
228
||
.
229
||
.
230
||
.
231
||
.
232
||
.
233
||
.
234
||
.
235
||
.
236
||
.
237
||
.
238
|
-
.
239
|
.
240
|
.
241
|
-
.
242
||
.
243
||
.
244
||
.
245
||
.
246
||
.
247
||
.
248
||
.
249
||
.
250
||
.
251
||
.
252
||
.
253
||
.
254
||
.
255
||
.
256
||
.
257
||
.
258
|
-
.
259
|
.
260
|
-
.
261
||
.
262
||
.
263
||
.
264
||
.
265
||
.
266
||
.
267
||
.
268
||
.
269
||
.
270
|
-
.
271
|
.
272
|
-
.
273
||
.
274
||
.
275
||
.
276
||
.
277
||
.
278
||
.
279
||
.
280
||
.
281
||
.
282
||
.
283
||
.
284
||
.
285
||
.
286
|
-
.
287
|
.
288
|
-
.
289
||
.
290
||
.
291
||
.
292
||
.
293
||
.
294
||
.
295
||
.
296
||
.
297
||
.
298
||
.
299
||
-
.
300
|||
.
301
|||
.
302
|||
.
303
|||
.
304
||
-
.
305
||
.
306
||
.
307
||
-
.
308
|||
.
309
|||
.
310
||
-
.
311
||
.
312
||
-
.
313
|||
.
314
|||
.
315
||
-
.
316
||
.
317
||
-
.
318
|||
.
319
|||
.
320
||
-
.
321
||
.
322
||
.
323
||
-
.
324
|||
.
325
|||
.
326
|||
.
327
|||
.
328
|||
.
329
|||
.
330
|||
.
331
|||
.
332
|||
.
333
|||
.
334
|||
.
335
|||
.
336
|||
.
337
|||
.
338
|||
-
.
339
||||
.
340
||||
.
341
||||
.
342
||||
.
343
||||
.
344
||||
.
345
||||
.
346
||||
.
347
||||
.
348
||||
.
349
||||
.
350
||||
.
351
||||
.
352
||||
.
353
||||
.
354
||||
.
355
||||
.
356
||||
.
357
||||
.
358
||||
.
359
||||
.
360
||||
.
361
||||
.
362
||||
.
363
||||
.
364
||||
.
365
||||
.
366
||||
.
367
||||
.
368
||||
.
369
||||
.
370
||||
.
371
||||
.
372
|||
-
.
373
|||
.
374
|||
-
.
375
||||
.
376
||||
.
377
||||
.
378
||||
.
379
||||
.
380
||||
.
381
||||
.
382
||||
.
383
||||
.
384
||||
.
385
||||
.
386
||||
.
387
||||
.
388
||||
.
389
||||
.
390
|||
-
.
391
|||
.
392
|||
-
.
393
||||
.
394
||||
.
395
||||
.
396
||||
.
397
||||
.
398
||||
.
399
||||
.
400
||||
.
401
||||
.
402
||||
.
403
||||
.
404
||||
.
405
||||
.
406
||||
.
407
|||
-
.
408
|||
.
409
|||
.
410
|||
.
411
|||
.
412
|||
.
413
|||
.
414
|||
.
415
|||
.
416
|||
.
417
|||
.
418
|||
.
419
|||
.
420
||
-
.
421
||
.
422
||
-
.
423
|||
.
424
|||
.
425
||
-
.
426
||
.
427
||
-
.
428
|||
.
429
|||
.
430
|||
.
431
|||
.
432
|||
.
433
|||
.
434
|||
.
435
|||
.
436
|||
.
437
|||
.
438
|||
.
439
|||
.
440
|||
.
441
|||
.
442
||
-
.
443
||
.
444
||
-
.
445
|||
.
446
|||
.
447
|||
.
448
|||
.
449
|||
.
450
|||
.
451
|||
.
452
|||
.
453
|||
.
454
|||
.
455
|||
.
456
|||
.
457
|||
.
458
|||
.
459
|||
.
460
||
-
.
461
||
.
462
||
-
.
463
|||
.
464
|||
.
465
||
-
.
466
||
.
467
|
-
.
468
|
.
469
|
-
.
470
||
.
471
||
.
472
||
.
473
||
.
474
||
.
475
||
.
476
||
.
477
||
-
.
478
|||
.
479
|||
.
480
|||
.
481
|||
.
482
|||
.
483
|||
.
484
|||
.
485
|||
.
486
|||
.
487
|||
.
488
|||
.
489
|||
.
490
|||
.
491
|||
.
492
|||
.
493
|||
.
494
|||
.
495
|||
.
496
|||
.
497
|||
.
498
|||
.
499
|||
.
500
||
-
.
501
||
.
502
|
-
.
503
|
.
504
-
.
505
|
.
506
|
.
507
|
.
508
|
.
509
|
.
510
|
.
511
-
.
512
|
.
513
|
-
.
514
||
.
515
||
.
516
||
.
517
||
.
518
||
.
519
||
.
520
||
.
521
||
.
522
||
.
523
||
.
524
||
.
525
||
.
526
||
.
527
||
.
528
||
.
529
||
.
530
||
.
531
||
.
532
||
.
533
||
.
534
||
.
535
||
.
536
||
.
537
||
.
538
||
.
539
||
.
540
||
.
541
||
.
542
||
.
543
||
.
544
||
.
545
||
.
546
||
.
547
||
.
548
||
.
549
||
.
550
||
.
551
||
.
552
||
.
553
||
.
554
||
.
555
||
.
556
||
.
557
||
.
558
||
.
559
||
.
560
||
.
561
|
-
.
562
-
.
563
|
.
564
|
.
565
|
.
566
|
.
567
-
.
568
|
.
569
|
-
.
570
||
.
571
||
.
572
||
.
573
||
.
574
||
.
575
||
.
576
||
.
577
||
.
578
||
.
579
||
.
580
||
.
581
||
.
582
||
.
583
||
.
584
||
.
585
||
.
586
||
.
587
||
.
588
||
.
589
||
.
590
||
.
591
||
.
592
||
.
593
||
.
594
||
.
595
||
.
596
|
-
.
597
|
.
598
|
.
599
-
.
600
.
601
-
.
602
|
.
603
|
.
604
|
.
605
|
-
.
606
||
.
607
||
.
608
|
-
.
609
|
.
610
|
-
.
611
||
.
612
|
-
.
613
|
.
614
|
-
.
615
||
.
616
|
-
.
617
-
.
618
.
619
using
System
;
using
System
.
Collections
.
Generic
;
using
System
.
Collections
.
ObjectModel
;
using
System
.
IO
;
using
System
.
Linq
;
using
System
.
Text
;
using
System
.
Text
.
RegularExpressions
;
using
CharMY
.
Arithmetic
;
using
CharMY
.
ComponentModel
;
using
CharMY
.
IO
;
using
CharMY
.
Net
;
using
CharMY
.
Numerics
;
using
CharMY
.
Text
;
namespace
CharMY
.
CodeToHtml
{
public
class
CodeToHtmlConverter
:
CharMYCore
.
NonElement
{
public
bool
ShowCollapceLevel
{
get
;
set
; }
public
string
CssFileName
{
get
;
set
; }
public
string
ScriptFileName
{
get
;
set
; }
private
readonly
ReadOnlyCollection
<
SettingToCssConverter
>
_css
;
public
CodeToHtmlConverter
(
string
className
,
params
VSEditorVersion
[]
version
)
{
ShowCollapceLevel
=
true
;
CssFileName
=
null
;
ScriptFileName
=
null
;
if
(
version
==
null
||
version
.
Length
==
0
)
version
=
new
[] {
VSEditorVersion
.
VS2010ExpressCSharp
};
_css
=
version
.
Select
(
v
=>
new
SettingToCssConverter
(
className
,
v
))
.
ToArray
()
.
ToReadOnlyCollection
();
}
#region
const tags
private
const
string
__spliter
=
"@@"
,
__indicator
=
"\"
,
__indicator_begin
=
__indicator
+
"_begin"
,
__indicator_end
=
__indicator
+
"_end"
,
__indicator_break
=
__indicator
+
"_break"
,
__indicator_spliter
=
__indicator
+
"_spliter"
,
__text_color_header
=
"\\cf"
,
__color_header
=
"\\colortbl"
,
__color_header_r
=
"\\red"
,
__color_header_g
=
"\\green"
,
__color_header_b
=
"\\blue"
,
__class_header_begin
=
@"<code class="""
,
__class_header_end
=
@""">"
,
__break_node
=
@"<br>"
;
protected
const
string
ClassFooter
=
"</code>"
;
#endregion
private
static
string
MakeRtfText
(
string
rtfSource
)
{
NumberFormat
_format
=
null
;
Encoding
_encode
=
null
;
var
format
=
TypeInference
.
Func
(()
=>
_format
??
(
_format
=
NumberFormats
.
Hex
()));
var
encode
=
TypeInference
.
Func
(()
=>
_encode
??
(
_encode
=
rtfSource
.
AllMatchOf
(
@"\\ansicpg([0-9]+)"
)
.
Select
(
m
=>
Encoding
.
GetEncoding
(
m
.
Groups
[
1
]
.
Value
.
To
(
0
)))
.
FirstOrDefault
(
Encoding
.
Default
)
));
rtfSource
=
rtfSource
.
ReplaceByRegex
(
@"\\'([0-9a-fA-F]+)"
,
m
=>
{
var
bytes
=
(
m
.
Groups
[
1
]
.
Value
.
To
(
0
,
format
())
&
0xFFFF
)
.
ToExInt
()
.
ToByteArray
();
var
result
=
new
string
(
encode
()
.
GetChars
(
bytes
));
return
result
;
})
.
ReplaceByRegex
(
@"\\uc1\\u((-|)[0-9]+)\?"
,
m
=>
{
var
result
=
((
char
)
m
.
Groups
[
1
]
.
Value
.
To
(
0
))
.
ToString
();
return
result
;
});
return
rtfSource
;
}
protected
IEnumerable
<
string
>
MakeHtmlCore
(
string
rtfSource
,
SettingToCssConverter
css
)
{
Checker
.
ArgumentNotNull
(
css
);
var
nodes
=
new
Queue
<
string
[]
>
();
#region
sprit
var
rtf
=
MakeRtfText
(
rtfSource
)
.
Replace
(
"\\\\"
,
__indicator
)
.
Replace
(
"\\{"
,
__indicator_begin
)
.
Replace
(
"\\}"
,
__indicator_end
)
.
Replace
(
"\r"
,
""
)
.
Replace
(
"\\par\n"
,
__indicator_break
)
.
ReplaceByRegex
(
@" *\\par "
,
__indicator_break
)
.
Replace
(
__spliter
,
__indicator_spliter
);
var
regex
=
StringExtensions
.
Regex
(
@"\{([^\{\}]+)\}"
);
bool
@continue
=
true
;
while
(
@continue
)
{
@continue
=
false
;
rtf
=
regex
.
Replace
(
rtf
,
m
=>
{
var
items
=
m
.
Groups
[
1
]
.
Value
.
Split
(
__spliter
,
StringSplitAdditionalOptions
.
SeparateBefore
);
foreach
(
var
item
in
items
)
nodes
.
Enqueue
(
item
.
Split
(
"\\"
,
StringSplitAdditionalOptions
.
SeparateBefore
)
.
Where
(
inner
=>
inner
.
Length
>
0
)
.
ToArray
()
);
@continue
=
true
;
return
__spliter
;
});
}
#if
WRITE_INFO
Console.WriteLine();
foreach (var items in nodes)
{
Console.WriteLine("@");
foreach (var item in items)
{
Console.WriteLine(" >" + item + "<");
}
}
#endif
#endregion
var
colors
=
new
List
<
string
>
();
#region
search colors
{
colors
.
Add
(
ToHtmlHeader
(
css
.
NameOfDefault
));
var
color_node
=
nodes
.
FirstOrDefault
(
items
=>
items
.
Length
>=
4
&&
items
[
0
]
.
StartsWith
(
__color_header
));
int
r
,
g
,
b
;
r
=
g
=
b
=
0
;
if
(
color_node
!=
null
)
foreach
(
var
item
in
color_node
.
Skip
(
1
)
.
ZipKey
(
item
=>
item
.
MatchOf
(
"[0-9]+"
)
.
Value
.
To
(
-
1
))
.
Where
(
pair
=>
pair
.
Key
>=
0
))
{
if
(
item
.
Value
.
StartsWith
(
__color_header_r
))
r
=
item
.
Key
;
else
if
(
item
.
Value
.
StartsWith
(
__color_header_g
))
g
=
item
.
Key
;
else
if
(
item
.
Value
.
StartsWith
(
__color_header_b
))
b
=
item
.
Key
;
if
(
item
.
Value
.
EndsWith
(
";"
))
{
var
color_class
=
css
.
ColorClass
(
r
,
g
,
b
);
colors
.
Add
(
color_class
);
}
}
}
#if
WRITE_INFO
for (int i = 0 ; i < colors.Count ; ++i)
Console.WriteLine(i + " " + colors[i]);
#endif
#endregion
var
last_node
=
nodes
.
LastOrDefault
();
return
this
.
MakeHtmlCore
(
colors
,
last_node
,
css
)
.
ToSingleString
()
.
Split
(
"<br>"
,
StringSplitAdditionalOptions
.
None
);
}
private
IEnumerable
<
string
>
MakeHtmlCore
(
List
<
string
>
colors
,
string
[]
node
,
SettingToCssConverter
css
)
{
string
node_class
=
ToHtmlHeader
(
css
.
NameOfDefault
);
string
node_text
=
""
;
foreach
(
var
item
in
node
.
Where
(
item
=>
!
item
.
StartsWith
(
__spliter
)))
{
if
(
item
.
StartsWith
(
__text_color_header
))
{
if
(
node_text
.
Length
>
0
)
yield
return
this
.
ToHtml
(
node_class
,
node_text
);
node_text
=
""
;
var
color_index
=
item
.
MatchOf
(
"[0-9]+"
)
.
Value
.
To
(
-
1
);
if
(
0
<=
color_index
&&
color_index
<
colors
.
Count
)
{
node_class
=
ToHtmlHeader
(
colors
[
color_index
]);
}
else
{
node_class
=
ToHtmlHeader
(
css
.
NameOfDefault
);
}
}
{
var
text
=
item
.
ReplaceByRegex
(
@"\\[a-z]+[0-9]*( |<br>|\\|)"
,
m
=>
{
if
(
!
string
.
IsNullOrWhiteSpace
(
m
.
Groups
[
1
]
.
Value
))
return
m
.
Groups
[
1
]
.
Value
;
return
""
;
});
node_text
+=
text
;
}
}
if
(
node_text
.
Length
>
0
)
yield
return
this
.
ToHtml
(
node_class
,
node_text
);
}
private
static
string
ToHtmlHeader
(
string
name
) {
return
__class_header_begin
+
name
+
__class_header_end
; }
protected
string
ToHtml
(
string
nodeClass
,
string
nodeText
)
{
var
class_head
=
nodeClass
;
nodeText
=
nodeText
.
RepalceToHtml
()
.
Replace
(
__indicator_spliter
,
__spliter
)
.
Replace
(
__indicator_begin
,
"{"
)
.
Replace
(
__indicator_end
,
"}"
)
.
Replace
(
__indicator_break
,
__break_node
)
.
Replace
(
__indicator
,
"\\"
);
nodeText
=
class_head
+
nodeText
.
ReplaceByRegex
(
__break_node
,
m
=>
ClassFooter
+
__break_node
+
nodeClass
)
+
ClassFooter
;
nodeText
=
nodeText
.
ReplaceByRegex
(
__class_header_begin
+
@"[^""]+"
+
__class_header_end
+
ClassFooter
,
""
);
return
nodeText
;
}
protected
virtual
IEnumerable
<
string
>
MakeLineNumbers
(
SettingToCssConverter
css
)
{
var
nums
=
Sequence
.
For
(
1
,
i
=>
true
,
i
=>
i
+
1
)
.
ToStrings
()
.
Select
(
num
=>
ToHtmlHeader
(
css
.
NameOfSpace
)
+
'.'
.
Repeat
(
4
-
num
.
Length
)
+
ClassFooter
+
ToHtmlHeader
(
css
.
NameOfLineNumber
)
+
num
+
ClassFooter
+
ToHtmlHeader
(
css
.
NameOfLineSeparator
)
+
"|"
+
ClassFooter
);
return
nums
;
}
protected
static
string
GetNodeClassName
(
string
nodeHeader
)
{
if
(
nodeHeader
.
StartsWith
(
__class_header_begin
))
{
int
name_length
=
nodeHeader
.
IndexOf
(
'"'
,
__class_header_begin
.
Length
)
-
__class_header_begin
.
Length
;
if
(
name_length
>
0
)
{
var
name
=
nodeHeader
.
Substring
(
__class_header_begin
.
Length
,
name_length
);
return
name
;
}
}
return
null
;
}
#region
make collapse blocks and line numbers
protected
static
string
RegexSpace
=
"("
+
" "
.
RepalceToHtml
()
+
")"
,
RegexClassHead
=
"<code [^>]+>"
,
RegexSpaceAny
=
"("
+
RegexClassHead
+
RegexSpace
+
"*)"
,
RegexSpace4Or8
=
RegexClassHead
+
"("
+
RegexSpace
+
"{4}){1,2}"
,
BlockKey
=
"blockkey"
,
LineBlockKey
=
"linekey"
;
protected
static
string
ToRegexBlock
(
string
beginKey
)
{
var
result
=
"("
+
ClassFooter
+
RegexClassHead
+
"|)"
+
"(?<"
+
BlockKey
+
">"
+
beginKey
+
").*"
+
ClassFooter
;
return
result
;
}
protected
virtual
IEnumerable
<
string
>
GetBlockBeginRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"#region("
+
ClassFooter
+
RegexClassHead
+
@"|)[&;0-9a-zA-Z]+"
);
yield
return
RegexSpace4Or8
+
ToRegexBlock
(
@"\{"
);
}
protected
virtual
IEnumerable
<
string
>
GetBlockEndRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"#endregion"
);
yield
return
RegexSpace4Or8
+
ToRegexBlock
(
@"\}"
);
}
protected
virtual
IEnumerable
<
string
>
GetLinesBlockRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"(?<"
+
LineBlockKey
+
@">using|//)"
);
yield
return
__class_header_begin
+
"(?<"
+
LineBlockKey
+
@">[^PS""]+)"
+
__class_header_end
+
"[^<>]+"
+
ClassFooter
+
"$"
;
}
private
string
[]
MakeLinesAndBlocks
(
string
[]
code
,
SettingToCssConverter
css
,
out
IEnumerable
<
string
>
lines
)
{
var
lines_array
=
this
.
MakeLineNumbers
(
css
)
.
Take
(
code
.
Length
)
.
ToArray
();
var
reg_comment
=
this
.
GetLinesBlockRegexs
()
.
ToArray
();
var
reg_begin
=
this
.
GetBlockBeginRegexs
()
.
ToArray
();
var
reg_end
=
this
.
GetBlockEndRegexs
()
.
ToArray
();
var
_collapse_index
=
0
;
var
collapse_indexes
=
new
Stack
<
int
>
();
int
comment_line_count
=
0
;
Match
comment_begin_match
=
null
;
for
(
int
i
=
0
;
i
<
code
.
Length
;
++
i
)
{
#region
comment match
{
var
match
=
reg_comment
.
SelectMany
(
reg
=>
code
[
i
]
.
AllMatchOf
(
reg
))
.
FirstOrDefault
();
if
(
match
!=
null
&&
match
.
Index
==
0
&&
match
.
Groups
[
LineBlockKey
]
!=
null
)
{
if
(
comment_begin_match
==
null
)
{
comment_line_count
=
0
;
comment_begin_match
=
match
;
}
if
(
match
.
Groups
[
LineBlockKey
]
.
Value
==
comment_begin_match
.
Groups
[
LineBlockKey
]
.
Value
)
{
++
comment_line_count
;
continue
;
}
}
if
(
comment_line_count
>=
2
)
{
var
i_begin
=
i
-
comment_line_count
;
var
i_end
=
i
-
1
;
++
_collapse_index
;
CollapseBegin
(
ref
code
[
i_begin
],
ref
lines_array
[
i_begin
],
comment_begin_match
,
_collapse_index
,
css
);
CollapseEnd
(
ref
code
[
i_end
],
ref
lines_array
[
i_end
],
null
,
_collapse_index
,
css
);
}
if
(
comment_begin_match
!=
null
)
{
comment_line_count
=
0
;
comment_begin_match
=
null
;
}
}
#endregion
#region
block begin
{
var
match
=
reg_begin
.
SelectMany
(
reg
=>
code
[
i
]
.
AllMatchOf
(
reg
))
.
FirstOrDefault
();
if
(
match
!=
null
&&
match
.
Index
==
0
)
{
collapse_indexes
.
Push
(
++
_collapse_index
);
this
.
CollapseLevelSet
(
ref
lines_array
[
i
],
collapse_indexes
.
Count
);
CollapseBegin
(
ref
code
[
i
],
ref
lines_array
[
i
],
match
,
collapse_indexes
.
Peek
(),
css
);
comment_line_count
=
0
;
comment_begin_match
=
null
;
continue
;
}
}
#endregion
#region
block end
{
var
match
=
reg_end
.
SelectMany
(
reg
=>
code
[
i
]
.
AllMatchOf
(
reg
))
.
FirstOrDefault
();
if
(
match
!=
null
&&
match
.
Index
==
0
)
{
this
.
CollapseLevelSet
(
ref
lines_array
[
i
],
collapse_indexes
.
Count
);
CollapseEnd
(
ref
code
[
i
],
ref
lines_array
[
i
],
match
,
collapse_indexes
.
Pop
(),
css
);
comment_line_count
=
0
;
comment_begin_match
=
null
;
continue
;
}
}
#endregion
this
.
CollapseLevelSet
(
ref
lines_array
[
i
],
collapse_indexes
.
Count
);
}
int
last
=
code
.
Length
-
1
;
while
(
collapse_indexes
.
Count
>
0
)
{
CollapseEnd
(
ref
code
[
last
],
ref
lines_array
[
last
],
null
,
collapse_indexes
.
Pop
(),
css
);
}
lines
=
lines_array
;
return
code
;
}
protected
void
CollapseLevelSet
(
ref
string
line
,
int
level
)
{
if
(
this
.
ShowCollapceLevel
)
line
=
line
.
Replace
(
"|"
,
Enumerable
.
Repeat
(
"|"
,
level
)
.
ToSingleString
());
}
private
static
void
CollapseBegin
(
ref
string
code
,
ref
string
line
,
Match
match
,
int
index
,
SettingToCssConverter
css
)
{
int
insert_index
=
code
.
Length
;
if
(
match
!=
null
&&
match
.
Groups
[
BlockKey
]
.
Length
>
0
)
{
var
group
=
match
.
Groups
[
BlockKey
];
insert_index
=
code
.
IndexOf
(
ClassFooter
,
group
.
Index
+
group
.
Length
);
insert_index
=
(
insert_index
<
0
)
?
code
.
Length
: (
insert_index
+
ClassFooter
.
Length
);
}
var
span
=
@"<span class=""collapse"
+
index
+
@""">"
;
code
=
code
.
Insert
(
insert_index
,
span
);
line
=
line
.
Replace
(
"|"
+
ClassFooter
,
ClassFooter
+
CollapseLineItem
(
index
,
css
,
true
)
+
span
);
}
private
static
void
CollapseEnd
(
ref
string
code
,
ref
string
line
,
Match
match
,
int
index
,
SettingToCssConverter
css
)
{
int
insert_index
=
code
.
Length
;
if
(
match
!=
null
&&
match
.
Groups
[
BlockKey
]
.
Length
>
0
)
{
var
group
=
match
.
Groups
[
BlockKey
];
insert_index
=
group
.
Index
;
}
var
span
=
@"</span>"
;
code
=
code
.
Insert
(
insert_index
,
span
);
line
=
line
.
Replace
(
"|"
+
ClassFooter
,
ClassFooter
+
CollapseLineItem
(
index
,
css
,
false
)
)
+
span
;
}
private
static
string
CollapseLineItem
(
int
index
,
SettingToCssConverter
css
,
bool
begin
)
{
var
result
=
ToHtmlHeader
(
begin
?
css
.
NameOfLineCollapse
:
css
.
NameOfLineCollapseEnd
)
+
@"- <!-- collapse"
+
index
+
@" -->"
+
ClassFooter
;
return
result
;
}
#endregion
#region
make link
private
static
string
__color_name
=
"colorname"
,
__class_name
=
"classname"
,
__reg_link_class
=
@"<code class=""(?<"
+
__color_name
+
@">"
+
SettingToCssConverter
.
__link_names
+
@")"">(?<"
+
__class_name
+
@">[ _A-Za-z0-9]+)"
+
ClassFooter
;
private
void
MakeLinks
(
string
[]
code
,
FileInfo
saveTarget
)
{
if
(
saveTarget
==
null
)
return
;
var
files
=
saveTarget
.
Directory
.
GetFiles
(
"*.html"
,
SearchOption
.
TopDirectoryOnly
)
.
Where
(
file
=>
file
.
Name
.
Length
>
0
&&
Char
.
IsLetter
(
file
.
Name
[
0
])
&&
!
saveTarget
.
PathEquals
(
file
))
.
SelectMany
(
file
=>
file
.
NameWithoutExtension
()
.
Split
(
'-'
)
.
ZipValue
(
_
=>
file
))
.
ToDictionary
();
for
(
int
i
=
0
;
i
<
code
.
Length
;
++
i
)
{
code
[
i
]
=
code
[
i
]
.
ReplaceByRegex
(
__reg_link_class
,
m
=>
{
if
(
!
files
.
ContainsKey
(
m
.
Groups
[
__class_name
]
.
Value
))
return
m
.
Value
;
var
result
=
@"<a class="""
+
m
.
Groups
[
__color_name
]
.
Value
+
@""" href=""./"
+
files
[
m
.
Groups
[
__class_name
]
.
Value
]
.
Name
+
@""">"
+
m
.
Value
+
@"</a>"
;
return
result
;
});
}
}
#endregion
"saveTarget"
"rtfSource"
"setting"
"useCss"
public
string
SaveHtmlFile
(
FileInfo
saveTarget
,
string
rtfSource
,
FileInfo
setting
=
null
,
bool
useCss
=
true
)
{
if
(
saveTarget
==
null
||
rtfSource
==
null
)
return
null
;
var
cssFile
=
saveTarget
.
ChangeName
((
name
,
ext
)
=>
(
this
.
CssFileName
??
name
)
+
".css"
);
var
scriptFile
=
saveTarget
.
ChangeName
((
name
,
ext
)
=>
(
this
.
ScriptFileName
??
name
)
+
".js"
);
var
css_link
=
@"
<link rel=""stylesheet"" type=""text/css"" href=""./"
+
cssFile
.
Name
+
@""" media=""all"" />
<script type=""text/javascript"" src=""./"
+
scriptFile
.
Name
+
@"""></script>
"
;
var
result
=
this
.
MakeHtmlAndCss
(
rtfSource
,
setting
,
saveTarget
)
.
OrderByDescending
(
tuple
=>
tuple
.
Item1
.
AllRangeOf
(
SettingToCssConverter
.
UndefinedName
)
.
Count
())
.
FirstOrDefault
();
if
(
!
useCss
)
{
scriptFile
=
null
;
cssFile
=
null
;
css_link
=
@"
<style>"
+
result
.
Item2
+
@" </style>
<script type=""text/javascript"">"
+
CollapceJavaScript
.
Code
+
@"</script>
"
;
}
var
htmlText
=
@"
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=""Content-Type"" content=""text/html; charset="
+
result
.
Item3
.
Encoding
.
WebName
.
ToLower
()
+
@""" />
<meta http-equiv=""Content-Style-Type"" content=""text/css"" />
"
+
css_link
+
@"
</head>
<body>
"
+
result
.
Item1
+
@"
</body>
"
;
var
io
=
Files
.
Text
(
result
.
Item3
.
Encoding
)
.
Base
;
io
.
Save
(
saveTarget
,
htmlText
);
if
(
cssFile
!=
null
)
io
.
Save
(
cssFile
,
result
.
Item2
);
if
(
scriptFile
!=
null
)
io
.
Save
(
scriptFile
,
CollapceJavaScript
.
Code
);
return
result
.
Item1
;
}
"rtfSource"
"setting"
public
IEnumerable
<
Tuple
<
string
,
string
,
SettingToCssConverter
>>
MakeHtmlAndCss
(
string
rtfSource
,
FileInfo
setting
=
null
,
FileInfo
saveTarget
=
null
)
{
foreach
(
var
css
in
_css
)
{
Console
.
WriteLine
(
"check "
+
css
);
var
cssText
=
css
.
MakeCss
(
setting
);
var
core
=
this
.
MakeHtmlCore
(
rtfSource
,
css
)
.
ToArrayCast
();
IEnumerable
<
string
>
lines
;
var
code
=
this
.
MakeLinesAndBlocks
(
core
,
css
,
out
lines
);
this
.
MakeLinks
(
code
,
saveTarget
);
var
htmlText
=
@"
<div class="""
+
css
.
ClassName
+
@""">
"
+
(
lines
==
null
?
""
:
@"<div class="""
+
css
.
ClassNameLineNumber
+
@""">"
+
lines
.
Take
(
code
.
Length
)
.
ToSingleString
(
__break_node
)
+
@"</div>"
)
+
@"
<div class="""
+
css
.
ClassNameCode
+
@""">"
+
code
.
Select
(
c
=>
c
??
""
)
.
ToSingleString
(
__break_node
)
+
@"</div>
</div>"
;
var
result
=
Tuple
.
Create
(
htmlText
,
cssText
,
css
);
yield
return
result
;
}
}
public
override
string
ToString
() {
return
"html"
; }
}
public
class
VBCodeToHtmlConverter
:
CodeToHtmlConverter
{
public
VBCodeToHtmlConverter
(
params
VSEditorVersion
[]
version
) :
base
(
"vbcode"
,
version
) { }
protected
override
IEnumerable
<
string
>
GetBlockBeginRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"Sub"
);
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"Func"
);
}
protected
override
IEnumerable
<
string
>
GetBlockEndRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"End"
);
}
protected
override
IEnumerable
<
string
>
GetLinesBlockRegexs
()
{
yield
return
RegexSpaceAny
+
ToRegexBlock
(
@"Using|'"
);
}
}
}