Skip to content

Commit

Permalink
Extend StreamFormatting to seperate linewrap and indenting
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson committed Jan 18, 2024
1 parent e94438a commit 7427745
Show file tree
Hide file tree
Showing 13 changed files with 391 additions and 100 deletions.
7 changes: 2 additions & 5 deletions lib/custom_streams.gi
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,8 @@ InstallMethod( PrintFormattingStatus, "output text custom",
##
InstallMethod( SetPrintFormattingStatus, "output text custom",
[IsOutputTextCustomRep and IsOutputTextStream,
IsBool],
IsObject],
function( str, stat)
if stat = fail then
Error("Print formatting status must be true or false");
else
CheckValidPrintFormattingStatus(stat);

Check warning on line 348 in lib/custom_streams.gi

View check run for this annotation

Codecov / codecov/patch

lib/custom_streams.gi#L348

Added line #L348 was not covered by tests
str!.formatting := stat;
fi;
end);
38 changes: 24 additions & 14 deletions lib/streams.gd
Original file line number Diff line number Diff line change
Expand Up @@ -959,24 +959,31 @@ DeclareGlobalFunction( "InputOutputLocalProcess" );
## and harmless if it to passed as input to ⪆,
## but may be unhelpful if the output is to be passed as input to another
## program.
## It is possible to turn off this behaviour for a stream using the
## <Ref Oper="SetPrintFormattingStatus"/> operation, and to test whether it
## is on or off using <Ref Oper="PrintFormattingStatus"/>.
## It is possible to control this behaviour for a stream using the
## <Ref Oper="SetPrintFormattingStatus"/> operation, and to query it
## using <Ref Oper="PrintFormattingStatus"/>.
## <P/>
## The formatting status is stored in a record with two members,
## <A>linewrap</A> and <A>indent</A>, which control if GAP wraps lines,
## or indents, respectively. These two both take a boolean.
## <P/>
## For backwards compatability, all functions which control print formatting
## will also take a boolean, which sets <A>linewrap</A> and <A>indent</A> to
## the given boolean value.
## <P/>
## <Ref Oper="SetPrintFormattingStatus"/> sets whether output sent to the
## output stream <A>stream</A> via <Ref Func="PrintTo"/>,
## <Ref Func="AppendTo"/>, etc.
## will be formatted with line breaks and
## indentation. If the second argument <A>newstatus</A> is <K>true</K>
## then output will be so formatted, and if <K>false</K> then it will not.
## If the stream is not a text stream, only <K>false</K> is allowed.
## indentation. The second argument <A>newstatus</A> is a record or boolean,
## as described above.
## If the stream is not a text stream, both <A>linewrap</A> and <A>indent</A>
## can only be set to <K>false</K>.
## <P/>
## <Ref Oper="PrintFormattingStatus"/> returns <K>true</K> if output sent to
## the output text stream <A>stream</A> via <Ref Func="PrintTo"/>,
## <Ref Func="AppendTo"/>, etc.
## will be formatted with line breaks and
## indentation, and <K>false</K> otherwise.
## For non-text streams, it returns <K>false</K>.
## <Ref Oper="PrintFormattingStatus"/> returns a record containing the
## current value of <A>linewrap</A> and <A>indent</A> for the output text
## stream <A>stream</A>. For non-text streams, these values area always
## both <K>false</K>.
## If as argument <A>stream</A> the string <C>"*stdout*"</C> is given, these
## functions refer to the formatting status of the standard output (so usually
## the user's terminal screen).<P/>
Expand All @@ -997,7 +1004,7 @@ DeclareGlobalFunction( "InputOutputLocalProcess" );
## gap> Print(s,"\n");
## [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
## 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 ]
## gap> SetPrintFormattingStatus(str, false);
## gap> SetPrintFormattingStatus(str, rec(indent:=false,linewrap:=false));
## gap> PrintTo(str,Primes{[1..30]});
## gap> s;
## "[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,\
Expand All @@ -1015,7 +1022,7 @@ DeclareGlobalFunction( "InputOutputLocalProcess" );
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation( "SetPrintFormattingStatus", [IsOutputStream, IsBool] );
DeclareOperation( "SetPrintFormattingStatus", [IsOutputStream, IsObject] );
DeclareOperation( "PrintFormattingStatus", [IsOutputStream] );


Expand Down Expand Up @@ -1259,3 +1266,6 @@ DeclareGlobalFunction( "InputFromUser" );
## <#/GAPDoc>
##
DeclareGlobalFunction( "OpenExternal" );

DeclareGlobalFunction( "_CheckValidPrintFormattingStatus");
DeclareGlobalFunction( "_DefaultPrintFormattingStatus");
73 changes: 49 additions & 24 deletions lib/streams.gi
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,8 @@ function( str, append )
Unbind(str[i]);
od;
fi;
return Objectify( OutputTextStringType, [ str, true ] );
return Objectify( OutputTextStringType,
[ str, _DefaultPrintFormattingStatus() ] );
end );


