api_docs_engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|