Page 1 of 1

Justification of data in strings

Posted: Thu Oct 06, 2022 12:55 pm
by miskox
Are there any built-in functions for string justification?

If we want to create fixed length fields using lots of spaces just doesn't look nice:

Code: Select all

Sequence_number Customer_number ____________ITEM____________ Value
--------------- --------------- ---------------------------- -----
              1           20000 itemname1                      100
              2           30001 itemname2                      200

Code: Select all

string1$="AA"
string2$="B"
numeric1.i=10
numeric2.i=200
Ljustified$=Left(string1$+"          ",5)
Debug "_"+Ljustified$+"_"
Rjustified$=Right("        "+string2$, 5)
Debug "_"+Rjustified$+"_"
Ljustified$=Left(Str(numeric1)+"            ",5)
Debug "_"+Ljustified$+"_"
Rjustified$=Right("        "+Str(numeric2), 5)
Debug "_"+Rjustified$+"_"
Output:

Code: Select all

_AA   _
_    B_
_10   _
_  200_
What we need is something like f$fao() in DCL on OpenVMS (see https://vmssoftware.com/docs/VSI_DCL_DICT_VOL_I.pdf).

Code: Select all

f$fao("!5SL", number)
;total number of characters is 5 with 'number' added (same as Right("        "+Str(numeric), 5) )
; SL=leading space, ZL=leading zero

f$fao("!20AS"," ")
; inserts 20x spaces so we don't have to type them. Could be used in: Left(string$+f$fao("!100AS"," "),100) to justify left
Or am I missing something? I checked manual but can't find any function that would do this?

Thanks.
Saso

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 12:59 pm
by STARGÅTE
I think you are looking for RSet() and LSet()

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 1:00 pm
by Kiffi
Take a look at LSet() And RSet()

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 1:27 pm
by miskox
Yes! This is it! I don't know how I missed that (too many functions I guess).

Thank you both.
Saso

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 3:36 pm
by netmaestro
LSet and RSet are a good start but they're not very useful if you don't use a monospace font. With those commands and a monospace font you're cooking with gas.

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 5:09 pm
by miskox
netmaestro wrote: Thu Oct 06, 2022 3:36 pm LSet and RSet are a good start but they're not very useful if you don't use a monospace font. With those commands and a monospace font you're cooking with gas.
I need this for console app (data processing) so Console font is used.
Thanks for the tip.

Saso

Re: Justification of data in strings

Posted: Thu Oct 06, 2022 9:03 pm
by AZJIO

Re: Justification of data in strings

Posted: Fri Oct 07, 2022 2:54 am
by Olli
Less useful, to center :

Code: Select all

Procedure.s CSet(a$, n, i = 1)
 Protected lenA = Len(a$)
 Protected overLen = n - lenA
 Protected leftSet = overLen / 2 + i * ((lenA ! n) & 1)
 Protected rightSet = n - leftSet - lenA
 ProcedureReturn Space(leftSet) + a$ + Space(rightSet)
EndProcedure

Re: Justification of data in strings

Posted: Sat Oct 08, 2022 9:56 am
by miskox
Olli wrote: Fri Oct 07, 2022 2:54 am Less useful, to center :

Code: Select all

Procedure.s CSet(a$, n, i = 1)
 Protected lenA = Len(a$)
 Protected overLen = n - lenA
 Protected leftSet = overLen / 2 + i * ((lenA ! n) & 1)
 Protected rightSet = n - leftSet - lenA
 ProcedureReturn Space(leftSet) + a$ + Space(rightSet)
EndProcedure
Thanks Olli! Great. I (or somebody else) might need it some day.

Saso

Re: Justification of data in strings

Posted: Sat Oct 08, 2022 10:17 am
by STARGÅTE
Please keep in mind, RSet and LSet also truncate the strings, if they are longer than the given length.
Here is a CSet which considers this behavior and also has the optional filling character.

Code: Select all

Procedure.s CSet(String.s, Length.i, Character.s=" ")
	Protected Spaces.i = Length - Len(String)
	If Spaces > 0 ; Extend
		ProcedureReturn RSet(LSet(String, Length-Spaces>>1, Character), Length, Character)
	ElseIf Spaces < 0 ; Truncate
		ProcedureReturn Left(Mid(String, 1+(-Spaces)>>1), Length)
	Else
		ProcedureReturn String
	EndIf
EndProcedure

Debug CSet("Hello World!", 20)
Debug CSet("Hello World!", 20, "-")
Debug CSet("Hello World!", 8)

Re: Justification of data in strings

Posted: Sat Oct 08, 2022 8:00 pm
by Olli
STARGÅTE wrote: Sat Oct 08, 2022 10:17 am Please keep in mind, RSet and LSet also truncate the strings, if they are longer than the given length.
In this case, it would be wise to warn the truncation with a default symbol (arrows, ellipsis, ... )

Price of this house :

Code: Select all

 200,00
euros. :mrgreen:

Re: Justification of data in strings

Posted: Sun Oct 09, 2022 3:46 pm
by Jeff8888
If you would prefer to use proportional fonts, which look better, then you need to use different space size. Unicode offers different space sizes starting with characters 2000 (hex). Note size of normal space is 7, whereas for digits it is 13. So for example with Ariel fonts the appropriate space character is hex 2007.

To display right justified numbers in a table use a the command for each column Rset(Str(variable),length,char($2007))

Here is a simple program to show the widths of various characters for the font (change for your preference) in the program. Note digits and character $2007 have the same width. Also note minus sign has a smaller width, same as character $2004.

Code: Select all

If OpenWindow(0, 0, 0, 1000,500,"", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  font1= LoadFont(#PB_Any, "Arial MS Unicode",18)
  StartDrawing(WindowOutput(0) )
  DrawingFont(FontID(font1))
  For i=32 To 127
    Debug Str(i)+"  " +Chr(i)+ "  " +StrF(TextWidth(Chr(i)))
  Next
  For i=$2000 To $200B
    Debug Hex(i)+"  " +Chr(i)+ "  " +StrF(TextWidth(Chr(i)))
  Next
  StopDrawing()  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
End
Using this information here is a code snippet from a program I wrote to display a matrix

Code: Select all

 For i=1 To ncmps          ;For each row of B-Matrix  (note B is a square matrix)
          p$=RSet(Str(i),6,Chr($2007))
          For k=1 To ncmps        ;For each col of B-Matrix
            If Bmatrix(i,k)<0                                ;use slightly different spacing due to minus sign
              p$=p$+#CRLF$+RSet(StrF(Bmatrix(i,k)*10000.0,3),6,Chr($2007))
            Else
              p$=p$+#CRLF$+Chr($2004)+RSet(StrF(Bmatrix(i,k)*10000.0,3),5,Chr($2007))
            EndIf
          Next
          AddGadgetItem(#Table1,-1,p$) 
          If Mod(i,5)=0
            SetGadgetItemColor(#Table1,i-1,#PB_Gadget_BackColor,ColorBack3,#PB_All)
          EndIf
        Next