libreoffice - run (python) macro to insert cross reference from Gnu/Linux command line - openoffice.org

I have verified that I can run both normal office and python macros from within office but I still haven't figured out how to run one (even the hello world one) from the command line.
I have googled and looked at other answers here but I'm still not entirely clear how to run an open office macro from the command line:
https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=8232
suggests to use:
office writer.odt "macro://Standard.Module1.Macro1()"
I have also seen:
office "macro://Standard.Module1.Macro1()" writer.odt
Either way around this just opens the document and and neither runs a macro nor reports an error.
Whereas How to call an existing LibreOffice python macro from a python script
suggests to run office listening on a port and communicate via that.
If I can get that far I still need to find API documentation that will explain how to insert an anchor (as per my other question
asciidoc: is there a way to create an anchor that will be visible in libreoffice writer?)
I'm using RHEL7 for context.
update
oowriter "foo.odt" macro:///Standard.Module1.addXref
works with a office basic macro.
I still haven't figured out the python one.
One issue is I can't find any debug information to look at. Are there any log files anywhere?
Another issue is which version of python to use.
The RHEL package installs site packages for python 2.7.
>rpm -q --whatprovides /usr/bin/writer
libreoffice-writer-4.3.7.2-5.el7_2.1.x86_64
>rpm -ql libreoffice-pyuno-4.3.7.2-5.el7_2.1
...
/usr/lib64/python2.7/site-packages/uno.py
Libreoffice5.1 includes 3.5 with the distro:
>/opt/libreoffice5.1/program/python --version
Python 3.5.0
So to start with I am looking for a hello world python example that pairs a known version of python with a known version of office. Preferably either of the two above (writer 4.3.7 & python 2.7? or writer 5.1 & python 3.5).
update2
Using python3.5 as installed with office5.1 I have a working hello world using the following:
import uno
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext )
# connect to the running office
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
# get the central desktop object
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
# access the current writer document
model = desktop.getCurrentComponent()
# access the document's text property
text = model.Text
# create a cursor
cursor = text.createTextCursor()
# insert the text into the document
text.insertString( cursor, "Hello World", 0 )
This works with either version of open office via:
/usr/bin/oowriter --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"
So the final part is to add the cross reference.

It looks like the command needs an extra slash. This worked for me on Ubuntu:
lowriter "Untitled 1.odt" macro:///Standard.Module1.SayHello
That calls this method in the module named Module1 under My Macros & Dialogs / Standard:
Sub SayHello
MsgBox("Hello, World!")
End Sub
The above approach only works for Basic macros. For Python macros, the standard command line approach is to connect to a listening instance of Office. Warning: This will be much (perhaps 10x) slower than running from within Office.
The link you suggested shows how to call a Python macro from a different Python script, which is more complex than what we need here. Instead, put the connecting code (starting with localContext = uno.getComponentContext()) and macro code in the same script. For an example of what should go in the script, see "First play with the Python shell to get familiar" at http://christopher5106.github.io/office/2015/12/06/openoffice-libreoffice-automate-your-office-tasks-with-python-macros.html.
As far as creating anchors, there are a number of different objects in LibreOffice that can function as anchors:
Headings
Bookmarks - example code to create them
Tables and Frames
Sections
Images and OLE Objects
This list was copied from How do I check for broken internal links in Star Basic?. In your other question you also asked about checking for broken links, so hopefully that question is helpful.
One way to create a hyperlink is to edit the HyperLinkURL property of some text. For example, say there is a bookmark called MyBookmark. Then the following code changes the currently selected text into a hyperlink:
viewcursor = currentController.getViewCursor()
viewcursor.HyperLinkURL = "#MyBookmark"
EDIT:
Regarding which version of python to use, currently LibreOffice uses python 3 and OpenOffice uses python 2.
For debugging information, you can set a checkpoint in the Basic IDE. For python, I use the logging module. OpenOffice also has various log files but I normally do not find them helpful.
Regarding problems with python, did you try the link I posted? If so, how far did you get?
I do not think you will find many RHEL examples. Try to get it working on a desktop distro like Ubuntu first, and then adapt that approach to RHEL.

Related

Multiline command-line editing in Gforth console

