From 5e0d6d97bf4676ab1c1ca9b06590dd774d263b0d Mon Sep 17 00:00:00 2001 From: murphy Date: Tue, 17 Oct 2006 10:10:35 +0000 Subject: Renamed demo files (trim demo_ prefix). --- sample/cache.out | 2 + sample/cache.rb | 12 + sample/count.out | 1 + sample/count.rb | 10 + sample/css.out | 104 ++++++ sample/css.rb | 4 + sample/div.out | 17 + sample/div.rb | 19 ++ sample/dump.out | 21 ++ sample/dump.rb | 15 + sample/encoder.out | 73 ++++ sample/encoder.rb | 39 +++ sample/global_vars.out | 3 + sample/global_vars.rb | 13 + sample/global_vars2.out | 10 + sample/global_vars2.rb | 28 ++ sample/highlight.out | 149 ++++++++ sample/highlight.rb | 14 + sample/html.out | 893 ++++++++++++++++++++++++++++++++++++++++++++++++ sample/html.rb | 394 +++++++++++++++++++++ sample/html2.out | 159 +++++++++ sample/html2.rb | 11 + sample/html_list.out | 134 ++++++++ sample/html_list.rb | 12 + sample/load_encoder.out | 8 + sample/load_encoder.rb | 25 ++ sample/load_scanner.out | 8 + sample/load_scanner.rb | 25 ++ sample/more.out | 2 + sample/more.rb | 205 +++++++++++ sample/scanner.out | 16 + sample/scanner.rb | 36 ++ sample/server.rb | 110 ++++++ sample/simple.out | 1 + sample/simple.rb | 10 + sample/stream.rb | 25 ++ sample/stream2.out | 2 + sample/stream2.rb | 8 + sample/suite.rb | 2 +- sample/tokens.out | 14 + sample/tokens.rb | 3 + 41 files changed, 2636 insertions(+), 1 deletion(-) create mode 100644 sample/cache.out create mode 100644 sample/cache.rb create mode 100644 sample/count.out create mode 100644 sample/count.rb create mode 100644 sample/css.out create mode 100644 sample/css.rb create mode 100644 sample/div.out create mode 100644 sample/div.rb create mode 100644 sample/dump.out create mode 100644 sample/dump.rb create mode 100644 sample/encoder.out create mode 100644 sample/encoder.rb create mode 100644 sample/global_vars.out create mode 100644 sample/global_vars.rb create mode 100644 sample/global_vars2.out create mode 100644 sample/global_vars2.rb create mode 100644 sample/highlight.out create mode 100644 sample/highlight.rb create mode 100644 sample/html.out create mode 100644 sample/html.rb create mode 100644 sample/html2.out create mode 100644 sample/html2.rb create mode 100644 sample/html_list.out create mode 100644 sample/html_list.rb create mode 100644 sample/load_encoder.out create mode 100644 sample/load_encoder.rb create mode 100644 sample/load_scanner.out create mode 100644 sample/load_scanner.rb create mode 100644 sample/more.out create mode 100644 sample/more.rb create mode 100644 sample/scanner.out create mode 100644 sample/scanner.rb create mode 100644 sample/server.rb create mode 100644 sample/simple.out create mode 100644 sample/simple.rb create mode 100644 sample/stream.rb create mode 100644 sample/stream2.out create mode 100644 sample/stream2.rb create mode 100644 sample/tokens.out create mode 100644 sample/tokens.rb diff --git a/sample/cache.out b/sample/cache.out new file mode 100644 index 0000000..f815e88 --- /dev/null +++ b/sample/cache.out @@ -0,0 +1,2 @@ +test <test> +test <test> diff --git a/sample/cache.rb b/sample/cache.rb new file mode 100644 index 0000000..0c0b847 --- /dev/null +++ b/sample/cache.rb @@ -0,0 +1,12 @@ +require 'coderay' + +html_encoder = CodeRay.encoder :html + +scanner = Hash.new do |h, lang| + h[lang] = CodeRay.scanner lang +end + +for lang in [:ruby, :html] + tokens = scanner[lang].tokenize 'test ' + puts html_encoder.encode_tokens(tokens) +end diff --git a/sample/count.out b/sample/count.out new file mode 100644 index 0000000..7f493b6 --- /dev/null +++ b/sample/count.out @@ -0,0 +1 @@ +2 out of 4 tokens have the kind :integer. diff --git a/sample/count.rb b/sample/count.rb new file mode 100644 index 0000000..bcb7c2d --- /dev/null +++ b/sample/count.rb @@ -0,0 +1,10 @@ +require 'coderay' + +stats = CodeRay.encoder(:statistic) +stats.encode("puts 17 + 4\n", :ruby) + +puts '%d out of %d tokens have the kind :integer.' % [ + stats.type_stats[:integer].count, + stats.real_token_count +] +#-> 2 out of 4 tokens have the kind :integer. diff --git a/sample/css.out b/sample/css.out new file mode 100644 index 0000000..713e3e7 --- /dev/null +++ b/sample/css.out @@ -0,0 +1,104 @@ +.CodeRay { + background-color: #f8f8f8; + border: 1px solid silver; + font-family: 'Courier New', 'Terminal', monospace; + color: #100; +} +.CodeRay pre { margin: 0px } + +div.CodeRay { } + +span.CodeRay { white-space: pre; border: 0px; padding: 2px } + +table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px } +table.CodeRay td { padding: 2px 4px; vertical-align: top } + +.CodeRay .line_numbers, .CodeRay .no { + background-color: #def; + color: gray; + text-align: right; +} +.CodeRay .line_numbers tt { font-weight: bold } +.CodeRay .no { padding: 0px 4px } +.CodeRay .code { width: 100% } + +ol.CodeRay { font-size: 10pt } +ol.CodeRay li { white-space: pre } + +.CodeRay .code pre { overflow: auto } + +.CodeRay .af { color:#00C } +.CodeRay .an { color:#007 } +.CodeRay .av { color:#700 } +.CodeRay .aw { color:#C00 } +.CodeRay .bi { color:#509; font-weight:bold } +.CodeRay .c { color:#888 } + +.CodeRay .ch { color:#04D } +.CodeRay .ch .k { color:#04D } +.CodeRay .ch .dl { color:#039 } + +.CodeRay .cl { color:#B06; font-weight:bold } +.CodeRay .co { color:#036; font-weight:bold } +.CodeRay .cr { color:#0A0 } +.CodeRay .cv { color:#369 } +.CodeRay .df { color:#099; font-weight:bold } +.CodeRay .di { color:#088; font-weight:bold } +.CodeRay .dl { color:black } +.CodeRay .do { color:#970 } +.CodeRay .ds { color:#D42; font-weight:bold } +.CodeRay .e { color:#666; font-weight:bold } +.CodeRay .en { color:#800; font-weight:bold } +.CodeRay .er { color:#F00; background-color:#FAA } +.CodeRay .ex { color:#F00; font-weight:bold } +.CodeRay .fl { color:#60E; font-weight:bold } +.CodeRay .fu { color:#06B; font-weight:bold } +.CodeRay .gv { color:#d70; font-weight:bold } +.CodeRay .hx { color:#058; font-weight:bold } +.CodeRay .i { color:#00D; font-weight:bold } +.CodeRay .ic { color:#B44; font-weight:bold } + +.CodeRay .il { background: #eee } +.CodeRay .il .il { background: #ddd } +.CodeRay .il .il .il { background: #ccc } +.CodeRay .il .dl { font-weight: bold ! important; color: #888 ! important } + +.CodeRay .in { color:#B2B; font-weight:bold } +.CodeRay .iv { color:#33B } +.CodeRay .la { color:#970; font-weight:bold } +.CodeRay .lv { color:#963 } +.CodeRay .oc { color:#40E; font-weight:bold } +.CodeRay .on { color:#000; font-weight:bold } +.CodeRay .op { } +.CodeRay .pc { color:#038; font-weight:bold } +.CodeRay .pd { color:#369; font-weight:bold } +.CodeRay .pp { color:#579 } +.CodeRay .pt { color:#339; font-weight:bold } +.CodeRay .r { color:#080; font-weight:bold } + +.CodeRay .rx { background-color:#fff0ff } +.CodeRay .rx .k { color:#808 } +.CodeRay .rx .dl { color:#404 } +.CodeRay .rx .mod { color:#C2C } +.CodeRay .rx .fu { color:#404; font-weight: bold } + +.CodeRay .s { background-color:#fff0f0 } +.CodeRay .s .s { background-color:#ffe0e0 } +.CodeRay .s .s .s { background-color:#ffd0d0 } +.CodeRay .s .k { color:#D20 } +.CodeRay .s .dl { color:#710 } + +.CodeRay .sh { background-color:#f0fff0 } +.CodeRay .sh .k { color:#2B2 } +.CodeRay .sh .dl { color:#161 } + +.CodeRay .sy { color:#A60 } +.CodeRay .sy .k { color:#A60 } +.CodeRay .sy .dl { color:#630 } + +.CodeRay .ta { color:#070 } +.CodeRay .tf { color:#070; font-weight:bold } +.CodeRay .ts { color:#D70; font-weight:bold } +.CodeRay .ty { color:#339; font-weight:bold } +.CodeRay .v { color:#036 } +.CodeRay .xt { color:#444 } diff --git a/sample/css.rb b/sample/css.rb new file mode 100644 index 0000000..52e4bcc --- /dev/null +++ b/sample/css.rb @@ -0,0 +1,4 @@ +require 'coderay' + +# print the default stylesheet for HTML codes +puts CodeRay::Encoders[:html]::CSS.new.stylesheet diff --git a/sample/div.out b/sample/div.out new file mode 100644 index 0000000..ec9676d --- /dev/null +++ b/sample/div.out @@ -0,0 +1,17 @@ +
+
for a in 0..255
+        a = a.chr
+        begin
+                x = eval("?\\#{a}")
+                if x == a[0]
+                        next
+                else
+                        print "#{a}: #{x}"
+                end
+        rescue SyntaxError => boom
+                print "#{a}: error"
+        end
+        puts
+end
+
+
diff --git a/sample/div.rb b/sample/div.rb new file mode 100644 index 0000000..27b6f32 --- /dev/null +++ b/sample/div.rb @@ -0,0 +1,19 @@ +require 'coderay' + +puts CodeRay.scan(DATA.read, :ruby).div + +__END__ +for a in 0..255 + a = a.chr + begin + x = eval("?\\#{a}") + if x == a[0] + next + else + print "#{a}: #{x}" + end + rescue SyntaxError => boom + print "#{a}: error" + end + puts +end diff --git a/sample/dump.out b/sample/dump.out new file mode 100644 index 0000000..2c24962 --- /dev/null +++ b/sample/dump.out @@ -0,0 +1,21 @@ +YAML: 2358 bytes +Dump: 1058 bytes +undumped: +
+
require 'coderay'
+
+# scan some code
+tokens = CodeRay.scan(File.read($0), :ruby)
+
+# dump using YAML
+yaml = tokens.yaml
+puts 'YAML: %4d bytes' % yaml.size
+
+# dump using Marshal
+dump = tokens.dump(0)
+puts 'Dump: %4d bytes' % dump.size
+
+# undump and encode
+puts 'undumped:', dump.undump.div(:css => :class)
+
+
diff --git a/sample/dump.rb b/sample/dump.rb new file mode 100644 index 0000000..cd68dc8 --- /dev/null +++ b/sample/dump.rb @@ -0,0 +1,15 @@ +require 'coderay' + +# scan some code +tokens = CodeRay.scan(File.read($0), :ruby) + +# dump using YAML +yaml = tokens.yaml +puts 'YAML: %4d bytes' % yaml.size + +# dump using Marshal +dump = tokens.dump(0) +puts 'Dump: %4d bytes' % dump.size + +# undump and encode +puts 'undumped:', dump.undump.div(:css => :class) diff --git a/sample/encoder.out b/sample/encoder.out new file mode 100644 index 0000000..c221d25 --- /dev/null +++ b/sample/encoder.out @@ -0,0 +1,73 @@ +Encoders Demo: puts 17 + 4 + +Statistic: + +Code Statistics + +Tokens 8 + Non-Whitespace 4 +Bytes Total 12 + +Token Types (4): + type count ratio size (average) +------------------------------------------------------------- + TOTAL 8 100.00 % 1.5 + space 4 50.00 % 1.0 + integer 2 25.00 % 1.5 + ident 1 12.50 % 4.0 + operator 1 12.50 % 1.0 + + +Original text: +ident puts +space +integer 17 +space +operator + +space +integer 4 +space \ + + +YAML: +--- +- - puts + - :ident +- - " " + - :space +- - "17" + - :integer +- - " " + - :space +- - + + - :operator +- - " " + - :space +- - "4" + - :integer +- - | + + + - :space + +Dump: +"x\332\355\314;\n\302@\024\205aP\311c\320\316\005\004[+A\020\356\224\331\201\330\245\n\346\"A\230\0312c\341\356M\"\242k\220\277\272\217\303wVE-\333\332wzn\237\"\027\177W\027\233E\265l\362]\031\036)\212\351;ui<\263JL\f\355U\307=?\234d\335\273\2447\035\346\310\346\323\330\313\306\a\035\332\344\177\277G[L\303\314\327\\j\263o.TEXT_FIELD(:NAME, "PANFRAGE OHNE $GV UND MIT #{<--$GV-->}").SET ARTIKEL +ODER +TEXT = <--$BLA-->.TEST(...) \ No newline at end of file diff --git a/sample/global_vars.rb b/sample/global_vars.rb new file mode 100644 index 0000000..8066d67 --- /dev/null +++ b/sample/global_vars.rb @@ -0,0 +1,13 @@ +code = <<'CODE' +$ie.text_field(:name, "pAnfrage ohne $gV und mit #{$gv}").set artikel +oder +text = $bla.test(...) +CODE + +require 'coderay' + +tokens = CodeRay.scan code, :ruby +tokens.each_text_token { |text, kind| text.upcase! } +tokens.each(:global_variable) { |text, kind| text.replace '<--%s-->' % text } + +print tokens diff --git a/sample/global_vars2.out b/sample/global_vars2.out new file mode 100644 index 0000000..964cf50 --- /dev/null +++ b/sample/global_vars2.out @@ -0,0 +1,10 @@ + + + + + +$ie.text_field(:name, "pAnfrage ohne $gV und mit #{$gv}").set artikel +oder +text = $bla.test(...) + + diff --git a/sample/global_vars2.rb b/sample/global_vars2.rb new file mode 100644 index 0000000..7646890 --- /dev/null +++ b/sample/global_vars2.rb @@ -0,0 +1,28 @@ +require 'coderay' +require 'erb' +include ERB::Util + +code = <<'CODE' +$ie.text_field(:name, "pAnfrage ohne $gV und mit #{$gv}").set artikel +oder +text = $bla.test(...) +CODE +puts < + + + + +HTML + +CodeRay.scan_stream code, :ruby do |text, kind| + next if text.is_a? Symbol + text = h(text) + text = '%s' % text if kind == :global_variable + print text +end + +puts < + +HTML diff --git a/sample/highlight.out b/sample/highlight.out new file mode 100644 index 0000000..7b50566 --- /dev/null +++ b/sample/highlight.out @@ -0,0 +1,149 @@ +
+
puts "Hello, World!"
+
+ + + + + + + + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+
require 'coderay'
+
+puts CodeRay.highlight('puts "Hello, World!"', :ruby)
+
+output = CodeRay.highlight_file($0, :line_numbers => :table)
+puts <<HTML
+<html>
+<head>
+#{output.stylesheet true}
+<body>
+#{output}
+</body>
+</html>
+HTML
+
+ + + diff --git a/sample/highlight.rb b/sample/highlight.rb new file mode 100644 index 0000000..846efa4 --- /dev/null +++ b/sample/highlight.rb @@ -0,0 +1,14 @@ +require 'coderay' + +puts CodeRay.highlight('puts "Hello, World!"', :ruby) + +output = CodeRay.highlight_file($0, :line_numbers => :table) +puts < + +#{output.stylesheet true} + +#{output} + + +HTML diff --git a/sample/html.out b/sample/html.out new file mode 100644 index 0000000..1e29612 --- /dev/null +++ b/sample/html.out @@ -0,0 +1,893 @@ + + + + + CodeRay HTML Encoder Example + + + + + + + +
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
+
require 'scanner'
+
+module CodeRay
+  
+  class RubyScanner < Scanner
+    
+    RESERVED_WORDS = [
+      'and', 'def', 'end', 'in', 'or', 'unless', 'begin',
+      'defined?', 'ensure', 'module', 'redo', 'super', 'until',
+      'BEGIN', 'break', 'do', 'next', 'rescue', 'then',
+      'when', 'END', 'case', 'else', 'for', 'retry',
+      'while', 'alias', 'class', 'elsif', 'if', 'not', 'return',
+      'undef', 'yield',
+    ]
+
+    DEF_KEYWORDS = ['def']
+    MODULE_KEYWORDS = ['class', 'module']
+    DEF_NEW_STATE = WordList.new(:initial).
+      add(DEF_KEYWORDS, :def_expected).
+      add(MODULE_KEYWORDS, :module_expected)
+
+    WORDS_ALLOWING_REGEXP = [
+      'and', 'or', 'not', 'while', 'until', 'unless', 'if', 'elsif', 'when'
+    ]
+    REGEXP_ALLOWED = WordList.new(false).
+      add(WORDS_ALLOWING_REGEXP, :set)
+    
+    PREDEFINED_CONSTANTS = [
+      'nil', 'true', 'false', 'self',
+      'DATA', 'ARGV', 'ARGF', '__FILE__', '__LINE__',
+    ]
+
+    IDENT_KIND = WordList.new(:ident).
+      add(RESERVED_WORDS, :reserved).
+      add(PREDEFINED_CONSTANTS, :pre_constant)
+
+    METHOD_NAME = / #{IDENT} [?!]? /xo
+    METHOD_NAME_EX = /
+     #{METHOD_NAME}  # common methods: split, foo=, empty?, gsub!
+     | \*\*?         # multiplication and power
+     | [-+~]@?       # plus, minus
+     | [\/%&|^`]     # division, modulo or format strings, &and, |or, ^xor, `system`
+     | \[\]=?        # array getter and setter
+     | <=?>? | >=?   # comparison, rocket operator
+     | << | >>       # append or shift left, shift right
+     | ===?          # simple equality and case equality
+    /ox
+    GLOBAL_VARIABLE = / \$ (?: #{IDENT} | \d+ | [~&+`'=\/,;_.<>!@0$?*":F\\] | -[a-zA-Z_0-9] ) /ox
+
+    DOUBLEQ = / "  [^"\#\\]*  (?: (?: \#\{.*?\} | \#(?:$")?  | \\. ) [^"\#\\]*  )* "?  /ox
+    SINGLEQ = / '  [^'\\]*    (?:                              \\.   [^'\\]*    )* '?  /ox
+    STRING  = / #{SINGLEQ} | #{DOUBLEQ} /ox
+    SHELL   = / `  [^`\#\\]*  (?: (?: \#\{.*?\} | \#(?:$`)?  | \\. ) [^`\#\\]*  )* `?  /ox
+    REGEXP  = / \/ [^\/\#\\]* (?: (?: \#\{.*?\} | \#(?:$\/)? | \\. ) [^\/\#\\]* )* \/? /ox
+    
+    DECIMAL = /\d+(?:_\d+)*/  # doesn't recognize 09 as octal error
+    OCTAL = /0_?[0-7]+(?:_[0-7]+)*/
+    HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/
+    BINARY = /0b[01]+(?:_[01]+)*/
+
+    EXPONENT = / [eE] [+-]? #{DECIMAL} /ox
+    FLOAT = / #{DECIMAL} (?: #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? ) /
+    INTEGER = /#{OCTAL}|#{HEXADECIMAL}|#{BINARY}|#{DECIMAL}/
+    
+    def reset
+      super
+      @regexp_allowed = false
+    end
+    
+    def next_token
+      return if @scanner.eos?
+
+      kind = :error
+      if @scanner.scan(/\s+/)  # in every state
+        kind = :space
+        @regexp_allowed = :set if @regexp_allowed or @scanner.matched.index(?\n)  # delayed flag setting
+
+      elsif @state == :def_expected
+        if @scanner.scan(/ (?: (?:#{IDENT}(?:\.|::))* | (?:@@?|$)? #{IDENT}(?:\.|::) ) #{METHOD_NAME_EX} /ox)
+          kind = :method
+          @state = :initial
+        else
+          @scanner.scan(/./)
+          kind = :error
+        end
+        @state = :initial
+        
+      elsif @state == :module_expected
+        if @scanner.scan(/<</)
+          kind = :operator
+        else
+          if @scanner.scan(/ (?: #{IDENT} (?:\.|::))* #{IDENT} /ox)
+            kind = :method
+          else
+            @scanner.scan(/./)
+            kind = :error
+          end
+          @state = :initial
+        end
+        
+      elsif # state == :initial
+        # IDENTIFIERS, KEYWORDS
+        if @scanner.scan(GLOBAL_VARIABLE)
+          kind = :global_variable
+        elsif @scanner.scan(/ @@ #{IDENT} /ox)
+          kind = :class_variable
+        elsif @scanner.scan(/ @ #{IDENT} /ox)
+          kind = :instance_variable
+        elsif @scanner.scan(/ __END__\n ( (?!\#CODE\#) .* )? | \#[^\n]* | =begin(?=\s).*? \n=end(?=\s|\z)(?:[^\n]*)? /x)
+          kind = :comment
+        elsif @scanner.scan(METHOD_NAME)
+          if @last_token_dot
+            kind = :ident
+          else
+            matched = @scanner.matched
+            kind = IDENT_KIND[matched]
+            if kind == :ident and matched =~ /^[A-Z]/
+              kind = :constant
+            elsif kind == :reserved
+              @state = DEF_NEW_STATE[matched]
+              @regexp_allowed = REGEXP_ALLOWED[matched]
+            end
+          end
+          
+        elsif @scanner.scan(STRING)
+          kind = :string
+        elsif @scanner.scan(SHELL)
+          kind = :shell
+        ## HEREDOCS
+        elsif @scanner.scan(/\//) and @regexp_allowed
+           @scanner.unscan
+           @scanner.scan(REGEXP)
+          kind = :regexp
+        ## %strings
+        elsif @scanner.scan(/:(?:#{GLOBAL_VARIABLE}|#{METHOD_NAME_EX}|#{STRING})/ox)
+          kind = :global_variable
+        elsif @scanner.scan(/
+          \? (?:
+            [^\s\\]
+          | 
+            \\ (?:M-\\C-|C-\\M-|M-\\c|c\\M-|c|C-|M-))? (?: \\ (?: . | [0-7]{3} | x[0-9A-Fa-f][0-9A-Fa-f] )
+          )
+        /ox)
+          kind = :integer
+          
+        elsif @scanner.scan(/ [-+*\/%=<>;,|&!()\[\]{}~?] | \.\.?\.? | ::? /x)
+          kind = :operator
+          @regexp_allowed = :set if @scanner.matched[-1,1] =~ /[~=!<>|&^,\(\[+\-\/\*%]\z/
+        elsif @scanner.scan(FLOAT)
+          kind = :float
+        elsif @scanner.scan(INTEGER)
+          kind = :integer
+        elsif @scanner.scan(/:(?:#{GLOBAL_VARIABLE}|#{METHOD_NAME_EX}|#{STRING})/ox)
+          kind = :global_variable
+        else
+          @scanner.scan(/./m)
+        end
+      end
+      
+      token = Token.new @scanner.matched, kind
+
+      if kind == :regexp
+        token.text << @scanner.scan(/[eimnosux]*/)
+      end
+      
+      @regexp_allowed = (@regexp_allowed == :set)  # delayed flag setting
+
+      token
+    end
+  end
+  
+  ScannerList.register RubyScanner, 'ruby'
+
+end
+
+module CodeRay
+  require 'scanner'
+
+  class Highlighter
+
+    def initialize lang
+      @scanner = Scanner[lang].new
+    end
+
+    def highlight code
+      @scanner.feed code
+      @scanner.all_tokens.map { |t| t.inspect }.join "\n"
+    end
+
+  end
+
+  class HTMLHighlighter < Highlighter
+    
+    ClassOfKind = {
+      :attribute_name => 'an',
+      :attribute_name_fat => 'af',
+      :attribute_value => 'av',
+      :attribute_value_fat => 'aw',
+      :bin => 'bi',
+       :char => 'ch',
+      :class => 'cl',
+      :class_variable => 'cv',
+      :color => 'cr',
+      :comment => 'c',
+      :constant => 'co',
+      :definition => 'df',
+      :directive => 'di',
+      :doc => 'do',
+      :doc_string => 'ds',
+      :exception => 'ex',
+      :error => 'er',
+      :float => 'fl',
+      :function => 'fu',
+      :global_variable => 'gv',
+      :hex => 'hx',
+      :include => 'ic',
+      :instance_variable => 'iv',
+      :integer => 'i',
+      :interpreted => 'in',
+      :label => 'la',
+      :local_variable => 'lv',
+      :oct => 'oc',
+      :operator_name => 'on',
+      :pre_constant => 'pc',
+      :pre_type => 'pt',
+      :predefined => 'pd',
+      :preprocessor => 'pp',
+      :regexp => 'rx',
+      :reserved => 'r',
+      :shell => 'sh',
+      :string => 's',
+      :symbol => 'sy',
+      :tag => 'ta',
+      :tag_fat => 'tf',
+      :tag_special => 'ts',
+      :type => 'ty',
+      :variable => 'v',
+      :xml_text => 'xt',
+
+      :ident => :NO_HIGHLIGHT,
+      :operator => :NO_HIGHLIGHT,
+      :space => :NO_HIGHLIGHT,
+    }
+    ClassOfKind[:procedure] = ClassOfKind[:method] = ClassOfKind[:function]
+    ClassOfKind.default = ClassOfKind[:error] or raise 'no class found for :error!'
+    
+    def initialize lang, options = {}
+      super lang
+      
+      @HTML_TAB = ' ' * options.fetch(:tabs2space, 8)
+      case level = options.fetch(:level, 'xhtml')
+        when 'html'
+          @HTML_BR = "<BR>\n"
+        when 'xhtml'
+          @HTML_BR = "<br />\n"
+      else
+        raise "Unknown HTML level: #{level}"
+      end
+    end
+
+    def highlight code
+      @scanner.feed code
+      
+      out = ''
+      while t = @scanner.next_token
+        warn t.inspect if t.text.nil?
+        out << to_html(t)
+      end
+      TEMPLATE =~ /<%CONTENT%>/
+      $` + out + $'
+    end
+    
+  private
+    def to_html token
+      css_class = ClassOfKind[token.kind]
+      if defined? ::DEBUG and not ClassOfKind.has_key? token.kind
+        warn "no token class found for :#{token.kind}"
+      end
+        
+      text = text_to_html token.text
+      if css_class == :NO_HIGHLIGHT
+        text
+      else
+        "<span class=\"#{css_class}\">#{text}</span>"
+      end
+    end
+    
+    def text_to_html text
+      return '' if text.empty?
+      text = text.dup  # important
+      if text.index(/["><&]/)
+        text.gsub!('&', '&amp;')
+        text.gsub!('"', '&quot;')
+        text.gsub!('>', '&gt;')
+        text.gsub!('<', '&lt;')
+      end
+      if text.index(/\s/)
+        text.gsub!("\n", @HTML_BR)
+        text.gsub!("\t", @HTML_TAB)
+        text.gsub!(/^ /, '&nbsp;')
+        text.gsub!('  ', ' &nbsp;')
+      end
+      text
+    end
+    
+    TEMPLATE = <<-'TEMPLATE'
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html dir="ltr">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta http-equiv="Content-Style-Type" content="text/css">
+
+<title>RubyBB BBCode</title>
+<style type="text/css">
+.code {
+  width: 100%;
+  background-color: #FAFAFA;
+  border: 1px solid #D1D7DC;
+  font-family: 'Courier New', 'Terminal', monospace;
+  font-size: 10pt;
+  color: black;
+  vertical-align: top;
+  text-align: left;
+}
+.code .af { color:#00C; }
+.code .an { color:#007; }
+.code .av { color:#700; }
+.code .aw { color:#C00; }
+.code .bi { color:#509; font-weight:bold; }
+.code .c  { color:#888; }
+.code .ch { color:#C28; font-weight:bold; }
+.code .cl { color:#B06; font-weight:bold; }
+.code .co { color:#036; font-weight:bold; }
+.code .cr { color:#0A0; }
+.code .cv { color:#369; }
+.code .df { color:#099; font-weight:bold; }
+.code .di { color:#088; font-weight:bold; }
+.code .do { color:#970; }
+.code .ds { color:#D42; font-weight:bold; }
+.code .er { color:#F00; background-color:#FAA; }
+.code .ex { color:#F00; font-weight:bold; }
+.code .fl { color:#60E; font-weight:bold; }
+.code .fu { color:#06B; font-weight:bold; }
+.code .gv { color:#800; font-weight:bold; }
+.code .hx { color:#058; font-weight:bold; }
+.code .i  { color:#00D; font-weight:bold; }
+.code .ic { color:#B44; font-weight:bold; }
+.code .in { color:#B2B; font-weight:bold; }
+.code .iv { color:#33B; }
+.code .la { color:#970; font-weight:bold; }
+.code .lv { color:#963; }
+.code .oc { color:#40E; font-weight:bold; }
+.code .on { color:#000; font-weight:bold; }
+.code .pc { color:#038; font-weight:bold; }
+.code .pd { color:#369; font-weight:bold; }
+.code .pp { color:#579; }
+.code .pt { color:#339; font-weight:bold; }
+.code .r  { color:#080; font-weight:bold; }
+.code .rx { color:#927; font-weight:bold; }
+.code .s  { color:#D42; font-weight:bold; }
+.code .sh { color:#B2B; font-weight:bold; }
+.code .sy { color:#A60; }
+.code .ta { color:#070; }
+.code .tf { color:#070; font-weight:bold; }
+.code .ts { color:#D70; font-weight:bold; }
+.code .ty { color:#339; font-weight:bold; }
+.code .v  { color:#036; }
+.code .xt { color:#444; }
+</style>
+</head>
+<body>
+<div class="code">
+<%CONTENT%>
+</div>
+<div class="validators">
+<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" height="31" width="88" style="border:none;"></a>
+<img style="border:0" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" >
+</div>    
+</body>
+</html>
+    TEMPLATE
+
+  end
+
+end
+
+ + + diff --git a/sample/html.rb b/sample/html.rb new file mode 100644 index 0000000..c854635 --- /dev/null +++ b/sample/html.rb @@ -0,0 +1,394 @@ +$: << '..' +require 'coderay' + +tokens = CodeRay.scan DATA.read, :ruby +html = tokens.html(:tab_width => 2, :line_numbers => :table) + +puts html.page + +__END__ +require 'scanner' + +module CodeRay + + class RubyScanner < Scanner + + RESERVED_WORDS = [ + 'and', 'def', 'end', 'in', 'or', 'unless', 'begin', + 'defined?', 'ensure', 'module', 'redo', 'super', 'until', + 'BEGIN', 'break', 'do', 'next', 'rescue', 'then', + 'when', 'END', 'case', 'else', 'for', 'retry', + 'while', 'alias', 'class', 'elsif', 'if', 'not', 'return', + 'undef', 'yield', + ] + + DEF_KEYWORDS = ['def'] + MODULE_KEYWORDS = ['class', 'module'] + DEF_NEW_STATE = WordList.new(:initial). + add(DEF_KEYWORDS, :def_expected). + add(MODULE_KEYWORDS, :module_expected) + + WORDS_ALLOWING_REGEXP = [ + 'and', 'or', 'not', 'while', 'until', 'unless', 'if', 'elsif', 'when' + ] + REGEXP_ALLOWED = WordList.new(false). + add(WORDS_ALLOWING_REGEXP, :set) + + PREDEFINED_CONSTANTS = [ + 'nil', 'true', 'false', 'self', + 'DATA', 'ARGV', 'ARGF', '__FILE__', '__LINE__', + ] + + IDENT_KIND = WordList.new(:ident). + add(RESERVED_WORDS, :reserved). + add(PREDEFINED_CONSTANTS, :pre_constant) + + METHOD_NAME = / #{IDENT} [?!]? /xo + METHOD_NAME_EX = / + #{METHOD_NAME} # common methods: split, foo=, empty?, gsub! + | \*\*? # multiplication and power + | [-+~]@? # plus, minus + | [\/%&|^`] # division, modulo or format strings, &and, |or, ^xor, `system` + | \[\]=? # array getter and setter + | <=?>? | >=? # comparison, rocket operator + | << | >> # append or shift left, shift right + | ===? # simple equality and case equality + /ox + GLOBAL_VARIABLE = / \$ (?: #{IDENT} | \d+ | [~&+`'=\/,;_.<>!@0$?*":F\\] | -[a-zA-Z_0-9] ) /ox + + DOUBLEQ = / " [^"\#\\]* (?: (?: \#\{.*?\} | \#(?:$")? | \\. ) [^"\#\\]* )* "? /ox + SINGLEQ = / ' [^'\\]* (?: \\. [^'\\]* )* '? /ox + STRING = / #{SINGLEQ} | #{DOUBLEQ} /ox + SHELL = / ` [^`\#\\]* (?: (?: \#\{.*?\} | \#(?:$`)? | \\. ) [^`\#\\]* )* `? /ox + REGEXP = / \/ [^\/\#\\]* (?: (?: \#\{.*?\} | \#(?:$\/)? | \\. ) [^\/\#\\]* )* \/? /ox + + DECIMAL = /\d+(?:_\d+)*/ # doesn't recognize 09 as octal error + OCTAL = /0_?[0-7]+(?:_[0-7]+)*/ + HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/ + BINARY = /0b[01]+(?:_[01]+)*/ + + EXPONENT = / [eE] [+-]? #{DECIMAL} /ox + FLOAT = / #{DECIMAL} (?: #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? ) / + INTEGER = /#{OCTAL}|#{HEXADECIMAL}|#{BINARY}|#{DECIMAL}/ + + def reset + super + @regexp_allowed = false + end + + def next_token + return if @scanner.eos? + + kind = :error + if @scanner.scan(/\s+/) # in every state + kind = :space + @regexp_allowed = :set if @regexp_allowed or @scanner.matched.index(?\n) # delayed flag setting + + elsif @state == :def_expected + if @scanner.scan(/ (?: (?:#{IDENT}(?:\.|::))* | (?:@@?|$)? #{IDENT}(?:\.|::) ) #{METHOD_NAME_EX} /ox) + kind = :method + @state = :initial + else + @scanner.scan(/./) + kind = :error + end + @state = :initial + + elsif @state == :module_expected + if @scanner.scan(/<;,|&!()\[\]{}~?] | \.\.?\.? | ::? /x) + kind = :operator + @regexp_allowed = :set if @scanner.matched[-1,1] =~ /[~=!<>|&^,\(\[+\-\/\*%]\z/ + elsif @scanner.scan(FLOAT) + kind = :float + elsif @scanner.scan(INTEGER) + kind = :integer + elsif @scanner.scan(/:(?:#{GLOBAL_VARIABLE}|#{METHOD_NAME_EX}|#{STRING})/ox) + kind = :global_variable + else + @scanner.scan(/./m) + end + end + + token = Token.new @scanner.matched, kind + + if kind == :regexp + token.text << @scanner.scan(/[eimnosux]*/) + end + + @regexp_allowed = (@regexp_allowed == :set) # delayed flag setting + + token + end + end + + ScannerList.register RubyScanner, 'ruby' + +end + +module CodeRay + require 'scanner' + + class Highlighter + + def initialize lang + @scanner = Scanner[lang].new + end + + def highlight code + @scanner.feed code + @scanner.all_tokens.map { |t| t.inspect }.join "\n" + end + + end + + class HTMLHighlighter < Highlighter + + ClassOfKind = { + :attribute_name => 'an', + :attribute_name_fat => 'af', + :attribute_value => 'av', + :attribute_value_fat => 'aw', + :bin => 'bi', + :char => 'ch', + :class => 'cl', + :class_variable => 'cv', + :color => 'cr', + :comment => 'c', + :constant => 'co', + :definition => 'df', + :directive => 'di', + :doc => 'do', + :doc_string => 'ds', + :exception => 'ex', + :error => 'er', + :float => 'fl', + :function => 'fu', + :global_variable => 'gv', + :hex => 'hx', + :include => 'ic', + :instance_variable => 'iv', + :integer => 'i', + :interpreted => 'in', + :label => 'la', + :local_variable => 'lv', + :oct => 'oc', + :operator_name => 'on', + :pre_constant => 'pc', + :pre_type => 'pt', + :predefined => 'pd', + :preprocessor => 'pp', + :regexp => 'rx', + :reserved => 'r', + :shell => 'sh', + :string => 's', + :symbol => 'sy', + :tag => 'ta', + :tag_fat => 'tf', + :tag_special => 'ts', + :type => 'ty', + :variable => 'v', + :xml_text => 'xt', + + :ident => :NO_HIGHLIGHT, + :operator => :NO_HIGHLIGHT, + :space => :NO_HIGHLIGHT, + } + ClassOfKind[:procedure] = ClassOfKind[:method] = ClassOfKind[:function] + ClassOfKind.default = ClassOfKind[:error] or raise 'no class found for :error!' + + def initialize lang, options = {} + super lang + + @HTML_TAB = ' ' * options.fetch(:tabs2space, 8) + case level = options.fetch(:level, 'xhtml') + when 'html' + @HTML_BR = "
\n" + when 'xhtml' + @HTML_BR = "
\n" + else + raise "Unknown HTML level: #{level}" + end + end + + def highlight code + @scanner.feed code + + out = '' + while t = @scanner.next_token + warn t.inspect if t.text.nil? + out << to_html(t) + end + TEMPLATE =~ /<%CONTENT%>/ + $` + out + $' + end + + private + def to_html token + css_class = ClassOfKind[token.kind] + if defined? ::DEBUG and not ClassOfKind.has_key? token.kind + warn "no token class found for :#{token.kind}" + end + + text = text_to_html token.text + if css_class == :NO_HIGHLIGHT + text + else + "#{text}" + end + end + + def text_to_html text + return '' if text.empty? + text = text.dup # important + if text.index(/["><&]/) + text.gsub!('&', '&') + text.gsub!('"', '"') + text.gsub!('>', '>') + text.gsub!('<', '<') + end + if text.index(/\s/) + text.gsub!("\n", @HTML_BR) + text.gsub!("\t", @HTML_TAB) + text.gsub!(/^ /, ' ') + text.gsub!(' ', '  ') + end + text + end + + TEMPLATE = <<-'TEMPLATE' + + + + + + +RubyBB BBCode + + + +
+<%CONTENT%> +
+
+Valid HTML 4.01! +Valid CSS! +
+ + + TEMPLATE + + end + +end diff --git a/sample/html2.out b/sample/html2.out new file mode 100644 index 0000000..ead61b2 --- /dev/null +++ b/sample/html2.out @@ -0,0 +1,159 @@ + + + + + CodeRay HTML Encoder Example + + + + + + + +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
require 'coderay'
+
+# scan this file
+tokens = CodeRay.scan(File.read($0) * 1, :ruby)
+
+# output it with two styles of line numbers
+out = tokens.div(:line_numbers => :table)
+out << '<hr />'
+out << tokens.div(:line_numbers => :inline, :line_number_start => 8)
+
+puts out.page
+
+
+
 8 require 'coderay'
+ 9 
+10 # scan this file
+11 tokens = CodeRay.scan(File.read($0) * 1, :ruby)
+12 
+13 # output it with two styles of line numbers
+14 out = tokens.div(:line_numbers => :table)
+15 out << '<hr />'
+16 out << tokens.div(:line_numbers => :inline, :line_number_start => 8)
+17 
+18 puts out.page
+
+
+ + + diff --git a/sample/html2.rb b/sample/html2.rb new file mode 100644 index 0000000..7ce9d60 --- /dev/null +++ b/sample/html2.rb @@ -0,0 +1,11 @@ +require 'coderay' + +# scan this file +tokens = CodeRay.scan(File.read($0) * 1, :ruby) + +# output it with two styles of line numbers +out = tokens.div(:line_numbers => :table) +out << '
' +out << tokens.div(:line_numbers => :inline, :line_number_start => 8) + +puts out.page diff --git a/sample/html_list.out b/sample/html_list.out new file mode 100644 index 0000000..aec2cf5 --- /dev/null +++ b/sample/html_list.out @@ -0,0 +1,134 @@ + + + + + CodeRay HTML Encoder Example + + + + +
+
-1 $: << '..'
+ 0 require 'coderay'
+ 1 
+ 2 tokens = CodeRay.scan File.read(__FILE__), :ruby
+ 3 html = tokens.html(:tab_width => 2, :line_numbers => :inline, :line_number_start => -1)
+ 4 
+ 5 puts html.page
+ 6 
+ 7 commment = <<_
+ 8 This code must be > 10 lines
+ 9 because I want to test the correct adjustment of the line numbers.
+10 _
+
+
+ + + diff --git a/sample/html_list.rb b/sample/html_list.rb new file mode 100644 index 0000000..97724f2 --- /dev/null +++ b/sample/html_list.rb @@ -0,0 +1,12 @@ +$: << '..' +require 'coderay' + +tokens = CodeRay.scan File.read(__FILE__), :ruby +html = tokens.html(:tab_width => 2, :line_numbers => :inline, :line_number_start => -1) + +puts html.page + +commment = <<_ +This code must be > 10 lines +because I want to test the correct adjustment of the line numbers. +_ diff --git a/sample/load_encoder.out b/sample/load_encoder.out new file mode 100644 index 0000000..1cff356 --- /dev/null +++ b/sample/load_encoder.out @@ -0,0 +1,8 @@ +CodeRay::Encoders::YAML is not defined; you must load it first. +Now it is loaded: CodeRay::Encoders::YAML +See? +Require is also possible: CodeRay::Encoders::Tokens +See? +Now load some mapped encoders: stats and plain. +Require all Encoders: +[[:count, CodeRay::Encoders::Count], [:debug, CodeRay::Encoders::Debug], [:div, CodeRay::Encoders::Div], [:html, CodeRay::Encoders::HTML], [:null, CodeRay::Encoders::Null], [:page, CodeRay::Encoders::Page], [:plain, :text], [:span, CodeRay::Encoders::Span], [:statistic, CodeRay::Encoders::Statistic], [:stats, CodeRay::Encoders::Statistic], [:text, CodeRay::Encoders::Text], [:tokens, CodeRay::Encoders::Tokens], [:xml, CodeRay::Encoders::XML], [:yaml, CodeRay::Encoders::YAML]] diff --git a/sample/load_encoder.rb b/sample/load_encoder.rb new file mode 100644 index 0000000..39d310d --- /dev/null +++ b/sample/load_encoder.rb @@ -0,0 +1,25 @@ +require 'coderay' + +begin + CodeRay::Encoders::YAML +rescue + puts 'CodeRay::Encoders::YAML is not defined; you must load it first.' +end + +yaml_encoder = CodeRay::Encoders[:yaml] +print 'Now it is loaded: ' +p yaml_encoder +puts 'See?' + +tokens_encoder = require_plugin 'CodeRay::Encoders/tokens' +print 'Require is also possible: ' +p tokens_encoder +puts 'See?' + +puts 'Now load some mapped encoders: stats and plain.' +require_plugin 'CodeRay::Encoders/stats' +require_plugin 'CodeRay::Encoders/plain' + +puts 'Require all Encoders:' +CodeRay::Encoders.load_all +p CodeRay::Encoders.plugin_hash.sort_by { |k,v| k.to_s } diff --git a/sample/load_scanner.out b/sample/load_scanner.out new file mode 100644 index 0000000..a2d200d --- /dev/null +++ b/sample/load_scanner.out @@ -0,0 +1,8 @@ +CodeRay::Encoders::Ruby is not defined; you must load it first. +Now it is loaded: CodeRay::Scanners::Ruby +See? +Require is also possible: CodeRay::Scanners::C +See? +Now load some mapped scanners: cpp and plain. +Require all Scanners: +[[nil, :plain], [:c, CodeRay::Scanners::C], [:cpp, :c], [:delphi, CodeRay::Scanners::Delphi], [:html, CodeRay::Scanners::HTML], [:irb, :ruby], [:nitro, :nitro_xhtml], [:nitro_xhtml, CodeRay::Scanners::NitroXHTML], [:pascal, :delphi], [:plain, CodeRay::Scanners::Plaintext], [:plaintext, CodeRay::Scanners::Plaintext], [:rhtml, CodeRay::Scanners::RHTML], [:ruby, CodeRay::Scanners::Ruby], [:xhtml, :nitro_xhtml], [:xml, :html]] diff --git a/sample/load_scanner.rb b/sample/load_scanner.rb new file mode 100644 index 0000000..5e503f0 --- /dev/null +++ b/sample/load_scanner.rb @@ -0,0 +1,25 @@ +require 'coderay' + +begin + CodeRay::Scanners::Ruby +rescue + puts 'CodeRay::Encoders::Ruby is not defined; you must load it first.' +end + +ruby_scanner = CodeRay::Scanners[:ruby] +print 'Now it is loaded: ' +p ruby_scanner +puts 'See?' + +c_scanner = require_plugin 'CodeRay::Scanners/c' +print 'Require is also possible: ' +p c_scanner +puts 'See?' + +puts 'Now load some mapped scanners: cpp and plain.' +require_plugin 'CodeRay::Scanners/cpp' +require_plugin 'CodeRay::Scanners/plain' + +puts 'Require all Scanners:' +CodeRay::Scanners.load_all +p CodeRay::Scanners.plugin_hash.sort_by { |k,v| k.to_s } diff --git a/sample/more.out b/sample/more.out new file mode 100644 index 0000000..aa26e61 --- /dev/null +++ b/sample/more.out @@ -0,0 +1,2 @@ +Input: 4983B, Output: 22546B +Take a look with your browser. diff --git a/sample/more.rb b/sample/more.rb new file mode 100644 index 0000000..0db7ba4 --- /dev/null +++ b/sample/more.rb @@ -0,0 +1,205 @@ +require 'coderay' + +c, ruby = DATA.read.split(/^---$/) +DATA.rewind +me = DATA.read[/.*^__END__$/m] +$input = c + ruby + me + +require 'benchmark' +time = Benchmark.realtime do + + # here CodeRay comes to play + hl = CodeRay.encoder(:html, :tab_width => 2, :line_numbers => :table, :wrap => :div) + c = hl.highlight c, :c + ruby = hl.highlight ruby, :ruby + me = hl.highlight me, :ruby + + body = %w[C Ruby Genereated\ by].zip([c, ruby, me]).map do |title, code| + "

#{title}

\n#{code}" + end.join + body = hl.class::Output.new(body, hl.css, :div).page! + + # CodeRay also provides a simple page generator + $output = body #hl.class.wrap_in_page body +end + +File.open('test.html', 'w') do |f| + f.write $output +end +puts 'Input: %dB, Output: %dB' % [$input.size, $output.size] +#puts 'Created "test.html" in %0.3f seconds (%d KB/s).' % [time, $input.size / 1024.0 / time] +puts 'Take a look with your browser.' + +__END__ +/********************************************************************** + + version.c - + + $Author: nobu $ + $Date: 2004/03/25 12:01:40 $ + created at: Thu Sep 30 20:08:01 JST 1993 + + Copyright (C) 1993-2003 Yukihiro Matsumoto + +**********************************************************************/ + +#include "ruby.h" +#include "version.h" +#include + +const char ruby_version[] = RUBY_VERSION; +const char ruby_release_date[] = RUBY_RELEASE_DATE; +const char ruby_platform[] = RUBY_PLATFORM; + +void +Init_version() +{ + VALUE v = rb_obj_freeze(rb_str_new2(ruby_version)); + VALUE d = rb_obj_freeze(rb_str_new2(ruby_release_date)); + VALUE p = rb_obj_freeze(rb_str_new2(ruby_platform)); + + rb_define_global_const("RUBY_VERSION", v); + rb_define_global_const("RUBY_RELEASE_DATE", d); + rb_define_global_const("RUBY_PLATFORM", p); +} + +void +ruby_show_version() +{ + printf("ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM); +} + +void +ruby_show_copyright() +{ + printf("ruby - Copyright (C) 1993-%d Yukihiro Matsumoto\n", RUBY_RELEASE_YEAR); + exit(0); +} +--- +# +# = ostruct.rb: OpenStruct implementation +# +# Author:: Yukihiro Matsumoto +# Documentation:: Gavin Sinclair +# +# OpenStruct allows the creation of data objects with arbitrary attributes. +# See OpenStruct for an example. +# + +# +# OpenStruct allows you to create data objects and set arbitrary attributes. +# For example: +# +# require 'ostruct' +# +# record = OpenStruct.new +# record.name = "John Smith" +# record.age = 70 +# record.pension = 300 +# +# puts record.name # -> "John Smith" +# puts record.address # -> nil +# +# It is like a hash with a different way to access the data. In fact, it is +# implemented with a hash, and you can initialize it with one. +# +# hash = { "country" => "Australia", :population => 20_000_000 } +# data = OpenStruct.new(hash) +# +# p data # -> +# +class OpenStruct + # + # Create a new OpenStruct object. The optional +hash+, if given, will + # generate attributes and values. For example. + # + # require 'ostruct' + # hash = { "country" => "Australia", :population => 20_000_000 } + # data = OpenStruct.new(hash) + # + # p data # -> + # + # By default, the resulting OpenStruct object will have no attributes. + # + def initialize(hash=nil) + @table = {} + if hash + for k,v in hash + @table[k.to_sym] = v + new_ostruct_member(k) + end + end + end + + # Duplicate an OpenStruct object members. + def initialize_copy(orig) + super + @table = @table.dup + end + + def marshal_dump + @table + end + def marshal_load(x) + @table = x + @table.each_key{|key| new_ostruct_member(key)} + end + + def new_ostruct_member(name) + unless self.respond_to?(name) + self.instance_eval %{ + def #{name}; @table[:#{name}]; end + def #{name}=(x); @table[:#{name}] = x; end + } + end + end + + def method_missing(mid, *args) # :nodoc: + mname = mid.id2name + len = args.length + if mname =~ /=$/ + if len != 1 + raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) + end + if self.frozen? + raise TypeError, "can't modify frozen #{self.class}", caller(1) + end + mname.chop! + @table[mname.intern] = args[0] + self.new_ostruct_member(mname) + elsif len == 0 + @table[mid] + else + raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1) + end + end + + # + # Remove the named field from the object. + # + def delete_field(name) + @table.delete name.to_sym + end + + # + # Returns a string containing a detailed summary of the keys and values. + # + def inspect + str = "<#{self.class}" + for k,v in @table + str << " #{k}=#{v.inspect}" + end + str << ">" + end + + attr_reader :table # :nodoc: + protected :table + + # + # Compare this object and +other+ for equality. + # + def ==(other) + return false unless(other.kind_of?(OpenStruct)) + return @table == other.table + end +end diff --git a/sample/scanner.out b/sample/scanner.out new file mode 100644 index 0000000..d35a06d --- /dev/null +++ b/sample/scanner.out @@ -0,0 +1,16 @@ +C Code: if (*p == '{') nest++; + +> print only operators: +(*==)++; +------------------------------ + +Ruby Code: ruby_code(:can, BE, %r[q[ui]te #{ /comple/x },] => $-s, &?\xee) + +> has a string? +false + +> number of regexps? +2 + +> has a string? +"ruby_code" (ident), "(" (operator), ":can" (symbol), "," (operator), " " (space), "BE" (constant), "," (operator), " " (space), "%r[" (delimiter), "q" (content), "[" (nesting_delimiter), "ui" (content), "]" (nesting_delimiter), "te " (content), "#{" (delimiter), " " (space), "/" (delimiter), "comple" (content), "/" (delimiter), "x" (modifier), " " (space), "}" (delimiter), "," (content), "]" (delimiter), " " (space), "=" (operator), ">" (operator), " " (space), "$-s" (global_variable), "," (operator), " " (space), "&" (operator), "?\xee" (integer), ")" (operator) diff --git a/sample/scanner.rb b/sample/scanner.rb new file mode 100644 index 0000000..6a0245e --- /dev/null +++ b/sample/scanner.rb @@ -0,0 +1,36 @@ +require 'coderay' + +c_code = "if (*p == '{') nest++;" +puts 'C Code: ' + c_code +puts + +c_scanner = CodeRay::Scanners[:c].new c_code + +puts '> print only operators:' +for text, kind in c_scanner + print text if kind == :operator +end +puts +puts '-' * 30 +puts + +ruby_code = %q!ruby_code(:can, BE, %r[q[ui]te #{ /comple/x },] => $-s, &?\xee)! +puts 'Ruby Code: ' + ruby_code +puts + +ruby_scanner = CodeRay::Scanners[:ruby].new ruby_code + +puts '> has a string?' +puts ruby_scanner. + any? { |text, kind| kind == :string } +puts + +puts '> number of regexps?' +puts ruby_scanner. + select { |token| token == [:open, :regexp] }.size +puts + +puts '> has a string?' +puts ruby_scanner. + reject { |text, kind| not text.is_a? String }. + map { |text, kind| %("#{text}" (#{kind})) }.join(', ') diff --git a/sample/server.rb b/sample/server.rb new file mode 100644 index 0000000..ccdff32 --- /dev/null +++ b/sample/server.rb @@ -0,0 +1,110 @@ +# CodeRay dynamic highlighter + +unless ARGV.grep(/-[hv]|--(help|version)/).empty? + puts <<-USAGE +CodeRay Server 0.5 +$Id: demo_server.rb 113 2006-03-15 23:24:37Z murphy $ + +Usage: + 1) Start this and your browser. + 2) Go to http://localhost:2468/? + and you should get the highlighted version. + +Parameters: + -d Debug mode; reload CodeRay engine for every file. + (prepare for MANY "already initialized" and "method redefined" + messages - ingore it.) + + ... More to come. + USAGE + exit +end + +require 'webrick' +require 'pathname' + +class << File + alias dir? directory? +end + +require 'erb' +include ERB::Util +def url_decode s + s.to_s.gsub(/%([0-9a-f]{2})/i) { [$1.hex].pack 'C' } +end + +class String + def to_link name = File.basename(self) + "#{name}" + end +end + +require 'coderay' +class CodeRayServlet < WEBrick::HTTPServlet::AbstractServlet + + STYLE = 'style="font-family: sans-serif; color: navy;"' + BANNER = '

Highlighted by CodeRay

' + + def do_GET req, res + q = req.query_string || '' + args = Hash[*q.scan(/(.*?)=(.*?)(?:&|$)/).flatten].each_value { |v| v.replace url_decode(v) } + path = args.fetch 'path', '.' + + backlinks = '

current path: %s
' % html_escape(path) + + (Pathname.new(path) + '..').cleanpath.to_s.to_link('up') + ' - ' + + '.'.to_link('current') + '

' + + res.body = + if File.dir? path + path = Pathname.new(path).cleanpath.to_s + dirs, files = Dir[File.join(path, '*')].sort.partition { |p| File.dir? p } + + page = "" + page << backlinks + + page << '
' + page << "
Directories
\n" + dirs.map do |p| + "
#{p.to_link}
\n" + end.join << "\n" + page << "
Files
\n" + files.map do |p| + "
#{p.to_link}
\n" + end.join << "\n" + page << "
\n" + page << "#{BANNER}" + + elsif File.exist? path + if $DEBUG + $".delete_if { |f| f =~ /coderay/ } + require 'coderay' + end + div = CodeRay.scan_file(path).html :tab_width => 8, :wrap => :div, :hint => :info + div.replace <<-DIV +
+ #{backlinks} +#{div} +
+ #{BANNER} + DIV + div.page + end + + res['Content-Type'] = 'text/html' + end +end + +# This port is taken by "qip_msgd" - I don't know that. Do you? +module CodeRay + PORT = 0xC0DE / 20 +end + +server = WEBrick::HTTPServer.new :Port => CodeRay::PORT + +server.mount '/', CodeRayServlet + +server.mount_proc '/version' do |req, res| + res.body = 'CodeRay::Version = ' + CodeRay::Version + res['Content-Type'] = "text/plain" +end + +trap("INT") { server.shutdown } +server.start diff --git a/sample/simple.out b/sample/simple.out new file mode 100644 index 0000000..7e9206a --- /dev/null +++ b/sample/simple.out @@ -0,0 +1 @@ +puts 'Hello, world!' diff --git a/sample/simple.rb b/sample/simple.rb new file mode 100644 index 0000000..a3129b0 --- /dev/null +++ b/sample/simple.rb @@ -0,0 +1,10 @@ + +# Load CodeRay +# If this doesn't work, try ruby -rubygems. +require 'coderay' + +# Generate HTML page for Ruby code. +page = CodeRay.scan("puts 'Hello, world!'", :ruby).span + +# Print it +puts page diff --git a/sample/stream.rb b/sample/stream.rb new file mode 100644 index 0000000..7ed8a22 --- /dev/null +++ b/sample/stream.rb @@ -0,0 +1,25 @@ +require 'coderay' + +code = File.read($0) * 500 +puts "Size of code: %d KB" % [code.size / 1024] + +puts "Use your system's memory tracker to see how much RAM this takes." +print 'Press some key to continue...'; gets + +require 'benchmark' +e = CodeRay.encoder(:div) +for do_stream in [true, false] + puts "Scanning and encoding in %s mode, please wait..." % + [do_stream ? 'streaming' : 'normal'] + output = '' + time = Benchmark.realtime do + if do_stream + output = e.encode_stream(code, :ruby) + else + output = e.encode_tokens(t = CodeRay.scan(code, :ruby)) + end + end + puts 'Finished after %4.2f seconds.' % time + puts "Size of output: %d KB" % [output.size / 1024] + print 'Press some key to continue...'; gets +end diff --git a/sample/stream2.out b/sample/stream2.out new file mode 100644 index 0000000..83aee98 --- /dev/null +++ b/sample/stream2.out @@ -0,0 +1,2 @@ +kind: regexp, text size: 5. +kind: space, text size: 1. diff --git a/sample/stream2.rb b/sample/stream2.rb new file mode 100644 index 0000000..d43cc9a --- /dev/null +++ b/sample/stream2.rb @@ -0,0 +1,8 @@ +require 'coderay' + +token_stream = CodeRay::TokenStream.new do |kind, text| + puts 'kind: %s, text size: %d.' % [kind, text.size] +end + +token_stream << [:regexp, '/\d+/'] << [:space, "\n"] +#-> kind: rexpexp, text size: 5. diff --git a/sample/suite.rb b/sample/suite.rb index 783fe70..e38cae4 100644 --- a/sample/suite.rb +++ b/sample/suite.rb @@ -33,7 +33,7 @@ class CodeRaySuite < TestCase if File.exist? output expected = File.read output ok = expected == result - computed = output.sub('.out', '.computed') + computed = output.sub('.expected', '.computed') unless ok File.open(computed, 'w') { |f| f.write result } print `diff #{output} #{computed}` if $DEBUG diff --git a/sample/tokens.out b/sample/tokens.out new file mode 100644 index 0000000..bbc2b94 --- /dev/null +++ b/sample/tokens.out @@ -0,0 +1,14 @@ +ident puts +space +integer 3 +space +operator + +space +integer 4 +operator , +space +:open string +delimiter ' +content 3 + 4 +delimiter ' +:close string diff --git a/sample/tokens.rb b/sample/tokens.rb new file mode 100644 index 0000000..eb8d448 --- /dev/null +++ b/sample/tokens.rb @@ -0,0 +1,3 @@ +require 'coderay' + +puts CodeRay.scan("puts 3 + 4, '3 + 4'", :ruby).tokens -- cgit v1.2.1