3

In Microsoft Word, there are two ways to display equations; Inline and Display. An inline equation is in line with text (as the name suggests), so that equations and text can be mixed. A display equation appears on its own line and is automatically centred, like so:

enter image description here

These are three separate equations, but because they are set to display mode they all appear centred and on their own line. If their mode is changed to inline, they all appear on the same line and not centred instead:

enter image description here enter image description here

My problem is that LibreOffice shows all equations using inline-mode, even if they are set to display-mode in the docx file. If I create the first example using display-mode equations Word, save it, and then open it in LibreOffice, the equations appear as if they are inline-mode:

enter image description here

Is there a setting which I can change to get display-mode equations to be on their own lines and centred, like they are in Word? Due to the sheer quantity of Word documents I have, I'd rather not modify the documents individually.

If not, is there an alternative word processor which displays the equations correctly?

2
  • 1
    @user68186 Whoops, sorry, I'll copy it into an answer. Feb 27, 2018 at 17:09
  • @user68186 Haha; I've had plenty of experience with moderating stuff like that on Stack Overflow, and it just didn't occur to me when it came to my own question... Feb 27, 2018 at 17:12

2 Answers 2

4
+100

When a formula is inserted in LibreOffice, it gets anchored As Character by default.

anchor as character

This means that it behaves the same as characters do. So we treat it the same way as if we had three characters, for example "abc" instead of three equations.

  1. Format -> Align -> Center
  2. Move the cursor after the first equation and press Enter.
  3. Repeat step 2 for the second equation.

Now, all three equations are centered and on separate lines.

three equations

Here is the result of these instructions for the "abc" example, showing that formulas behave the same as characters. (Pressing Enter auto-corrected to upper case "A").

a b c on separate lines

To make this work in both MS Word and LibreOffice, perhaps use the Inline setting only. However, I do not have a copy of MS Word to verify this, and Word Online cannot edit formulas (but can display them if that is all you need).

Is there an alternative word processor which uses the Display formula setting as MS Word does? Quite possibly; there are a number of alternatives either paid or free. Whatever alternative you choose, though, there will be incompatibilities of some kind.

2
  • While this does work, it requires that the documents are modified, which isn't really ideal; I have almost two years worth of Word documents using Display-mode equations, and now I'm trying to switch to Linux. Still, thanks a bunch for your detailed answer. Feb 25, 2018 at 15:55
  • This answer seems to be the only way to go, so I automated it into a Ruby script (see my answer). Thank you very much for pointing me in the right direction! Feb 27, 2018 at 17:10
3

I've accepted that it's unlikely there is a Word processor with this functionality for Linux, so I decided to automate Jim K's answer by creating a Ruby script.

The origin of the issue is that LibreOffice ignores the m:oMathPara XML element, which is also what Word wraps a display-mode equation in to centre it and put it on its own paragraph.

The Ruby script below uses the Nokogiri XML parsing library to replace all occurences of m:oMathPara with standard w:p paragraphs, which are also formatted to be centre-aligned. It does the following:

  1. Copies the DOCX (specified as a command-line argument) to /tmp, unzips it, and opens document.xml
  2. Scans the XML for m:oMathPara elements
  3. Replaces them with formatted w:p elements
  4. Re-zips the DOCX into /tmp
  5. Opens the resulting DOCX in LibreOffice
  6. Asks if the user wants to keep the changes; if they answer yes, the transformed DOCX is copied over the original to overwrite it

This hasn't been tested much, so you should back up any files you use it on just in case. Note that it will only work on Linux, and requires the unzip tool to be installed. (It's on universe if you don't have it: sudo apt install unzip.) You might need to gem install nokogiri too.

    #!/usr/bin/ruby
# THIS IS LINUX ONLY!
# You'll also need to install `unzip`:
#     sudo apt install unzip

require "pp"
require "zip"
require "fileutils"
require "nokogiri"

def error(msg)
    puts msg
    exit
end

temp_dir = "/tmp/dispeqfix/"

filename = ARGV[0]

error "Please pass a filename as an argument." if filename.nil?

# Remove the directory if this tool has been run before
FileUtils.remove_dir(temp_dir) if Dir.exist? temp_dir

# Extract file as a zip
%x{unzip '#{filename}' -d '#{temp_dir}'}

# Get path to document.xml, the file we need to modify
document_path = "/tmp/dispeqfix/word/document.xml"
error "document.xml not found - are you sure this file is a DOCX?" unless File.exist? document_path

xml = Nokogiri::XML(File.read(document_path))

# 'm:oMathPara' is the element which LibreOffice doesn't support
xml.search("//m:oMathPara").each do |math_para|
    # Get the paragraph containing this one
    parent_para = math_para.parent

    # Get the 'm:oMath' contained within the 'm:oMathPara'
    math_para.dup.children.each do |math|
        # Insert a new paragraph with contains the 'm:oMath'
        new_para = Nokogiri::XML::Node.new("w:p", xml)
        math.parent = new_para
        parent_para.after(new_para)

        # Centre the paragraph
        math.before("<w:pPr><w:jc w:val=\"center\"/><w:rPr/></w:pPr><w:r><w:rPr/></w:r>")
    end

    math_para.remove
end

# Write this temporary file
File.write(document_path, xml.to_xml)

# Re-zip and open it
%x{ cd /tmp/dispeqfix; zip -r ../dispeqfix.docx * }
preview = spawn("libreoffice --writer /tmp/dispeqfix.docx 2>&1 > /dev/null", out: File::NULL)
Process.detach(preview)

# Prompt for overwrite
print "Would you like to overwrite the original document with this one? [y/n] "
if $stdin.gets.chomp == "y"
    %x{ cp -f /tmp/dispeqfix.docx #{filename} }
    puts "Overwritten."
else
    puts "No change made."
end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.