I have just started learning the Forth programming language.
I'm using Gforth on Ubuntu. In Gforth interactive console, I want to do indentation but it requires changing line. Enter key didn't work, it executed code. For comparison, for example, when one tests JavaScript code in web browser console, shift+enter change line without executing code. I want something like that. What key should I press? Is there a way other than using text editors like vim?
Best.
Gforth doesn't support multiline editing (see the manual).
A workaround is to edit a file in your favorite editor in another window and reload this file in Gforth console as:
include /tmp/scratch.fs
An external file can be also edited in Gforth console via a command like:
"vim /tmp/scratch.fs" system
So a one-liner for that is:
"vim /tmp/scratch.fs" system "/tmp/scratch.fs" included
That can be wrapped into a definition as:
: scratch "vim /tmp/scratch.fs" system "/tmp/scratch.fs" included ;
So the word scratch will open an editor and than load the edited file.
NB: if you use a quite old build of Gforth, you have to use s" ccc" instead of "ccc" for string literals.
To conditionally include/exclude some parts in a file the words [defined] and [if] can be used; to erase the previous instance of the loaded definitions the word marker can be used as:
[defined] _clear [if] _clear [then]
marker _clear
\ some definitions
\ ...
Take into account that usual control-flow words can be used in definitions only.

Nice way to display Terraform Plan output in Jenkins

I am working on a requirement where I need to show terraform plan output in a nicer way so that user can understand what resources it is going to create etc.
Currently we are printing terraform plan output in jenkins console in json format but we need this output in graphical format like we have Blue Ocean plugin in jenkins. I did research for various plugins bit not find any.
Do we have any kind of Jenkins plugin which shows terraform plan in the form of any visual representation like graph or do we have any alternate option where we can show the terraform plan output anywhere where user can understand it easily as we are looking for good visual representation.
Here is a link for output options of the terraform plan command. I don't think there are any visual representations regarding the plan. We are using json format and find it very readable.
You can install the AnsiColor plugin and enable the 'Color ANSI Console Output' checkbox (under Build Environments) in job configuration.
I found a few workarounds that are not jenkins specific but still work nicely in a pipeline. For simple stuff you can pipe through dot and render it using:
terraform graph -var-file=config/$TARGET.tfvars | dot -Tpng > qa-graph.png
It ain't pretty, but it works...
Now: graphviz will take that dot output and render it a little nicer. It even gives you some pretty sexy rendering options - but even though you can put lipstick on a pig, it's still a pig! The problem is the graph, itself... I think programmers have been trying to solve this for like 30 or 40 years. The '(not-so) old-school' solution is here --> stackoverflow://1494492/graphviz-how-to-go-from-dot-to-a-graph
Currently, I have been playing with graph beautifier which takes the output of tf-graph and renders it as javascript. I just push the html to nginx instead of the output from graphviz. Then, I just print the url to the output of jenkins, and open the link in a new tab. I know it's kinda-hacky, but I couldn't find any cleaner way - which brought me here, today...
ANYWAY: depending on how modular your tf-code is, the graph-beautifier creates a nice little spider-web screenshot of graph-beautifier
Below is a bash snip-it from the end of my jenkinsfile which rendered that screenshot
#------------------------------------------------------------------------------
# * VISUALIZER: data analysis tool to help make deployments & audits faster
# creates a tf-graph file & publish to the web using local nginx server
#> requires nginx & graphviz -- https://graphviz.org
#------------------------------------------------------------------------------
WEBHOST='myserver.example.com'
WEBROOT='/usr/share/nginx/html'
WEBPATH="graphviz/$BRANCH"
WEBDEST="$WEBROOT/$WEBPATH"
WEBPAGE="index.html"
# * create the target dir if it doesn't exist
[ -d $WEBDEST ] || mkdir -vp $WEBDEST
##------------------------------------------------------------------------------
## 21-1124JN - unhappy with just an image I switched to an interactive visualizer
## ? -- https://github.com/pcasteran/terraform-graph-beautifier
##------------------------------------------------------------------------------
terraform graph | /usr/share/go/bin/terraform-graph-beautifier \
--exclude="module.root.provider" \
--output-type=cyto-html \
--embed-modules=true \
> $WEBDEST/$WEBPAGE
echo -en "\n\n tf-graph --> http://$WEBHOST/$WEBPATH \n\n"
##------------------------------------------------------------------------------
## NOTE: the beautifier is just a POC. it's something I have used before and
##> threw together in a few hours for demo. There are newer projects that
##> are actively maintained & seem to have a lot cleaner ways of working with
##> larger data-sets & graphs. One is called the Rover - Terraform Visualizer
##> and is available here --> https://github.com/im2nguyen/rover check it out
##------------------------------------------------------------------------------
last but not least (as I mention in my code comments) is the Rover Terraform Visualizer - a new one that came out of the brain of one of the hashicorp-kids which is super-promising and has recently been released to open source. It is also written in go, but I haven't gotten it to work yet in my pipeline. Check out his demo.

Running spss syntax file on multiple data files automatically

