Skip to content

Commit

Permalink
Extend StreamFormatting to seperate linewrap and indenting
Browse files Browse the repository at this point in the history
As indenting and line wrapping hints are implemented teogether, we
always track indent and linewrapping hints, but only make use of them
when indenting, or linewrapping, are enabled.
  • Loading branch information
ChrisJefferson committed Jan 23, 2024
1 parent 63b79a7 commit e6956ad
Show file tree
Hide file tree
Showing 13 changed files with 390 additions and 108 deletions.
7 changes: 2 additions & 5 deletions lib/custom_streams.gi
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,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 344 in lib/custom_streams.gi

View check run for this annotation

Codecov / codecov/patch

lib/custom_streams.gi#L344

Added line #L344 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) );
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");

Check warning on line 1674 in lib/streams.gi

View check run for this annotation

Codecov / codecov/patch

lib/streams.gi#L1674

Added line #L1674 was not covered by tests
fi;
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
Loading

0 comments on commit e6956ad

Please sign in to comment.