api_docs_engine 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/assets/javascripts/docs.js.coffee +42 -0
- data/app/assets/javascripts/highlight.js +1 -0
- data/app/assets/stylesheets/docs.css.scss +127 -0
- data/app/assets/stylesheets/highlight/styles/github.css +129 -0
- data/app/controllers/concerns/docs/manage_resource.rb +98 -0
- data/app/controllers/docs/application_controller.rb +24 -0
- data/app/controllers/docs/markdown_controller.rb +8 -0
- data/app/controllers/docs/missing_docs_controller.rb +7 -0
- data/app/controllers/docs/page_categories_controller.rb +27 -0
- data/app/controllers/docs/pages_controller.rb +56 -0
- data/app/helpers/docs/application_helper.rb +47 -0
- data/app/models/docs/missing_collection.rb +11 -0
- data/app/models/docs/page.rb +64 -0
- data/app/models/docs/page_category.rb +30 -0
- data/app/models/docs/routes_collection.rb +71 -0
- data/app/views/docs/application/edit.html.slim +2 -0
- data/app/views/docs/application/new.html.slim +2 -0
- data/app/views/docs/layouts/docs.html.slim +24 -0
- data/app/views/docs/markdown/create.json.erb +3 -0
- data/app/views/docs/missing_docs/index.html.slim +9 -0
- data/app/views/docs/page_categories/_form.html.slim +19 -0
- data/app/views/docs/pages/_form.html.slim +35 -0
- data/app/views/docs/pages/_page.html.slim +24 -0
- data/app/views/docs/pages/index.html.slim +34 -0
- data/config/initializers/formtastic.rb +1 -0
- data/config/routes.rb +5 -0
- data/lib/api_docs_engine/docs.rb +50 -0
- data/lib/api_docs_engine.rb +2 -0
- data/lib/bootstrap/active_link_to.rb +135 -0
- data/lib/bootstrap/markdown_renderer.rb +10 -0
- data/lib/docs/core_ext.rb +39 -0
- data/lib/docs/engine.rb +9 -0
- data/lib/generators/active_record/api_docs_engine_generator.rb +16 -0
- data/lib/generators/active_record/templates/migration.rb +27 -0
- data/lib/generators/api_docs_engine/api_docs_engine_generator.rb +12 -0
- data/lib/generators/api_docs_engine/install_generator.rb +16 -0
- data/lib/generators/api_docs_engine/orm_helpers.rb +10 -0
- data/lib/generators/templates/api_docs_engine.rb +11 -0
- metadata +284 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 704b4383489a584b6492682992016927e54e649e
|
4
|
+
data.tar.gz: 3d70c586a9bcf1976df23f9edb083e84a429c98b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 85efb2b2da337b4b4b01760dae68c6d5843b9aa8de3e1d3c85e42b58ccf587e626e6ae82f5d895f3ec1afc12465f34596b00e62ade08da3e22a2b52292c4be09
|
7
|
+
data.tar.gz: 74ff7960fed4ecc13031a4cbe3b4d78a0c666be8bc74ed358c8ed02da029ab1dfe40e42a4cff08f3eba51e777fe576e441e35f1820369137893f696e24991bb9
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#= require jquery
|
2
|
+
#= require jquery_ujs
|
3
|
+
#= require bootstrap
|
4
|
+
#= require bootstrap/affix
|
5
|
+
#= require turbolinks
|
6
|
+
#= require highlight
|
7
|
+
|
8
|
+
unless $.fn.doOnce
|
9
|
+
$.fn.doOnce = (fn) -> fn.call(@) if @length > 0
|
10
|
+
|
11
|
+
$.fn.add_edit_link = (classnames) ->
|
12
|
+
@toggleClass 'col-sm-10', on
|
13
|
+
@after -> """<a href="#{@dataset.editPath}" class="col-sm-2 #{classnames}"><i class="fa fa-edit"></i></a>"""
|
14
|
+
|
15
|
+
$.fn.highlight = (sel) ->
|
16
|
+
@find(sel).each (i, block) -> hljs.highlightBlock(block)
|
17
|
+
|
18
|
+
process_request = (source, callback) ->
|
19
|
+
$.post '/docs/markdown.json', source: source, callback, 'json'
|
20
|
+
|
21
|
+
$.fn.markdownize = (target) ->
|
22
|
+
@on 'change', -> process_request @value, (json) ->
|
23
|
+
($ target).doOnce ->
|
24
|
+
@html json.result
|
25
|
+
@highlight 'pre code, pre samp'
|
26
|
+
|
27
|
+
jQuery ->
|
28
|
+
page_loaded = ->
|
29
|
+
($ document).highlight('pre code, pre samp')
|
30
|
+
|
31
|
+
($ "#left-sidebar [data-edit-path]").each ->
|
32
|
+
($ @).add_edit_link "sidebar-edit-link text-muted"
|
33
|
+
|
34
|
+
($ '.preview-markdown').each ->
|
35
|
+
($ @dataset.source).markdownize(this).change()
|
36
|
+
|
37
|
+
($ '.navbar-spyscroll').doOnce ->
|
38
|
+
($ 'body').scrollspy target: '.navbar-spyscroll'
|
39
|
+
@affix()
|
40
|
+
|
41
|
+
($ document).on 'page:load', page_loaded
|
42
|
+
do page_loaded
|
@@ -0,0 +1 @@
|
|
1
|
+
var hljs=new function(){function j(v){return v.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">")}function t(v){return v.nodeName.toLowerCase()}function h(w,x){var v=w&&w.exec(x);return v&&v.index==0}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^lang(uage)?-/,"")});return v.filter(function(x){return i(x)||/no(-?)highlight/.test(x)})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);if(!t(A).match(/br|hr|img|input/)){v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset<y[0].offset)?w:y}return y[0].event=="start"?w:y}function A(H){function G(I){return" "+I.nodeName+'="'+j(I.value)+'"'}F+="<"+t(H)+Array.prototype.map.call(H.attributes,G).join("")+">"}function E(G){F+="</"+t(G)+">"}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=j(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+j(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};var E=function(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})};if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b="\\b("+D.bK.split(" ").join("|")+")\\b"}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?("+F.b+")\\.?":F.b}).concat([D.tE,D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}}}x(y)}function c(T,L,J,R){function v(V,W){for(var U=0;U<W.c.length;U++){if(h(W.c[U].bR,V)){return W.c[U]}}}function z(V,U){if(h(V.eR,U)){return V}if(V.eW){return z(V.parent,U)}}function A(U,V){return !J&&h(V.iR,U)}function E(W,U){var V=M.cI?U[0].toLowerCase():U[0];return W.k.hasOwnProperty(V)&&W.k[V]}function w(aa,Y,X,W){var U=W?"":b.classPrefix,V='<span class="'+U,Z=X?"":"</span>";V+=aa+'">';return V+Y+Z}function N(){if(!I.k){return j(C)}var U="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(C);while(V){U+=j(C.substr(X,V.index-X));var W=E(I,V);if(W){H+=W[1];U+=w(W[0],j(V[0]))}else{U+=j(V[0])}X=I.lR.lastIndex;V=I.lR.exec(C)}return U+j(C.substr(X))}function F(){if(I.sL&&!f[I.sL]){return j(C)}var U=I.sL?c(I.sL,C,true,S):e(C);if(I.r>0){H+=U.r}if(I.subLanguageMode=="continuous"){S=U.top}return w(U.language,U.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(W,V){var U=W.cN?w(W.cN,"",true):"";if(W.rB){D+=U;C=""}else{if(W.eB){D+=j(V)+U;C=""}else{D+=U;C=V}}I=Object.create(W,{parent:{value:I}})}function G(U,Y){C+=U;if(Y===undefined){D+=Q();return 0}var W=v(Y,I);if(W){D+=Q();P(W,Y);return W.rB?0:Y.length}var X=z(I,Y);if(X){var V=I;if(!(V.rE||V.eE)){C+=Y}D+=Q();do{if(I.cN){D+="</span>"}H+=I.r;I=I.parent}while(I!=X.parent);if(V.eE){D+=j(Y)}C="";if(X.starts){P(X.starts,"")}return V.rE?0:Y.length}if(A(Y,I)){throw new Error('Illegal lexeme "'+Y+'" for mode "'+(I.cN||"<unnamed>")+'"')}C+=Y;return Y.length||1}var M=i(T);if(!M){throw new Error('Unknown language: "'+T+'"')}m(M);var I=R||M;var S;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,"",true)+D}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+="</span>"}}return{r:H,value:D,language:T,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:j(L)}}else{throw O}}}function e(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:j(y)};var w=v;x.forEach(function(z){if(!i(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function g(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"<br>")}return v}function p(A){var B=r(A);if(/no(-?)highlight/.test(B)){return}var y;if(b.useBR){y=document.createElementNS("http://www.w3.org/1999/xhtml","div");y.innerHTML=A.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")}else{y=A}var z=y.textContent;var v=B?c(B,z,true):e(z);var x=u(y);if(x.length){var w=document.createElementNS("http://www.w3.org/1999/xhtml","div");w.innerHTML=v.value;v.value=q(x,u(w),z)}v.value=g(v.value);A.innerHTML=v.value;A.className+=" hljs "+(!B&&v.language||"");A.result={language:v.language,re:v.r};if(v.second_best){A.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function d(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function k(){return Object.keys(f)}function i(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=e;this.fixMarkup=g;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=d;this.listLanguages=k;this.getLanguage=i;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/};this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]};this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]};this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0};this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("json",function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}});
|
@@ -0,0 +1,127 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*/
|
13
|
+
|
14
|
+
@import "bootstrap";
|
15
|
+
@import "formtastic-bootstrap";
|
16
|
+
@import "font-awesome";
|
17
|
+
@import "highlight/styles/github";
|
18
|
+
|
19
|
+
.sidebar { display: none; }
|
20
|
+
|
21
|
+
@media (min-width: 768px) {
|
22
|
+
.sidebar {
|
23
|
+
position: fixed;
|
24
|
+
top: 0;
|
25
|
+
bottom: 0;
|
26
|
+
left: 0;
|
27
|
+
z-index: 1000;
|
28
|
+
display: block;
|
29
|
+
padding: 20px;
|
30
|
+
overflow-x: hidden;
|
31
|
+
overflow-y: auto;
|
32
|
+
background-color: #f5f5f5;
|
33
|
+
border-right: 1px solid $gray-lighter;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
// Sidebar navigation
|
38
|
+
.nav-sidebar {
|
39
|
+
margin-right: -21px;
|
40
|
+
margin-bottom: 20px;
|
41
|
+
margin-left: -20px;
|
42
|
+
> li > a {
|
43
|
+
padding-right: 20px;
|
44
|
+
padding-left: 20px;
|
45
|
+
}
|
46
|
+
> li.active > a,
|
47
|
+
> li.active:hover > a {
|
48
|
+
color: $component-active-color;
|
49
|
+
background-color: $component-active-bg;
|
50
|
+
}
|
51
|
+
> li > a.sidebar-edit-link > i {
|
52
|
+
visibility: hidden;
|
53
|
+
}
|
54
|
+
> li:hover > a.sidebar-edit-link > i {
|
55
|
+
visibility: visible;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
// Main content
|
60
|
+
.main { padding: 20px; }
|
61
|
+
|
62
|
+
@media (min-width: 768px) {
|
63
|
+
.main {
|
64
|
+
padding-right: 40px;
|
65
|
+
padding-left: 40px;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
.main .page-header { margin-top: 0; }
|
70
|
+
|
71
|
+
.table-data {
|
72
|
+
td.col-actions ul.list-inline {
|
73
|
+
margin-bottom: 0;
|
74
|
+
}
|
75
|
+
.table-condensed {
|
76
|
+
font-size: 0.80em;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
textarea.form-control {
|
81
|
+
font: 13px $font-family-monospace;
|
82
|
+
resize: vertical;
|
83
|
+
|
84
|
+
}
|
85
|
+
|
86
|
+
pre samp {
|
87
|
+
white-space: pre-wrap;
|
88
|
+
font-size: inherit;
|
89
|
+
color: inherit;
|
90
|
+
}
|
91
|
+
|
92
|
+
ul.nav.nav-right-spy {
|
93
|
+
font-size: 13px;
|
94
|
+
margin-bottom: 20px;
|
95
|
+
|
96
|
+
> li > a {
|
97
|
+
padding-top: 5px;
|
98
|
+
padding-bottom: 5px;
|
99
|
+
color: $gray-light;
|
100
|
+
}
|
101
|
+
> li.active > a,
|
102
|
+
> li > a:hover {
|
103
|
+
border-left: 2px solid #A13D26;
|
104
|
+
margin-left: -2px;
|
105
|
+
color: #A13D26;
|
106
|
+
background: transparent;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
.panel-navbar {
|
111
|
+
min-height: 40px;
|
112
|
+
margin-bottom: 0px;
|
113
|
+
.navbar-nav > li > a {
|
114
|
+
padding-top: 10px;
|
115
|
+
padding-bottom: 10px;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
.actions {
|
120
|
+
margin-top: 100px;
|
121
|
+
.action {
|
122
|
+
margin-top: 50px;
|
123
|
+
margin-bottom: 50px;
|
124
|
+
border-top: 1px solid $gray-lighter;
|
125
|
+
> h3 { margin-top: 10px; }
|
126
|
+
}
|
127
|
+
}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
/*
|
2
|
+
|
3
|
+
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
4
|
+
|
5
|
+
*/
|
6
|
+
pre {
|
7
|
+
background-color: #f8f8f8;
|
8
|
+
}
|
9
|
+
|
10
|
+
.hljs {
|
11
|
+
display: block;
|
12
|
+
overflow-x: auto;
|
13
|
+
padding: 0.5em;
|
14
|
+
color: #333;
|
15
|
+
-webkit-text-size-adjust: none;
|
16
|
+
}
|
17
|
+
|
18
|
+
.hljs-comment,
|
19
|
+
.hljs-template_comment,
|
20
|
+
.diff .hljs-header,
|
21
|
+
.hljs-javadoc {
|
22
|
+
color: #998;
|
23
|
+
font-style: italic;
|
24
|
+
}
|
25
|
+
|
26
|
+
.hljs-keyword,
|
27
|
+
.css .rule .hljs-keyword,
|
28
|
+
.hljs-winutils,
|
29
|
+
.javascript .hljs-title,
|
30
|
+
.nginx .hljs-title,
|
31
|
+
.hljs-subst,
|
32
|
+
.hljs-request,
|
33
|
+
.hljs-status {
|
34
|
+
color: #333;
|
35
|
+
font-weight: bold;
|
36
|
+
}
|
37
|
+
|
38
|
+
.hljs-number,
|
39
|
+
.hljs-hexcolor,
|
40
|
+
.ruby .hljs-constant {
|
41
|
+
color: #008080;
|
42
|
+
}
|
43
|
+
|
44
|
+
.hljs-string,
|
45
|
+
.hljs-tag .hljs-value,
|
46
|
+
.hljs-phpdoc,
|
47
|
+
.hljs-dartdoc,
|
48
|
+
.tex .hljs-formula {
|
49
|
+
color: #d14;
|
50
|
+
}
|
51
|
+
|
52
|
+
.hljs-title,
|
53
|
+
.hljs-id,
|
54
|
+
.scss .hljs-preprocessor {
|
55
|
+
color: #900;
|
56
|
+
font-weight: bold;
|
57
|
+
}
|
58
|
+
|
59
|
+
.javascript .hljs-title,
|
60
|
+
.hljs-list .hljs-keyword,
|
61
|
+
.hljs-subst {
|
62
|
+
font-weight: normal;
|
63
|
+
}
|
64
|
+
|
65
|
+
.hljs-class .hljs-title,
|
66
|
+
.hljs-type,
|
67
|
+
.vhdl .hljs-literal,
|
68
|
+
.tex .hljs-command {
|
69
|
+
color: #458;
|
70
|
+
font-weight: bold;
|
71
|
+
}
|
72
|
+
|
73
|
+
.hljs-tag,
|
74
|
+
.hljs-tag .hljs-title,
|
75
|
+
.hljs-rules .hljs-property,
|
76
|
+
.django .hljs-tag .hljs-keyword {
|
77
|
+
color: #000080;
|
78
|
+
font-weight: normal;
|
79
|
+
}
|
80
|
+
|
81
|
+
.hljs-attribute,
|
82
|
+
.hljs-variable,
|
83
|
+
.lisp .hljs-body {
|
84
|
+
color: #008080;
|
85
|
+
}
|
86
|
+
|
87
|
+
.hljs-regexp {
|
88
|
+
color: #009926;
|
89
|
+
}
|
90
|
+
|
91
|
+
.hljs-symbol,
|
92
|
+
.ruby .hljs-symbol .hljs-string,
|
93
|
+
.lisp .hljs-keyword,
|
94
|
+
.clojure .hljs-keyword,
|
95
|
+
.scheme .hljs-keyword,
|
96
|
+
.tex .hljs-special,
|
97
|
+
.hljs-prompt {
|
98
|
+
color: #990073;
|
99
|
+
}
|
100
|
+
|
101
|
+
.hljs-built_in {
|
102
|
+
color: #0086b3;
|
103
|
+
}
|
104
|
+
|
105
|
+
.hljs-preprocessor,
|
106
|
+
.hljs-pragma,
|
107
|
+
.hljs-pi,
|
108
|
+
.hljs-doctype,
|
109
|
+
.hljs-shebang,
|
110
|
+
.hljs-cdata {
|
111
|
+
color: #999;
|
112
|
+
font-weight: bold;
|
113
|
+
}
|
114
|
+
|
115
|
+
.hljs-deletion {
|
116
|
+
background: #fdd;
|
117
|
+
}
|
118
|
+
|
119
|
+
.hljs-addition {
|
120
|
+
background: #dfd;
|
121
|
+
}
|
122
|
+
|
123
|
+
.diff .hljs-change {
|
124
|
+
background: #0086b3;
|
125
|
+
}
|
126
|
+
|
127
|
+
.hljs-chunk {
|
128
|
+
color: #aaa;
|
129
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
|
3
|
+
module Docs
|
4
|
+
module ManageResource
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
def collection
|
9
|
+
instance_variable_get collection_var_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def resource
|
13
|
+
instance_variable_get resource_var_name
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :single_resource, :resource
|
17
|
+
helper_method :collection, :resource, :single_resource
|
18
|
+
end
|
19
|
+
|
20
|
+
def show
|
21
|
+
end
|
22
|
+
|
23
|
+
def index
|
24
|
+
set_collection resource_class.all
|
25
|
+
end
|
26
|
+
|
27
|
+
def new
|
28
|
+
set_resource resource_class.new(resource_params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def edit
|
32
|
+
resource.attributes = resource_params
|
33
|
+
end
|
34
|
+
|
35
|
+
def create(&block)
|
36
|
+
set_resource resource_class.new(permitted_params)
|
37
|
+
create!(&block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def update(&block)
|
41
|
+
update!(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy(&block)
|
45
|
+
destroy!(&block)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def create!(&block)
|
50
|
+
if resource.save
|
51
|
+
yield_or_redirect_to_root! &block
|
52
|
+
else
|
53
|
+
render "new"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def update!(&block)
|
58
|
+
if resource.update_attributes(permitted_params)
|
59
|
+
yield_or_redirect_to_root! &block
|
60
|
+
else
|
61
|
+
render "edit"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def destroy!(&block)
|
66
|
+
resource.destroy
|
67
|
+
yield_or_redirect_to_root! &block
|
68
|
+
end
|
69
|
+
|
70
|
+
def yield_or_redirect_to_root!
|
71
|
+
if block_given?
|
72
|
+
yield
|
73
|
+
else
|
74
|
+
redirect_to root_path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_resource(new_resource)
|
79
|
+
instance_variable_set resource_var_name, new_resource
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_collection(new_collection)
|
83
|
+
instance_variable_set collection_var_name, new_resource
|
84
|
+
end
|
85
|
+
|
86
|
+
def resource_var_name
|
87
|
+
@resource_var_name ||= "@#{controller_name.singularize}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def collection_var_name
|
91
|
+
@collection_var_name ||= "@#{controller_name.pluralize}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def resource_class
|
95
|
+
controller_name.pluralize.classify.constantize
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Docs
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
if Docs.auth.is_a? Proc
|
4
|
+
Docs.auth.call(self)
|
5
|
+
end
|
6
|
+
|
7
|
+
protect_from_forgery
|
8
|
+
layout 'docs/layouts/docs'
|
9
|
+
before_filter :set_locale
|
10
|
+
|
11
|
+
private
|
12
|
+
def set_locale
|
13
|
+
I18n.locale = I18n.default_locale
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_page
|
17
|
+
@page = Page.find params[:id]
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_page_category
|
21
|
+
@page_category = PageCategory.friendly.find(params[:page_category_id].presence || params[:id])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Docs
|
2
|
+
class PageCategoriesController < ::Docs::ApplicationController
|
3
|
+
before_action :load_page_category, except: %i[index new create]
|
4
|
+
include ManageResource
|
5
|
+
|
6
|
+
def create
|
7
|
+
super { redirect_to [resource, :pages] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def update
|
11
|
+
super { redirect_to [resource, :pages] }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def permitted_params
|
16
|
+
params.require(:page_category).permit(:slug, :title, :body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def resource_params
|
20
|
+
params.fetch :page_category, {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def resource_class
|
24
|
+
PageCategory
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Docs
|
2
|
+
class PagesController < ::Docs::ApplicationController
|
3
|
+
before_action :load_page_category, only: %i[index]
|
4
|
+
before_action :load_page, only: %i[show edit update destroy]
|
5
|
+
include ManageResource
|
6
|
+
|
7
|
+
def index
|
8
|
+
@pages = @page_category.pages.order("via ASC, path ASC").sort_by &:weight
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@page = build_resource
|
13
|
+
@page.set_body_with_default_table
|
14
|
+
end
|
15
|
+
|
16
|
+
def edit
|
17
|
+
super
|
18
|
+
resource.set_body_with_default_table
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
@page = build_resource
|
23
|
+
create! { redirect_to page_category_pages_path(@page.page_category) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
super { redirect_to page_category_pages_path(@page.page_category) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
super { redirect_to page_category_pages_path(@page.page_category) }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def build_resource
|
36
|
+
if params[:page_category_id].present?
|
37
|
+
load_page_category
|
38
|
+
@page_category.pages.build resource_params
|
39
|
+
else
|
40
|
+
Page.new resource_params
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def permitted_params
|
45
|
+
params.require(:page).permit(:path, :via, :title, :body, :example, :reqs, :page_category_slug, :weight)
|
46
|
+
end
|
47
|
+
|
48
|
+
def resource_params
|
49
|
+
params.fetch :page, {}
|
50
|
+
end
|
51
|
+
|
52
|
+
def resource_class
|
53
|
+
Page
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "bootstrap/active_link_to"
|
2
|
+
require "bootstrap/markdown_renderer"
|
3
|
+
|
4
|
+
module Docs
|
5
|
+
module ApplicationHelper
|
6
|
+
include Bootstrap::ActiveLinkTo
|
7
|
+
include FontAwesome::Rails::IconHelper
|
8
|
+
|
9
|
+
def li_active_to(*args, &block)
|
10
|
+
options = args.extract_options!
|
11
|
+
if block_given?
|
12
|
+
buffer = capture(&block)
|
13
|
+
if options.has_key?(:dropdown)
|
14
|
+
options[:dropdown_html] = buffer
|
15
|
+
else
|
16
|
+
args.unshift(buffer)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
options[:wrap_tag] = :li
|
20
|
+
active_link_to *args, options
|
21
|
+
end
|
22
|
+
|
23
|
+
def li_link_to(*args, &block)
|
24
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
25
|
+
url = args.pop
|
26
|
+
title = args.pop unless block_given?
|
27
|
+
|
28
|
+
link_options = options.delete(:link).presence || {}
|
29
|
+
li_options = { class: (%w(active) if current_page?(url)) }.smart_merge!(options.delete(:li).presence || {})
|
30
|
+
|
31
|
+
link = block_given? ? link_to(url, link_options, &block) : link_to(title, url, link_options)
|
32
|
+
|
33
|
+
content_tag :li, raw(link), li_options
|
34
|
+
end
|
35
|
+
|
36
|
+
def markdown(text)
|
37
|
+
renderer = Bootstrap::MarkdownRenderer.new(hard_wrap: true, filter_html: true)
|
38
|
+
options = {
|
39
|
+
autolink: true,
|
40
|
+
fenced_code_blocks: true,
|
41
|
+
superscript: true,
|
42
|
+
tables: true
|
43
|
+
}
|
44
|
+
Redcarpet::Markdown.new(renderer, options).render(text).html_safe
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Docs
|
2
|
+
class Page < ActiveRecord::Base
|
3
|
+
belongs_to :page_category, autosave: true
|
4
|
+
store_accessor :data, :notice, :reqs, :weight
|
5
|
+
|
6
|
+
default_value_for :via, "GET"
|
7
|
+
|
8
|
+
before_validation :upcase_via, if: :via?
|
9
|
+
|
10
|
+
validates :path, :via, :title, presence: true
|
11
|
+
|
12
|
+
def weight
|
13
|
+
super.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_path
|
17
|
+
@method_path ||= [via, only_path].join(" ")
|
18
|
+
end
|
19
|
+
|
20
|
+
def page_category_slug
|
21
|
+
@page_category_slug ||= page_category.try(:slug)
|
22
|
+
end
|
23
|
+
|
24
|
+
def page_category_slug=(slug)
|
25
|
+
@page_category_slug = begin
|
26
|
+
slug = slug.to_s.downcase.underscore
|
27
|
+
self.page_category = PageCategory.find_or_initialize_by(slug: slug)
|
28
|
+
page_category.try(:slug)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def anchor
|
33
|
+
@anchor ||= method_path.downcase.gsub(/[^\w]/, "_")
|
34
|
+
end
|
35
|
+
|
36
|
+
def only_path
|
37
|
+
@only_path ||= path.split("?").first
|
38
|
+
end
|
39
|
+
|
40
|
+
def only_query
|
41
|
+
@only_query ||= splitted_path.length > 1 ? "?#{splitted_path.last}" : ""
|
42
|
+
end
|
43
|
+
|
44
|
+
def splitted_path
|
45
|
+
@splitted_path ||= path.split('?')
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_body_with_default_table
|
49
|
+
return body if body.present?
|
50
|
+
self.body = <<-markdown.gsub(/^\s+\.|/, '')
|
51
|
+
.| Параметр | Описание |
|
52
|
+
.|----------|----------|
|
53
|
+
.| | |
|
54
|
+
.
|
55
|
+
.
|
56
|
+
markdown
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def upcase_via
|
61
|
+
via.upcase!; true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|