Expand Down Expand Up @@ -929,13 +930,9 @@ InstallMethod( PrintFormattingStatus, "output text string",
##
InstallMethod( SetPrintFormattingStatus, "output text string",
[IsOutputTextStringRep and IsOutputTextStream,
IsBool],
IsObject],
function( str, stat)
if stat = fail then
Error("Print formatting status must be true or false");
else
str![2] := stat;
fi;
str![2] := _CheckValidPrintFormattingStatus(stat);
end);


Expand Down Expand Up @@ -994,7 +991,8 @@ function( str, append )
atomic OutputTextFileStillOpen do
AddSet( OutputTextFileStillOpen, fid );
od;
return Objectify( OutputTextFileType, [fid, Immutable(str), true] );
return Objectify( OutputTextFileType,
[fid, Immutable(str), _DefaultPrintFormattingStatus()]);
fi;
end );

Expand Down Expand Up @@ -1025,7 +1023,8 @@ function( str, append )
atomic OutputTextFileStillOpen do
AddSet( OutputTextFileStillOpen, fid );
od;
return Objectify( OutputTextFileType, [fid, Immutable(str), true] );
return Objectify( OutputTextFileType,
[fid, Immutable(str), _DefaultPrintFormattingStatus() ] );
fi;
end );

Expand Down Expand Up @@ -1130,13 +1129,9 @@ InstallMethod( PrintFormattingStatus, "output text file",
##
InstallMethod( SetPrintFormattingStatus, "output text file",
[IsOutputTextFileRep and IsOutputTextStream,
IsBool],
IsObject],
function( str, stat)
if stat = fail then
Error("Print formatting status must be true or false");
else
str![3] := stat;
fi;
str![3] := _CheckValidPrintFormattingStatus(stat);
end);

## formatting status for stdout or current output
Expand All @@ -1151,7 +1146,7 @@ function(str)
fi;
end);

InstallOtherMethod( SetPrintFormattingStatus, "for stdout", [IsString, IsBool],
InstallOtherMethod( SetPrintFormattingStatus, "for stdout", [IsString, IsObject],
function(str, status)
if str = "*stdout*" then
SET_PRINT_FORMATTING_STDOUT(status);
Expand Down Expand Up @@ -1255,9 +1250,7 @@ InstallMethod( SetPrintFormattingStatus, "output text none",
[IsOutputTextNoneRep and IsOutputTextNone,
IsBool],
function( str, stat)
if stat = fail then
Error("Print formatting status must be true or false");
fi;
_CheckValidPrintFormattingStatus(stat);
end);


Expand Down Expand Up @@ -1661,7 +1654,7 @@ function ( str )
if IsOutputTextStream( str ) then
TryNextMethod();
fi;
return false;
return Immutable(rec(indent := false, linewrap := false) );

Check warning on line 1657 in lib/streams.gi

View check run for this annotation

Codecov / codecov/patch

lib/streams.gi#L1657

Added line #L1657 was not covered by tests
end);


Expand All @@ -1676,13 +1669,45 @@ InstallMethod( SetPrintFormattingStatus, "for non-text output stream",
TryNextMethod();
fi;

if stat = true then
Error("non-text streams support onlyPrint formatting status false");
elif stat = fail then
Error("Print formatting status must be true or false");
stat := _CheckValidPrintFormattingStatus(stat);
if stat.linewrap or stat.indent then
Error("non-text streams do not support print formatting");
fi;

Check warning on line 1675 in lib/streams.gi

View check run for this annotation

Codecov / codecov/patch

lib/streams.gi#L1672-L1675

Added lines #L1672 - L1675 were not covered by tests
end);


InstallGlobalFunction( "_CheckValidPrintFormattingStatus",
function(fs)
local r;
if IsBool(fs) then
if fs = fail then
Error("Formatting status cannot be 'fail'");
fi;
elif IsRecord(fs) then
if Set(RecNames(fs)) <> ["indent", "linewrap"] then
Error("Formatting status records must contain exactly two components, named 'indent' and 'linewrap'");
fi;
for r in ["indent","linewrap"] do
if not fs.(r) in [false, true] then
Error(Concatenation(r, " must be 'true' or 'false' in formatting status record"));
fi;
od;
else
Error("Formatting status must be a boolean or a record");
fi;

if fs = true then
fs := rec(indent := true, linewrap := true);
elif fs = false then
fs := rec(indent := false, linewrap := false);
fi;
return Immutable(ShallowCopy(fs));
end);

InstallGlobalFunction( "_DefaultPrintFormattingStatus",
function()
return Immutable(rec(linewrap := true, indent := true));
end);

#############################################################################
##
Expand Down
2 changes: 1 addition & 1 deletion lib/string.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ InstallGlobalFunction(StringFormatted, function(s, data...)
fi;
str := "";
stream := OutputTextString(str, false);
SetPrintFormattingStatus(stream, false);
SetPrintFormattingStatus(stream, rec(linewrap := false, indent := true));

CallFuncList(PrintToFormatted, Concatenation([stream, s], data));
return str;
Expand Down
Loading

0 comments on commit 7427745

Please sign in to comment.