Skip to content

Commit cf4e7b2

Browse files
committed
Trying to access page.content too early will now raise an error.
utf8.getLength() now returns the first error position. XML: Fixed contentsToXml/Html() encoding the node itself if it was a text node.
1 parent 5ecd81c commit cf4e7b2

File tree

7 files changed

+69
-69
lines changed

7 files changed

+69
-69
lines changed

src/app.lua2p

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ local function setup()
441441
-- Lua libraries.
442442
json = jsonLib,
443443
lfs = lfs,
444-
utf8 = utf8, -- @Doc
444+
utf8 = utf8,
445445
xml = xmlLib,
446446

447447
toml = { -- @Cleanup: Don't use 3rd party TOML library.
@@ -472,11 +472,11 @@ local function setup()
472472
generatorMeta = generatorMeta,
473473
getFilename = getFilename,
474474
getKeys = getKeys,
475-
gmatchAndBetween = gmatchAndBetween, -- @Doc
475+
gmatchAndBetween = gmatchAndBetween,
476476
indexOf = indexOf,
477477
ipairsr = ipairsr,
478478
isAny = isAny,
479-
isValueHtml = doesValueLookLikeHtml, -- @Doc
479+
isValueHtml = doesValueLookLikeHtml,
480480
markdown = markdownToHtml,
481481
max = math.max,
482482
min = math.min,
@@ -535,22 +535,22 @@ local function setup()
535535
return (getBasename_internal(getFilename(genericPath)))
536536
end,
537537

538-
X = function(node, tagName) -- @Doc
538+
X = function(node, tagName) -- @Cleanup: Remove this!
539539
if type(node) ~= "table" then error("Invalid XML argument.", 2) end
540540
return (itemWith(node, "tag", tagName))
541541
end,
542542

543-
Xs = function(node, tagName) -- @Doc
543+
Xs = function(node, tagName) -- @Cleanup: Remove this!
544544
if type(node) ~= "table" then error("Invalid XML argument.", 2) end
545545
return (itemWithAll(node, "tag", tagName))
546546
end,
547547

548-
forXml = function(node, tagName) -- @Doc
548+
forXml = function(node, tagName) -- @Cleanup: Remove this!
549549
if type(node) ~= "table" then error("Invalid XML argument.", 2) end
550550
return ipairs(itemWithAll(node, "tag", tagName))
551551
end,
552552

553-
printXmlTree = function(node) -- @Doc
553+
printXmlTree = function(node) -- @Cleanup: Remove this!
554554
if type(node) ~= "table" then error("Invalid XML argument.", 2) end
555555

556556
local function printNode(node, indent)
@@ -781,7 +781,7 @@ local function setup()
781781
return fileInfos
782782
end,
783783

784-
getGeneratedPages = function() -- @Doc
784+
getGeneratedPages = function()
785785
-- Just like getOutputtedFiles(), there's no reason to restrict context for this function, I don't think. 2021-05-18
786786
local generatedPages = {}
787787

@@ -818,7 +818,6 @@ local function setup()
818818
return _dataParsers
819819
end,
820820

821-
-- array = clampArray( array, length ) -- @Doc
822821
clampArray = function(t, len)
823822
for i = #t, len+1, -1 do
824823
t[i] = nil
@@ -827,7 +826,7 @@ local function setup()
827826
end,
828827

829828
--
830-
-- html = summarize( html, maxCharacters [, keepSomeElements=false ] ) -- @Doc
829+
-- html = summarize( html, maxCharacters [, keepSomeElements=false ] )
831830
--
832831
-- Limit the amount of text and restrict allowed tags in an HTML string
833832
-- to be used e.g. as the description for an item in an RSS feed.
@@ -1041,7 +1040,7 @@ local function setup()
10411040
table.insert(getContext"template".out, tostringForTemplates(s))
10421041
end,
10431042

1044-
echoSmart = function(v) -- @Doc
1043+
echoSmart = function(v)
10451044
assertContext("template", "echoSmart")
10461045
if v == nil then
10471046
-- void Echo nothing.
@@ -1543,8 +1542,9 @@ local function buildWebsite()
15431542
-- Template.
15441543
elseif site._fileTypes[extLower] then
15451544
-- Generate these later so e.g. urlExists() works better.
1546-
local pagesArray = ((site._fileTypes[extLower] == "markdown" or site._fileTypes[extLower] == "html") and site._pages or nonPagePages)
1547-
table.insert(pagesArray, newPage(pathRel, false))
1545+
local page = newPage(pathRel, false)
1546+
local pagesArray = (page.isPage and site._pages or nonPagePages)
1547+
table.insert(pagesArray, page)
15481548

15491549
-- Special.
15501550
elseif pathRel == ".htaccess" and handleHtaccess then
@@ -1572,7 +1572,7 @@ local function buildWebsite()
15721572
end)
15731573

