Box Drawing Characters

Shared Libraries
Forum rules
For sharing working examples of macros / scripts. These can be in any script language supported by OpenOffice.org [Basic, Python, Netbean] or as source code files in Java or C# even - but requires the actual source code listing. This section is not for asking questions about writing your own macros.
Post Reply
JeJe
Volunteer
Posts: 2778
Joined: Wed Mar 09, 2016 2:40 pm

Box Drawing Characters

Post by JeJe »

Code to draw simple boxes with box characters round non-proportional font text such as used in the IDE or in a plain text document.

Simple test creates a Writer document with some boxed text based on an array of strings. Put in a module and run test 1

Code: Select all

'     ╔══════════════════╗
'     ║This is an example║
'     ║  of box drawing. ║
'     ╚══════════════════╝

sub test1
	oDoc = Stardesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0,Array())
	wait 200
	odoc.currentcontroller.componentwindow.setfocus
	'font needs to be non proportional and support then unicode box characters.
	'not "Courier New" is a Windows font
	oDoc.currentcontroller.viewcursor.charfontname ="Courier New" 
	sarray=array("This is an example","  of box drawing. ") 
	'boxchars = "┌─┐││└─┘"
	boxchars ="╔═╗║║╚═╝"
	'boxchars ="░░░░░░░░"
	'boxchars ="▓▓▓▓▓▓▓▓"
	'boxchars ="████████"
	'boxchars ="$$$$$$$$"
	'boxchars ="▓▓▓▓▓▓▓▓"
	'boxchars ="@@@@@@@@"
	boxRoundStringArray(odoc,sarray,boxchars ,"'     ")
end sub


sub  boxRoundStringArray(doc,sarray,boxchars ,prestring)
	for i = 0 to ubound(sarray)
		leni= len(sarray(i))
		if leni >mx then mx = leni
	next
	otext = doc.gettext
	tc = otext.createtextcursorbyrange(otext.getstart)

	tc.string =prestring & mid(boxchars,1,1) & string(mx,mid(boxchars,2,1)) & mid(boxchars,3,1)
	tc.collapsetoend
	oText.insertControlCharacter(tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)

	for i = 0 to ubound(sarray)

		st =prestring & mid(boxchars,4,1) & sarray(i)
		v = mx-len(sarray(i))
		if v>0 then st = st & string(v," ")
		st =st & mid(boxchars,5,1)
		tc.string = st
		tc.collapsetoend
		oText.insertControlCharacter(tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)

	next

	tc.string =prestring & mid(boxchars,6,1) & string(mx,mid(boxchars,7,1)) & mid(boxchars,8,1)

end sub



Test 2 uses a different approach - first create some paragraphs consisting of lines of space characters in a blank Writer document. Then make a selection using the block selection mode. The macro draws the boxes on by replacing space characters with the box characters.

Code: Select all





sub test2


	'┌───────────────────────────────────┐
	'│Call insertSpacedlines             │
	'│in a Writer document               │
	'│to add some lines full             │
	'│of spaces. Write something         │
	'│using overtype mode.               │
	'│Use BLK select mode to             │
	'│select round it. Then choose       │
	'│a pattern and call drawboxBlKSel.  │
	'│A non-proportional font will be    │
	'│needed.                            │
	'└───────────────────────────────────┘
	'
	boxchars = "┌─┐││└─┘"
	'boxchars ="╔═╗║║╚═╝"
	'boxchars ="░░░░░░░░"
	'boxchars ="▓▓▓▓▓▓▓▓"
	'boxchars ="████████"
	'boxchars ="$$$$$$$$"
	'boxchars ="▓▓▓▓▓▓▓▓"
	'boxchars ="@@@@@@@@"

	insertSpacedlines(20,40) 'CALL THIS FIRST IN A NEW WRITER DOCUMENT 
	'select a rectangle using BLK select mode
	'THEN COMMENT OUT that line and uncomment the below line and run 
	'
'	drawboxBlKSel boxchars
end sub

sub insertSpacedlines(no,width)
	st=string(width," ")
	otext=thiscomponent.text
	tc = otext.createtextcursorbyrange(otext.getend)
	for i= 1 to no

		tc.string =st
		tc.collapsetoend
		oText.insertControlCharacter(tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)

	next
end sub

