yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
0586e5ab4
master
1using System ; 2using System . Collections . Generic ; 3using System . IO ; 4using System . Linq ; 5using System . Text ; 6namespace toc 7{ 8public class Builder 9{ 10public static string getAnchorId ( string title ) 11{ 12StringBuilder sb = new StringBuilder (); 13title = title . Trim (). ToLower (); 14 15foreach ( var ch in title ) 16{ 17if ( ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' 18|| ch == '-' || ch == '_' ) 19sb . Append ( ch ); 20else if ( ch == ' ' ) 21sb . Append ( '-' ); 22} 23return sb . ToString (); 24} 25 26public class Node 27{ 28public List < string > fileNamePrefix = new List < string > (); 29public string title ; 30public string shortTitle ; 31public string fileID ; 32public List < string > sections = new List < string > (); 33public List < string > sectionShortTitles = new List < string > (); 34public List < Node > children = new List < Node > (); 35} 36 37public static void buildTOC ( StringBuilder sb , Node n ) 38{ 39sb . AppendFormat ( "<li data-link=\"{0}\"><span>{1}</span>\n" , n . fileID , n . shortTitle ); 40if ( n . children . Count != 0 ) 41{ 42sb . AppendLine ( "<ul class=\"toc_list\">" ); 43foreach ( var c in n . children ) 44buildTOC ( sb , c ); 45sb . AppendLine ( "</ul>" ); 46} 47else if ( n . sections . Count != 0 ) 48{ 49sb . AppendLine ( "<ul class=\"toc_list\">" ); 50for ( int i = 0 ; i < n . sections . Count ; i ++ ) 51{ 52var s = n . sections [ i ]; 53var shortTitle = n . sectionShortTitles [ i ]; 54sb . AppendFormat ( "<li data-link=\"{0}#{1}\"><span>{2}</span></li>\n" , n . fileID , getAnchorId ( s ), shortTitle ); 55} 56sb . AppendLine ( "</ul>" ); 57} 58sb . AppendLine ( "</li>" ); 59} 60public static string buildTOC ( Node n ) 61{ 62StringBuilder sb = new StringBuilder (); 63sb . Append ( @"<ul class=""toc_root_list"">" ); 64buildTOC ( sb , n ); 65sb . Append ( @"</ul>" ); 66return sb . ToString (); 67} 68 69public static bool isChild ( Node parent , Node child ) 70{ 71if ( parent . fileNamePrefix . Count < child . fileNamePrefix . Count ) 72{ 73bool equal = true ; 74for ( int k = 0 ; k < parent . fileNamePrefix . Count ; k ++ ) 75{ 76if ( parent . fileNamePrefix [ k ] != child . fileNamePrefix [ k ]) 77{ 78equal = false ; 79break ; 80} 81} 82return equal ; 83} 84return false ; 85} 86 87public static string getNextNonEmptyLine ( string [] lines , int i ) 88{ 89i ++ ; 90while ( i < lines . Length ) 91{ 92if ( lines [ i ]. Trim (). Length != 0 ) 93return lines [ i ]; 94i ++ ; 95} 96return "" ; 97} 98const string shortTitlePrefix = "[//]: # (ShortTitle: " ; 99 100public static string maybeGetShortTitleImpl ( string originalTitle , string [] lines , int line ) 101{ 102string nextLine = getNextNonEmptyLine ( lines , line ); 103if ( nextLine . StartsWith ( shortTitlePrefix )) 104{ 105return nextLine . Substring ( shortTitlePrefix . Length , nextLine . Length - shortTitlePrefix . Length - 1 ). Trim (); 106} 107return originalTitle ; 108} 109 110public static string escapeString ( string input ) 111{ 112StringBuilder sb = new StringBuilder (); 113foreach ( var ch in input ) 114{ 115if ( ch == '<' ) 116sb . Append ( "<" ); 117else if ( ch == '>' ) 118sb . Append ( ">" ); 119else 120sb . Append ( ch ); 121} 122return sb . ToString (); 123} 124public static string maybeGetShortTitle ( string originalTitle , string [] lines , int line ) 125{ 126string title = maybeGetShortTitleImpl ( originalTitle , lines , line ); 127return escapeString ( title ); 128} 129public static string Run ( string path ) 130{ 131StringBuilder outputSB = new StringBuilder (); 132outputSB . AppendFormat ( "Building table of contents from {0}...\n" , path ); 133var files = System . IO . Directory . EnumerateFiles ( path , "*.md" ). OrderBy ( f=> System . IO . Path . GetFileName ( f )); 134List < Node > nodes = new List < Node > (); 135foreach ( var f in files ) 136{ 137var content = File . ReadAllLines ( f ); 138Node node = new Node (); 139node . fileID = Path . GetFileNameWithoutExtension ( f ); 140outputSB . AppendFormat ( " {0}.md\n" , node . fileID ); 141bool mainTitleFound = false ; 142for ( int i = 1 ; i < content . Length ; i ++ ) 143{ 144if ( content [ i ]. StartsWith ( "===" )) 145{ 146mainTitleFound = true ; 147node . title = content [ i - 1 ]; 148node . shortTitle = maybeGetShortTitle ( node . title , content , i ); 149} 150if ( content [ i ]. StartsWith ( "---" )) 151{ 152if ( ! mainTitleFound ) continue ; 153node . sections . Add ( content [ i - 1 ]); 154node . sectionShortTitles . Add ( maybeGetShortTitle ( content [ i - 1 ], content , i )); 155} 156if ( content [ i ]. StartsWith ( "#" ) && ! content [ i ]. StartsWith ( "##" ) && node . title == null ) 157{ 158mainTitleFound = true ; 159node . title = content [ i ]. Substring ( 1 , content [ i ]. Length - 1 ). Trim (); 160node . shortTitle = maybeGetShortTitle ( node . title , content , i ); 161} 162if ( content [ i ]. StartsWith ( "##" ) && ! content [ i ]. StartsWith ( "###" )) 163{ 164if ( ! mainTitleFound ) continue ; 165var sectionStr = content [ i ]. Substring ( 2 , content [ i ]. Length - 2 ). Trim (); 166node . sections . Add ( sectionStr ); 167node . sectionShortTitles . Add ( maybeGetShortTitle ( sectionStr , content , i )); 168} 169if ( content [ i ]. StartsWith ( "permalink:" )) 170{ 171var prefixLength = ( "permalink:" ). Length ; 172var permaPath = content [ i ]. Substring ( prefixLength , content [ i ]. Length - prefixLength ). Trim (); 173node . fileID = Path . GetFileName ( permaPath ); 174} 175} 176if ( node . title == null ) 177{ 178outputSB . AppendFormat ( "Error: {0} does not define a title." , f ); 179node . title = "Untitiled" ; 180} 181var titleSecs = Path . GetFileName ( f ). Split ( '-' ); 182foreach ( var s in titleSecs ) 183{ 184if ( s . Length == 2 && s [ 1 ] >= '0' && s [ 1 ] <= '9' ) 185{ 186node . fileNamePrefix . Add ( s ); 187} 188else 189{ 190break ; 191} 192} 193// Find parent node. 194Node parent = null ; 195for ( int l = nodes . Count - 1 ; l >= 0 ; l -- ) 196{ 197var n = nodes [ l ]; 198if ( isChild ( n , node )) 199{ 200parent = n ; 201break ; 202} 203} 204if ( parent != null ) 205parent . children . Add ( node ); 206else 207{ 208// find child 209foreach ( var other in nodes ) 210{ 211if ( isChild ( node , other )) 212{ 213node . children . Add ( other ); 214} 215} 216foreach ( var c in node . children ) 217{ 218nodes . Remove ( c ); 219 220} 221nodes . Add ( node ); 222} 223} 224var root = nodes . Find ( x=> x . fileID == "index" ); 225if ( root != null ) 226{ 227var html = buildTOC ( root ); 228var outPath = Path . Combine ( path , "toc.html" ); 229File . WriteAllText ( outPath , html ); 230outputSB . AppendFormat ( "Output written to: {0}\n" , outPath ); 231} 232return outputSB . ToString (); 233} 234} 235}