|
24 | 24 | generatorMeta |
25 | 25 | getCwd |
26 | 26 | getDirectory, getFilename, getExtension, getBasename |
27 | | - getFileContents |
| 27 | + getFileContentsBinary, getFileContentsText |
28 | 28 | getKeys |
29 | 29 | getLayoutTemplate |
30 | 30 | getLineNumber |
|
48 | 48 | pairsSorted |
49 | 49 | parseAndRunTemplate |
50 | 50 | pathToSitePath, sitePathToPath |
51 | | - printNoLog, printfNoLog, log, print, printOnce, printf, printfOnce, timestampPrint, timestampPrintOnce, timestampPrintVerbose, timestampPrintError, timestampPrintWarning, timestampPrintWarningOnce, printobj |
| 51 | + printNoLog, printfNoLog, log, print, printOnce, printf, printfOnce, timestampPrint, timestampPrintOnce, timestampPrintVerbose, timestampPrintError, timestampPrintWarning, timestampPrintWarningOnce, printObject |
52 | 52 | pushContext, popContext, assertContext, getContext |
53 | 53 | removeItem |
54 | 54 | rewriteOutputPath |
@@ -139,12 +139,27 @@ end |
139 | 139 |
|
140 | 140 |
|
141 | 141 |
|
142 | | -function _G.getFileContents(path) |
| 142 | +function _G.getFileContentsBinary(path) |
143 | 143 | local file, err = io.open(path, "rb") |
144 | 144 | if not file then return nil, err end |
145 | 145 |
|
146 | | - local contents = file:read("*all") |
| 146 | + local contents = file:read"*a" |
147 | 147 | file:close() |
| 148 | + |
| 149 | + return contents |
| 150 | +end |
| 151 | + |
| 152 | +function _G.getFileContentsText(path) |
| 153 | + local file, err = io.open(path, "r") |
| 154 | + if not file then return nil, err end |
| 155 | + |
| 156 | + local contents = file:read"*a" |
| 157 | + file:close() |
| 158 | + |
| 159 | + if contents:find("\r", 1, true) then |
| 160 | + contents = contents:gsub("\n?\r\n?", "\n") |
| 161 | + end |
| 162 | + |
148 | 163 | return contents |
149 | 164 | end |
150 | 165 |
|
|
153 | 168 | do |
154 | 169 | -- isValueExpression = insertLuaForEchoingIfExpression( luaOutputBuffer, luaCode ) |
155 | 170 | local function insertLuaForEchoingIfExpression(out, luaCode) |
| 171 | + -- Note: echo() and echoRaw() do the same thing in e.g. CSS files, so we |
| 172 | + -- can output the same code here no matter what file is being processed. |
| 173 | + -- It is a thing we can optimize though. @Speed |
156 | 174 | local doBlock = F("do local v = (%s) if type__(v) == 'string' and v:find'^%%s*<[!%%a/].*>%%s*$' then echoRaw__(v) elseif v ~= nil then echo__(v) end end ", luaCode) |
157 | 175 | if not loadstring(doBlock) then return false end |
158 | 176 |
|
|
351 | 369 |
|
352 | 370 | if pos <= echoI2 then |
353 | 371 | local plainSegment = template:sub(pos, echoI2) |
354 | | - table.insert(out, "echoRaw__'") -- Note: Templates will probably have more double quotes than single, that's why we use single quotes here - for nicer metaprogram output. |
| 372 | + table.insert(out, "echoRaw__'") -- Note: Templates will probably have more double quotes than single, that's why we use single quotes here - for nicer metaprogram output. :TemplateOutputQuotes |
355 | 373 | table.insert(out, (plainSegment:gsub("[\\'\n]", "\\%0"))) |
356 | 374 | table.insert(out, "'") |
357 | 375 | end |
|
622 | 640 |
|
623 | 641 | if pos <= #template then |
624 | 642 | local plainSegment = template:sub(pos) |
625 | | - table.insert(out, 'echoRaw__"') |
626 | | - table.insert(out, (plainSegment:gsub("[\\\"\n]", "\\%0"))) |
627 | | - table.insert(out, '"') |
| 643 | + table.insert(out, "echoRaw__'") -- :TemplateOutputQuotes |
| 644 | + table.insert(out, (plainSegment:gsub("[\\'\n]", "\\%0"))) |
| 645 | + table.insert(out, "'") |
628 | 646 | end |
629 | 647 |
|
630 | 648 | if tcsLevel > 1 then |
@@ -1040,65 +1058,71 @@ function _G.timestampPrintWarningOnce(s, ...) |
1040 | 1058 | log(s) |
1041 | 1059 | end |
1042 | 1060 |
|
1043 | | --- printobj( ... ) |
| 1061 | +-- printObject( value1, ... ) |
1044 | 1062 | -- Note: Does not write to log. |
1045 | 1063 | do |
1046 | 1064 | local stdoutWrite = io.write |
1047 | 1065 |
|
1048 | 1066 | local function toStringBetter(v) |
1049 | | - return (tostring(v):gsub("^table: ", "")) |
| 1067 | + local s = tostring(v) |
| 1068 | + return s:find"^table: " |
| 1069 | + and s:gsub("^table: ", ""):gsub("^0x", ""):gsub("^%w+", string.upper) |
| 1070 | + or s |
1050 | 1071 | end |
1051 | 1072 |
|
1052 | 1073 | local function compareKeys(a, b) |
1053 | 1074 | return compareNatural(toStringBetter(a), toStringBetter(b)) |
1054 | 1075 | end |
1055 | 1076 |
|
1056 | | - local function _printobj(v, tables) |
| 1077 | + local function _printObject(v, printedTables, firstLevel) |
1057 | 1078 | local vType = type(v) |
1058 | 1079 |
|
1059 | | - if vType == "table" then |
1060 | | - if tables[v] then |
1061 | | - stdoutWrite(toStringBetter(v), " ") |
1062 | | - return |
1063 | | - end |
| 1080 | + if printedTables[v] then |
| 1081 | + stdoutWrite(toStringBetter(v)) |
1064 | 1082 |
|
1065 | | - stdoutWrite(toStringBetter(v), "{ ") |
1066 | | - tables[v] = true |
| 1083 | + elseif vType == "table" then |
| 1084 | + printedTables[v] = true |
| 1085 | + stdoutWrite(toStringBetter(v), (firstLevel and "{\n" or "{ ")) |
1067 | 1086 |
|
1068 | 1087 | local indices = {} |
1069 | 1088 | for i = 1, #v do indices[i] = true end |
1070 | 1089 |
|
1071 | 1090 | for _, k in ipairs(sort(getKeys(v), compareKeys)) do |
1072 | 1091 | if not indices[k] then |
| 1092 | + if firstLevel then stdoutWrite("\t") end |
1073 | 1093 | stdoutWrite(toStringBetter(k), "=") |
1074 | | - _printobj(v[k], tables) |
| 1094 | + _printObject(v[k], printedTables, false) |
| 1095 | + if firstLevel then stdoutWrite("\n") end |
1075 | 1096 | end |
1076 | 1097 | end |
1077 | 1098 |
|
1078 | 1099 | for i = 1, #v do |
| 1100 | + if firstLevel then stdoutWrite("\t") end |
1079 | 1101 | stdoutWrite(i, "=") |
1080 | | - _printobj(v[i], tables) |
| 1102 | + _printObject(v[i], printedTables, false) |
| 1103 | + if firstLevel then stdoutWrite("\n") end |
1081 | 1104 | end |
1082 | 1105 |
|
1083 | | - stdoutWrite("} ") |
| 1106 | + stdoutWrite("}") |
1084 | 1107 |
|
1085 | 1108 | elseif vType == "number" then |
1086 | | - stdoutWrite(F("%g ", v)) |
| 1109 | + stdoutWrite(tostring(v)) |
1087 | 1110 |
|
1088 | 1111 | elseif vType == "string" then |
1089 | | - stdoutWrite('"', v:gsub("%z", "\\0"):gsub("\n", "\\n"), '" ') |
| 1112 | + stdoutWrite('"', v:gsub("%z", "\\0"):gsub("\n", "\\n"), '"') |
1090 | 1113 |
|
1091 | 1114 | else |
1092 | | - stdoutWrite(toStringBetter(v), " ") |
| 1115 | + stdoutWrite(toStringBetter(v)) |
1093 | 1116 | end |
1094 | 1117 |
|
| 1118 | + if not firstLevel then stdoutWrite(" ") end |
1095 | 1119 | end |
1096 | 1120 |
|
1097 | | - function _G.printobj(...) |
| 1121 | + function _G.printObject(...) |
1098 | 1122 | for i = 1, select("#", ...) do |
1099 | 1123 | if i > 1 then stdoutWrite("\t") end |
1100 | 1124 |
|
1101 | | - _printobj(select(i, ...), {}) |
| 1125 | + _printObject(select(i, ...), {}, true) |
1102 | 1126 | end |
1103 | 1127 | stdoutWrite("\n") |
1104 | 1128 | end |
@@ -1321,12 +1345,12 @@ function _G.newDataFolderReader(path, checkDirExistance) |
1321 | 1345 |
|
1322 | 1346 | elseif isFile(F("%s/%s.toml", path, k)) then |
1323 | 1347 | local filePath = F("%s/%s.toml", path, k) |
1324 | | - local contents = assert(getFileContents(filePath)) |
| 1348 | + local contents = assert(getFileContentsText(filePath)) |
1325 | 1349 | dataObj = assert(tomlLib.parse(contents)) |
1326 | 1350 |
|
1327 | 1351 | elseif isFile(F("%s/%s.xml", path, k)) then |
1328 | 1352 | local filePath = F("%s/%s.xml", path, k) |
1329 | | - local contents = assert(getFileContents(filePath)) |
| 1353 | + local contents = assert(getFileContentsText(filePath)) |
1330 | 1354 | dataObj = assert(xmlLib.parse(contents, false)) |
1331 | 1355 |
|
1332 | 1356 | elseif isDirectory(F("%s/%s", path, k)) then |
@@ -1533,7 +1557,7 @@ function _G.generateFromTemplateFile(page) |
1533 | 1557 | if page._isGenerating and page._isLocked then return end -- Allowed recursion. |
1534 | 1558 |
|
1535 | 1559 | local path = DIR_CONTENT.."/"..page._path |
1536 | | - local template = assert(getFileContents(path)) |
| 1560 | + local template = assert(getFileContentsText(path)) |
1537 | 1561 | local modTime = lfs.attributes(path, "modification") |
1538 | 1562 |
|
1539 | 1563 | if modTime then |
@@ -1721,7 +1745,7 @@ function _G.getLayoutTemplate(page) |
1721 | 1745 | local template = layoutTemplates[path] |
1722 | 1746 | if template then return template, path end |
1723 | 1747 |
|
1724 | | - local template, err = getFileContents(path) |
| 1748 | + local template, err = getFileContentsText(path) |
1725 | 1749 | if not template then |
1726 | 1750 | errorf("%s: Could not load layout '%s'. (%s)", page._path, page.layout.v, err) |
1727 | 1751 | end |
@@ -2257,6 +2281,7 @@ end |
2257 | 2281 |
|
2258 | 2282 |
|
2259 | 2283 | -- removeItem( array, value1, ... ) |
| 2284 | +-- @Incomplete: Change into this: anythingGotRemoved = removeItem( array, value1, ... ) |
2260 | 2285 | function _G.removeItem(t, ...) |
2261 | 2286 | for i = 1, select("#", ...) do |
2262 | 2287 | local iToRemove = indexOf(t, select(i, ...)) |
|
0 commit comments