diff --git a/lib/rdoc/generator/template/rails/_head.rhtml b/lib/rdoc/generator/template/rails/_head.rhtml index 13ce0f3e..887c8c23 100644 --- a/lib/rdoc/generator/template/rails/_head.rhtml +++ b/lib/rdoc/generator/template/rails/_head.rhtml @@ -1,10 +1,9 @@ - + - @@ -14,4 +13,4 @@ <% if ENV['HORO_CANONICAL_URL'] %> -<% end %> \ No newline at end of file +<% end %> diff --git a/lib/rdoc/generator/template/rails/resources/css/github.css b/lib/rdoc/generator/template/rails/resources/css/github.css deleted file mode 100644 index 29486761..00000000 --- a/lib/rdoc/generator/template/rails/resources/css/github.css +++ /dev/null @@ -1,124 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -pre .comment, -pre .template_comment, -pre .diff .header, -pre .javadoc { - color: #998; - font-style: italic -} - -pre .keyword, -pre .css .rule .keyword, -pre .winutils, -pre .javascript .title, -pre .lisp .title, -pre .subst { - color: #000; - font-weight: bold -} - -pre .number, -pre .hexcolor { - color: #40a070 -} - -pre .string, -pre .tag .value, -pre .phpdoc, -pre .tex .formula { - color: #d14 -} - -pre .title, -pre .id { - color: #900; - font-weight: bold -} - -pre .javascript .title, -pre .lisp .title, -pre .subst { - font-weight: normal -} - -pre .class .title, -pre .haskell .label, -pre .tex .command { - color: #458; - font-weight: bold -} - -pre .tag, -pre .tag .title, -pre .rules .property, -pre .django .tag .keyword { - color: #000080; - font-weight: normal -} - -pre .attribute, -pre .variable, -pre .instancevar, -pre .lisp .body { - color: #008080 -} - -pre .regexp { - color: #009926 -} - -pre .class, -pre .constant { - color: #458; - font-weight: bold -} - -pre .symbol, -pre .ruby .symbol .string, -pre .ruby .symbol .keyword, -pre .ruby .symbol .keymethods, -pre .lisp .keyword, -pre .tex .special, -pre .input_number { - color: #990073 -} - -pre .builtin, -pre .built_in, -pre .lisp .title { - color: #0086b3 -} - -pre .preprocessor, -pre .pi, -pre .doctype, -pre .shebang, -pre .cdata { - color: #999; - font-weight: bold -} - -pre .deletion { - background: #fdd -} - -pre .addition { - background: #dfd -} - -pre .diff .change { - background: #0086b3 -} - -pre .chunk { - color: #aaa -} - -pre .tex .formula { - opacity: 0.5; -} diff --git a/lib/rdoc/generator/template/rails/resources/css/highlight.css b/lib/rdoc/generator/template/rails/resources/css/highlight.css new file mode 100644 index 00000000..936ced4c --- /dev/null +++ b/lib/rdoc/generator/template/rails/resources/css/highlight.css @@ -0,0 +1,278 @@ +/* From https://github.com/rails/rails/blob/a3b26873ebf80da6e218cf58b2c9c6669f2d2f1e/guides/assets/stylesheets/highlight.css */ + +.highlight table td { padding: 5px; } +.highlight table pre { margin: 0; } +.highlight .cm { + color: #6c6c65; + font-style: italic; +} +.highlight .cp { + color: #6c6c6c; + font-weight: bold; +} +.highlight .c1 { + color: #6c6c65; + font-style: italic; +} +.highlight .cs { + color: #6c6c6c; + font-weight: bold; + font-style: italic; +} +.highlight .c, .highlight .ch, .highlight .cd, .highlight .cpf { + color: #6c6c65; + font-style: italic; +} +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} +.highlight .ge { + color: #000000; + font-style: italic; +} +.highlight .gr { + color: #aa0000; +} +.highlight .gh { + color: #6c6c6c; +} +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} +.highlight .go { + color: #6c6c6c; +} +.highlight .gp { + color: #555555; +} +.highlight .gs { + font-weight: bold; +} +.highlight .gu { + color: #6c6c6c; +} +.highlight .gt { + color: #aa0000; +} +.highlight .kc { + color: #000000; + font-weight: bold; +} +.highlight .kd { + color: #000000; + font-weight: bold; +} +.highlight .kn { + color: #000000; + font-weight: bold; +} +.highlight .kp { + color: #000000; + font-weight: bold; +} +.highlight .kr { + color: #000000; + font-weight: bold; +} +.highlight .kt { + color: #445588; + font-weight: bold; +} +.highlight .k, .highlight .kv { + color: #0073a6; +} +.highlight .mf { + color: #007979; +} +.highlight .mh { + color: #007979; +} +.highlight .il { + color: #007979; +} +.highlight .mi { + color: #007979; +} +.highlight .mo { + color: #007979; +} +.highlight .m, .highlight .mb, .highlight .mx { + color: #007979; +} +.highlight .sb { + color: #d51144; +} +.highlight .sc { + color: #d51144; +} +.highlight .sd { + color: #d51144; +} +.highlight .s2 { + color: #d51144; +} +.highlight .se { + color: #d51144; +} +.highlight .sh { + color: #d51144; +} +.highlight .si { + color: #d51144; +} +.highlight .sx { + color: #d51144; +} +.highlight .sr { + color: #007e26; +} +.highlight .s1 { + color: #d51144; +} +.highlight .ss { + color: #990073; +} +.highlight .s, .highlight .sa, .highlight .dl { + color: #d51144; +} +.highlight .na { + color: #007979; +} +.highlight .bp { + color: #6c6c6c; +} +.highlight .nb { + color: #0074a1; +} +.highlight .nc { + color: #445588; + font-weight: bold; +} +.highlight .no { + color: #007979; +} +.highlight .nd { + color: #3c5d5d; + font-weight: bold; +} +.highlight .ni { + color: #800080; +} +.highlight .ne { + color: #990000; + font-weight: bold; +} +.highlight .nf, .highlight .fm { + color: #990000; + font-weight: bold; +} +.highlight .nl { + color: #990000; + font-weight: bold; +} +.highlight .nn { + color: #555555; +} +.highlight .nt { + color: #000080; +} +.highlight .vc { + color: #007979; +} +.highlight .vg { + color: #007979; +} +.highlight .vi { + color: #005cc5; +} +.highlight .nv, .highlight .vm { + color: #007979; +} +.highlight .ow { + color: #000000; + font-weight: bold; +} +.highlight .o { + color: #000000; + font-weight: bold; +} +.highlight .w { + color: #6c6c6c; +} +.highlight { + background-color: transparent; +} + +@media (prefers-color-scheme: dark) { + .highlight pre { background-color: #272822; } + .highlight .hll { background-color: #272822; } + .highlight .c { color: #75715e } /* Comment */ + .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ + .highlight .k { color: #66d9ef } /* Keyword */ + .highlight .l { color: #ae81ff } /* Literal */ + .highlight .n { color: #f8f8f2 } /* Name */ + .highlight .o { color: #f92672 } /* Operator */ + .highlight .p { color: #f8f8f2 } /* Punctuation */ + .highlight .cm { color: #75715e } /* Comment.Multiline */ + .highlight .cp { color: #75715e } /* Comment.Preproc */ + .highlight .c1 { color: #75715e } /* Comment.Single */ + .highlight .cs { color: #75715e } /* Comment.Special */ + .highlight .ge { font-style: italic } /* Generic.Emph */ + .highlight .gs { font-weight: bold } /* Generic.Strong */ + .highlight .kc { color: #66d9ef } /* Keyword.Constant */ + .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ + .highlight .kn { color: #f92672 } /* Keyword.Namespace */ + .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ + .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ + .highlight .kt { color: #66d9ef } /* Keyword.Type */ + .highlight .ld { color: #e6db74 } /* Literal.Date */ + .highlight .m { color: #ae81ff } /* Literal.Number */ + .highlight .s { color: #e6db74 } /* Literal.String */ + .highlight .na { color: #a6e22e } /* Name.Attribute */ + .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ + .highlight .nc { color: #a6e22e } /* Name.Class */ + .highlight .no { color: #66d9ef } /* Name.Constant */ + .highlight .nd { color: #a6e22e } /* Name.Decorator */ + .highlight .ni { color: #f8f8f2 } /* Name.Entity */ + .highlight .ne { color: #a6e22e } /* Name.Exception */ + .highlight .nf { color: #a6e22e } /* Name.Function */ + .highlight .nl { color: #f8f8f2 } /* Name.Label */ + .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ + .highlight .nx { color: #a6e22e } /* Name.Other */ + .highlight .py { color: #f8f8f2 } /* Name.Property */ + .highlight .nt { color: #f92672 } /* Name.Tag */ + .highlight .nv { color: #f8f8f2 } /* Name.Variable */ + .highlight .ow { color: #f92672 } /* Operator.Word */ + .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ + .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ + .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ + .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ + .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ + .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ + .highlight .sc { color: #e6db74 } /* Literal.String.Char */ + .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ + .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ + .highlight .se { color: #ae81ff } /* Literal.String.Escape */ + .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ + .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ + .highlight .sx { color: #e6db74 } /* Literal.String.Other */ + .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ + .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ + .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ + .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ + .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ + .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ + .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ + .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ + + .highlight .gh { } /* Generic Heading & Diff Header */ + .highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ + .highlight .gd { color: #f92672; background-color: unset; } /* Generic.Deleted & Diff Deleted */ + .highlight .gi { color: #a6e22e; background-color: unset; } /* Generic.Inserted & Diff Inserted */ +} diff --git a/lib/rdoc/generator/template/rails/resources/css/main.css b/lib/rdoc/generator/template/rails/resources/css/main.css index 7ce5d649..af4cd24e 100644 --- a/lib/rdoc/generator/template/rails/resources/css/main.css +++ b/lib/rdoc/generator/template/rails/resources/css/main.css @@ -405,13 +405,13 @@ tt { color: #40A070; } -@keyframes highlight { +@keyframes spotlight { from { background-color: yellow; } to { background-color: white; } } -.highlight { - animation-name: highlight; +.spotlight { + animation-name: spotlight; animation-duration: 1s; } diff --git a/lib/rdoc/generator/template/rails/resources/js/.gitattributes b/lib/rdoc/generator/template/rails/resources/js/.gitattributes index 685b63e6..2976c939 100644 --- a/lib/rdoc/generator/template/rails/resources/js/.gitattributes +++ b/lib/rdoc/generator/template/rails/resources/js/.gitattributes @@ -1,3 +1,2 @@ @hotwired--turbo.js binary -highlight.pack.js binary jquery-*.min.js binary diff --git a/lib/rdoc/generator/template/rails/resources/js/highlight.pack.js b/lib/rdoc/generator/template/rails/resources/js/highlight.pack.js deleted file mode 100644 index 01b59273..00000000 --- a/lib/rdoc/generator/template/rails/resources/js/highlight.pack.js +++ /dev/null @@ -1 +0,0 @@ -var hljs=new function(){function l(o){return o.replace(/&/gm,"&").replace(/"}while(x.length||y.length){var u=t().splice(0,1)[0];v+=l(w.substr(q,u.offset-q));q=u.offset;if(u.event=="start"){v+=r(u.node);s.push(u.node)}else{if(u.event=="stop"){var p=s.length;do{p--;var o=s[p];v+=("")}while(o!=u.node);s.splice(p,1);while(p'+l(K[0])+""}else{M+=l(K[0])}O=N.lR.lastIndex;K=N.lR.exec(L)}M+=l(L.substr(O,L.length-O));return M}function J(r,L){if(L.sL&&d[L.sL]){var K=f(L.sL,r);s+=K.keyword_count;return K.value}else{return E(r,L)}}function H(L,r){var K=L.cN?'':"";if(L.rB){p+=K;L.buffer=""}else{if(L.eB){p+=l(r)+K;L.buffer=""}else{p+=K;L.buffer=r}}B.push(L);A+=L.r}function D(N,K,P){var Q=B[B.length-1];if(P){p+=J(Q.buffer+N,Q);return false}var L=y(K,Q);if(L){p+=J(Q.buffer+N,Q);H(L,K);return L.rB}var r=v(B.length-1,K);if(r){var M=Q.cN?"":"";if(Q.rE){p+=J(Q.buffer+N,Q)+M}else{if(Q.eE){p+=J(Q.buffer+N,Q)+M+l(K)}else{p+=J(Q.buffer+N+K,Q)+M}}while(r>1){M=B[B.length-2].cN?"":"";p+=M;r--;B.length--}var O=B[B.length-1];B.length--;B[B.length-1].buffer="";if(O.starts){H(O.starts,"")}return Q.rE}if(w(K,Q)){throw"Illegal"}}var G=d[I];var B=[G.dM];var A=0;var s=0;var p="";try{var u=0;G.dM.buffer="";do{var x=q(C,u);var t=D(x[0],x[1],x[2]);u+=x[0].length;if(!t){u+=x[1].length}}while(!x[2]);if(B.length>1){throw"Illegal"}return{language:I,r:A,keyword_count:s,value:p}}catch(F){if(F=="Illegal"){return{language:null,r:0,keyword_count:0,value:l(C)}}else{throw F}}}function h(){function o(t,s,u){if(t.compiled){return}if(!u){t.bR=c(s,t.b?t.b:"\\B|\\b");if(!t.e&&!t.eW){t.e="\\B|\\b"}if(t.e){t.eR=c(s,t.e)}}if(t.i){t.iR=c(s,t.i)}if(t.r==undefined){t.r=1}if(t.k){t.lR=c(s,t.l||hljs.IR,true)}for(var r in t.k){if(!t.k.hasOwnProperty(r)){continue}if(t.k[r] instanceof Object){t.kG=t.k}else{t.kG={keyword:t.k}}break}if(!t.c){t.c=[]}t.compiled=true;for(var q=0;qx.keyword_count+x.r){x=u}if(u.keyword_count+u.r>w.keyword_count+w.r){x=w;w=u}}}var s=t.className;if(!s.match(w.language)){s=s?(s+" "+w.language):w.language}var o=b(t);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=k(o,b(q),A)}if(y){w.value=w.value.replace(/^((<[^>]+>|\t)+)/gm,function(B,E,D,C){return E.replace(/\t/g,y)})}if(p){w.value=w.value.replace(/\n/g,"
")}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){var q=t.parentNode;var v=document.createElement("div");v.innerHTML="
"+w.value+"
";t=v.firstChild.firstChild;v.firstChild.cN=q.cN;q.parentNode.replaceChild(v.firstChild,q)}else{t.innerHTML=w.value}t.className=s;t.dataset={};t.dataset.result={language:w.language,kw:w.keyword_count,re:w.r};if(x&&x.language){t.dataset.second_best={language:x.language,kw:x.keyword_count,re:x.r}}}function j(){if(j.called){return}j.called=true;e();var q=document.getElementsByTagName("pre");for(var o=0;o|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.inherit=function(o,r){var q={};for(var p in o){q[p]=o[p]}if(r){for(var p in r){q[p]=r[p]}}return q}}();hljs.LANGUAGES.ruby=function(){var g="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var a="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var n={keyword:{and:1,"false":1,then:1,defined:1,module:1,"in":1,"return":1,redo:1,"if":1,BEGIN:1,retry:1,end:1,"for":1,"true":1,self:1,when:1,next:1,until:1,"do":1,begin:1,unless:1,END:1,rescue:1,nil:1,"else":1,"break":1,undef:1,not:1,"super":1,"class":1,"case":1,require:1,yield:1,alias:1,"while":1,ensure:1,elsif:1,or:1,def:1},keymethods:{__id__:1,__send__:1,abort:1,abs:1,"all?":1,allocate:1,ancestors:1,"any?":1,arity:1,assoc:1,at:1,at_exit:1,autoload:1,"autoload?":1,"between?":1,binding:1,binmode:1,"block_given?":1,call:1,callcc:1,caller:1,capitalize:1,"capitalize!":1,casecmp:1,"catch":1,ceil:1,center:1,chomp:1,"chomp!":1,chop:1,"chop!":1,chr:1,"class":1,class_eval:1,"class_variable_defined?":1,class_variables:1,clear:1,clone:1,close:1,close_read:1,close_write:1,"closed?":1,coerce:1,collect:1,"collect!":1,compact:1,"compact!":1,concat:1,"const_defined?":1,const_get:1,const_missing:1,const_set:1,constants:1,count:1,crypt:1,"default":1,default_proc:1,"delete":1,"delete!":1,delete_at:1,delete_if:1,detect:1,display:1,div:1,divmod:1,downcase:1,"downcase!":1,downto:1,dump:1,dup:1,each:1,each_byte:1,each_index:1,each_key:1,each_line:1,each_pair:1,each_value:1,each_with_index:1,"empty?":1,entries:1,eof:1,"eof?":1,"eql?":1,"equal?":1,"eval":1,exec:1,exit:1,"exit!":1,extend:1,fail:1,fcntl:1,fetch:1,fileno:1,fill:1,find:1,find_all:1,first:1,flatten:1,"flatten!":1,floor:1,flush:1,for_fd:1,foreach:1,fork:1,format:1,freeze:1,"frozen?":1,fsync:1,getc:1,gets:1,global_variables:1,grep:1,gsub:1,"gsub!":1,"has_key?":1,"has_value?":1,hash:1,hex:1,id:1,include:1,"include?":1,included_modules:1,index:1,indexes:1,indices:1,induced_from:1,inject:1,insert:1,inspect:1,instance_eval:1,instance_method:1,instance_methods:1,"instance_of?":1,"instance_variable_defined?":1,instance_variable_get:1,instance_variable_set:1,instance_variables:1,"integer?":1,intern:1,invert:1,ioctl:1,"is_a?":1,isatty:1,"iterator?":1,join:1,"key?":1,keys:1,"kind_of?":1,lambda:1,last:1,length:1,lineno:1,ljust:1,load:1,local_variables:1,loop:1,lstrip:1,"lstrip!":1,map:1,"map!":1,match:1,max:1,"member?":1,merge:1,"merge!":1,method:1,"method_defined?":1,method_missing:1,methods:1,min:1,module_eval:1,modulo:1,name:1,nesting:1,"new":1,next:1,"next!":1,"nil?":1,nitems:1,"nonzero?":1,object_id:1,oct:1,open:1,pack:1,partition:1,pid:1,pipe:1,pop:1,popen:1,pos:1,prec:1,prec_f:1,prec_i:1,print:1,printf:1,private_class_method:1,private_instance_methods:1,"private_method_defined?":1,private_methods:1,proc:1,protected_instance_methods:1,"protected_method_defined?":1,protected_methods:1,public_class_method:1,public_instance_methods:1,"public_method_defined?":1,public_methods:1,push:1,putc:1,puts:1,quo:1,raise:1,rand:1,rassoc:1,read:1,read_nonblock:1,readchar:1,readline:1,readlines:1,readpartial:1,rehash:1,reject:1,"reject!":1,remainder:1,reopen:1,replace:1,require:1,"respond_to?":1,reverse:1,"reverse!":1,reverse_each:1,rewind:1,rindex:1,rjust:1,round:1,rstrip:1,"rstrip!":1,scan:1,seek:1,select:1,send:1,set_trace_func:1,shift:1,singleton_method_added:1,singleton_methods:1,size:1,sleep:1,slice:1,"slice!":1,sort:1,"sort!":1,sort_by:1,split:1,sprintf:1,squeeze:1,"squeeze!":1,srand:1,stat:1,step:1,store:1,strip:1,"strip!":1,sub:1,"sub!":1,succ:1,"succ!":1,sum:1,superclass:1,swapcase:1,"swapcase!":1,sync:1,syscall:1,sysopen:1,sysread:1,sysseek:1,system:1,syswrite:1,taint:1,"tainted?":1,tell:1,test:1,"throw":1,times:1,to_a:1,to_ary:1,to_f:1,to_hash:1,to_i:1,to_int:1,to_io:1,to_proc:1,to_s:1,to_str:1,to_sym:1,tr:1,"tr!":1,tr_s:1,"tr_s!":1,trace_var:1,transpose:1,trap:1,truncate:1,"tty?":1,type:1,ungetc:1,uniq:1,"uniq!":1,unpack:1,unshift:1,untaint:1,untrace_var:1,upcase:1,"upcase!":1,update:1,upto:1,"value?":1,values:1,values_at:1,warn:1,write:1,write_nonblock:1,"zero?":1,zip:1}};var h={cN:"yardoctag",b:"@[A-Za-z]+"};var d={cN:"comment",b:"#",e:"$",c:[h]};var c={cN:"comment",b:"^\\=begin",e:"^\\=end",c:[h],r:10};var b={cN:"comment",b:"^__END__",e:"\\n$"};var u={cN:"subst",b:"#\\{",e:"}",l:g,k:n};var p=[hljs.BE,u];var s={cN:"string",b:"'",e:"'",c:p,r:0};var r={cN:"string",b:'"',e:'"',c:p,r:0};var q={cN:"string",b:"%[qw]?\\(",e:"\\)",c:p,r:10};var o={cN:"string",b:"%[qw]?\\[",e:"\\]",c:p,r:10};var m={cN:"string",b:"%[qw]?{",e:"}",c:p,r:10};var l={cN:"string",b:"%[qw]?<",e:">",c:p,r:10};var k={cN:"string",b:"%[qw]?/",e:"/",c:p,r:10};var j={cN:"string",b:"%[qw]?%",e:"%",c:p,r:10};var i={cN:"string",b:"%[qw]?-",e:"-",c:p,r:10};var t={cN:"string",b:"%[qw]?\\|",e:"\\|",c:p,r:10};var e={cN:"function",b:"\\bdef\\s+",e:" |$|;",l:g,k:n,c:[{cN:"title",b:a,l:g,k:n},{cN:"params",b:"\\(",e:"\\)",l:g,k:n},d,c,b]};var f={cN:"identifier",b:g,l:g,k:n,r:0};var v=[d,c,b,s,r,q,o,m,l,k,j,i,t,{cN:"class",b:"\\b(class|module)\\b",e:"$|;",k:{"class":1,module:1},c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+hljs.IR+"::)?"+hljs.IR}]},d,c,b]},e,{cN:"constant",b:"(::)?([A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:[s,r,q,o,m,l,k,j,i,t,f],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},f,{b:"("+hljs.RSR+")\\s*",c:[d,c,b,{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[hljs.BE]}],r:0}];u.c=v;e.c[1].c=v;return{dM:{l:g,k:n,c:v}}}();hljs.LANGUAGES.javascript={dM:{k:{keyword:{"in":1,"if":1,"for":1,"while":1,"finally":1,"var":1,"new":1,"function":1,"do":1,"return":1,"void":1,"else":1,"break":1,"catch":1,"instanceof":1,"with":1,"throw":1,"case":1,"default":1,"try":1,"this":1,"switch":1,"continue":1,"typeof":1,"delete":1},literal:{"true":1,"false":1,"null":1}},c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM,hljs.CNM,{b:"("+hljs.RSR+"|case|return|throw)\\s*",k:{"return":1,"throw":1,"case":1},c:[hljs.CLCM,hljs.CBLCLM,{cN:"regexp",b:"/.*?[^\\\\/]/[gim]*"}],r:0},{cN:"function",b:"\\bfunction\\b",e:"{",k:{"function":1},c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*"},{cN:"params",b:"\\(",e:"\\)",c:[hljs.ASM,hljs.QSM,hljs.CLCM,hljs.CBLCLM]}]}]}};hljs.LANGUAGES.css=function(){var a={cN:"function",b:hljs.IR+"\\(",e:"\\)",c:[{eW:true,eE:true,c:[hljs.NM,hljs.ASM,hljs.QSM]}]};return{cI:true,dM:{i:"[=/|']",c:[hljs.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@font-face",l:"[a-z-]+",k:{"font-face":1}},{cN:"at_rule",b:"@",e:"[{;]",eE:true,k:{"import":1,page:1,media:1,charset:1},c:[a,hljs.ASM,hljs.QSM,hljs.NM]},{cN:"tag",b:hljs.IR,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[hljs.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[a,hljs.NM,hljs.QSM,hljs.ASM,hljs.CBLCLM,{cN:"hexcolor",b:"\\#[0-9A-F]+"},{cN:"important",b:"!important"}]}}]}]}]}}}();hljs.LANGUAGES.xml=function(){var b="[A-Za-z0-9\\._:-]+";var a={eW:true,c:[{cN:"attribute",b:b,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,dM:{c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"",r:10},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"",k:{title:{style:1}},c:[a],starts:{cN:"css",e:"",rE:true,sL:"css"}},{cN:"tag",b:"",k:{title:{script:1}},c:[a],starts:{cN:"javascript",e:"<\/script>",rE:true,sL:"javascript"}},{cN:"vbscript",b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"",c:[{cN:"title",b:"[^ />]+"},a]}]}}}();hljs.LANGUAGES.cpp=function(){var b={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};var a={cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b.built_in,r:10};a.c=[a];return{dM:{k:b,i:" code").each do |element| + code = element.inner_text + language = guess_code_language(code) + element.inner_html = highlight_code(code, language) + element.append_class("highlight").append_class(language) + end + end + + def highlight_code(code, language) + lexer = Rouge::Lexer.find_fancy(language) + Rouge::Formatters::HTML.format(lexer.lex(code)) + end + + def guess_code_language(code) + case code + when /^\$ / + "console" + when /--[+|]--/ # ASCII-art table + "plaintext" + when /(?:GET|POST|PUT|PATCH|DELETE|HEAD) +\// # routes listing or HTTP request + "plaintext" + when /\A(?:SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP) / + "sql" + when /^(?:To|Cc|Bcc): .+@/ + "email" + when /^(?:- )?\w+:(?:\n| [#&|>])/ # YAML dictionary or list of dictionaries + if code.include?("<%") + code.include?("<<:") ? "plaintext" : "erb" + else + "yaml" + end + when /^ *<[%a-z]/i + "erb" # also highlights HTML + else + "ruby" + end + end +end diff --git a/lib/sdoc/templatable.rb b/lib/sdoc/templatable.rb index 12e52c9f..221003be 100644 --- a/lib/sdoc/templatable.rb +++ b/lib/sdoc/templatable.rb @@ -1,4 +1,5 @@ require 'erb' +require_relative "postprocessor" module SDoc::Templatable ### Load and render the erb template in the given +templatefile+ within the @@ -32,7 +33,7 @@ def include_template(template_name, local_assigns = {}) ### specified +context+ (a Binding object) and write it out to +outfile+. ### Both +templatefile+ and +outfile+ should be Pathname-like objects. def render_template( templatefile, context, outfile ) - output = eval_template(templatefile, context) + output = SDoc::Postprocessor.process(eval_template(templatefile, context)) unless $dryrun outfile.dirname.mkpath diff --git a/sdoc.gemspec b/sdoc.gemspec index 4410ef4b..2dbb7f0b 100644 --- a/sdoc.gemspec +++ b/sdoc.gemspec @@ -20,7 +20,9 @@ Gem::Specification.new do |s| s.rdoc_options = ["--charset=UTF-8"] s.extra_rdoc_files = ["README.md"] - s.add_runtime_dependency("rdoc", ">= 5.0") + s.add_runtime_dependency "rdoc", ">= 5.0" + s.add_runtime_dependency "nokogiri" + s.add_runtime_dependency "rouge" s.files = `git ls-files`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } diff --git a/spec/postprocessor_spec.rb b/spec/postprocessor_spec.rb new file mode 100644 index 00000000..c54aa03e --- /dev/null +++ b/spec/postprocessor_spec.rb @@ -0,0 +1,199 @@ +require "spec_helper" + +describe SDoc::Postprocessor do + describe "#process" do + it "highlights code blocks" do + rendered = <<~HTML +
+

Ruby:

+
1 + 1
+

ERB:

+
<%= 1 + 1 %>
+
+ HTML + + expected = <<~HTML +
+

Ruby:

+
#{SDoc::Postprocessor.highlight_code("1 + 1", "ruby")}
+

ERB:

+
#{SDoc::Postprocessor.highlight_code("<%= 1 + 1 %>", "erb")}
+
+ HTML + + _(SDoc::Postprocessor.process(rendered)).must_include expected + end + end + + describe "#highlight_code" do + it "returns highlighted HTML" do + _(SDoc::Postprocessor.highlight_code("1 + 1", "ruby")). + must_equal %{1 + 1} + + _(SDoc::Postprocessor.highlight_code("$ rails s", "console")). + must_equal %{$ rails s} + end + end + + describe "#guess_code_language" do + it "guesses console for CLI session" do + _(SDoc::Postprocessor.guess_code_language(<<~CLI)).must_equal "console" + $ rails server + Booting + CLI + end + + it "guesses plaintext for ASCII-art table" do + _(SDoc::Postprocessor.guess_code_language(<<~TABLE)).must_equal "plaintext" + a | b + --+-- + 1 | 2 + TABLE + + _(SDoc::Postprocessor.guess_code_language(<<~TABLE)).must_equal "plaintext" + a | b + --|-- + 1 | 2 + TABLE + end + + it "guesses plaintext for routes listing" do + _(SDoc::Postprocessor.guess_code_language(<<~ROUTES)).must_equal "plaintext" + post GET /posts/:id(.:format) posts#show + DELETE /posts/:id(.:format) posts#destroy + ROUTES + + _(SDoc::Postprocessor.guess_code_language(<<~ROUTES)).must_equal "plaintext" + DELETE /posts/:id + ROUTES + end + + it "guesses sql for SQL query" do + _(SDoc::Postprocessor.guess_code_language(<<~SQL)).must_equal "sql" + SELECT * FROM posts + SQL + + _(SDoc::Postprocessor.guess_code_language(<<~SQL)).must_equal "sql" + DELETE FROM posts WHERE id = 1 + SQL + end + + it "guesses email for email message" do + _(SDoc::Postprocessor.guess_code_language(<<~EMAIL)).must_equal "email" + To: recipient@example.com + EMAIL + + _(SDoc::Postprocessor.guess_code_language(<<~EMAIL)).must_equal "email" + Cc: recipient@example.com + EMAIL + + _(SDoc::Postprocessor.guess_code_language(<<~EMAIL)).must_equal "email" + Bcc: recipient@example.com + EMAIL + end + + it "guesses yaml for YAML" do + _(SDoc::Postprocessor.guess_code_language(<<~YAML)).must_equal "yaml" + foo: + bar: 1 + YAML + + _(SDoc::Postprocessor.guess_code_language(<<~YAML)).must_equal "yaml" + foo: # comment + bar: 1 + YAML + + _(SDoc::Postprocessor.guess_code_language(<<~YAML)).must_equal "yaml" + base: &base + baz: 1 + + foo: + <<: *base + bar: 2 + YAML + + _(SDoc::Postprocessor.guess_code_language(<<~YAML)).must_equal "yaml" + foo: | + bar + YAML + + _(SDoc::Postprocessor.guess_code_language(<<~YAML)).must_equal "yaml" + foo: > + bar + YAML + end + + it "guesses erb for YAML that includes ERB" do + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "erb" + foo: + bar: <%= 1 + 1 %> + ERB + end + + it "guesses plaintext for YAML that includes ERB and HTML-incompatible markup" do + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "plaintext" + base: &base + baz: 1 + + foo: + <<: *base + bar: <%= 1 + 1 %> + ERB + end + + it "guesses erb for ERB" do + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "erb" + <%= 1 + 1 %> + ERB + + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "erb" + <% x = 1 + 1 %> + ERB + + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "erb" + <%- x = 1 + 1 -%> + ERB + end + + it "guesses erb for HTML" do + _(SDoc::Postprocessor.guess_code_language(<<~HTML)).must_equal "erb" +

1 + 1 = 2

+ HTML + end + + it "guesses erb for HTML that includes ERB" do + _(SDoc::Postprocessor.guess_code_language(<<~ERB)).must_equal "erb" +

1 + 1 = <%= 1 + 1 %>

+ ERB + end + + it "guesses ruby for Ruby code" do + _(SDoc::Postprocessor.guess_code_language(<<~RUBY)).must_equal "ruby" + 1 + 1 + RUBY + end + + it "guesses ruby for Ruby return value comment" do + _(SDoc::Postprocessor.guess_code_language(<<~RUBY)).must_equal "ruby" + Object.new # => # + RUBY + + _(SDoc::Postprocessor.guess_code_language(<<~RUBY)).must_equal "ruby" + image_tag("image.png") + # => + RUBY + end + + it "guesses ruby for Ruby code that includes an ERB string" do + _(SDoc::Postprocessor.guess_code_language(<<~RUBY)).must_equal "ruby" + ApplicationController.render inline: "<%= 1 + 1 %>" + RUBY + end + + it "guesses ruby by default" do + _(SDoc::Postprocessor.guess_code_language(<<~RUBY)).must_equal "ruby" + f x + RUBY + end + end +end