Sub DrawBoxBlKSel(boxchars as string)
	dim boo as boolean

	on error resume next
	w = thiscomponent.currentcontroller.frame.componentwindow.windows(0).accessiblecontext.getaccessiblechild(0).accessiblecontext.getaccessiblechild(0)
	for i = 0 to  w.accessiblecontext.getaccessiblechildcount -1
		a =w.accessiblecontext.getaccessiblechild(i)
		with a
			if .getselectionstart <> -1 then
				if not boo then
					boo = true
					startline =i
				end if
				.replacetext .getselectionstart ,.getselectionstart+1,mid(boxchars,4,1)
				.replacetext .getselectionend -1 ,.getselectionend,mid(boxchars,5,1)
				endline=i
			end if

		end with
	next

	a =w.accessiblecontext.getaccessiblechild(startline)
	with a
		.replacetext .getselectionstart ,.getselectionstart+1,mid(boxchars,1,1)
		.replacetext .getselectionend -1 ,.getselectionend,mid(boxchars,3,1)
		st = string(.getselectionend-.getselectionstart-2,mid(boxchars,2,1)
		.replacetext .getselectionstart+1,.getselectionend -1,st
	end with
	a =w.accessiblecontext.getaccessiblechild(endline)
	with a
		.replacetext .getselectionstart ,.getselectionstart+1,mid(boxchars,6,1)
		.replacetext .getselectionend -1 ,.getselectionend,mid(boxchars,8,1)
		st = string(.getselectionend-.getselectionstart-2,mid(boxchars,7,1))
		.replacetext .getselectionstart+1,.getselectionend -1,st
	end with

hr:
End Sub


Edit: removed some surplus code I didn't remove in the test2 listing.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2778
Joined: Wed Mar 09, 2016 2:40 pm

Re: Box Drawing Characters

Post by JeJe »

This code will convert a simple texttable in Writer to a box character based version for text files displaying non proportional fonts.
table.jpg

Code: Select all


	'┌─┬─┐
	'│ │ │
	'├─┼─┤
	'│ │ │
	'└─┴─┘
	'

	'put cursor in a simple single lines of text regular texttable
	'and it will be converted to a box character version and disposed
sub test
	ch = "┌┐└┘─│┬┴├┤┼"
	'ch = "░░░░░░░░░░░"
	converttable(ch)
end sub

sub converttable(ch)
	cc = thiscomponent.currentcontroller
	vc = thiscomponent.currentcontroller.viewcursor
	if isnull(vc.texttable)=false then
		t = vc.texttable
		st = gettablestring(t,ch)
		thiscomponent.currentcontroller.select(t.anchor.start)
		thiscomponent.text.removetextcontent(t)
		thiscomponent.currentcontroller.selection.getbyindex(0).string = st
	end if
end sub

Function GetTablestring(t,ch)
	if ch ="" then ch=  "┌┐└┘─│┬┴├┤┼"


	cols = t.columns.count
	rows = t.rows.count

	dim colwidths(cols -1)

	for x = 0 to cols -1
		for y = 0 to rows - 1
			ll= len(t.getcellbyposition(y,x).string)
			if ll>colwidths(y) then colwidths(y) = ll
		next
	next

	tot =-1
	for x = 0 to cols -1
		tot =tot + colwidths(x) +1
	next

	blankrow= mid(ch,9,1) & string(tot,mid(ch,5,1)) & mid(ch,10,1) & chr(13)
	firstblankrow = blankrow
	lastblankrow = blankrow
	n = 1
	for x = 0 to cols -1
		n= n+colwidths(x) +1
		mid(blankrow,n,1) = mid(ch,11,1)
		mid(firstblankrow,n,1) = mid(ch,7,1)
		mid(lastblankrow,n,1) = mid(ch,8,1)
	next

	mid(blankrow,len(blankrow)-1,1)=mid(ch,10,1)
	mid(firstblankrow,1,1)=mid(ch,1,1)
	mid(firstblankrow,len(firstblankrow)-1,1)=mid(ch,2,1)
	mid(lastblankrow,1,1)=mid(ch,3,1)
	mid(lastblankrow,len(lastblankrow) -1,1)=mid(ch,4,1)

	tst = firstblankrow

	for x = 0 to cols -1
		tst  =tst & mid(ch,6,1)
		for y = 0 to rows - 1
			st = t.getcellbyposition(y,x).string
			st = st &  string( colwidths(y) - len(st)," ")  & mid(ch,6,1)
			tst = tst & st
		next

		tst = tst  & chr(13)
		if x <> cols -1 then tst = tst & blankrow
	next

	tst = tst & lastblankrow
	gettablestring =tst

End function
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2778
Joined: Wed Mar 09, 2016 2:40 pm

Re: Box Drawing Characters

Post by JeJe »

This code converts a texttable where the cells can have more than one line of text.
The test sub needs a document with a texttable and also a frame after it for the result.

Code: Select all



'Converts a table to a matching text only version
'with box characters for the borders
'needs a non-proportional font such as Courier New

private type stringarray
	sts() as string
end type

sub test 
'create a document with a single table 
'and add a text frame after it sized big enough for the result to be added to it

	'boxchars ="╔═╗║║╚═╝╣╠╬╦╩"
	boxchars = "┌─┐││└─┘┤├┼┬┴"
	'boxchars ="░░░░░░░░░░░░░░░"
	'boxchars ="▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓"
	'boxchars ="███████████████"
	'boxchars ="@@@@@@@@@@@@@@@"
	'boxchars ="             "
	'boxchars ="•••••••••••••"
	'boxchars ="............."


	doc = thiscomponent

	st = GetTableString(doc,doc.texttables.getbyindex(0),boxchars)

	with doc.textframes.getbyindex(0).text
	.string =""
	.createenumeration.nextelement.CharFontName = "Courier New" 'we need a non-proportional font
	.text.string= st
	end with
end sub


Function GetTableString(doc,t,boxchars)
	dim c as long

	ubc= t.columns.count -1

	ubr = t.rows.count-1

	dim ii(ubc,ubr) as stringarray
	dim maxlens(ubc)
	dim maxrows(ubr)

	for i = 0 to ubc
		c=0
		for j=0 to ubr

			ii(i,j)=new stringarray
			with ii(i,j)

				txt =t.getcellbyposition(i,j).text

				doc.currentcontroller.select(txt.getstart)
				vc = doc.currentcontroller.viewcursor
				mxr =0
				c=0
				do	
					tmp= ii(i,j).sts
					redim preserve tmp(c)
					vc.collapsetostart
					vc.gotoEndOfLine(true)
					tc = vc.text.createtextcursorbyrange(vc)
					tmp(c) = tc.string
					ii(i,j).sts = tmp
					lenvc= len(tc.string())
					if lenvc >= maxlens(i) then maxlens(i) =lenvc
					c=c+1

					vc.collapsetostart
					vc.godown(1,false)

					if equalunoobjects(vc.text,txt) = false then exit do
					vc.gotostartOfLine(false)
					mxr =mxr +1
				loop

				if mxr > maxrows(j) then maxrows(j) = mxr


			end with
		next

	next


	for i = 0 to ubc
		ll= maxlens(i)

		for j= 0 to ubr

			tmp=ii(i,j).sts

			redim preserve tmp(maxrows(j))

			for l = 0 to maxrows(j)
				st = tmp(l)
				if len(st) < ll then st = st & space(ll- len(st))
				tmp(l)=st
			next
			ii(i,j).sts =tmp
		next
	next

	st = ""
	tleftc= mid(boxchars,1,1)
	trightc= mid(boxchars,3,1)
	bleftc= mid(boxchars,6,1)
	trightc= mid(boxchars,8,1)
	vline = mid(boxchars,4,1)
	hline = mid(boxchars,2,1)

	crossline = mid(boxchars,10,1)
	firstline = mid(boxchars,1,1)
	endline = mid(boxchars,6,1)
	for i = 0 to ubc
		crossline = crossline & string(maxlens(i),hline)
		firstline = firstline & string(maxlens(i),hline)
		endline = endline & string(maxlens(i),hline)
		if i <> ubc then
			crossline = crossline & mid(boxchars,11,1)
			firstline = firstline & mid(boxchars,12,1)
			endline = endline & mid(boxchars,13,1)
		else
			crossline = crossline & mid(boxchars,9,1)
			firstline = firstline & mid(boxchars,3,1)
			endline = endline & mid(boxchars,8,1)
		end if
	next

	st =firstline & chr(13)
	for j = 0 to ubr
		for mx =0 to maxrows(j)
			st = st & vline
			for i = 0 to ubc
				st = st & ii(i,j).sts(mx)
				st = st & vline
			next
			st = st & chr(13)
		next
		if j<> ubr then	st = st  & crossline & chr(13)
	next
	st = st  & endline
	GetTableString=st
End function



Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2778
Joined: Wed Mar 09, 2016 2:40 pm

Re: Box Drawing Characters

Post by JeJe »

The table code has been improved a little and put in the attached extension.

Install extension. Run MyMacro JeText/AAA/ShowBoxCharacterDialog

Shows dialog to make non-proportional text documents from writer document
Including converting tables to aligned text and added spaces for the paragraph indent
Also tools to enter text upon a series of blank-space lines
Help is the tooltips

Usual caveats, use at own risk, work in progress, consider preliminary code etc.
Attachments
JeText.oxt
(17.02 KiB) Downloaded 281 times
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Post Reply