|
Post by rogerm on Oct 8, 2020 17:30:30 GMT
Hello all!
Very brief background: I support a legacy DOS-based accounting program (written in PC-BASIC) as part of my job duties. Over time I have taken it from running on native hardware (dedicated x86 workstation and a dot matrix printer), to running in an XP environment in a compatibility mode terminal window using DOSPRN to handle the printing. However I'd like to get beyond XP for security purposes and I was looking to port the entire program into a newer version of BASIC. Just BASIC seems ideal as there's minimal conversion from the original source and I love being able to print with no go-betweens.
However...
Many (most) of the original reports make extensive use of the old high ASCII box characters. I know Windows isn't a fan of ASCII, and it appears based on my searches here in the forum that Just BASIC isn't compatible with Unicode. Do I have any other option at all to get these characters translated over? I've thought about replacing them with some generic character like an asterisk or something but 1) there are a LOT of borders and boxes and they're all hard-coded, and 2) even if I can do all that I've still got users who don't deal well with change so maintaining the look and feel of the original (early 1990's) system is unfortunately pretty important.
Thanks all! Roger M
Edit to add - just in case anyone is unfamiliar with what I'm talking about, the original code uses the ASCII equivalents of the following:
I have a Unicode compatible font (DejaVu Sans) and I can fairly easily use the characters in Word or even here (┏┳┳┓╔══════╗) but when I paste them into Just Basic I get a string of question marks.
|
|
|
Post by tsh73 on Oct 8, 2020 20:45:17 GMT
I'm afraid you'll have to convert your box characters to whatever JB gives you.
for i = 0 to 15 print using ("##",i);" "; for j = 0 to 15 print chr$(i*16+j); next print next
While Windows could have some OEM DOS fonts, like Terminal, with box characters - I didn't found a way to make JB use that OEM encoding.
So tables in reports get to look like this (then printed in monospaced font like Courier New, Lucida Console, Andale Mono)
+==========+==========+ | X | Y | +==========+==========+ | 0.00 | 0.00000 | | 0.30 | 0.29552 | | 0.60 | 0.56464 | | 0.90 | 0.78333 | | 1.20 | 0.93204 | | 1.50 | 0.99749 | | 1.80 | 0.97385 | | 2.10 | 0.86321 | | 2.40 | 0.67546 | | 2.70 | 0.42738 | | 3.00 | 0.14112 | | 3.30 | -0.15775 | | 3.60 | -0.44252 | | 3.90 | -0.68777 | | 4.20 | -0.87158 | | 4.50 | -0.97753 | | 4.80 | -0.99616 | | 5.10 | -0.92581 | | 5.40 | -0.77276 | | 5.70 | -0.55069 | | 6.00 | -0.27942 | | 6.30 | 0.01681 | +----------+----------+
print "+";string$("=", 10);"+";string$("=", 10);"+" print "|";center$("X",10);"|";center$("Y",10);"|" print "+";string$("=", 10);"+";string$("=", 10);"+"
for x = 0 to 6.3 step 0.3 y = sin(x) print "|";center$(using ("#.##",x),10);"|";center$(using ("##.#####",y),10);"|" next print "+";string$("-", 10);"+";string$("-", 10);"+"
'functions '--------------------------------------------- function string$(c$, n) for i = 1 to n string$ = string$ +c$ next end function
'adds spaces from the left until 'n' symbols 'if n<len(a$) returns left$(a$,n) function padl$(a$,n) padl$ = left$(space$(n-len(a$))+a$,n) end function
'adds spaces from the right until 'n' symbols 'if n<len(a$) returns left$(a$,n) function padr$(a$,n) padr$ = left$(a$+space$(n-len(a$)),n) end function
function center$(a$,n) center$ = left$(space$((n-len(a$))/2)+a$+space$((n-len(a$))/2+1),n) end function
|
|
|
Post by rogerm on Oct 8, 2020 21:20:15 GMT
Thank you for the heads up! Bit of a bummer but I'll keep at it. To me, tables made of pipes and equals and plus signs are perfectly serviceable. Like I said though I have users who like things the way they like them (i.e., stuck in the prior century). :-) It's also occurred to me that I could use my current setup (or even Word, for that matter) to generate a blank form for the report and use Just BASIC to output to the correct places on the sheet. As I said I'll keep working on it.
|
|
|
Post by Rod on Oct 9, 2020 7:00:53 GMT
Look at printform.bas that ships with Just BASIC. You will see that it is relatively easy to draw professional looking documents. You would need to draw the outlines, draw text, print the form. The form must be paged that’s probably your next hurdle.
You might also consider drawing a .bmp for each character. You could have a little .bmp for each ASCII character. Then you have one print function that takes the text you want printed ands swaps it to bmps.
Might be worth coding a demo since it has been discussed before. Not sure when I can get time but there are many proficient coders on here that could code this solution.
|
|
|
Post by Rod on Oct 9, 2020 8:28:02 GMT
How many characters wide are you printing?
|
|
rnbw
New Member
Posts: 4
|
Post by rnbw on Oct 9, 2020 8:44:25 GMT
PC_BASIC still runs on Windows 10, albeit only in 32-bit mode. There are other directly compatible solutions in QB64 or Freebasic. You may find these easier to resolve your problem, although I am sure that the team at JB will do their best to help you.
|
|
|
Post by Rod on Oct 9, 2020 9:44:09 GMT
Yes another BASIC may be an easier solution but you wont find anything as much fun or as flexible as Just BASIC This is some code to use a code437 image. I am sure there will be a wrinkle or two to sort out. You will need this image. And this code, you will need to tell us about the width and the page lengths you are printing. List the print commands you currently use. 'left margin 36 pixels +60 chrs @ 12 pixels + right margin 36 pixels = 800 pixel drawing 'top margin 36 pixels global pos,lin,margin margin=36 pos=margin lin=margin
WindowWidth = 860 WindowHeight = 700 UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2) graphicbox #1.g, 30, 30, 800, 600 open "Code 437 Demo" for window_nf as #1 #1 "trapclose [quit]" #1.g "down"
'load our "font" as a bmp and slice it up loadbmp "code437","code437.bmp" #1.g "drawbmp code437 0 0" c=0 for y=0 to 15 for x= 0 to 15 #1.g "getbmp bmp";c;" ";x*12;" ";y*12;" 12 12" c=c+1 next next
'create random line of text longer than the 60 character display width for t=1 to 65 t$=t$+chr$(int(rnd(0)*256)) next
'clear screen and print that line 20 times #1.g "cls" pos=margin lin=margin for n=1 to 20 nul=dosprint(t$) next
'if we want to print the page #1.g "flush" '#1.g "print 800"
wait
[quit] close #1
'this function draws appropriate bmp for each character in the string 'and moves the print position. Currently it will not handle backspace, newline 'and other control characters it will just print their symbol function dosprint(t$) length=len(t$) while p<=length #1.g "drawbmp bmp";asc(mid$(t$,p,1));" ";pos;" ";lin;" 12 12" p=p+1 pos=pos+12 if pos>756 then lin=lin+12 : pos=margin wend end function
|
|
|
Post by tsh73 on Oct 9, 2020 13:13:52 GMT
Neat Here is text screenshot of FAR mahager which uses box characters 2.txt
Left Files Commands Options Right єn Name ЙННННННННННННННННННННННННННННННН> єєn Name _ Name є є.. є Find file Alt-F7 є єє.. _RestoreSettings.bat є є1.txt є History Alt-F8 є єєAddons _SaveSettings.bat є є2.txt є Video mode Alt-F9 є єєDocumentation _Uninstall.exe є єcode437.bmp є Find folder Alt-F10 є єєPlugins _uninstall.log є єdosPrint01.bas є File view history Alt-F11 є єєa.out _ є єdosPrint02.bas є Folders history Alt-F12 є єєbatlev.bat _ є є ЗДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД єєClearPluginsCache.bat _ є є є Swap panels Ctrl-U є єєDescript.ion _ є є є Panels On/Off Ctrl-O є єєFar.exe _ є є є Compare folders є єєFar.ico _ є є ЗДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД єєFar.Site.txt _ є є є Edit user menu є єєFarEng.hlf _ є є є File associations є єєFarEng.lng _ є є є Folder shortcuts є єєFarRus.hlf _ є є є Edit sort groups є єєFarRus.lng _ є є є File panel filter Ctrl-I є єєFarSave1.reg _ є є ЗДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД єєFarSave2.reg _ є є є Plugin commands F11 є єєFile_id.diz _ є є є Screens list F12 є єєLicense.txt _ є є є Task list Ctrl-W є єєLicense.xUSSR.txt _ є є ИННННННННННННННННННННННННННННННН_ єєReadme.txt _ є є _ єєregister.frm _ є є _ єєRegister.txt _ є ЗДДДДДДДДДДДДДДДДДДД Evaluation version ДДДДДДДДДДДДДДДДДДДЗДДДДДДДДДДДДДДДДДДД Evaluation version ДДДДДДДДДДДДДДДДДДД є.. Up 09.10.20 16:03єє.. Up 31.10.19 13:55є ИНННННННННННННННН 120,942 bytes in 5 files НННННННННННННННН_ИНННННННННННННН 1,276,566 bytes in 23 files ННННННННННННННН_ C:\fromOld\C\wrk\JustBasic\_others progs\dosprintbyRod> 1Help 2UserMn 3View 4Edit 5Copy 6RenMov 7MkFold 8Delete 9ConfMn 10Quit 11Plugin 12Screen
It is 120 characters wide. Here Rod's program modified to read file 2.txt - shows first 59 columns of the file, new line after each dosprint
'left margin 36 pixels +60 chrs @ 12 pixels + right margin 36 pixels = 800 pixel drawing 'top margin 36 pixels global pos,lin,margin margin=36 pos=margin lin=margin
WindowWidth = 860 WindowHeight = 700 UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2) graphicbox #1.g, 30, 30, 800, 600 open "Code 437 Demo" for window_nf as #1 #1 "trapclose [quit]" #1.g "down"
'load our "font" as a bmp and slice it up loadbmp "code437","code437.bmp" #1.g "drawbmp code437 0 0" c=0 for y=0 to 15 for x= 0 to 15 #1.g "getbmp bmp";c;" ";x*12;" ";y*12;" 12 12" c=c+1 next next
'create random line of text longer than the 60 character display width for t=1 to 65 t$=t$+chr$(int(rnd(0)*256)) next
'clear screen and print that line 20 times #1.g "cls" pos=margin lin=margin
open "2.txt" for input as #txt while not(eof(#txt)) line input #txt, a$ nul=dosprintLN(left$(a$, 59)) wend close #txt
'if we want to print the page #1.g "flush" '#1.g "print 800"
wait
[quit] close #1
'this function draws appropriate bmp for each character in the string 'and moves the print position. Currently it will not handle backspace, newline 'and other control characters it will just print their symbol function dosprint(t$) length=len(t$) while p<=length #1.g "drawbmp bmp";asc(mid$(t$,p,1));" ";pos;" ";lin;" 12 12" p=p+1 pos=pos+12 if pos>756 then lin=lin+12 : pos=margin wend end function
function dosprintLN(t$) 'with LineFeed at the end length=len(t$) while p<=length #1.g "drawbmp bmp";asc(mid$(t$,p,1));" ";pos;" ";lin;" 12 12" p=p+1 pos=pos+12 if pos>756 then lin=lin+12 : pos=margin wend lin=lin+12 : pos=margin end function
|
|
|
Post by tsh73 on Oct 9, 2020 13:17:06 GMT
Result (*actually your result with text from page above will be less perfect. Uploading/ downloading killed single vertical line )
|
|
|
Post by tenochtitlanuk on Oct 9, 2020 15:17:06 GMT
A fun thread! It got me creating code to write text in Runic ( Ogham next) using block images of each glyph grabbed from a page showing them all. By having in memory a list of all possible characters it is just like having a set of printer's wood or lead blocks and an ink pad... I've blurred the image so you'll have to look up runic to read the message. Tell me if you translated it! Will put code on my site in a couple of days.
|
|
|
Post by Rod on Oct 9, 2020 15:54:33 GMT
Cool, wingdings springs to mind as well. But I would quite like to get a fully functional display/print of code 437 so some output code from the OP would help tweak the solution.
|
|
|
Post by rogerm on Oct 9, 2020 15:54:52 GMT
That's a really interesting solution! I'll definitely play around with that. All of these reports are 80 column. (Actually officially I think they're 79 to avoid auto LF).
Also - I'm not ignoring your request for sample output code. I just can't quite figure out how to copy and paste it because of this same character encoding problem. The ASCII box drawing characters are included in line with the print statements. So for instance if I use the pipe character to stand in for the vertical box side character, a typical line is:
340 print "| |"; date$; "|$"; amt; "|"
Where date$ is of course xx/xx/xxxx and amt is a value that's presumed (for formatting purposes) to be in the form xxx.xx. If you have an amount of xxxx.xx it just pushes the side border another space over. I get the impression whoever wrote it was more of a number cruncher and not so much interested in formatting their output. It's interesting code to read (and even more interesting to keep running) but it definitely doesn't follow best practices, even for the period when it was written. And it was completely undocumented. One of the things I've done over time is add REM lines as I've figured out what sections do what.
There's really not a lot of complicated computation that happens here; if anything it's like a rudimentary database that just sends arrays out to a text file (and reads from the same file). The only stumbling block is making the printouts fit with my users' expected experience. It would probably be easier to rewrite it. Most of the read/write portions and menus could be copied over as-is but there are definitely spots where the report formatting could be more elegant.
|
|
|
Post by Rod on Oct 9, 2020 19:27:59 GMT
Yeah, forget about trying to mimic the code just show us some actual code lines Quite hard to find examples of this old printing method online.
|
|
|
Post by tenochtitlanuk on Oct 9, 2020 23:00:59 GMT
While the methods using graphic tiles are great and versatile.... in view of 'KISS' (- "Keep it simple, stupid!" ) how about..
dim transn$( 50) dim dates$( 50) dim amt( 50)
transn$( 1) ="Profits from book sales" transn$( 2) ="Charity donations." transn$( 3) ="Found under the mattress"
dates$( 1) ="09:10:2020" dates$( 2) ="09:04:1946" dates$( 3) ="27:07:1971"
amt( 1) =123.45 amt( 2) = 54.32 amt( 3) = 3.66
' long space for up to 56 chars 10 chars 6 chars
call oldPrint "H==========================================================|============|=========H" call oldPrint "H A typical entry | | H" for k =1 to 3 p$ ="H " +left$( transn$( k) +space$( 56), 56) +" | " +right$( " " +dates$( k), 10) +" | $" +right$( " " +str$( amt( k)), 6) +" H" call oldPrint p$ next k call oldPrint "H | | H" call oldPrint "H etc... | | H" call oldPrint "H==========================================================|============|=========H"
wait
sub oldPrint i$ for j =1 to len( i$) P =asc( mid$( i$, j, 1)) print chr$( P); 'lprint chr$( P); next j print "" 'lprint "" end sub
.. which produces output like..
H==========================================================|============|=========H H A typical entry | | H H Profits from book sales | 09:10:2020 | $123.45 H H Charity donations. | 09:04:1946 | $ 54.32 H H Found under the mattress | 27:07:1971 | $ 3.66 H H | | H H etc... | | H H==========================================================|============|=========H
Note I formatted the entries to always occupy the planned number of spaces.
|
|
|
Post by Rod on Oct 10, 2020 10:16:12 GMT
Ok, this is more useful, I attempt to replace the print commands you have been using rather than reformat the output. This will happily print portrait on A4 but if you put your printer inti landscape mode you will get the output you are perhaps used to.
nomainwin '80x60 character page 'left margin 32 pixels +80 chrs @ 12 pixels + right margin 32 pixels = 1024 pixel width 'top margin 32 pixels +60 chrs @ 12 pixels + bottom margin 32 pixels = 784 pixel height global pos,lin,mar,pag mar=24 '24 lines up better than 32 pos=mar lin=mar
WindowWidth = 1050 WindowHeight = 850 UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2) graphicbox #1.g, 10,10,1024,784 open "DosPrint" for window_nf as #1 #1 "trapclose [quit]" #1.g "down"
'load our "font" as a bmp and slice it up loadbmp "code437","code437.bmp" #1.g "drawbmp code437 0 0" c=0 for y=0 to 15 for x= 0 to 15 #1.g "getbmp bmp";c;" ";x*12;" ";y*12;" 12 12" c=c+1 next next #1.g "cls"
nul=doslocate(0,0) nul=dosprint("Hello") nul=doslocate(20,20) nul=dosprint("How are you?") nul=dosdump()
'create random line of text 85 characters long to check line feed for t=1 to 85 t$=t$+chr$(int(rnd(0)*256)) next
for n=1 to 6 nul=dosprint(t$) next nul=dosdump()
wait
[quit] close #1
function doslocate(x,y) pos=x*12+mar lin=y*12+mar end function
function dosdump() 'force print whatever has been drawn and start new page #1.g "flush" #1.g "print 1024" #1.g "cls" lin=mar pos=mar end function
function dosprint(t$) length=len(t$) 'work through the string drawing each symbol and moving 'the print position and line, page if needed. while p<=length #1.g "drawbmp bmp";asc(mid$(t$,p,1));" ";pos;" ";lin;" 12 12" p=p+1 pos=pos+12 'new line? if pos>996 then lin=lin+12 : pos=mar 'new page? if lin>744 then #1.g "flush" #1.g "print 1024" #1.g "cls" lin=mar pos=mar end if wend end function
|
|