1
+ <!doctype html>
2
+ < html >
3
+ < head >
4
+ < meta name ="viewport " content ="width=device-width ">
5
+ < link rel ="stylesheet " href ="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.css " />
6
+ < script src ="https://cdn.jsdelivr.net/npm/marked/marked.min.js "> </ script >
7
+ < script src ="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js "> </ script >
8
+ < script src ="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js "> </ script >
9
+ < style >
10
+ @media (max-width : 767px ) {
11
+ .markdown-body {
12
+ padding : 15px ;
13
+ }
14
+
15
+ # search {
16
+ max-width : 85% ;
17
+ }
18
+ }
19
+ body {
20
+ overflow : scroll;
21
+ }
22
+ .markdown-body {
23
+ box-sizing : border-box;
24
+ min-width : 200px ;
25
+ max-width : 980px ;
26
+ margin : 0 auto;
27
+ padding : 45px ;
28
+ }
29
+ # search {
30
+ border : 1px solid # d1d5da ;
31
+ padding-left : 30px ;
32
+ overflow : hidden;
33
+ }
34
+ .searchCondition {
35
+ display : flex;
36
+ flex-wrap : wrap;
37
+ }
38
+ .searchCondition > div {
39
+ margin-right : 30px ;
40
+ }
41
+ </ style >
42
+ </ head >
43
+ < body >
44
+ < div id ="app ">
45
+ < article class ="markdown-body ">
46
+ < div class ="searchCondition ">
47
+ < div >
48
+ < form style ="display:flex; ">
49
+ < label for ="search " style ="margin-right: 3px; " > search:</ label >
50
+ < div style ="position: relative; ">
51
+ < input id ="search " placeholder ="Search all options " v-model ="searchCondition ">
52
+ < svg style ="position: absolute; left: 8px; top: 7px; " class ="octicon octicon-search subnav-search-icon " viewBox ="0 0 16 16 " version ="1.1 " width ="16 " height ="16 " aria-hidden ="true ">
53
+ < path fill-rule ="evenodd " d ="M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z "> </ path >
54
+ </ svg >
55
+ </ div >
56
+ </ form >
57
+ </ div >
58
+ < div >
59
+ < label for ="stable "> stable: </ label >
60
+ < input type ="checkbox " id ="stable " v-model ="shouldStable ">
61
+ </ div >
62
+ </ div >
63
+ < div v-html ="aboutHtml "> </ div >
64
+ < div v-html ="configurationAboutHtml "> </ div >
65
+ < div v-html ="outputHtml "> </ div >
66
+ </ article >
67
+ </ div >
68
+ < script >
69
+ const ConfigurationMdUrl = 'https://raw.githubusercontent.com/rust-lang/rustfmt/master/Configurations.md' ;
70
+ new Vue ( {
71
+ el : '#app' ,
72
+ data ( ) {
73
+ const configurationDescriptions = [ ] ;
74
+ configurationDescriptions . links = { }
75
+ return {
76
+ aboutHtml : '' ,
77
+ configurationAboutHtml : '' ,
78
+ searchCondition : '' ,
79
+ configurationDescriptions,
80
+ shouldStable : false
81
+ }
82
+ } ,
83
+ computed : {
84
+ outputHtml ( ) {
85
+ const ast = this . configurationDescriptions
86
+ . filter ( ( { head, text, stable } ) => {
87
+
88
+ if (
89
+ text . includes ( this . searchCondition ) === false &&
90
+ head . includes ( this . searchCondition ) === false
91
+ ) {
92
+ return false ;
93
+ }
94
+ return ( this . shouldStable )
95
+ ? stable === true
96
+ : true ;
97
+ } )
98
+ . reduce ( ( stack , { value } ) => {
99
+ return stack . concat ( value ) ;
100
+ } , [ ] ) ;
101
+ ast . links = { } ;
102
+ return marked . parser ( ast ) ;
103
+ }
104
+ } ,
105
+ mounted : async function ( ) {
106
+ const res = await axios . get ( ConfigurationMdUrl ) ;
107
+ const {
108
+ about,
109
+ configurationAbout,
110
+ configurationDescriptions
111
+ } = parseMarkdownAst ( res . data ) ;
112
+ this . aboutHtml = marked . parser ( about ) ;
113
+ this . configurationAboutHtml = marked . parser ( configurationAbout ) ;
114
+ this . configurationDescriptions = configurationDescriptions ;
115
+ }
116
+ } ) ;
117
+ const extractDepthOnes = ( ast ) => {
118
+ return ast . reduce ( ( stack , next ) => {
119
+ if ( next . depth === 1 ) {
120
+ stack . push ( [ ] ) ;
121
+ }
122
+ const lastIndex = stack . length - 1 ;
123
+ stack [ lastIndex ] . push ( next ) ;
124
+ return stack ;
125
+ } , [ ] ) ;
126
+ }
127
+ const extractDepthTwos = ( ast ) => {
128
+ return ast . map ( ( elem ) => {
129
+ return elem . reduce ( ( stack , next ) => {
130
+ if ( next . depth === 2 ) {
131
+ stack . push ( [ ] ) ;
132
+ }
133
+ const lastIndex = stack . length - 1 ;
134
+ stack [ lastIndex ] . push ( next ) ;
135
+ return stack ;
136
+ } ,
137
+ [ [ ] ] ) ;
138
+ } ) ;
139
+ }
140
+ const createHeadAndValue = ( ast ) => {
141
+ return ast . map ( ( elem ) => {
142
+ return elem . map ( ( val ) => {
143
+ return {
144
+ head : val [ 0 ] . text ,
145
+ value : val ,
146
+ stable : val . some ( ( elem ) => {
147
+ return ! ! elem . text && elem . text . includes ( "**Stable**: Yes" )
148
+ } ) ,
149
+ text : val . reduce ( ( result , next ) => {
150
+ return next . text != null
151
+ ? `${ result } ${ next . text } `
152
+ : result ;
153
+ } , '' )
154
+ }
155
+ } ) ;
156
+ } )
157
+ }
158
+ const parseMarkdownAst = ( rawMarkdown ) => {
159
+ const ast = marked . lexer ( rawMarkdown ) ;
160
+ const depthOnes = extractDepthOnes ( ast ) ;
161
+ const depthTwos = extractDepthTwos ( depthOnes ) ;
162
+ const [
163
+ abouts , configurations
164
+ ] = createHeadAndValue ( depthTwos ) ;
165
+ const about = abouts [ 0 ] . value ;
166
+ about . links = { } ;
167
+ const [
168
+ configurationAbout , ...configurationDescriptions
169
+ ] = configurations ;
170
+ configurationAbout . value . links = { } ;
171
+
172
+ return {
173
+ about,
174
+ configurationAbout : configurationAbout . value ,
175
+ configurationDescriptions
176
+ } ;
177
+ }
178
+ </ script >
179
+ </ body >
180
+ </ html >
0 commit comments