15741574
for _, page in ipairs(nonPagePages) do
1575-
generateFromTemplateFile(page)
1575+
generateFromTemplateFile(page) -- Note that this template may trigger generation of actual pages (e.g. by calling subpages()).
15761576
end
15771577

15781578
for _, page in ipairs(site._pages) do

src/functions.lua2p

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,7 @@ function _G.getProtectionWrapper(obj, objName)
16631663
errorf(2, "[internal] No getter for %s.%s", objName, k)
16641664
end
16651665

1666-
return field:g()
1666+
return (field:g())
16671667
end,
16681668

16691669
__newindex = function(wrapper, k, vNew)
@@ -1770,16 +1770,14 @@ function _G.generateFromTemplateString(page, template, modTime, onPageInit)
17701770
return
17711771
end
17721772

1773+
page.content.v = pageContent
1774+
page._contentIsAvailable = true
1775+
17731776
if page.layout.v == "" then
17741777
result = pageContent
1775-
17761778
else
1777-
page.content.v = pageContent
1778-
17791779
local layoutTemplate, layoutPath = getLayoutTemplate(page)
17801780
result = parseAndRunTemplate(page, layoutPath, layoutTemplate, "html", true, nil)
1781-
1782-
-- page.content.v = "" -- We don't need this anymore. (Actually, things like RSS feeds do!)
17831781
end
17841782

17851783
else
@@ -2204,7 +2202,7 @@ function _G.newSite()
22042202
_ignoreFolders = {--[[ filenamePattern1, ... ]]},
22052203
_ignorePaths = {--[[ pathPattern1, ... ]]},
22062204

2207-
_fileTypes = {["md"]="markdown", ["html"]="html", ["xml"]="xml", ["css"]="othertemplate"},
2205+
_fileTypes = {["md"]="markdown", ["markdown"]="markdown", ["html"]="html", ["htm"]="html", ["xml"]="xml", ["css"]="othertemplate"},
22082206
_fileProcessors = {--[[ [extension1]=function(data, sitePath), ... ]]},
22092207

