summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2014-11-04 19:15:03 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2014-11-04 19:15:03 +0100
commitf717601b37191318ca44d793ccee6fa1cc2381e7 (patch)
tree44cdafd343dd844748cd0a1b9c8bc12ae24b225e
parent8d590f58ca0d10d33517e0f42283b128c5a450d4 (diff)
downloadcontext-f717601b37191318ca44d793ccee6fa1cc2381e7.tar.gz
2014-11-04 19:12:00
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4382 -> 4386 bytes
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/publ-aut.lua7
-rw-r--r--tex/context/base/publ-dat.lua18
-rw-r--r--tex/context/base/publ-imp-apa.lua120
-rw-r--r--tex/context/base/publ-ini.lua269
-rw-r--r--tex/context/base/publ-ini.mkiv2
-rw-r--r--tex/context/base/publ-tra.lua31
-rw-r--r--tex/context/base/status-files.pdfbin24679 -> 24680 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin334509 -> 334514 bytes
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2
12 files changed, 269 insertions, 184 deletions
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index c959e6242..d76b46418 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2014.11.04 11:02}
+\newcontextversion{2014.11.04 19:10}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index abe538702..175cd14ea 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index d1bea46bb..360233529 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -28,7 +28,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2014.11.04 11:02}
+\edef\contextversion{2014.11.04 19:10}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/publ-aut.lua b/tex/context/base/publ-aut.lua
index 53f270d08..971dee45e 100644
--- a/tex/context/base/publ-aut.lua
+++ b/tex/context/base/publ-aut.lua
@@ -463,9 +463,7 @@ end
writers.author = writer
writers.editor = editor
--- how to deal with publisher?
-
-local default = { "author", "editor" }
+local default = { "author" }
function authors.getauthor(dataset,tag,categories)
local current = datasets[dataset]
@@ -482,7 +480,8 @@ function authors.getauthor(dataset,tag,categories)
if categories then
local c = categories[category]
if c then
- list = c.author or default
+ local sets = c.sets
+ list = sets and sets.author and sets.authors or default
else
list = default
end
diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua
index e5a956553..43e523f59 100644
--- a/tex/context/base/publ-dat.lua
+++ b/tex/context/base/publ-dat.lua
@@ -149,7 +149,8 @@ local default = {
fields = setmetatableindex(unknownfield),
}
-local types = { "optional", "required", "virtual" }
+local types = { "optional", "required", "virtual" }
+local virtuals = { "authoryear", "authoryears", "authornum", "num", "suffix" } -- defaults
local specifications = setmetatableindex(function(t,name)
if not name then
@@ -166,7 +167,7 @@ local specifications = setmetatableindex(function(t,name)
report("invalid data definition file %a for %a",fullname,name)
return default
end
- -- goodie for alan ...
+ --
local categories = specification.categories
if not categories then
categories = { }
@@ -181,15 +182,28 @@ local specifications = setmetatableindex(function(t,name)
--
local fields = setmetatableindex(unknownfield)
specification.fields = fields
+ --
+ local virtual = specification.virtual
+ if virtual == nil then -- so false is valid
+ virtual = virtuals
+ specification.virtual = virtual
+ end
+ --
for category, data in next, categories do
local list = setmetatableindex({},extrafields)
fields[category] = list
+ data.fields = list
+ local sets = data.sets or { }
+ if data.virtual == nil then -- so false is valid
+ data.virtual = virtual
+ end
for i=1,#types do
local t = types[i]
local d = data[t]
if d then
for i=1,#d do
local di = d[i]
+ di = sets[di] or di
if type(di) == "table" then
for i=1,#di do
list[di[i]] = t
diff --git a/tex/context/base/publ-imp-apa.lua b/tex/context/base/publ-imp-apa.lua
index 821c09607..e2ef62e25 100644
--- a/tex/context/base/publ-imp-apa.lua
+++ b/tex/context/base/publ-imp-apa.lua
@@ -1,6 +1,20 @@
--- to be checked
+-- category = {
+-- sets = {
+-- authors = { "author", "editor" },
+-- },
+-- required = { "authors", "title" },
+-- optional = { "year", "journal", "editor", "volume", "number", "pages" },
+-- virtual = { "authoryear", "authoryears", "authornum", "num", "suffix" },
+-- }
-local virtual = { "authoryear", "authoryears", "authornum", "num", "suffix" }
+-- category = {
+-- sets = {
+-- author = { "author", "editor" },
+-- },
+-- required = { "author", "title" },
+-- optional = { "year", "journal", "editor", "volume", "number", "pages" },
+-- virtual = { "authoryear", "authoryears", "authornum", "num", "suffix" },
+-- }
return {
name = "apa",
@@ -8,142 +22,148 @@ return {
comment = "APA specification.",
author = "Alan Braslau and Hans Hagen",
copyright = "ConTeXt development team",
+ virtual = {
+ -- all share the same default set
+ "authoryear", "authoryears", "authornum", "num", "suffix",
+ },
categories = {
article = {
- required = { { "author", "editor" }, "title" },
+ sets = {
+ author = { "author", "editor" },
+ },
+ required = { "author", "title" },
optional = { "year", "type", "journal", "volume", "number", "pages", "url", "note", "doi" },
- virtual = virtual,
- author = { "author", "editor" },
},
magazine = {
- required = { { "author", "editor" }, "title", "journal", "year" },
+ sets = {
+ author = { "author", "editor" },
+ },
+ required = { "author", "editor", "title", "journal", "year" },
optional = { "volume", "number", "pages", "month", "day", "note", "url", "doi" },
- virtual = virtual,
- author = { "author", "editor" },
},
newspaper = {
- required = { { "author", "editor" }, "title", "journal", "year" },
+ sets = {
+ author = { "author", "editor" },
+ },
+ required = { "author", "title", "journal", "year" },
optional = { "volume", "number", "pages", "month", "day", "note", "url", "doi" },
- virtual = virtual,
- author = { "author", "editor" },
},
book = {
+ sets = {
+ author = { "author", "editor", "publisher" },
+ },
virtual = { "authoryear" },
- required = { { "author", "editor", "publisher" }, "title" },
+ required = { "author", "title" },
optional = { "year", "month", "day", "title", "type", "edition", "series", "volume", "number", "pages", "address", "publisher", "url", "note", "ISBN" },
- virtual = virtual,
- author = { "author", "editor", "publisher" },
},
booklet = {
required = { "title" },
optional = { "author", "howpublished", "address", "month", "year", "note" },
- virtual = virtual,
- author = { "author" },
},
inbook = {
- required = { { "author", "editor", "publisher" }, "title", "chapter", "pages", "year" },
+ sets = {
+ author = { "author", "editor", "publisher" },
+ },
+ required = { "author", "title", "chapter", "pages", "year" },
optional = { "volume", "number", "series", "type", "address", "edition", "month", "note", "ISBN" },
- virtual = virtual,
author = { "author", "editor", "publisher" },
},
incollection = {
+ sets = {
+ author = { "author", "editor", "publisher" },
+ },
required = { "author", "title", "booktitle", "publisher", "year" },
optional = { "editor", "volume", "number", "series", "type", "chapter", "pages", "address", "edition", "month", "note", "ISBN" },
- virtual = virtual,
- author = { "author", "editor", "publisher" },
},
inproceedings = {
+ sets = {
+ author = { "author", "editor", "publisher" },
+ },
required = { "author", "title", "booktitle", "year" },
optional = { "editor", "volume", "number", "series", "pages", "address", "month", "organization", "publisher", "note", "ISBN" },
- virtual = virtual,
- author = { "author", "editor", "publisher" },
},
conference =
"inproceedings", -- Alan: does this work? Hans: I just made it work.
manual = {
required = { "title" },
optional = { "author", "organization", "address", "edition", "month", "year", "note" },
- virtual = virtual,
- author = { "author" },
},
mastersthesis = {
required = { "author", "title", "school", "year" },
optional = { "type", "address", "month", "note" },
- virtual = virtual,
- author = { "author" },
},
phdthesis = {
required = { "author", "title", "school", "year" },
optional = { "type", "address", "month", "note" },
- virtual = virtual,
- author = { "author" },
},
thesis = {
required = { "author", "title", "school", "year", "type" },
optional = { "address", "month", "note" },
- virtual = virtual,
- author = { "author" },
},
misc = {
required = { },
optional = { "author", "title", "howpublished", "month", "year", "note" },
- virtual = virtual,
- author = { "author" },
},
-- Not sure yet how "periodical" is used... but "jabref" includes it as standard.
-- strangely, "jabref" does not include "author" as required nor optional..
periodical = {
+ sets = {
+ author = { "editor", "publisher" },
+ },
required = { "title", "year" },
optional = { "author", "editor", "month", "note", "number", "organization", "series", "volume" },
- virtual = virtual,
- author = { "author", "editor" },
},
proceedings = {
required = { "title", "year" },
optional = { "editor", "volume", "number", "series", "address", "month", "organization", "publisher", "note", "pages", "ISBN" },
- virtual = virtual,
- author = { "editor", "publisher" },
},
techreport = {
required = { "author", "title", "institution", "year" },
optional = { "type", "number", "address", "month", "note" },
- virtual = virtual,
- author = { "author" },
},
other = {
- required = { { "author", "title" }, "year" },
+ required = { "author", "title", "year" },
optional = { "note", "doi" },
- virtual = virtual,
- author = { "author" },
},
patent = {
required = { "nationality", "number", "year", "yearfiled" },
optional = { "author", "title", "language", "assignee", "address", "type", "day", "dayfiled", "month", "monthfiled", "note", },
- virtual = virtual,
- author = { "author" },
},
electronic = {
required = { "title" },
optional = { "address", "author", "howpublished", "month", "note", "organization", "year", "url", "doi", "type" },
- virtual = virtual,
- author = { "author" },
},
-- check this!
standard = {
- required = { { "author", "institution", "organization" }, "title", "year", "note", "url" },
+ sets = {
+ author = { "author", "institution", "organization" },
+ },
+ required = { "author", "title", "year", "note", "url" },
optional = { "doi", },
- virtual = virtual,
- author = { "author", "institution", "organization" },
},
unpublished = {
required = { "author", "title", "note" },
optional = { "month", "year" },
- virtual = virtual,
- author = { "author" },
},
literal = {
required = { "key", "text", },
optional = { },
+ virtual = false,
+ },
+ --
+ ["demo-a"] = {
+ sets = {
+ author = { "author", "institution", "organization" },
+ },
+ required = { "author", "title", "year", "note", "url" },
+ optional = { "doi", },
+ },
+ ["demo-b"] = {
+ sets = {
+ authors = { "author", "institution", "organization" },
+ },
+ required = { "authors", "title", "year", "note", "url" },
+ optional = { "doi", },
},
},
}
diff --git a/tex/context/base/publ-ini.lua b/tex/context/base/publ-ini.lua
index 3f17dbcf0..8e273be00 100644
--- a/tex/context/base/publ-ini.lua
+++ b/tex/context/base/publ-ini.lua
@@ -681,6 +681,11 @@ local function shortsorter(a,b)
return a[4] < b[4]
end
+local authorkeys = {
+ "author",
+ "editor",
+}
+
function publications.enhance(dataset) -- for the moment split runs (maybe publications.enhancers)
statistics.starttiming(publications)
if type(dataset) == "string" then
@@ -692,14 +697,17 @@ function publications.enhance(dataset) -- for the moment split runs (maybe publi
local luadata = dataset.luadata
local details = dataset.details
local ordered = dataset.ordered
- -- author, editor
+ -- authors: todo, get authorkeys from current specification (so we need to redo when that spec changes)
for tag, entry in next, luadata do
- local author = entry.author
- local editor = entry.editor
- details[tag] = {
- author = author and splitauthorstring(author),
- editor = editor and splitauthorstring(editor),
- }
+ local detail = { }
+ details[tag] = detail
+ for i=1,#authorkeys do
+ local key = authorkeys[i]
+ local value = entry[key]
+ if value then
+ detail[key] = splitauthorstring(value)
+ end
+ end
end
-- short
local shorts = { }
@@ -873,149 +881,176 @@ end
-- rendering of fields
-local function found(category,field)
- local fieldspec = currentspecificationfields[category][field]
- if ignoredfields and fieldspec == "optional" and ignoredfields[field] then
- return false
- else
- return true
+do
+
+ local function permitted(category,field)
+ local catspec = currentspecificationcategories[category]
+ if not catspec then
+ report("invalid category %a, %s",category,"no specification")
+ return false
+ end
+ local fields = catspec.fields
+ if not fields then
+ report("invalid category %a, %s",category,"no fields")
+ return false
+ end
+ local kind = fields[field]
+ if ignoredfields and kind == "optional" and ignoredfields[field] then
+ return false
+ else
+ local sets = catspec.sets
+ return sets and sets[field] or true
+ end
end
-end
-function commands.btxflush(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local fields = dataset.luadata[tag]
- if fields then
- local category = fields.category
- if found(category,field) then
- local manipulator, field = splitmanipulation(field)
- local value = fields[field]
- if type(value) == "string" then
- context(manipulator and applymanipulation(manipulator,value) or value)
- return
+ local function found(dataset,tag,field,valid,fields)
+ local details = nil
+ local function check_f(field)
+ local value = fields[field]
+ if type(value) == "string" then
+ return value
+ end
+ end
+ local function check_d(field)
+ local value = details[field]
+ if type(value) == "string" then
+ return value
+ end
+ end
+ if valid == true then
+ -- local fields = dataset.luadata[tag]
+ local okay = check_f(field)
+ if okay then
+ return okay
+ end
+ details = dataset.details[tag]
+ local okay = check_d(field)
+ if okay then
+ return okay
+ end
+ elseif valid then
+ -- local fields = dataset.luadata[tag]
+ for i=1,#valid do
+ local field = valid[i]
+ local okay = check_f(field)
+ if okay then
+ return okay
end
- local details = dataset.details[tag]
- if details then
- local value = details[field]
- if type(value) == "string" then
- context(manipulator and applymanipulation(manipulator,value) or value)
- return
- end
+ end
+ details = dataset.details[tag]
+ for i=1,#valid do
+ local okay = check_d(field)
+ if okay then
+ return okay
end
- report("unknown field %a of tag %a in dataset %a",field,tag,name)
end
- else
- report("unknown tag %a in dataset %a",tag,name)
end
- else
- report("unknown dataset %a",name)
end
-end
-function commands.btxdetail(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local details = dataset.details[tag]
- if details then
- local category = fields.category
- if found(category,field) then
+ function commands.btxflush(name,tag,field)
+ local dataset = rawget(datasets,name)
+ if dataset then
+ local fields = dataset.luadata[tag]
+ if fields then
local manipulator, field = splitmanipulation(field)
- local value = details[field]
- if type(value) == "string" then
- context(manipulator and applymanipulation(manipulator,value) or value)
+ local category = fields.category
+ local valid = permitted(category,field)
+ if valid then
+ local okay = found(dataset,tag,field,valid,fields)
+ if okay then
+ context(manipulator and applymanipulation(manipulator,okay) or okay)
+ else
+ report("%s %s %a in category %a for tag %a in dataset %a","unknown","entry",field,category,tag,name)
+ end
else
- report("unknown detail %a of tag %a in dataset %a",field,tag,name)
+ report("%s %s %a in category %a for tag %a in dataset %a","invalid","entry",field,category,tag,name)
end
+ else
+ report("unknown tag %a in dataset %a",tag,name)
end
else
- report("unknown tag %a in dataset %a",tag,name)
+ report("unknown dataset %a",name)
end
- else
- report("unknown dataset %a",name)
end
-end
-function commands.btxfield(name,tag,field)
- local dataset = rawget(datasets,name)
- if dataset then
- local fields = dataset.luadata[tag]
- if fields then
- local category = fields.category
- if found(category,field) then
- local manipulator, field = splitmanipulation(field)
- local value = fields[field]
- if type(value) == "string" then
- context(manipulator and applymanipulation(manipulator,value) or value)
+ function commands.btxdetail(name,tag,field)
+ local dataset = rawget(datasets,name)
+ if dataset then
+ local fields = dataset.luadata[tag]
+ if fields then
+ local details = dataset.details[tag]
+ if details then
+ local category = fields.category
+ if permitted(category,field) then
+ local manipulator, field = splitmanipulation(field)
+ local value = details[field]
+ if type(value) == "string" then
+ context(manipulator and applymanipulation(manipulator,value) or value)
+ else
+ report("%s %s %a in category %a for tag %a in dataset %a","unknown","detail",field,category,tag,name)
+ end
+ else
+ report("%s %s %a in category %a for tag %a in dataset %a","invalid","detail",field,category,tag,name)
+ end
else
- report("unknown field %a of tag %a in dataset %a",field,tag,name)
+ report("no details for tag %a in dataset %a",tag,name)
end
+ else
+ report("unknown tag %a in dataset %a",tag,name)
end
else
- report("unknown tag %a in dataset %a",tag,name)
+ report("unknown dataset %a",name)
end
- else
- report("unknown dataset %a",name)
end
-end
-
--- testing: to be speed up with testcase
-local function found(name,tag,field,yes)
- local dataset = rawget(datasets,name)
- if dataset then
- local data = dataset.luadata[tag]
- if data then
- local category = data.category
- local fieldspec = currentspecificationfields[category][field]
- if ignoredfields and fieldspec == "optional" and ignoredfields[field] then
- fieldspec = false
- end
- if fieldspec then
- local value = data[field]
- if value then
- if value ~= "" then
- return true
+ function commands.btxfield(name,tag,field)
+ local dataset = rawget(datasets,name)
+ if dataset then
+ local fields = dataset.luadata[tag]
+ if fields then
+ local category = fields.category
+ if permitted(category,field) then
+ local manipulator, field = splitmanipulation(field)
+ local value = fields[field]
+ if type(value) == "string" then
+ context(manipulator and applymanipulation(manipulator,value) or value)
+ else
+ report("%s %s %a in category %a for tag %a in dataset %a","unknown","field",field,category,tag,name)
end
else
- local data = dataset.details[tag]
- if data then
- local value = data[field]
- if value then
- if value ~= "" then
- return true
- end
- end
- end
+ report("%s %s %a in category %a for tag %a in dataset %a","invalid","field",field,category,tag,name)
end
+ else
+ report("unknown tag %a in dataset %a",tag,name)
end
+ else
+ report("unknown dataset %a",name)
end
end
- return false
-end
-function commands.btxdoifelse(name,tag,field)
- if found(name,tag,field) then
- ctx_firstoftwoarguments()
- else
- ctx_secondoftwoarguments()
+ local function okay(name,tag,field)
+ local dataset = rawget(datasets,name)
+ if dataset then
+ local fields = dataset.luadata[tag]
+ if fields then
+ local category = fields.category
+ local valid = permitted(category,field)
+ if valid then
+-- print("!!!!!!",found(dataset,tag,field,valid,fields))
+ return found(dataset,tag,field,valid,fields)
+ end
+ end
+ end
end
-end
-function commands.btxdoif(name,tag,field)
- if found(name,tag,field) then
- ctx_firstofoneargument()
- else
- ctx_gobbleoneargument()
- end
-end
+ local ctx_doifelse = commands.doifelse
+ local ctx_doif = commands.doif
+ local ctx_doifnot = commands.doifnot
+
+ function commands.btxdoifelse(name,tag,field) ctx_doifelse(okay(name,tag,field)) end
+ function commands.btxdoif (name,tag,field) ctx_doif (okay(name,tag,field)) end
+ function commands.btxdoifnot (name,tag,field) ctx_doifnot (okay(name,tag,field)) end
-function commands.btxdoifnot(name,tag,field)
- if found(name,tag,field) then
- ctx_gobbleoneargument()
- else
- ctx_firstofoneargument()
- end
end
-- -- alternative approach: keep data at the tex end
diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv
index b8cd50036..05e5b564b 100644
--- a/tex/context/base/publ-ini.mkiv
+++ b/tex/context/base/publ-ini.mkiv
@@ -729,6 +729,8 @@
\else\iffirstargument
\let\currentbtxrendering\currentbtxdataset
\setupcurrentbtxrendering[#1]%
+ \else
+ \let\currentbtxrendering\currentbtxdataset
\fi\fi
\the\everybtxlistrendering
\publ_place_list_indeed
diff --git a/tex/context/base/publ-tra.lua b/tex/context/base/publ-tra.lua
index 82f101a6c..69117351f 100644
--- a/tex/context/base/publ-tra.lua
+++ b/tex/context/base/publ-tra.lua
@@ -155,10 +155,12 @@ function tracers.showdatasetcompleteness(settings)
ctx_FL()
if fields then
local requiredfields = fields.required
+ local sets = fields.sets or { }
local done = false
if requiredfields then
for i=1,#requiredfields do
local r = requiredfields[i]
+ local r = sets[r] or r
if type(r) == "table" then
-- this has to be done differently now
local okay = false
@@ -189,6 +191,7 @@ function tracers.showdatasetcompleteness(settings)
if optionalfields then
for i=1,#optionalfields do
local o = optionalfields[i]
+ local o = sets[o] or o
if type(o) == "table" then
-- this has to be done differently now
for i=1,#o do
@@ -236,17 +239,29 @@ function tracers.showfields(settings)
local categories = fielddata.categories
local fieldspecs = fielddata.fields
local validfields = { }
+ local function makevalid(list,sets)
+ for i=1,#list do
+ local li = list[i]
+ if sets and sets[li] then
+ -- ignore
+ elseif type(li) == "table" then
+ for i=1,#li do
+ validfields[li[i]] = true
+ end
+ else
+ validfields[li] = true
+ end
+ end
+ end
for category, fields in next, categories do
+ local sets = fields.sets
for name, list in next, fields do
- for i=1,#list do
- local li = list[i]
- if type(li) == "table" then
- for i=1,#li do
- validfields[li[i]] = true
- end
- else
- validfields[li] = true
+ if list == sets then
+ for k, v in next, list do
+ makevalid(v,sets)
end
+ else
+ makevalid(list,sets)
end
end
end
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index 7446a21af..ec195ea83 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index bdc9baeb7..aeaa95681 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 84483c2d8..d64b89c3c 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 11/04/14 11:02:25
+-- merge date : 11/04/14 19:10:15
do -- begin closure to overcome local limits and interference