diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2010-05-24 14:05:02 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2010-05-24 14:05:02 +0000 |
commit | 57ea7dad48fbf2541c04e434c31bde655ada3ac4 (patch) | |
tree | 1f8b43bc7cb92939271e1f5bec610710be69097f /Master/texmf-dist/tex/context/base/l-dimen.lua | |
parent | 6ee41e1f1822657f7f23231ec56c0272de3855e3 (diff) |
here is context 2010.05.24 13:05
git-svn-id: svn://tug.org/texlive/trunk@18445 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/l-dimen.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/l-dimen.lua | 109 |
1 files changed, 86 insertions, 23 deletions
diff --git a/Master/texmf-dist/tex/context/base/l-dimen.lua b/Master/texmf-dist/tex/context/base/l-dimen.lua index 32becb2768e..da5ab143e58 100644 --- a/Master/texmf-dist/tex/context/base/l-dimen.lua +++ b/Master/texmf-dist/tex/context/base/l-dimen.lua @@ -15,14 +15,20 @@ done by using the conversion factors collected in the following table.</p> --ldx]]-- -local format, type = string.format, type +local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable +local P, S, R, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.match + +number = number or { } + +number.tonumberf = function(n) return match(format("%.20f",n),"(.-0?)0*$") end -- one zero too much but alas +number.tonumberg = function(n) return format("%.20g",n) end local dimenfactors = { ["pt"] = 1/65536, ["in"] = ( 100/ 7227)/65536, ["cm"] = ( 254/ 7227)/65536, - ["mm"] = ( 254/72270)/65536, - ["sp"] = 1, + ["mm"] = ( 2540/ 7227)/65536, + ["sp"] = 1, -- 65536 sp in 1pt ["bp"] = ( 7200/ 7227)/65536, ["pc"] = ( 1/ 12)/65536, ["dd"] = ( 1157/ 1238)/65536, @@ -31,17 +37,62 @@ local dimenfactors = { ["nc"] = ( 5080/65043)/65536 } +--~ print(table.serialize(dimenfactors)) +--~ +--~ %.99g: +--~ +--~ t={ +--~ ["bp"]=1.5201782378580324e-005, +--~ ["cc"]=1.1883696112892098e-006, +--~ ["cm"]=5.3628510057769479e-007, +--~ ["dd"]=1.4260435335470516e-005, +--~ ["em"]=0.000152587890625, +--~ ["ex"]=6.103515625e-005, +--~ ["in"]=2.1113586636917117e-007, +--~ ["mm"]=5.3628510057769473e-008, +--~ ["nc"]=1.1917446679504327e-006, +--~ ["nd"]=1.4300936015405194e-005, +--~ ["pc"]=1.2715657552083333e-006, +--~ ["pt"]=1.52587890625e-005, +--~ ["sp"]=1, +--~ } +--~ +--~ patched %s and tonumber +--~ +--~ t={ +--~ ["bp"]=0.00001520178238, +--~ ["cc"]=0.00000118836961, +--~ ["cm"]=0.0000005362851, +--~ ["dd"]=0.00001426043534, +--~ ["em"]=0.00015258789063, +--~ ["ex"]=0.00006103515625, +--~ ["in"]=0.00000021113587, +--~ ["mm"]=0.00000005362851, +--~ ["nc"]=0.00000119174467, +--~ ["nd"]=0.00001430093602, +--~ ["pc"]=0.00000127156576, +--~ ["pt"]=0.00001525878906, +--~ ["sp"]=1, +--~ } + --[[ldx-- <p>A conversion function that takes a number, unit (string) and optional format (string) is implemented using this table.</p> --ldx]]-- +-- was: + local function todimen(n,unit,fmt) if type(n) == 'string' then return n else unit = unit or 'pt' - return format(fmt or "%.5f%s",n*dimenfactors[unit],unit) + return format(fmt or "%s%s",n*dimenfactors[unit],unit) + -- if fmt then + -- return format(fmt,n*dimenfactors[unit],unit) + -- else + -- return match(format("%.20f",n*dimenfactors[unit]),"(.-0?)0*$") .. unit + -- end end end @@ -49,8 +100,7 @@ end <p>We collect a bunch of converters in the <type>number</type> namespace.</p> --ldx]]-- -number = number or { } - +number.maxdimen = 1073741823 number.todimen = todimen number.dimenfactors = dimenfactors @@ -75,10 +125,12 @@ a number and optionally a unit. When no unit is given a constant capture takes place.</p> --ldx]]-- -local amount = (lpeg.S("+-")^0 * lpeg.R("09")^0 * lpeg.P(".")^0 * lpeg.R("09")^0) + lpeg.Cc("0") -local unit = lpeg.R("az")^1 +local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0") +local unit = R("az")^1 -local pattern = amount/tonumber * (unit^1/dimenfactors + lpeg.Cc(1)) -- tonumber is new +local dimenpair = amount/tonumber * (unit^1/dimenfactors + Cc(1)) -- tonumber is new + +lpeg.patterns.dimenpair = dimenpair --[[ldx-- <p>We use a metatable to intercept errors. When no key is found in @@ -89,30 +141,37 @@ alternative index function.</p> local mt = { } setmetatable(dimenfactors,mt) mt.__index = function(t,s) - error("wrong dimension: " .. s) - return 1 + -- error("wrong dimension: " .. (s or "?")) -- better a message + return false end function string:todimen() if type(self) == "number" then return self else - local value, unit = pattern:match(self) - print(value,unit) + local value, unit = lpegmatch(dimenpair,self) return value/unit end end +local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0 +local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") + + P("pc") + P("dd") + P("cc") + P("nd") + P("nc") + +local validdimen = amount * unit + +lpeg.patterns.validdimen = pattern + --[[ldx-- <p>This converter accepts calls like:</p> <typing> -string.todimen("10")) -string.todimen(".10")) -string.todimen("10.0")) -string.todimen("10.0pt")) -string.todimen("10pt")) -string.todimen("10.0pt")) +string.todimen("10") +string.todimen(".10") +string.todimen("10.0") +string.todimen("10.0pt") +string.todimen("10pt") +string.todimen("10.0pt") </typing> <p>And of course the often more efficient:</p> @@ -145,7 +204,7 @@ function dimen(a) if a then local ta= type(a) if ta == "string" then - local value, unit = pattern:match(a) + local value, unit = lpegmatch(pattern,a) if type(unit) == "function" then k = value/unit() else @@ -262,7 +321,7 @@ is loaded, the relevant tables that hold the functions needed may not yet be available.</p> --ldx]]-- -function dimensions.texify() +function dimensions.texify() -- todo: % local fti, fc = fonts and fonts.ids and fonts.ids, font and font.current if fti and fc then dimenfactors["ex"] = function() return fti[fc()].ex_height end @@ -312,7 +371,7 @@ function dimen(a) if k then a = k else - local value, unit = pattern:match(a) + local value, unit = lpegmatch(dimenpair,a) if type(unit) == "function" then k = value/unit() else @@ -336,7 +395,7 @@ function string:todimen() else local k = known[self] if not k then - local value, unit = pattern:match(self) + local value, unit = lpegmatch(dimenpair,self) if value and unit then k = value/unit else @@ -349,6 +408,10 @@ function string:todimen() end end +function number.toscaled(d) + return format("0.5f",d/2^16) +end + --[[ldx-- <p>In a similar fashion we can define a glue datatype. In that case we probably use a hash instead of a one-element table.</p> |