22102208
_htaErrors = {--[[ [httpStatusCode1]=document1, ... ]]},
@@ -2244,7 +2242,7 @@ function _G.newSite()
22442242
v = "",
22452243
g = function(field) return field.v end,
22462244
},
2247-
description = { -- @Doc
2245+
description = {
22482246
v = "",
22492247
g = function(field) return field.v end,
22502248
},
@@ -2315,15 +2313,16 @@ do
23152313
local page; page = {
23162314
_readonly = false,
23172315

2318-
_category = category,
2319-
_isGenerating = false,
2320-
_isGenerated = false,
2321-
_isSkipped = false,
2322-
_isLocked = false, -- @Cleanup: Is this always synced with _readonly? If so, just remove _isLocked.
2323-
_path = pathRel,
2324-
_pathOut = pathRelOut,
2325-
_pathForError = F("%s/%s", DIR_CONTENT, pathRel),
2326-
_extension = extLower,
2316+
_category = category,
2317+
_isGenerating = false,
2318+
_isGenerated = false,
2319+
_isSkipped = false,
2320+
_isLocked = false, -- @Cleanup: Is this always synced with _readonly? If so, just remove _isLocked.
2321+
_contentIsAvailable = false,
2322+
_path = pathRel,
2323+
_pathOut = pathRelOut,
2324+
_pathForError = F("%s/%s", DIR_CONTENT, pathRel),
2325+
_extension = extLower,
23272326

23282327
isPage = {
23292328
v = isPage,
@@ -2348,14 +2347,22 @@ do
23482347
g = function(field) return field.v end,
23492348
s = function(field, title) field.v = title end,
23502349
},
2351-
description = { -- @Doc
2350+
description = {
23522351
v = "",
23532352
g = function(field) return field.v end,
23542353
s = function(field, description) field.v = description end,
23552354
},
23562355
content = {
23572356
v = "",
2358-
g = function(field) return field.v end,
2357+
g = function(field)
2358+
if page._contentIsAvailable then
2359+
return field.v
2360+
elseif not page.isPage.v then
2361+
errorf(3, "page.content isn't available for non-page templates. (%s)", page._pathForError)
2362+
else
2363+
errorf(3, "page.content isn't available (probably because the page hasn't finished generating). (%s)", page._pathForError)
2364+
end
2365+
end,
23592366
},
23602367

23612368
date = {
@@ -2830,8 +2837,8 @@ end
28302837

28312838

28322839
do
2833-
-- for isMatch, position, match1, ... in gmatchAndBetween( string, pattern )
2834-
-- If isMatch is false then match1 is the string between the last match and the next. (This string will never be empty.)
2840+
-- for position, isMatch, capture1, ... in gmatchAndBetween( string, pattern )
2841+
-- If isMatch is false then capture1 is the string between the last match and the next. (This string will never be empty.)
28352842
function _G.gmatchAndBetween(s, pat)
28362843
local nextPos = 1
28372844
local i1, i2 = nil

src/utf8.lua2p

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ local tableInsert = table.insert
2525

2626

2727

28-
-- string = codepointToString( cp )
29-
-- codepointToString( cp, outputBuffer )
28+
-- string = codepointToString( codepoint )
29+
-- codepointToString( codepoint, outputBuffer )
3030
function utf8.codepointToString(cp, buffer)
3131
if cp < 0 or cp > 0x10ffff then
3232
errorf("Codepoint %d is outside the valid range (0..10FFFF).", cp)
@@ -86,7 +86,7 @@ end
8686

8787

8888

89-
-- length|nil = getCharacterLength( string [, position=1 ] )
89+
-- length = getCharacterLength( string [, position=1 ] )
9090
-- Returns nil if the string is invalid at the position.
9191
function utf8.getCharacterLength(s, pos)
9292
pos = pos or 1
@@ -137,15 +137,15 @@ end
137137

138138

139139

140-
-- length|nil = getLength( string [, startPosition=1 ] )
141-
-- Returns nil if the string is invalid.
140+
-- length = getLength( string [, startPosition=1 ] )
141+
-- Returns nil and the first error position if the string is invalid.
142142
function utf8.getLength(s, pos)
143143
pos = pos or 1
144144
local len = 0
145145

146146
while pos <= #s do
147147
local charLen = utf8.getCharacterLength(s, pos)
148-
if not charLen then return nil end
148+
if not charLen then return nil, pos end
149149

150150
len = len + 1
151151
pos = pos + charLen
@@ -156,13 +156,14 @@ end
156156

157157

158158

159-
-- position|nil = getStartOfCharacter( string, position )
159+
-- position = getStartOfCharacter( string, position )
160160
-- Returns nil if the string is invalid at the position.
161161
function utf8.getStartOfCharacter(s, pos)
162162
for pos = pos, math.max(pos-3, 1), -1 do
163163
local b = getByte(s, pos)
164164

165165
if b <= 127 or (b >= 194 and b <= 244) then
166+
-- @Robustness: Verify that the following bytes are valid.
166167
return pos
167168
end
168169
end

src/xml.lua2p

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ do
725725
end
726726
end
727727

728-
-- text = Element:getHtmlText( ) -- @Doc
728+
-- text = Element:getHtmlText( )
729729
function Element.getHtmlText(el)
730730
local buffer = {}
731731
_getHtmlText(buffer, el)
@@ -1131,18 +1131,14 @@ function xml.toXml(node, preface)
11311131
end
11321132
Element.toXml = xml.toXml -- :Alias
11331133

1134-
-- xmlString = xml.contentsToXml( node ) -- @Doc
1134+
-- xmlString = xml.contentsToXml( node )
11351135
function xml.contentsToXml(node)
1136-
local buffer = {}
1136+
if !!(IS_TEXT`node`) then return "" end
11371137

1138-
if !!(IS_TEXT`node`) then
1139-
nodeToXml(buffer, node)
1140-
else
1141-
for _, childNode in ipairs(node) do
1142-
nodeToXml(buffer, childNode)
1143-
end
1138+
local buffer = {}
1139+
for _, childNode in ipairs(node) do
1140+
nodeToXml(buffer, childNode)
11441141
end
1145-
11461142
return table.concat(buffer, "")
11471143
end
11481144
Element.contentsToXml = xml.contentsToXml -- :Alias
@@ -1312,18 +1308,14 @@ function xml.toHtml(node, preface)
13121308
end
13131309
Element.toHtml = xml.toHtml -- :Alias
13141310

1315-
-- htmlString = xml.contentsToHtml( node ) -- @Doc
1311+
-- htmlString = xml.contentsToHtml( node )
13161312
function xml.contentsToHtml(node)
1317-
local buffer = {}
1313+
if !!(IS_TEXT`node`) then return "" end
13181314

1319-
if !!(IS_TEXT`node`) then
1320-
nodeToHtml(buffer, node)
1321-
else
1322-
for _, childNode in ipairs(node) do
1323-
nodeToHtml(buffer, childNode)
1324-
end
1315+
local buffer = {}
1316+
for _, childNode in ipairs(node) do
1317+
nodeToHtml(buffer, childNode)
13251318
end
1326-
13271319
return table.concat(buffer, "")
13281320
end
13291321
Element.contentsToHtml = xml.contentsToHtml -- :Alias
@@ -1684,12 +1676,12 @@ local CHAR_TO_ENTITY = {
16841676
}
16851677

16861678
-- Encode special characters.
1687-
function xml.encodeRequiredEntities(s) -- @Doc
1679+
function xml.encodeRequiredEntities(s)
16881680
return (s:gsub("[&<>\"']", CHAR_TO_ENTITY))
16891681
end
16901682

16911683
-- Encode special characters and some additional characters (like non-breaking space).
1692-
function xml.encodeMoreEntities(s) -- @Doc
1684+
function xml.encodeMoreEntities(s)
16931685
s = xml.encodeRequiredEntities(s)
16941686

16951687
-- Note: We encode HTML entities in XML documents too. It's probably fine, but who knows!

testsite/content/all-lists-all/a.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ lock()
55

66
## Page List
77

8-
{{fori page in subpages(true)}}
9-
- {{page.title}}
8+
{{fori subpage in subpages(true)}}
9+
- {{subpage.title}}
1010
{{end}}

testsite/content/all-lists-all/b.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ lock()
55

66
## Page List
77

8-
{{fori page in subpages(true)}}
9-
- {{page.title}}
8+
{{fori subpage in subpages(true)}}
9+
- {{subpage.title}}
1010
{{end}}

testsite/content/all-lists-all/c.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ lock()
55

66
## Page List
77

8-
{{fori page in subpages(true)}}
9-
- {{page.title}}
8+
{{fori subpage in subpages(true)}}
9+
- {{subpage.title}}
1010
{{end}}

0 commit comments

Comments
 (0)