Commit 59b937aa32728ff999f3f0b2bf5596d650287850

Added CodeRay syntax highlighting to Wiki

Commit diff

app/helpers/wikis_helper.rb

 
11#
2# Wiki parsing is handled by the Mediacloth - http://mediacloth.rubyforge.org/
3# Use the trunk version
2# Wiki parsing is handled by the Bluecloth - http://www.deveiate.org/projects/BlueCloth
3# Bluecloth uses Markdown syntax - http://daringfireball.net/projects/markdown/syntax
4#
5# Syntax highlighting from CodeRay - http://nullcreations.net/entry/coderay-helper-for-rails
46#
57
68require 'bluecloth'
9require 'coderay'
710
811module WikisHelper
912
1515
1616 def render_wiki
1717 out = ""
18 #TODO include this in header
19 out << "<style>#{CodeRay::Encoders[:html]::CSS.new(:appcast).stylesheet}</style>"
1820 out << "<h1 class='pagetitle'>" << @wiki.title << "</h1>\n"
19
20# out << MediaCloth::wiki_to_html()
21
22 bc = BlueCloth::new(@wiki.page)
23 out << bc.to_html
24
21 bc = BlueCloth::new(parse_coderay(@wiki.page))
22 out << bc.to_html
2523 out
2624 end
25
26 def parse_coderay(text)
27 text.scan(/(<code\:([a-z].+?)>(.+?)<\/code>)/m).each do |match|
28 text.gsub!(match[0],CodeRay.scan(match[2], match[1].to_sym).div( :line_numbers => :table,:css => :class))
29 end
30 return text
31 end
2732
2833 def breadcrumb_wiki
2934 if @extrabreadcrumb then
toggle raw diff

app/views/articles/ac_new.html.erb

 
1<h1>Create a new project</h1>
1<h1>Create a new article</h1>
22
3<%= error_messages_for :project -%>
3<%= error_messages_for :article -%>
44
5<% form_for :project, :url => projects_path do |f| -%>
5<% form_for :article, :url => projects_path do |f| -%>
66 <%= render :partial => "form", :locals => {:form => f} -%>
77
88 <p class="hint">
toggle raw diff

