|
21 | 21 | F, formatBytes, formatTemplate |
22 | 22 | generateFromTemplateString, generateFromTemplateFile, generateRedirection |
23 | 23 | generateNonPages |
24 | | - generatorMeta |
25 | 24 | getCwd |
26 | 25 | getDirectory, getFilename, getExtension, getBasename |
27 | 26 | getFileContentsBinary, getFileContentsText |
| 27 | + getGeneratorHtmlMetaTag |
28 | 28 | getKeys |
29 | 29 | getLayoutTemplate |
30 | 30 | getLineNumber |
|
51 | 51 | pairsSorted |
52 | 52 | parseAndRunTemplate |
53 | 53 | pathToSitePath, sitePathToPath |
| 54 | + percentEncode, partialEncodeUrl, fixRelativeUrlAndEncode, toAbsoluteAndEncodedUrl, urlize, urlToPrettyText |
54 | 55 | printNoLog, printfNoLog, log, print, printOnce, printf, printfOnce, timestampPrint, timestampPrintOnce, timestampPrintVerbose, timestampPrintError, timestampPrintWarning, timestampPrintWarningOnce, printObject, logErrorTraceback |
55 | 56 | pushContext, assertContext, getContext, isContext |
56 | 57 | removeItem |
|
62 | 63 | splitString |
63 | 64 | toNormalPath, toWindowsPath |
64 | 65 | tostringForTemplates |
65 | | - toUrl, toUrlAbsolute, urlize, toPrettyUrl |
66 | 66 | traverseDirectory, traverseFiles |
67 | 67 | trim, trimNewlines |
68 | 68 | unindent |
@@ -1305,52 +1305,102 @@ end |
1305 | 1305 |
|
1306 | 1306 |
|
1307 | 1307 | do |
1308 | | - local URI_PERCENT_CODES_TO_NOT_ENCODE = { |
1309 | | - ["%2d"]="-",["%2e"]=".",["%7e"]="~",--["???"]="_", |
1310 | | - ["%21"]="!",["%23"]="#",["%24"]="$",["%26"]="&",["%27"]="'",["%28"]="(",["%29"]=")",["%2a"]="*",["%2b"]="+", |
1311 | | - ["%2c"]=",",["%2f"]="/",["%3a"]=":",["%3b"]=";",["%3d"]="=",["%3f"]="?",["%40"]="@",["%5b"]="[",["%5d"]="]", |
| 1308 | + _G.percentEncode = urlLib.escape |
| 1309 | + |
| 1310 | + local URI_PERCENT_CODES_TO_NOT_ENCODE = { -- AKA reserved characters (except non-ASCII characters). |
| 1311 | + -- Note: These characters are explicitly unreserved and are thus never encoded |
| 1312 | + -- in the first place: A-Z a-z 0-9 - _ . ~ |
| 1313 | + |
| 1314 | + -- Note: This is similar to encodeURI() in JavaScript, except we also don't |
| 1315 | + -- encode '[' and ']' (because of RFC 3986 which added those characters as |
| 1316 | + -- reserved for IPv6 support). |
| 1317 | + |
| 1318 | + ["%21"]="!",["%23"]="#",["%24"]="$",["%26"]="&",["%27"]="'",["%28"]="(",["%29"]=")",["%2a"]="*", |
| 1319 | + ["%2b"]="+",["%2c"]=",",["%2f"]="/",["%3a"]=":",["%3b"]=";",["%3d"]="=",["%3f"]="?",["%40"]="@", |
| 1320 | + |
| 1321 | + -- IPv6. |
| 1322 | + ["%5b"]="[",["%5d"]="]", |
| 1323 | + |
| 1324 | + -- Prevent double-encoding, because lots of URLs in text form everywhere |
| 1325 | + -- already have %xx sequences. (We assume URLs don't have literal percent |
| 1326 | + -- signs, which might be a problem in rare cases. However, we never return an |
| 1327 | + -- incorrectly encoded URL. :EnsureValidPercentEncoding) |
| 1328 | + ["%25"]="%", |
| 1329 | + |
| 1330 | + -- Info: |
| 1331 | + -- JavaScript's encodeURI() does not encode: A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; , / ? : @ & = + $ # |
| 1332 | + -- JavaScript's encodeURIComponent() does not encode: A-Z a-z 0-9 - _ . ! ~ * ' ( ) |
1312 | 1333 | } |
1313 | 1334 |
|
1314 | | - function _G.toUrl(url) |
1315 | | - if type(url) ~= "string" then |
1316 | | - errorf(2, "Bad type of 'url' argument. (Got %s)", type(url)) |
1317 | | - end |
| 1335 | + -- This mostly just encodes non-ASCII characters (but also e.g. spaces). |
| 1336 | + function _G.partialEncodeUrl(url) |
| 1337 | + -- |
| 1338 | + -- :EnsureValidPercentEncoding |
| 1339 | + -- Make sure all existing percent signs denote encoded characters before we do |
| 1340 | + -- anything else. It's possible that this breaks some URLs in extremely rare |
| 1341 | + -- cases (if the given URL is a bit ambiguous), but we have to assume properly |
| 1342 | + -- percent-encoded characters already exist in many URLs. |
| 1343 | + -- |
| 1344 | + url = url:gsub("%%([^%%]?[^%%]?)", function(hopefullyHex) |
| 1345 | + if not hopefullyHex:find"^%x%x$" then |
| 1346 | + return "%25"..hopefullyHex |
| 1347 | + end |
| 1348 | + end) |
1318 | 1349 |
|
1319 | | - url = urlLib.escape(url) |
1320 | | - url = url:gsub("%%%x%x", URI_PERCENT_CODES_TO_NOT_ENCODE) |
| 1350 | + return (urlLib.escape(url):gsub("%%%x%x", URI_PERCENT_CODES_TO_NOT_ENCODE)) |
| 1351 | + end |
1321 | 1352 |
|
1322 | | - return url |
| 1353 | + function _G.fixRelativeUrlAndEncode(url) |
| 1354 | + !ARGS "url:string" |
| 1355 | + url = url:gsub("^/%f[^/]", (site.baseUrl.v:gsub("^%w+://[^/]+", ""))) -- @Speed |
| 1356 | + return (partialEncodeUrl(url)) |
1323 | 1357 | end |
1324 | 1358 |
|
1325 | | - -- print(toUrl("http://www.example.com/some-path/File~With (Stuff_åäö).jpg?key=value&foo=bar#hash")) -- TEST |
1326 | | -end |
| 1359 | + function _G.toAbsoluteAndEncodedUrl(url) |
| 1360 | + !ARGS "url:string" |
| 1361 | + url = url:gsub("^/%f[^/]", site.baseUrl.v) |
| 1362 | + return (partialEncodeUrl(url)) |
| 1363 | + end |
1327 | 1364 |
|
1328 | | -function _G.toUrlAbsolute(url) |
1329 | | - url = url:gsub("^/%f[^/]", site.baseUrl.v) |
1330 | | - return (toUrl(url)) |
| 1365 | + --[[ TEST @Cleanup: Include this in testsite (and add more URL encoding tests). |
| 1366 | + _G.site = {baseUrl={v="http://example.com/sub-folder/"}} |
| 1367 | + local urlAbs = "http://example.com/some-path/File~With (Stuff_åäö).jpg?key=value&foo=bar#hash" |
| 1368 | + local urlRel = "/images/cat.jpg" |
| 1369 | + local result = percentEncode(urlAbs) ; print("PercentEncode", result) ; assert(result == "http%3a%2f%2fexample.com%2fsome-path%2fFile~With%20%28Stuff_%c3%a5%c3%a4%c3%b6%29.jpg%3fkey%3dvalue%26foo%3dbar%23hash") |
| 1370 | + local result = partialEncodeUrl(urlAbs) ; print("PartialEncode", result) ; assert(result == "http://example.com/some-path/File~With%20(Stuff_%c3%a5%c3%a4%c3%b6).jpg?key=value&foo=bar#hash") |
| 1371 | + local result = partialEncodeUrl("cool%20any%%20run") ; print("BadUrl ", result) ; assert(result == "cool%20any%25%20run") |
| 1372 | + local result = fixRelativeUrlAndEncode(urlRel) ; print("RelativeUrl ", result) ; assert(result == "/sub-folder/images/cat.jpg") |
| 1373 | + local result = toAbsoluteAndEncodedUrl(urlRel) ; print("AbsoluteUrl ", result) ; assert(result == "http://example.com/sub-folder/images/cat.jpg") |
| 1374 | + os.exit(2) |
| 1375 | + --]] |
1331 | 1376 | end |
1332 | 1377 |
|
1333 | 1378 | function _G.urlize(text) |
1334 | | - text = text |
| 1379 | + !ARGS "text:string" |
| 1380 | + text = ( |
| 1381 | + text |
| 1382 | + :gsub("[%p%s]+", "-") |
| 1383 | + :gsub("^%-+", "") |
| 1384 | + :gsub("%-+$", "") |
1335 | 1385 | :lower() |
1336 | | - :gsub("[%p ]+", "-") |
1337 | | - :gsub("^%-+", "") |
1338 | | - :gsub("%-+$", "") |
1339 | | - |
| 1386 | + ) |
1340 | 1387 | return text == "" and "-" or text |
1341 | 1388 | end |
1342 | 1389 |
|
1343 | | -function _G.toPrettyUrl(url) |
1344 | | - return (url |
| 1390 | +function _G.urlToPrettyText(url) |
| 1391 | + !ARGS "url:string" |
| 1392 | + return ( |
| 1393 | + urlLib.unescape(url) |
1345 | 1394 | :gsub("^https?://", "") |
1346 | | - :gsub("^www%.", "") |
1347 | | - :gsub("/+$", "") |
| 1395 | + :gsub("^www%.", "") |
| 1396 | + :gsub("/+$", "") |
| 1397 | + :gsub(" ", "+") -- Because we unescaped all characters. |
1348 | 1398 | ) |
1349 | 1399 | end |
1350 | 1400 |
|
1351 | 1401 |
|
1352 | 1402 |
|
1353 | | -function _G.generatorMeta(hideVersion) |
| 1403 | +function _G.getGeneratorHtmlMetaTag(hideVersion) |
1354 | 1404 | return |
1355 | 1405 | hideVersion |
1356 | 1406 | and '<meta name="generator" content="LuaWebGen">' |
@@ -1895,16 +1945,16 @@ function _G.generateRedirection(url, targetUrl, sourcePath) |
1895 | 1945 | <meta charset="utf-8"> |
1896 | 1946 | <meta name="robots" content="noindex, follow"> |
1897 | 1947 | <meta http-equiv="refresh" content="3; url=:urlAbsPercent:"> |
1898 | | - <title>:url:</title> |
| 1948 | + <title>:urlPretty:</title> |
1899 | 1949 | </head> |
1900 | 1950 | <body> |
1901 | 1951 | <p>Page has moved. If you are not redirected automatically, |
1902 | 1952 | click <a href=":urlAbsPercent:">here</a>.</p> |
1903 | 1953 | </body> |
1904 | 1954 | </html> |
1905 | 1955 | ]=], { |
1906 | | - url = encodeHtmlEntities( targetUrl ), |
1907 | | - urlAbsPercent = encodeHtmlEntities(toUrlAbsolute(targetUrl)), |
| 1956 | + urlPretty = encodeHtmlEntities(urlToPrettyText (targetUrl)), |
| 1957 | + urlAbsPercent = encodeHtmlEntities(toAbsoluteAndEncodedUrl(targetUrl)), |
1908 | 1958 | } |
1909 | 1959 | ) |
1910 | 1960 |
|
|
2846 | 2896 |
|
2847 | 2897 | local imageLoader = imageLoaders[extLower] |
2848 | 2898 | if not imageLoader then |
2849 | | - return nil, F("Unknown image file format '%'.", extLower) |
| 2899 | + return nil, F("Unknown image file format '%s'.", extLower) |
2850 | 2900 | end |
2851 | 2901 |
|
2852 | 2902 | local image = imageLoader(pathImage) |
@@ -2875,7 +2925,7 @@ function _G.getImageDimensions(pathImageRel, mustBeFast) |
2875 | 2925 | end |
2876 | 2926 |
|
2877 | 2927 | if mustBeFast then |
2878 | | - return nil, F("Could not determine the dimensions of '%'.", maybeFullPath(DIR_CONTENT.."/"..pathImageRel)) |
| 2928 | + return nil, F("Could not determine the dimensions of '%s'.", maybeFullPath(DIR_CONTENT.."/"..pathImageRel)) |
2879 | 2929 | end |
2880 | 2930 |
|
2881 | 2931 | -- Try the much slower method using GD. |
|
0 commit comments