| | @@ -2014,10 +2014,14 @@ |
| 2014 | 2014 | |
| 2015 | 2015 | /* |
| 2016 | 2016 | ** The "z" argument is a string that contains the text of a source |
| 2017 | 2017 | ** code file and nZ is its length in bytes. This routine appends that |
| 2018 | 2018 | ** text to the HTTP reply with line numbering. |
| 2019 | +** |
| 2020 | +** zName is the content's file name, if any (it may be NULL). If that |
| 2021 | +** name contains a '.' then the part after the final '.' is used as |
| 2022 | +** the X part of a "language-X" CSS class on the generate CODE block. |
| 2019 | 2023 | ** |
| 2020 | 2024 | ** zLn is the ?ln= parameter for the HTTP query. If there is an argument, |
| 2021 | 2025 | ** then highlight that line number and scroll to it once the page loads. |
| 2022 | 2026 | ** If there are two line numbers, highlight the range of lines. |
| 2023 | 2027 | ** Multiple ranges can be highlighed by adding additional line numbers |
| | @@ -2024,17 +2028,19 @@ |
| 2024 | 2028 | ** separated by a non-digit character (also not one of [-,.]). |
| 2025 | 2029 | */ |
| 2026 | 2030 | void output_text_with_line_numbers( |
| 2027 | 2031 | const char *z, |
| 2028 | 2032 | int nZ, |
| 2033 | + const char *zName, |
| 2029 | 2034 | const char *zLn |
| 2030 | 2035 | ){ |
| 2031 | 2036 | int iStart, iEnd; /* Start and end of region to highlight */ |
| 2032 | 2037 | int n = 0; /* Current line number */ |
| 2033 | 2038 | int i = 0; /* Loop index */ |
| 2034 | 2039 | int iTop = 0; /* Scroll so that this line is on top of screen. */ |
| 2035 | 2040 | int nLine = 0; |
| 2041 | + const char *zExt = file_extension(zName); |
| 2036 | 2042 | Stmt q; |
| 2037 | 2043 | |
| 2038 | 2044 | iStart = iEnd = atoi(zLn); |
| 2039 | 2045 | db_multi_exec( |
| 2040 | 2046 | "CREATE TEMP TABLE lnos(iStart INTEGER PRIMARY KEY, iEnd INTEGER)"); |
| | @@ -2066,11 +2072,16 @@ |
| 2066 | 2072 | CX("<table class='numbered-lines'><tbody><tr><td>"); |
| 2067 | 2073 | count_lines(z, nZ, &nLine); |
| 2068 | 2074 | for(i=0; i < nLine; ++i){ |
| 2069 | 2075 | CX("<span>%6d</span>", i+1); |
| 2070 | 2076 | } |
| 2071 | | - CX("</td><td><pre><code>"); |
| 2077 | + CX("</td><td><pre>"); |
| 2078 | + if(zExt && *zExt){ |
| 2079 | + CX("<code class='language-%h'>",zExt); |
| 2080 | + }else{ |
| 2081 | + CX("<code>"); |
| 2082 | + } |
| 2072 | 2083 | assert(!n); |
| 2073 | 2084 | while( z[0] ){ |
| 2074 | 2085 | n++; |
| 2075 | 2086 | db_prepare(&q, |
| 2076 | 2087 | "SELECT min(iStart), max(iEnd) FROM lnos" |
| | @@ -2123,11 +2134,12 @@ |
| 2123 | 2134 | db_find_and_open_repository(0,0); |
| 2124 | 2135 | zFilename = g.argv[2]; |
| 2125 | 2136 | fossil_print("%s %s\n", zFilename, zLn); |
| 2126 | 2137 | |
| 2127 | 2138 | blob_read_from_file(&content, zFilename, ExtFILE); |
| 2128 | | - output_text_with_line_numbers(blob_str(&content), blob_size(&content), zLn); |
| 2139 | + output_text_with_line_numbers(blob_str(&content), blob_size(&content), |
| 2140 | + zFilename, zLn); |
| 2129 | 2141 | blob_reset(&content); |
| 2130 | 2142 | fossil_print("%b\n", cgi_output_blob()); |
| 2131 | 2143 | } |
| 2132 | 2144 | |
| 2133 | 2145 | /* |
| | @@ -2430,13 +2442,14 @@ |
| 2430 | 2442 | zFileName = db_text(0, |
| 2431 | 2443 | "SELECT name FROM mlink, filename" |
| 2432 | 2444 | " WHERE filename.fnid=mlink.fnid" |
| 2433 | 2445 | " AND mlink.fid=%d", |
| 2434 | 2446 | rid); |
| 2435 | | - zExt = zFileName ? strrchr(zFileName, '.') : 0; |
| 2447 | + zExt = file_extension(zFileName); |
| 2436 | 2448 | if( zLn ){ |
| 2437 | | - output_text_with_line_numbers(z, blob_size(&content), zLn); |
| 2449 | + output_text_with_line_numbers(z, blob_size(&content), |
| 2450 | + zFileName, zLn); |
| 2438 | 2451 | }else if( zExt && zExt[1] ){ |
| 2439 | 2452 | @ <pre> |
| 2440 | 2453 | @ <code class="language-%s(zExt+1)">%h(z)</code> |
| 2441 | 2454 | @ </pre> |
| 2442 | 2455 | }else{ |
| 2443 | 2456 | |