Run LibreOffice Basic macros in Docker

This is the 25th day article of LibreOffice Advent Calendar 2020.


In the first place, when I wrote "I wrote a Lisp interpreter (mal) in LibreOffice Basic", I wanted to prepare up to the point that "You can try REPL using Docker". However, I tried it a little and it seemed that I couldn't make it in time, so I put it off.

After that, I investigated it again and managed to move the REPL even though there were some suspicious points (I added it to the article).

So, I am writing this because it may be useful for someone to cut out and write only the part that executes the Basic macro with Docker. Where you can think of it, you can use it for test automation.

Minimal sample

This is a minimal example using only the Standard library + Module1 module.

File to prepare

Dockerfile

FROM ubuntu:18.04

RUN apt-get update \
  && apt-get -y install --no-install-recommends \
    libreoffice-calc \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

# ~/.config/Generate libreoffice below
RUN libreoffice --headless --terminate_after_init

WORKDIR /root/work

sample.sh (script to be executed in the container)

escape_xml() {
  cat \
    | sed -e 's/&/\&/g' \
    | sed -e 's/"/\"/g' \
    | sed -e "s/'/\'/g" \
    | sed -e 's/</\&lt;/g' \
    | sed -e 's/>/\&gt;/g'
}

print_basic_src() {
  cat << BAS
Sub Main
  Dim fid As Integer
  fid = Freefile
  Open "/tmp/output" For Binary Access Write As fid
  Put(fid, 1, CStr(Time()) & Chr(10))
  Close fid
End Sub
BAS
}

user_bas_dir="${HOME}/.config/libreoffice/4/user/basic"
mod_name=Module1
mod_file="${user_bas_dir}/Standard/${mod_name}.xba"

cat << XML > ${mod_file}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
  <script:module
    xmlns:script="http://openoffice.org/2000/script"
    script:name="${mod_name}"
    script:language="StarBasic"
  >
    $(print_basic_src | escape_xml)
  </script:module>
XML

libreoffice \
  --headless --norestore --nologo --nofirststartwizard --nolockcheck \
  "vnd.sun.star.script:Standard.${mod_name}.Main?language=Basic&location=application"

cat /tmp/output

It may not be necessary to explain because it is short, but the processing content is as follows.

--Store the Basic code in ~/.config/libreoffice/4/user/basic/Standard/Module1.xba ――I think it's better to read and write XML properly if possible, but since it is a minimum sample, it overwrites Module1.xba entirely. --Execute macro with libreoffice command --The current time is written to a temporary file --Display the contents output to the temporary file

Run

#Build image
docker build -t libreoffice-basic:trial .
#Run
docker run --rm -v "$(pwd):/root/work" libreoffice-basic:trial bash sample.sh

If it works, the current time will be printed every time you run docker run ~ (it will be different from the Japanese time because you have not set the time zone).

Note

Macro security level and execution in CUI

At first, I tried to put the Basic code in a file and execute it, but in this case, I can not execute it without the GUI unless the security level is set to "low". He could change the security level without a GUI if he messed up the configuration file ... I thought about it and tried it, but I don't want to do that much ...

So, I settled on the method of registering and executing it as a user-managed macro (the one displayed as "My Macro" in the macro management dialog) instead of a file. With Docker, you can do it boldly without worrying about polluting the existing environment.

image.png

Initialize settings

The location of user-managed macros is under ~/.config/libreoffice/4/user/basic, but if you just install libreoffice with apt, this directory and other configuration files will not be generated. It is generated when LibreOffice is started once, but when it is started normally, it remains started, so you have to kill it separately ....

When I was wondering what to do, I was looking at the list of command line options and found an option called --terminate_after_init, which, as the name suggests, seems to be prepared for this purpose.

Developer arguments:
   --terminate_after_init
                       Exit after initialization complete (no documents loaded).

This is what I use in the Dockerfile. I haven't confirmed it in the document, so I'm sorry if it's used for other purposes.

When adding a library

In the above example, it is not necessary because it uses the existing Standard library, but if you want to add another library, go to ~/.config/libreoffice/4/user/basic/script.xlc. It is necessary to add.

Below is an example of adding a library called Mylib.

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE library:libraries PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "libraries.dtd">
 <library:libraries xmlns:library="http://openoffice.org/2000/library" xmlns:xlink="http://www.w3.org/1999/xlink">
   <library:library library:name="Standard" xlink:href="$(USER)/basic/Standard/script.xlb/" xlink:type="simple" library:link="false"/>
+  <library:library library:name="Mylib" xlink:href="$(USER)/basic/Mylib/script.xlb/" xlink:type="simple" library:link="false"/>
 </library:libraries>

environment

Relation

-Create a Docker image with LibreOffice Calc and run it headless --memo88

Recommended Posts

Run LibreOffice Basic macros in Docker
Docker basic summary
docker basic command
Docker basic commands
Docker in LXD
(Basic authentication) environment variables in rails and Docker
Run Pico with docker
Run Payara with Docker
Run phpunit on Docker
Install / run a standalone robot simulator in wsl2 / docker environment!
Write DiscordBot to Spreadsheets Write in Ruby and run with Docker
What is docker run -it?
Run VS Code on Docker
Run TAO Core with Docker
Install yarn in docker image
Run openvpn on Docker (windows)
[Docker] Introduction of basic Docker Instruction
Implement Basic authentication in Java
Basic knowledge in method definition
Run Rails whenever with docker
Decomposing the Docker run command. .. ..
npm error in docker tutorial
Docker Compact Manual (1: Basic / Basic Command)
[Java] Basic terms in programming
How to run a job with docker login in AWS batch