You've already forked lazarus-ccr
fpspreadsheet: Add support for fraction formats having a fixed denominator ("# ?/4" for quarters, etc.)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4101 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -177,9 +177,19 @@ begin
|
||||
AddToList(nfcFraction, '# ?/?');
|
||||
AddToList(nfcFraction, '# ??/??');
|
||||
AddToList(nfcFraction, '# ???/???');
|
||||
AddToList(nfcFraction, '# ?/2');
|
||||
AddToList(nfcFraction, '# ?/4');
|
||||
AddToList(nfcFraction, '# ?/8');
|
||||
AddToList(nfcFraction, '# ?/16');
|
||||
AddToList(nfcFraction, '# ?/32');
|
||||
AddToList(nfcFraction, '?/?');
|
||||
AddToList(nfcFraction, '?/??');
|
||||
AddToList(nfcFraction, '?/???');
|
||||
AddToList(nfcFraction, '?/2');
|
||||
AddToList(nfcFraction, '?/4');
|
||||
AddToList(nfcFraction, '?/8');
|
||||
AddToList(nfcFraction, '?/16');
|
||||
AddToList(nfcFraction, '?/32');
|
||||
|
||||
AddToList(nfcCurrency, '#,##0 [$$];-#,##0 [$$]');
|
||||
AddToList(nfcCurrency, '#,##0.00 [$$];-#,##0.00 [$$]');
|
||||
|
@ -1307,6 +1307,20 @@ begin
|
||||
else
|
||||
AddElement(nftIntZeroDigit, n);
|
||||
end;
|
||||
'1'..'9':
|
||||
begin
|
||||
if isFrac then
|
||||
begin
|
||||
n := 0;
|
||||
while (FToken in ['1'..'9','0']) do //and (FToken <= FEnd) do
|
||||
begin
|
||||
n := n*10 + StrToInt(FToken);
|
||||
FToken := nextToken;
|
||||
end;
|
||||
AddElement(nftFracDenom, n);
|
||||
end else
|
||||
AddElement(nftText, FToken);
|
||||
end;
|
||||
'?': begin
|
||||
ScanAndCount('?', n);
|
||||
FToken := PrevToken;
|
||||
|
@ -318,6 +318,7 @@ var
|
||||
mask: String;
|
||||
timeIntervalStr: String;
|
||||
styleMapStr: String;
|
||||
int,num,denom: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
|
||||
@ -391,28 +392,72 @@ begin
|
||||
end;
|
||||
|
||||
nftFracNumZeroDigit, nftFracNumOptDigit, nftFracNumSpaceDigit:
|
||||
if (el+2 < nel) and (Elements[el+1].Token = nftFracSymbol) then
|
||||
begin
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-numerator-digits="' + IntToStr(Elements[el].IntValue) +
|
||||
'" number:min-denominator-digits="' + IntToStr(Elements[el+2].IntValue) +
|
||||
'" />';
|
||||
inc(el, 2);
|
||||
num := Elements[el].IntValue;
|
||||
inc(el);
|
||||
while (el < nel) and (Elements[el].Token in [nftSpace, nftText, nftEscaped]) do
|
||||
inc(el);
|
||||
if (el < nel) and (Elements[el].Token <> nftFracSymbol) then
|
||||
Continue;
|
||||
while (el < nel) and (Elements[el].Token in [nftSpace, nftText, nftEscaped]) do
|
||||
inc(el);
|
||||
if (el < nel) and
|
||||
(Elements[el].Token in [nftFracDenomOptDigit, nftFracDenomSpaceDigit, nftFracDenomZeroDigit, nftFracDenom])
|
||||
then
|
||||
denom := Elements[el].IntValue
|
||||
else
|
||||
Continue;
|
||||
if Elements[el].Token = nftFracDenom then // fixed denominator
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-numerator-digits="' + IntToStr(num) +
|
||||
'" number:min-denominator-digits="' + IntToStr(num) +
|
||||
'" number:denominator-value="' + IntToStr(denom) +
|
||||
'" />'
|
||||
else
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-numerator-digits="' + IntToStr(num) +
|
||||
'" number:min-denominator-digits="' + IntToStr(num) +
|
||||
'" />'
|
||||
end;
|
||||
|
||||
nftIntZeroDigit, nftIntOptDigit, nftIntSpaceDigit:
|
||||
begin
|
||||
// Mixed fraction
|
||||
if (el+4 < nel) and (Elements[el+1].Token = nftSpace) and (Elements[el+3].Token = nftFracSymbol)
|
||||
then begin
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-integer-digits="' + IntToStr(Elements[el].IntValue) +
|
||||
'" number:min-numerator-digits="' + IntToStr(Elements[el+2].IntValue) +
|
||||
'" number:min-denominator-digits="' + IntToStr(Elements[el+4].IntValue) +
|
||||
'" />';
|
||||
inc(el, 4);
|
||||
if nfkFraction in Kind then
|
||||
begin
|
||||
int := Elements[el].IntValue;
|
||||
inc(el);
|
||||
while (el < nel) and not
|
||||
(Elements[el].Token in [nftFracNumZeroDigit, nftFracNumOptDigit, nftFracNumSpaceDigit])
|
||||
do
|
||||
inc(el);
|
||||
if el = nel then
|
||||
Continue;
|
||||
num := Elements[el].IntValue;
|
||||
while (el < nel) and not
|
||||
(Elements[el].Token in [nftFracDenomZeroDigit, nftFracDenomOptDigit, nftFracDenomSpaceDigit, nftFracDenom])
|
||||
do
|
||||
inc(el);
|
||||
if el = nel then
|
||||
Continue;
|
||||
denom := Elements[el].IntValue;
|
||||
if (Elements[el].Token = nftFracDenom) then
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-integer-digits="' + IntToStr(int) +
|
||||
'" number:min-numerator-digits="' + IntToStr(num) +
|
||||
'" number:min-denominator-digits="' + IntToStr(num) +
|
||||
'" number:denominator-value="' + IntToStr(denom) +
|
||||
'" />'
|
||||
else
|
||||
Result := Result +
|
||||
'<number:fraction' +
|
||||
' number:min-integer-digits="' + IntToStr(int) +
|
||||
'" number:min-numerator-digits="' + IntToStr(num) +
|
||||
'" number:min-denominator-digits="' + IntToStr(denom) +
|
||||
'" />';
|
||||
end
|
||||
else
|
||||
// Scientific, no decimals
|
||||
@ -1624,6 +1669,8 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
|
||||
if s <> '' then fracNum := StrToInt(s) else fracNum := 0;
|
||||
s := GetAttrValue(node, 'number:min-denominator-digits');
|
||||
if s <> '' then fracDenom := StrToInt(s) else fracDenom := 0;
|
||||
s := GetAttrValue(node, 'number:denominator-value');
|
||||
if s <> '' then fracDenom := -StrToInt(s);
|
||||
nfs := nfs + BuildFractionFormatString(fracInt > 0, fracNum, fracDenom);
|
||||
end else
|
||||
if nodeName = 'number:scientific-number' then
|
||||
|
@ -480,6 +480,7 @@ type
|
||||
nftFracDenomOptDigit, // '#' in denominator, count stored in IntValue
|
||||
nftFracDenomSpaceDigit,// '?' in denominator, count stored in IntValue
|
||||
nftFracDenomZeroDigit, // '0' in denominator, count stored in IntValue
|
||||
nftFracDenom, // specified denominator, value stored in IntValue
|
||||
nftCurrSymbol, // e.g., '"$"', stored in TextValue
|
||||
nftCountry,
|
||||
nftColor, // e.g., '[red]', Color in IntValue
|
||||
@ -866,6 +867,8 @@ begin
|
||||
nftIntSpaceDigit, nftSpaceDecs, nftFracNumSpaceDigit, nftFracDenomSpaceDigit:
|
||||
if element.Intvalue > 0 then
|
||||
Result := result + DupeString('?', element.IntValue);
|
||||
nftFracDenom:
|
||||
Result := Result + IntToStr(element.IntValue);
|
||||
nftIntTh:
|
||||
case element.Intvalue of
|
||||
0: Result := Result + '#,###';
|
||||
|
@ -1179,9 +1179,14 @@ end;
|
||||
function BuildFractionFormatString(AMixedFraction: Boolean;
|
||||
ANumeratorDigits, ADenominatorDigits: Integer): String;
|
||||
begin
|
||||
Result := Format('%s/%s', [
|
||||
DupeString('#', ANumeratorDigits), DupeString('#', ADenominatorDigits)
|
||||
]);
|
||||
if ADenominatorDigits < 0 then // a negative value indicates a fixed denominator value
|
||||
Result := Format('%s/%d', [
|
||||
DupeString('?', ANumeratorDigits), -ADenominatorDigits
|
||||
])
|
||||
else
|
||||
Result := Format('%s/%s', [
|
||||
DupeString('?', ANumeratorDigits), DupeString('?', ADenominatorDigits)
|
||||
]);
|
||||
if AMixedFraction then
|
||||
Result := '# ' + Result;
|
||||
end;
|
||||
@ -2413,7 +2418,7 @@ const
|
||||
FRACNUM_TOKENS: TsNumFormatTokenSet =
|
||||
[nftFracNumOptDigit, nftFracNumZeroDigit, nftFracNumSpaceDigit];
|
||||
FRACDENOM_TOKENS: TsNumFormatTokenSet =
|
||||
[nftFracDenomOptDigit, nftFracDenomZeroDigit, nftFracDenomSpaceDigit];
|
||||
[nftFracDenomOptDigit, nftFracDenomZeroDigit, nftFracDenomSpaceDigit, nftFracDenom];
|
||||
EXP_TOKENS: TsNumFormatTokenSet =
|
||||
[nftExpDigits]; // todo: expand by optional digits (0.00E+#)
|
||||
|
||||
@ -2490,12 +2495,12 @@ begin
|
||||
// Here follows the ordinary fraction (no integer split off); sample format "??/??"
|
||||
while (i < numEl) and (AElements[i].Token in FRACNUM_TOKENS) do inc(i);
|
||||
while (i < numEl) and (AElements[i].Token in TERMINATING_TOKENS) do inc(i);
|
||||
if (AElements[i].Token <> nftFracSymbol) then
|
||||
if (i = numEl) or (AElements[i].Token <> nftFracSymbol) then
|
||||
exit(False);
|
||||
|
||||
inc(i);
|
||||
while (i < numEl) and (AElements[i].Token in TERMINATING_TOKENS) do inc(i);
|
||||
if not (AElements[i].Token in FRACDENOM_TOKENS) then
|
||||
if (i = numEl) or (not (AElements[i].Token in FRACDENOM_TOKENS)) then
|
||||
exit(false);
|
||||
|
||||
while (i < numEL) and (AElements[i].Token in FRACDENOM_TOKENS) do
|
||||
@ -2504,6 +2509,7 @@ begin
|
||||
nftFracDenomZeroDigit : inc(digits, AElements[i].IntValue);
|
||||
nftFracDenomSpaceDigit: inc(digits, AElements[i].IntValue);
|
||||
nftFracDenomOptDigit : inc(digits, AElements[i].IntValue);
|
||||
nftFracDenom : digits := -AElements[i].IntValue; // "-" indicates a literal denominator value!
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
@ -2723,8 +2729,10 @@ begin
|
||||
snumsymspace := '';
|
||||
ssymdenomspace := '';
|
||||
sfrsym := '/';
|
||||
maxDenom := Round(IntPower(10, ADigits));
|
||||
prec := 1/maxDenom;
|
||||
if ADigits >= 0 then begin
|
||||
maxDenom := Round(IntPower(10, ADigits));
|
||||
prec := 1/maxDenom;
|
||||
end;
|
||||
numEl := Length(AElements);
|
||||
|
||||
i := AIndex;
|
||||
@ -2737,10 +2745,16 @@ begin
|
||||
AValue := frac(AValue);
|
||||
end else
|
||||
frint := 0;
|
||||
FloatToFraction(AValue, prec, MaxInt, maxdenom, frnum, frdenom);
|
||||
if ADigits >= 0 then
|
||||
FloatToFraction(AValue, prec, MaxInt, maxdenom, frnum, frdenom)
|
||||
else
|
||||
begin
|
||||
frdenom := -ADigits;
|
||||
frnum := round(AValue*frdenom);
|
||||
end;
|
||||
sfrint := ProcessIntegerFormat(IntToStr(frint), fs, AElements, i,
|
||||
INT_TOKENS, false, (AElements[i].Token = nftIntTh));
|
||||
inc(i);
|
||||
//inc(i);
|
||||
while (i < numEl) and (AElements[i].Token in TERMINATING_TOKENS) do
|
||||
begin
|
||||
sintnumspace := sintnumspace + AElements[i].TextValue;
|
||||
@ -2751,7 +2765,13 @@ begin
|
||||
// "normal" fraction
|
||||
mixed := false;
|
||||
sfrint := '';
|
||||
FloatToFraction(AValue, prec, MaxInt, maxdenom, frnum, frdenom);
|
||||
if ADigits > 0 then
|
||||
FloatToFraction(AValue, prec, MaxInt, maxdenom, frnum, frdenom)
|
||||
else
|
||||
begin
|
||||
frdenom := -ADigits;
|
||||
frnum := round(AValue*frdenom);
|
||||
end;
|
||||
sintnumspace := '';
|
||||
end;
|
||||
|
||||
@ -2769,6 +2789,7 @@ begin
|
||||
ssymdenomspace := ssymdenomspace + AElements[i].TextValue;
|
||||
inc(i);
|
||||
end;
|
||||
|
||||
sfrdenom := ProcessIntegerFormat(IntToStr(frdenom), fs, AElements, i,
|
||||
FRACDENOM_TOKENS, false, false);
|
||||
AIndex := i+1;
|
||||
@ -2894,8 +2915,8 @@ begin
|
||||
// Check for fraction format
|
||||
if CheckFraction(section.Elements, el, digits) then
|
||||
s := ProcessFracFormat(AValue, fs, digits, section.Elements, el)
|
||||
// Floating-point or integer
|
||||
else
|
||||
// Floating-point or integer
|
||||
s := ProcessFloatFormat(AValue, fs, section.Elements, el);
|
||||
if (sidx = 0) and isNeg then s := '-' + s;
|
||||
Result := Result + s;
|
||||
|
Reference in New Issue
Block a user