| 
									
										
										
										
											2019-03-16 09:37:35 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2019-03-15 01:32:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2020-03-03 00:24:10 +00:00
										 |  |  | # Copyright (C) 2006-2020  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Redmine | 
					
						
							|  |  |  |   module SyntaxHighlighting | 
					
						
							|  |  |  |     class << self | 
					
						
							|  |  |  |       attr_reader :highlighter | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |       def highlighter=(name) | 
					
						
							|  |  |  |         if name.is_a?(Module) | 
					
						
							|  |  |  |           @highlighter = name | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           @highlighter = const_get(name) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2013-12-23 12:39:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def highlight_by_filename(text, filename) | 
					
						
							|  |  |  |         highlighter.highlight_by_filename(text, filename) | 
					
						
							|  |  |  |       rescue | 
					
						
							|  |  |  |         ERB::Util.h(text) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def highlight_by_language(text, language) | 
					
						
							|  |  |  |         highlighter.highlight_by_language(text, language) | 
					
						
							|  |  |  |       rescue | 
					
						
							|  |  |  |         ERB::Util.h(text) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-04-06 16:37:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def language_supported?(language) | 
					
						
							|  |  |  |         if highlighter.respond_to? :language_supported? | 
					
						
							|  |  |  |           highlighter.language_supported? language | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           true | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       rescue | 
					
						
							|  |  |  |         false | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-05-04 09:32:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       def filename_supported?(filename) | 
					
						
							|  |  |  |         if highlighter.respond_to? :filename_supported? | 
					
						
							|  |  |  |           highlighter.filename_supported? filename | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |     module Rouge | 
					
						
							|  |  |  |       require 'rouge' | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |       # Customized formatter based on Rouge::Formatters::HTMLLinewise | 
					
						
							|  |  |  |       # Syntax highlighting is completed within each line. | 
					
						
							|  |  |  |       class CustomHTMLLinewise < ::Rouge::Formatter | 
					
						
							|  |  |  |         def initialize(formatter) | 
					
						
							|  |  |  |           @formatter = formatter | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2017-06-06 21:55:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |         def stream(tokens, &b) | 
					
						
							|  |  |  |           token_lines(tokens) do |line| | 
					
						
							|  |  |  |             line.each do |tok, val| | 
					
						
							|  |  |  |               yield @formatter.span(tok, val) | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             yield "\n" | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-06-06 21:55:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |       class << self | 
					
						
							|  |  |  |         # Highlights +text+ as the content of +filename+ | 
					
						
							|  |  |  |         # Should not return line numbers nor outer pre tag | 
					
						
							|  |  |  |         def highlight_by_filename(text, filename) | 
					
						
							| 
									
										
										
										
											2019-02-03 22:34:08 +00:00
										 |  |  |           # TODO: Delete the following workaround for #30434 and | 
					
						
							|  |  |  |           # test_syntax_highlight_should_normalize_line_endings in | 
					
						
							|  |  |  |           # application_helper_test.rb when Rouge is improved to | 
					
						
							|  |  |  |           # handle CRLF properly. | 
					
						
							|  |  |  |           # See also: https://github.com/jneen/rouge/pull/1078 | 
					
						
							|  |  |  |           text = text.gsub(/\r\n?/, "\n") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-03 07:31:46 +00:00
										 |  |  |           lexer =::Rouge::Lexer.guess(:source => text, :filename => filename) | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |           formatter = ::Rouge::Formatters::HTML.new | 
					
						
							|  |  |  |           ::Rouge.highlight(text, lexer, CustomHTMLLinewise.new(formatter)) | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |         # Highlights +text+ using +language+ syntax | 
					
						
							|  |  |  |         # Should not return outer pre tag | 
					
						
							|  |  |  |         def highlight_by_language(text, language) | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |           lexer = | 
					
						
							|  |  |  |             find_lexer(language.to_s.downcase) || ::Rouge::Lexers::PlainText | 
					
						
							|  |  |  |           ::Rouge.highlight(text, lexer, ::Rouge::Formatters::HTML) | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2017-04-06 16:37:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def language_supported?(language) | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |           find_lexer(language.to_s.downcase) ? true : false | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2019-05-04 09:32:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def filename_supported?(filename) | 
					
						
							|  |  |  |           !::Rouge::Lexer.guesses(:filename => filename).empty? | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |         private | 
					
						
							| 
									
										
										
										
											2019-11-09 17:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |         # Alias names used by CodeRay and not supported by Rouge | 
					
						
							|  |  |  |         LANG_ALIASES = { | 
					
						
							|  |  |  |           'delphi' => 'pascal', | 
					
						
							|  |  |  |           'cplusplus' => 'cpp', | 
					
						
							|  |  |  |           'ecmascript' => 'javascript', | 
					
						
							|  |  |  |           'ecma_script' => 'javascript', | 
					
						
							|  |  |  |           'java_script' => 'javascript', | 
					
						
							|  |  |  |           'xhtml' => 'html' | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def find_lexer(language) | 
					
						
							|  |  |  |           ::Rouge::Lexer.find(language) || | 
					
						
							|  |  |  |             ::Rouge::Lexer.find(LANG_ALIASES[language]) | 
					
						
							| 
									
										
										
										
											2017-04-06 16:37:18 +00:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 06:57:40 +00:00
										 |  |  |   SyntaxHighlighting.highlighter = 'Rouge' | 
					
						
							| 
									
										
										
										
											2010-03-14 12:57:08 +00:00
										 |  |  | end |