Overview
Comment: | add path class; add URI support for HTML link output |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
8c11f3b6696754197f3fd2223687309f |
User & Date: | lexi on 2022-09-10 01:02:12 |
Other Links: | manifest | tags |
Context
2022-09-10
| ||
03:11 | add xref blocks, minor refactors check-in: 76fe4885f4 user: lexi tags: trunk | |
01:02 | add path class; add URI support for HTML link output check-in: 8c11f3b669 user: lexi tags: trunk | |
2022-09-09
| ||
23:22 | ref now recurses into parents properly check-in: 47905a08e6 user: lexi tags: trunk | |
Changes
Modified cortav.lua from [00eceed9de] to [08a1a9b804].
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
return arg else return sp end end) end local function checkFromSec(sec,doc) if sec and not id:find'%.' then local rid = sec.refs[id] if rid then return rid, id, sec end if doc.sections[rid] then return nil, id, doc.sections[rid] end else local secid, ref = string.match(id, "(.-)%.(.+)") local s s = s or doc.sections[secid] if s then if s.refs[ref] then ................................................................................ rid = self.invocation.origin:ref(id) if rid then return rid, id, self.invocation.origin.sec end end end o,i,s = scanParents(doc) if o or s then return o,i,s end self:fail("ID “%s” does not name an object or section", id) end }; } |
|
>
|
|
|
|
>
|
|
|
|
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
return arg else return sp end end) end local function checkFromSec(sec,doc) if not id:find'%.' then if sec then local rid = sec.refs[id] if rid then return rid, id, sec end end if doc.sections[id] then return nil, id, doc.sections[id] end else local secid, ref = string.match(id, "(.-)%.(.+)") local s s = s or doc.sections[secid] if s then if s.refs[ref] then ................................................................................ rid = self.invocation.origin:ref(id) if rid then return rid, id, self.invocation.origin.sec end end end o,i,s = scanParents(self.doc) if o or s then return o,i,s end self:fail("ID “%s” does not name an object or section", id) end }; } |
Modified render/html.lua from [f159ef53c2] to [78b49cf252].
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 |
end function span_renderers.raw(v,b,s) return htmlSpan(v.spans, b, s) end function span_renderers.link(sp,b,s) local href if b.origin.doc.sections[sp.ref] then href = '#' .. getSafeID(sp) else if sp.addr then href = sp.addr else local r = b.origin:ref(sp.ref) if type(r) == 'table' then href = '#' .. getSafeID(r) else href = r end end end return tag('a',{href=href},next(sp.spans) and htmlSpan(sp.spans,b,s) or href) end span_renderers['line-break'] = function(sp,b,s) return elt('br') |
> < > > | | < | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | |
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
end function span_renderers.raw(v,b,s) return htmlSpan(v.spans, b, s) end function span_renderers.link(sp,b,s) local dest_o, _, dest_s = b.origin:ref(sp.ref) local href if dest_o == nil then -- link is to the section itself href = '#' .. getSafeID(dest_s) else -- if sp.addr then href = sp.addr else if type(dest_o) == 'table' then href = '#' .. getSafeID(dest_o) else -- URI in reference local uri = ss.uri(dest_o) if uri.class[1] == 'file' or uri.class[1] == 'asset' then if uri.namespace == 'localhost' then -- emit an actual file url href = 'file://' .. uri:construct('path','frag') elseif uri.namespace == nil then -- this is gonna be tricky. first we establish the location -- of the CWD/asset base relative to the output file (if any; -- assume equivalent otherwise) then express the difference -- as a directory prefix. -- jk tho for now we just emit the path+frag sadlol TODO href = uri:construct('path','frag') else b.origin:fail('file: URI namespace must be empty or “localhost” for HTML links; others are not meaningful (offending URI: “%s”)', dest_o) end elseif uri:canfetch() == 'http' then local sc = 'http' if uri.class[1] == 'https' or uri.class[2] == 'tls' then sc = 'https' end if uri.namespace == nil and uri.auth == nil and uri.svc == nil then -- omit the scheme so we can use a relative path href = uri:construct('path','query','frag') else uri.class = {sc} href = tostring(uri) end else href = tostring(uri) end end end return tag('a',{href=href},next(sp.spans) and htmlSpan(sp.spans,b,s) or href) end span_renderers['line-break'] = function(sp,b,s) return elt('br') |
Modified sirsem.lua from [dec9af930b] to [9b28e1fde4].
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 .... 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 .... 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 .... 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 |
return str end }; } function ss.classinstance(o) local g = getmetatable(o) if not o then return nil end local mm = getmetatable(g) if not o then return nil end if mm.__name == 'class' then return g else return nil end end ................................................................................ if #a ~= #b then return false end eq = eq or function(p,q) return p == q end for i = 1, #a do if not eq(a[i],b[i]) then return false end end return true end ss.uri = ss.declare { ident = 'uri'; mk = function() return { class = nil; namespace = nil; path = nil; ................................................................................ local s,r = rem:match '^([^:]+):(.*)$' s_class, rem = s,r end if not rem then ss.uri.exn('invalid URI “%s”', str):throw() end local s_ns do local s,r = rem:match '^//([^/]*)(.*)$' if s then s_ns, rem = s,r end end local h_query local s_frag local s_path if rem ~= '' then local s,q,r = rem:match '^([^?#]*)([?#]?)(.*)$' if s == '' then s = nil end ................................................................................ me.namespace = dec(s_ns) me.path = dec(s_path) me.query = dec(s_query) me.frag = dec(s_frag) end; cast = { string = function(me) local function san(str, chars) -- TODO IRI support chars = chars or '' local ptn = '-a-zA-Z0-9_.,;' ptn = ptn .. chars return (str:gsub('[^'..ptn..']', function(c) if c == ' ' then return '+' end return string.format('%%%02X', string.byte(c)) end)) end if me.class == nil or next(me.class) == nil then return 'none:' end local parts = { table.concat(ss.map(san,me.class), '+') .. ':'; } if me.namespace or me.auth or me.svc then table.insert(parts, '//') if me.auth then table.insert(parts, san(me.auth,':') .. '@') end if me.namespace then table.insert(parts, san(me.namespace)) end if me.svc then table.insert(parts, ':' .. san(me.svc)) end if me.path and not ss.str.begins(me.path, '/') then table.insert(parts, '/') end end if me.path then table.insert(parts, san(me.path,'+/=&')) end if me.query then table.insert(parts, '?' .. san(me.query,'?+/=&')) end if me.frag then table.insert(parts, '#' .. san(me.frag,'+/=&')) end return table.concat(parts) end; }; fns = { canfetch = function(me) for id, pr in pairs(fetchableProtocols) do for _, p in ipairs(pr.proto) do if ss.match(me.class, p) then return id end end end return false end; fetch = function(me, env) local pid = me:canfetch() if (not pid) or fetchableProtocols[pid].fetch == nil then ss.uri.exn("URI “%s” is unfetchable", tostring(me)):throw() end local proto = fetchableProtocols[pid] |
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > > | < < | | | | | | | | | | | | | | | < > > | < < > | < < > | | < | < < < < < < < < < |
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 .... 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 .... 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 .... 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 |
return str end }; } function ss.classinstance(o) local g = getmetatable(o) if not g then return nil end local mm = getmetatable(g) if not mm then return nil end if mm.__name == 'class' then return g else return nil end end ................................................................................ if #a ~= #b then return false end eq = eq or function(p,q) return p == q end for i = 1, #a do if not eq(a[i],b[i]) then return false end end return true end ss.os = {} function ss.os.getcwd() return os.getenv 'PWD' -- :((( HAX end ss.path = ss.declare { ident = 'path'; mk = function() return { relative = true; elts = {}; } end; construct = function(me, o, rel) if type(o) == 'string' then if o:sub(1,1) == '/' then me.relative = false end me.elts = ss.str.split(ss.str.enc.ascii, o, '/') elseif type(o) == 'table' then me.elts = o me.relative = rel end end; clonesetup = function(me) me.elts = ss.clone(me.elts) end; cast = { string = function(me) return (me.relative and '' or '/') .. table.concat(me.elts, '/') end; }; op = { sub = function(a,b) if a.relative ~= b.relative then return nil end local np = ss.path({}, true) local brk = false for i=1, math.max(#a.elts,#b.elts) do if not brk then if a.elts[i] ~= b.elts[i] then brk = true end end if brk then table.insert(np.elts, b.elts[i]) end end return np end; sum = function(a,b) if b.relative == false then return nil end local n = a:clone() local i = #n.elts for j, v in ipairs(b.elts) do n.elts[i+j] = v end return n end; lt = function(a,b) -- '/a/b/c' < '/a/b/c/d' -- 'q/f/g' < 'q/f/g/p/d' -- '/a' !< '/b', '/a' !< 'a' if a.relative ~= b.relative then return false end if #a.elts > #b.elts then return false end for i=1, #a.elts do if a.elts[i] ~= b.elts[i] then return false end end return true end; }; fns = { dir = function(me) local n = ss.copy(me.elts) n[#n] = nil local p = ss.path(n, me.relative) end; normalize = function(me) local np = ss.path({}, me.relative) for i, e in ipairs(me.elts) do if e == '..' then if me.relative and ( next(np.elts) == nil or np.elts[#np.elts] == '..' ) then table.insert(np.elts, '..') else table.remove(np.elts) end elseif e ~= '.' then table.insert(np.elts, e) end end return np end }; cfns = { cwd = function() return ss.path(ss.os.getcwd()) end; }; } ss.uri = ss.declare { ident = 'uri'; mk = function() return { class = nil; namespace = nil; path = nil; ................................................................................ local s,r = rem:match '^([^:]+):(.*)$' s_class, rem = s,r end if not rem then ss.uri.exn('invalid URI “%s”', str):throw() end local s_ns do local s,r = rem:match '^//([^/?#]*)(.*)$' if s then s_ns, rem = s,r end end local h_query local s_frag local s_path if rem ~= '' then local s,q,r = rem:match '^([^?#]*)([?#]?)(.*)$' if s == '' then s = nil end ................................................................................ me.namespace = dec(s_ns) me.path = dec(s_path) me.query = dec(s_query) me.frag = dec(s_frag) end; cast = { string = function(me) return me:construct('class','namespace','path','query','frag') end; }; fns = { canfetch = function(me) for id, pr in pairs(fetchableProtocols) do for _, p in ipairs(pr.proto) do if ss.match(me.class, p) then return id end end end return false end; construct = function(me, ...) local parts = {} local function add(n, ...) if n == nil then return end table.insert(parts, me:part(n)) add(...) end add(...) return table.concat(parts) end; part = function(me, p) local function san(str, chars) -- TODO IRI support chars = chars or '' local ptn = '-a-zA-Z0-9_.,;' ptn = ptn .. chars return (str:gsub('[^'..ptn..']', function(c) if c == ' ' then return '+' end return string.format('%%%02X', string.byte(c)) end)) end if p == 'class' then if me.class == nil or next(me.class) == nil then return 'none:' end return table.concat(ss.map(san,me.class), '+') .. ':'; else if me[p] == nil then return '' end if p == 'namespace' then local parts = {} if me.namespace or me.auth or me.svc then table.insert(parts, '//') if me.auth then table.insert(parts, san(me.auth,':') .. '@') end if me.namespace then table.insert(parts, san(me.namespace)) end if me.svc then table.insert(parts, ':' .. san(me.svc)) end if me.path and not ss.str.begins(me.path, '/') then table.insert(parts, '/') end end return table.concat(parts) elseif p == 'path' then return san(me.path,'+/=&') elseif p == 'query' then return '?' .. san(me.query,'?+/=&') elseif p == 'frag' then return '#' .. san(me.frag,'+/=&') end end end; fetch = function(me, env) local pid = me:canfetch() if (not pid) or fetchableProtocols[pid].fetch == nil then ss.uri.exn("URI “%s” is unfetchable", tostring(me)):throw() end local proto = fetchableProtocols[pid] |