test/fixtures/wiki_pages/_appcast_contents.txt

 
1[[appcast_credits|Appcast Project Credits]]
1[Appcast Project Credits](/projects/appcast/wikis/appcast_credits)
22
33
4[http://localhost:3001/projects/appcast/wikis/appcast_installation_guide Appcast Installation Guide]
4[Appcast Installation Guide](/projects/appcast/wikis/appcast_installation_guide)
55
66
7[http://localhost:3001/projects/appcast/wikis/gitorious-merge-notes Appcast/Gitorious Merge Notes]
8
9
10[http://localhost:3001/projects/appcast/wikis/appcast-dev-notes Appcast Developer Notes]
11
7[Appcast/Gitorious Merge Notes](/projects/appcast/wikis/gitorious-merge-notes)
128
139
10[Appcast Developer Notes](/projects/appcast/wikis/appcast-dev-notes)
toggle raw diff

test/fixtures/wiki_pages/_test_wiki_page.txt

 
1''italic''
21
2Syntax Here:
33
4'''bold'''
54
5http://daringfireball.net/projects/markdown/syntax
66
7'''''bold and italic'''''
87
98
10:Indent
9### Code Test
1110
1211
13==heading==
12<code:ruby>
1413
15===level 2===
14case variable
1615
17====level 3====
16 when x
1817
19=====level 4=====
18 when y
2019
21[[Link to another page]]
20end
2221
2322
24[[Link|different title]]
25
26
27[http://www.example.org Text]
28
29
30[[fr:Page en français]]
31
32
33[[Category:Example]]
34
35----
36
37* one
38
39** one.a
40
41** one.b
42
43* two
44
45* three
46
47
48#one
49
50#two
51
52#three
53
54
55[[Image:File.jpg|Text]]
56
57
58[[Image:File.jpg|frame|Text]]
59
60
61[[Image:File.jpg|thumb|Text]]
62
63
64[[Media:File.ogg]]
65
66
67{{Name}}
68
69
70--~~~
71
72
73--~~~~
74
75
76--~~~~~
77
78
79#REDIRECT [[Other article]]
80
23</code>
8124
8225
8326
toggle raw diff

test/fixtures/wiki_pages/_wiki_contents.txt

 
1[http://localhost:3001/wikis/wiki_contents Wiki Contents]
1[Test Wiki Page](/wikis/test_wiki_page)
22
33
4[http://localhost:3001/wikis/test_wiki_page Test Wiki Page]
4[Wiki Todo List](/wikis/wiki_todo_list)
55
66
7[http://localhost:3001/wikis/wiki_todo_list Wiki Todo List]
7[Ubuntu Crib Sheet](/wikis/ubuntu_crib_sheet)
88
99
10[http://localhost:3001/wikis/appcast_contents Appcast Contents]
10[Ruby Crib Sheet](/wikis/ruby_crib_sheet)
1111
1212
13[http://localhost:3001/wikis/appcast_credits Appcast Project Credits]
13[Rails Crib Sheet](/wikis/rails_crib_sheet)
1414
1515
16[http://localhost:3001/wikis/appcast_installation_guide Appcast Installation Guide]
16[Git Crib Sheet](/wikis/git_crib_sheet)
1717
1818
19[http://localhost:3001/wikis/ubuntu_crib_sheet Ubuntu Crib Sheet]
19### Projects
2020
2121
22[http://localhost:3001/wikis/ruby_crib_sheet Ruby Crib Sheet]
22* [Appcast](/projects/appcast/wikis/appcast_contents)
2323
2424
25[http://localhost:3001/wikis/rails_crib_sheet Rails Crib Sheet]
2625
2726
28[http://localhost:3001/wikis/git_crib_sheet Git Crib Sheet]
29
30
31[http://localhost:3001/wikis/gitorious-merge-notes Appcast/Gitorious Merge Notes]
32
33
34[http://localhost:3001/wikis/appcast-dev-notes Appcast Developer Notes]
35
3627
3728
3829
toggle raw diff

vendor/coderay.rb

 
1# = CodeRay Library
2#
3# $Id: coderay.rb 70 2006-07-11 13:42:07Z murphy $
4#
5# CodeRay is a Ruby library for syntax highlighting.
6#
7# I try to make CodeRay easy to use and intuitive, but at the same time fully featured, complete,
8# fast and efficient.
9#
10# See README.
11#
12# It consists mainly of
13# * the main engine: CodeRay (Scanners::Scanner, Tokens/TokenStream, Encoders::Encoder), PluginHost
14# * the scanners in CodeRay::Scanners
15# * the encoders in CodeRay::Encoders
16#
17# Here's a fancy graphic to light up this gray docu:
18#
19# http://rd.cYcnus.de/coderay/scheme.png
20#
21# == Documentation
22#
23# See CodeRay, Encoders, Scanners, Tokens.
24#
25# == Usage
26#
27# Remember you need RubyGems to use CodeRay. Run Ruby with -rubygems option
28# if required.
29#
30# === Highlight Ruby code in a string as html
31#
32# require 'coderay'
33# print CodeRay.scan('puts "Hello, world!"', :ruby).html
34#
35# # prints something like this:
36# puts <span class="s">&quot;Hello, world!&quot;</span>
37#
38#
39# === Highlight C code from a file in a html div
40#
41# require 'coderay'
42# print CodeRay.scan(File.read('ruby.h'), :c).div
43# print CodeRay.scan_file('ruby.h').html.div
44#
45# You can include this div in your page. The used CSS styles can be printed with
46#
47# % ruby -rcoderay -e "print CodeRay::Encoders[:html]::CSS"
48#
49# === Highlight without typing too much
50#
51# If you are one of the hasty (or lazy, or extremely curious) people, just run this file:
52#
53# % ruby -rubygems coderay.rb
54#
55# If the output was to fast for you, try
56#
57# % ruby -rubygems coderay.rb > example.html
58#
59# and look at the file it created.
60#
61# = CodeRay Module
62#
63# The CodeRay module provides convenience methods for the engine.
64#
65# * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are
66# simply lower-case symbols, like <tt>:python</tt> or <tt>:html</tt>.
67# * All methods take an optional hash as last parameter, +options+, that is send to
68# the Encoder / Scanner.
69# * Input and language are always sorted in this order: +code+, +lang+.
70# (This is in alphabetical order, if you need a mnemonic ;)
71#
72# You should be able to highlight everything you want just using these methods;
73# so there is no need to dive into CodeRay's deep class hierarchy.
74#
75# The examples in the demo directory demonstrate common cases using this interface.
76#
77# = Basic Access Ways
78#
79# Read this to get a general view what CodeRay provides.
80#
81# == Scanning
82#
83# Scanning means analysing an input string, splitting it up into Tokens.
84# Each Token knows about what type it is: string, comment, class name, etc.
85#
86# Each +lang+ (language) has its own Scanner; for example, <tt>:ruby</tt> code is
87# handled by CodeRay::Scanners::Ruby.
88#
89# CodeRay.scan:: Scan a string in a given language into Tokens.
90# This is the most common method to use.
91# CodeRay.scan_file:: Scan a file and guess the language using FileType.
92#
93# The Tokens object you get from these methods can encode itself; see Tokens.
94#
95# == Encoding
96#
97# Encoding means compiling Tokens into an output. This can be colored HTML or
98# LaTeX, a textual statistic or just the number of non-whitespace tokens.
99#
100# Each Encoder provides output in a specific +format+, so you select Encoders via
101# formats like <tt>:html</tt> or <tt>:statistic</tt>.
102#
103# CodeRay.encode:: Scan and encode a string in a given language.
104# CodeRay.encode_tokens:: Encode the given tokens.
105# CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it.
106#
107# == Streaming
108#
109# Streaming saves RAM by running Scanner and Encoder in some sort of
110# pipe mode; see TokenStream.
111#
112# CodeRay.scan_stream:: Scan in stream mode.
113#
114# == All-in-One Encoding
115#
116# CodeRay.encode:: Highlight a string with a given input and output format.
117#
118# == Instanciating
119#
120# You can use an Encoder instance to highlight multiple inputs. This way, the setup
121# for this Encoder must only be done once.
122#
123# CodeRay.encoder:: Create an Encoder instance with format and options.
124#
125# There is no CodeRay.scanner method because Scanners are bound to an input string
126# on creation; you can't re-use them with another string.
127#
128# The scanning methods provide more flexibility; we recommend to use these.
129module CodeRay
130
131 # Version: Major.Minor.Teeny[.Revision]
132 # Major: 0 for pre-release
133 # Minor: odd for beta, even for stable
134 # Teeny: development state
135 # Revision: Subversion Revision number (generated on rake)
136 Version = '0.7.2'
137
138 require 'coderay/tokens'
139 require 'coderay/scanner'
140 require 'coderay/encoder'
141 require 'coderay/duo'
142 require 'coderay/style'
143
144
145 class << self
146
147 # Scans the given +code+ (a String) with the Scanner for +lang+.
148 #
149 # This is a simple way to use CodeRay. Example:
150 # require 'coderay'
151 # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html
152 #
153 # See also demo/demo_simple.
154 def scan code, lang, options = {}, &block
155 scanner = Scanners[lang].new code, options, &block
156 scanner.tokenize
157 end
158
159 # Scans +filename+ (a path to a code file) with the Scanner for +lang+.
160 #
161 # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to
162 # determine it. If it cannot find out what type it is, it uses
163 # CodeRay::Scanners::Plaintext.
164 #
165 # Calls CodeRay.scan.
166 #
167 # Example:
168 # require 'coderay'
169 # page = CodeRay.scan_file('some_c_code.c').html
170 def scan_file filename, lang = :auto, options = {}, &block
171 file = IO.read filename
172 if lang == :auto
173 require 'coderay/helpers/filetype'
174 lang = FileType.fetch filename, :plaintext, true
175 end
176 scan file, lang, options = {}, &block
177 end
178
179 # Scan the +code+ (a string) with the scanner for +lang+.
180 #
181 # Calls scan.
182 #
183 # See CodeRay.scan.
184 def scan_stream code, lang, options = {}, &block
185 options[:stream] = true
186 scan code, lang, options, &block
187 end
188
189 # Encode a string in Streaming mode.
190 #
191 # This starts scanning +code+ with the the Scanner for +lang+
192 # while encodes the output with the Encoder for +format+.
193 # +options+ will be passed to the Encoder.
194 #
195 # See CodeRay::Encoder.encode_stream
196 def encode_stream code, lang, format, options = {}
197 encoder(format, options).encode_stream code, lang, options
198 end
199
200 # Encode a string.
201 #
202 # This scans +code+ with the the Scanner for +lang+ and then
203 # encodes it with the Encoder for +format+.
204 # +options+ will be passed to the Encoder.
205 #
206 # See CodeRay::Encoder.encode
207 def encode code, lang, format, options = {}
208 encoder(format, options).encode code, lang, options
209 end
210
211 # Highlight a string into a HTML <div>.
212 #
213 # CSS styles use classes, so you have to include a stylesheet
214 # in your output.
215 #
216 # See encode.
217 def highlight code, lang, options = { :css => :class }, format = :div
218 encode code, lang, format, options
219 end
220
221 # Encode pre-scanned Tokens.
222 # Use this together with CodeRay.scan:
223 #
224 # require 'coderay'
225 #
226 # # Highlight a short Ruby code example in a HTML span
227 # tokens = CodeRay.scan '1 + 2', :ruby
228 # puts CodeRay.encode_tokens(tokens, :span)
229 #
230 def encode_tokens tokens, format, options = {}
231 encoder(format, options).encode_tokens tokens, options
232 end
233
234 # Encodes +filename+ (a path to a code file) with the Scanner for +lang+.
235 #
236 # See CodeRay.scan_file.
237 # Notice that the second argument is the output +format+, not the input language.
238 #
239 # Example:
240 # require 'coderay'
241 # page = CodeRay.encode_file 'some_c_code.c', :html
242 def encode_file filename, format, options = {}
243 tokens = scan_file filename, :auto, get_scanner_options(options)
244 encode_tokens tokens, format, options
245 end
246
247 # Highlight a file into a HTML <div>.
248 #
249 # CSS styles use classes, so you have to include a stylesheet
250 # in your output.
251 #
252 # See encode.
253 def highlight_file filename, options = { :css => :class }, format = :div
254 encode_file filename, format, options
255 end
256
257 # Finds the Encoder class for +format+ and creates an instance, passing
258 # +options+ to it.
259 #
260 # Example:
261 # require 'coderay'
262 #
263 # stats = CodeRay.encoder(:statistic)
264 # stats.encode("puts 17 + 4\n", :ruby)
265 #
266 # puts '%d out of %d tokens have the kind :integer.' % [
267 # stats.type_stats[:integer].count,
268 # stats.real_token_count
269 # ]
270 # #-> 2 out of 4 tokens have the kind :integer.
271 def encoder format, options = {}
272 Encoders[format].new options
273 end
274
275 # Finds the Scanner class for +lang+ and creates an instance, passing
276 # +options+ to it.
277 #
278 # See Scanner.new.
279 def scanner lang, options = {}
280 Scanners[lang].new '', options
281 end
282
283 # Extract the options for the scanner from the +options+ hash.
284 #
285 # Returns an empty Hash if <tt>:scanner_options</tt> is not set.
286 #
287 # This is used if a method like CodeRay.encode has to provide options
288 # for Encoder _and_ scanner.
289 def get_scanner_options options
290 options.fetch :scanner_options, {}
291 end
292
293 end
294
295 # This Exception is raised when you try to stream with something that is not
296 # capable of streaming.
297 class NotStreamableError < Exception
298 def initialize obj
299 @obj = obj
300 end
301
302 def to_s
303 '%s is not Streamable!' % @obj.class
304 end
305 end
306
307 # A dummy module that is included by subclasses of CodeRay::Scanner an CodeRay::Encoder
308 # to show that they are able to handle streams.
309 module Streamable
310 end
311
312end
313
314# Run a test script.
315if $0 == __FILE__
316 $stderr.print 'Press key to print demo.'; gets
317 code = File.read($0)[/module CodeRay.*/m]
318 print CodeRay.scan(code, :ruby).html
319end
toggle raw diff

vendor/coderay/duo.rb

 
1module CodeRay
2
3 # = Duo
4 #
5 # $Id: scanner.rb 123 2006-03-21 14:46:34Z murphy $
6 #
7 # TODO: Doc.
8 class Duo
9
10 attr_accessor :scanner, :encoder
11
12 def initialize lang, format, options = {}
13 @scanner = CodeRay.scanner lang, CodeRay.get_scanner_options(options)
14 @encoder = CodeRay.encoder format, options
15 end
16
17 class << self
18 alias [] new
19 end
20
21 def encode code
22 @scanner.string = code
23 @encoder.encode_tokens(scanner.tokenize)
24 end
25 alias highlight encode
26
27 end
28
29end
toggle raw diff

vendor/coderay/encoder.rb

 
1module CodeRay
2
3 # This module holds the Encoder class and its subclasses.
4 # For example, the HTML encoder is named CodeRay::Encoders::HTML
5 # can be found in coderay/encoders/html.
6 #
7 # Encoders also provides methods and constants for the register
8 # mechanism and the [] method that returns the Encoder class
9 # belonging to the given format.
10 module Encoders
11 extend PluginHost
12 plugin_path File.dirname(__FILE__), 'encoders'
13
14 # = Encoder
15 #
16 # The Encoder base class. Together with Scanner and
17 # Tokens, it forms the highlighting triad.
18 #
19 # Encoder instances take a Tokens object and do something with it.
20 #
21 # The most common Encoder is surely the HTML encoder
22 # (CodeRay::Encoders::HTML). It highlights the code in a colorful
23 # html page.
24 # If you want the highlighted code in a div or a span instead,
25 # use its subclasses Div and Span.
26 class Encoder
27 extend Plugin
28 plugin_host Encoders
29
30 attr_reader :token_stream
31
32 class << self
33
34 # Returns if the Encoder can be used in streaming mode.
35 def streamable?
36 is_a? Streamable
37 end
38
39 # If FILE_EXTENSION isn't defined, this method returns the
40 # downcase class name instead.
41 def const_missing sym
42 if sym == :FILE_EXTENSION
43 sym.to_s.downcase
44 else
45 super
46 end
47 end
48
49 end
50
51 # Subclasses are to store their default options in this constant.
52 DEFAULT_OPTIONS = { :stream => false }
53
54 # The options you gave the Encoder at creating.
55 attr_accessor :options
56
57 # Creates a new Encoder.
58 # +options+ is saved and used for all encode operations, as long
59 # as you don't overwrite it there by passing additional options.
60 #
61 # Encoder objects provide three encode methods:
62 # - encode simply takes a +code+ string and a +lang+
63 # - encode_tokens expects a +tokens+ object instead
64 # - encode_stream is like encode, but uses streaming mode.
65 #
66 # Each method has an optional +options+ parameter. These are
67 # added to the options you passed at creation.
68 def initialize options = {}
69 @options = self.class::DEFAULT_OPTIONS.merge options
70 raise "I am only the basic Encoder class. I can't encode "\
71 "anything. :( Use my subclasses." if self.class == Encoder
72 end