I have a spss syntax file that I need to run on multiple files each in a different directory with the same name as the file, and I am trying to too do this automatically. So far I have tried doing it with syntax code and am trying to avoid doing python is spss, but all I have been able to get is the code bellow which does not work.
VECTOR v = key.
LOOP #i = 1 to 41.
GET
FILE=CONCAT('C:\Users\myDir\otherDir\anotherDir\output\',v(#i),'\',v(#i),'.sav').
DATASET NAME Data#i WINDOW=FRONT.
*Do stuff to the opened file
END LOOP.
EXE.
key is the only column in a file that contains all the names of the files.
I am having trouble debugging since I don't know how to print to the screen if it is possible. So my question is: is there a way to get the code above to work, or another option that accomplishes the same thing?
You can't use an expression like that on a GET command. There are two choices. Use the macro language to put this together (see DEFINE in the Command Syntax Reference via the Help menu) or use the SPSSINC PROCESS FILES extension command or your own Python code to select the files with a wildcard.
The extension command or a Python program require the free Python Essentials available from the SPSS Community website or available with your Statistics version.

What is the best way to print a Gtk.Widget to the printer?

I have a couple of (mostly) text widgets that I would like to render to a printer through a standard "Print..." menu option. One widget is a Mono.TextEditor document, and the other is a Gtk.TextView.
I'm looking for a pretty basic print for now, which might wrap long lines, and add page numbers. Do I need to code all of this myself somehow?
If you have pointers, that would be great, especially if they were in C#.
For line wrap and justification, one can use pango Layout
options, as described for Python at pygtk/class-pangolayout or for C at pango/pango-Layout-Objects. See functions pango_layout_set_wrap() and pango_layout_set_justify().
Also see the example-code routines begin_print, do_page_setup, and do_print in file pygtk-demo/demos/print_editor.py, if you have installed pygtk on your system. (On my system, the full path to directory of Python Gtk demo files currently is /usr/share/doc/pygtk2-2.17.0/examples/pygtk-demo/demos)
For printer setup dialog, see gtk-High-level-Printing-API for C, or class-gtkprintoperation for Python.

Ruby relative_path_from call on Windows

I'm running into an issue with the portion of the Rails generation script that searches the plugin path for appropriately named files to find generators. On one of my systems, I have Ruby installed in c:\dev\ruby and have my project directory at d:\local\projects
The Ruby Pathname#relative_path_from method (which is called by the Rails generator script) chokes on this configuration when it attempts to find the relative path between c:\ and d:\...
Has anyone run into this situation with relative_path_from and multiple drives on Windows? Is there a workaround for the rails generator script?
Here's a sample from IRB:
>> x = Pathname.new('c:/dev/ruby')
=> #<Pathname:c:/dev/ruby>
>> y = Pathname.new('d:/local/projects')
=> #<Pathname:d:/local/projects>
>> x.relative_path_from(y)
ArgumentError: different prefix: "c:/" and "d:/local/projects"
from c:/dev/ruby/lib/ruby/1.8/pathname.rb:709:in `relative_path_from'
from (irb)...
If there's no solution, I could always make sure my Ruby install and project directories are on the same drive, but that would prevent me from ever working off a project directory on a pendrive...
UPDATE: Turns out the issue is related specifically to some modification that the Radiant CMS makes to the Rails configuration variables. This change adds additional plugin directories to the project, some of which can cross drive boundaries. Since the Rails generator code doesn't expect that sort of drive-jumping, the generator breaks on my computer...
Would there be a way to compute a relative path across two different drives in Windows? I don't know.
You can avoid the problem by mounting your D: drive as a folder on your C: drive, assuming you're using NTFS. If that's not acceptable, you could create a junction from D:\local to C:\local which would let you access D:\local from both D: and C:. Then, running the same script from the C: drive should pose no problems.
How to create and use NTFS mounted drives in Windows XP and in Windows Server 2003
How to create and manipulate NTFS junction points
Junction Utility by SysInternals
The problem is this as documented in a ticket at http://redmine.ruby-lang.org/issues/show/1366
On Windows, the case of the drive letter can be either upper-case or lower-case (e.g., "C:" or "c:") on the same machine at the same time in different Command Prompt Windows (see below for details). Dir.pwd will return either lower-case or upper-case for the drive letter ("C:" or "c:") depending on the Command Prompt it is run from. However, __FILE__ always uses lower-case drive letter. This can cause an ArgumentError when comparing Dir.pwd and __FILE__ using Pathname#relative_path_from. This happens with version 1.9.1p0 as well. Pathname#relative_path_from should deal with the case where the case of the argument is different.
I have both my ruby install folder and my project folder on c: drive, but I still get the error. I monkey-patched the following lines in pathname.rb file as shown below marked within two asterisk. Remove the two asterisk when you patch.
def relative_path_from(base_directory)
dest_directory = self.cleanpath.to_s.**capitalize**
base_directory = base_directory.cleanpath.to_s.**capitalize**
...
It works after the patch. Hope it helps.

Resources