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