Formatting MS Word 2003 Documents for Kindle publishing: MS Word VBA Macro
The Kindle Direct Publishing program is a great way for authors to self-publish their books for Kindle users. There are several limitations however when it comes to readying your book for the Kindle since Kindle only supports very basic HTML. You have to abandon any fancy formatting you may have done in recent word processors and give your book a ’1999 Netscape Navigator 3.0 compatible website’ look.
I recently decided to move one of my Dad’s books into this channel. The book was written in MS-word and formatted to properly print on both sides of a page. Additionally there were many non-standard formatting techniques – eg different Header styles applied to different chapter headings. Properly formatting the book for Kindle would have taken a lot of effort, so I decided to accomplish at least part of that effort, using VBA for MS-word.
The VBA Macro I developed is below with instructions for use. This macro Kindle-readies a word document by:
1 – Transforming Page size to be 4.5″x5.5″, plus very small margins.
2 – Justifies all paragraphs, and reduces their indents to a very small value
3 – Merges all columns within Tables, so there are only tables with one column and as many rows as originally existed. I did this because the tables in my word documents were poorly formatted, and I decided to go with a 1-column table layout that the kindle could handle more easily.
4 – Centers all tables and shapes on the page
This macro will also save the current document and save a copy as a HTML (Filtered) file in a specified subdirectory with a “KDP_” prefix. You can choose to switch off either option.
What this macro does not do -
1 – Clean up headers/footers
2 – Standardize formatting – e.g. the header styles for different sections
3 – Clean up any font issues
4 – Clean up the resulting HTML code – I recommend running HTMLTidy within Notepad++ on the HTML files generated through this code. One specific problem that HTMLTidy resolved was long strings of space, newline or tab characters that create unnecessary whitespace on the Kindle. As this kind of whitespace may have specific purpose in your word document, I did not make this cleanup part of the code.
5 – Reduce image size. Still need to figure this one out – does Kindle automatically reduce all images to viewable size?
6 – a lot of other issues your word files may have!
Below are instructions on using the code and the code itself. Please note this was made for a very specific purpose, and there are absolutely no warranties of any kind. Use this at your own risk! And take a backup of all your files before proceeding. Also I will only make future updates to the code as required to suit my purpose. This macro was designed and tested on MS Office 2003.
How to use this macro -
- I run this Macro in the Normal.dot file. See these steps at the end to know how to insert this code into the Normal.dot file
- After the Macro has been inserted into the Normal.dot file, I created a toolbar button to run it. You could choose to run it from the Tools menu everytime.
- If you would like to save resulting HTML files in a subdirectory of the folder where your word document is, then modify the KDPPATH variable in the macro.
- This macro will save the current document (Doc) and also save a HTML version. To stop either option, you can comment out the corresponding line in the macro.
- Open the word document that you need to convert.
- Run the macro using the toolbar button or from the Tools menu.
- Wait until you get a ‘Done’ message box. Then your doc/html file should be ready. The MSWord window will show the HTML file after completion (unless you opted out of the HTML generation).
- You may need to further work on the DOC file and address other issues before it is finally ready for Kindle formatting. If you do this, you will need to save it as an HTML from the File menu yourself.
Macro Code
Option Explicit
Dim KDPPATH As String
Dim INDENTVALUE As Single
Public Sub PerformKindleFormatting()
‘if you have a subdirectory in the SAME folder as the DOC file where you want the KDP html files to be saved, then
‘put that subdirectory name in the KDPPATH variable below. Leave blank if you want html files to be in the same location as the DOC
KDPPATH = “myKDP/” ‘ don’t remove the trailing backslash \ if you put a value here !!!!!INDENTVALUE = 1 / 72
‘MsgBox “Starting ‘” & ActiveDocument.Name & “‘ You will receive another message when the process is done.”
Step1DoPagesetup
Step2FixAlignments
‘ Step3
‘Step4SaveDocument ‘ comment out this line if you don’t want to save the modified DOC file itself
Step5SaveAsWebpage ‘ comment out this line if you don’t want to save a copy in HTML (Filtered) format
MsgBox “Done”
End SubSub Step1DoPagesetup()
‘ MOST OF THE CODE HERE GENERATED BY RECORDING A MACRO..SOME TWEAKS AS COMMENTED BELOW
With ActiveDocument.Styles(wdStyleNormal).Font
If .NameFarEast = .NameAscii Then
.NameAscii = “”
End If
.NameFarEast = “”
End With
With ActiveDocument.PageSetup
.LineNumbering.Active = False
.Orientation = wdOrientPortrait
.TopMargin = InchesToPoints(INDENTVALUE) ‘VERY SMALL MARGIN
.BottomMargin = InchesToPoints(INDENTVALUE) ‘VERY SMALL MARGIN
.LeftMargin = InchesToPoints(INDENTVALUE) ‘VERY SMALL MARGIN
.RightMargin = InchesToPoints(INDENTVALUE) ‘VERY SMALL MARGIN
.Gutter = InchesToPoints(0)
.HeaderDistance = InchesToPoints(0) ‘HEADER IS RIGHT ON TOP
.FooterDistance = InchesToPoints(0) ‘FOOTER IS RIGHT AT BOTTOM
.PageWidth = InchesToPoints(4.5) ‘USING 4.5 INCHES TO SOMEWHAT ALIGN WITH KINDLE VIEWABLE SCREEN WIDTH
.PageHeight = InchesToPoints(5.5) ‘USING 5.5 INCHES TO SOMEWHAT ALIGN WITH KINDLE VIEWABLE SCREEN HEIGHT
.FirstPageTray = wdPrinterDefaultBin
.OtherPagesTray = wdPrinterDefaultBin
.SectionStart = wdSectionContinuous ‘ MODIFIED THIS TO CONTINOUS. TEST WITH NEWPAGE OPTION ALSO?
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.VerticalAlignment = wdAlignVerticalTop
.SuppressEndnotes = False
.MirrorMargins = False
.TwoPagesOnOne = False
.BookFoldPrinting = False
.BookFoldRevPrinting = False
.BookFoldPrintingSheets = 1
.GutterPos = wdGutterPosLeft
End With
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow.ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub
Public Sub Step2FixAlignments()
Dim i As Long
Dim j As Long
With ActiveDocument
For i = 1 To .Paragraphs.Count
.Paragraphs(i).Alignment = wdAlignParagraphJustify ‘ JUSTIFY ALL TEXT
.Paragraphs(i).FirstLineIndent = InchesToPoints(INDENTVALUE) ‘ SMALL INDENT TO FIRST LINE OF PARAS
.Paragraphs(i).LeftIndent = InchesToPoints(INDENTVALUE) ‘ SMALL INDENT TO PARA
Next i
For i = 1 To .Sections.Count
‘Sections(i).Range.Borders.InsideLineStyle = wdLineStyleThickThinLargeGap ‘DOING NOTHIN TO SECTIONS
Next i
For i = .Tables.Count To 1 Step -1
For j = 1 To .Tables(i).Rows.Count
.Tables(i).Rows(j).Select
Selection.Cells.Merge ‘ MERGE COLUMNS IN TABLES SO THERE ARE ONLY TABLES WITH SINGLE COLUMNS
Next j
.Tables(i).Rows.Alignment = wdAlignRowCenter ‘CENTER TABLE
.Tables(i).AutoFitBehavior (wdAutoFitWindow) ‘MAKE TABLE AUTOFIT TO WINDOW
Next i
‘For i = 1 To .InlineShapes.Count
‘ .InlineShapes(i).Borders.Enable = True
‘ .InlineShapes(i).Borders.OutsideLineWidth = wdLineWidth150pt
‘ .InlineShapes(i).Borders.OutsideColor = wdColorBrightGreen
‘ .InlineShapes(i).Borders.OutsideLineStyle = wdLineStyleDashLargeGap
‘Next i
Dim oILShp As InlineShape
For Each oILShp In ActiveDocument.InlineShapes
oILShp.Select
Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter ‘ CAUSE INLINE SHAPES TO CENTER
Next
For i = 1 To .Shapes.Count
.Shapes(i).Left = wdShapeCenter
.Shapes(i).RelativeHorizontalPosition = wdRelativeHorizontalPositionMargin ‘CENTER SHAPES
Next i
End With
End Sub
Sub Step4SaveDocument()
‘ Currently we just save the document AS-IS. We don’t save a copy. Because if we save a copy,
‘ its the copy that’s open when the HTML file is being saved next, and that distorts the path/filenames
ActiveDocument.Save‘Dim fn As String
‘fn = “KDP_” & ActiveDocument.Name
‘Debug.Print “Saving as ” & ActiveDocument.Path & fn
‘ActiveDocument.SaveAs FileName:=ActiveDocument.Path & “\” & KDPPATH & fn, FileFormat:=wdFormatDocumentEnd Sub
Sub Step5SaveAsWebpage()With ActiveDocument.WebOptions
.RelyOnCSS = False ‘ STILL RESULTS IN CSS .. MSWORD #FML
.OptimizeForBrowser = True ‘ OK YA?
.OrganizeInFolder = True
.UseLongFileNames = True
.RelyOnVML = False ‘ VML HA HA
.AllowPNG = False ‘ I LIKE MY LAWSUITS IN GIF
.ScreenSize = msoScreenSize640x480 ‘ CLOSEST OPTION TO KINDLE?
.PixelsPerInch = 72 ‘ READ SOMEWHERE THAT KINDLE IS GOOD WITH 72 DPI?
.Encoding = msoEncodingWestern
End With
With Application.DefaultWebOptions
.UpdateLinksOnSave = True
.CheckIfOfficeIsHTMLEditor = True
.CheckIfWordIsDefaultHTMLEditor = True
.AlwaysSaveInDefaultEncoding = False
.SaveNewWebPagesAsWebArchives = False
End With‘ this part takes the file name, removes the DOC (or any) extension, and prepends KDP to form a new filename with extension html
‘ it will save the new html file in the same location as the original DOC file.
‘ If you put a value in the KDPPATH variable in the GLOBAL section on the top of this code,
‘ the html file will be saved in the resulting KDPPATH subdirectory
Dim fn As String
fn = ActiveDocument.Name
fn = “KDP_” & Left(fn, InStr(fn, “.”) – 1)
Debug.Print “Saving as ” & ActiveDocument.Path & fn
ActiveDocument.SaveAs FileName:=ActiveDocument.Path & “\” & KDPPATH & fn, FileFormat:=wdFormatFilteredHTML
End Sub
Other Useful links:
- John August’s basics for Kindle formatting
- Aaron Shepard’s tutorial on word to Kindle formatting
- Kindle Formatting Faq
- HTML tags compatible with Kindle
- Understand Normal.dot
How to add a macro to your Normal.dot file
1 – Open MS Word
— Close any documents such as the “New blank document” that opens up.
2 – Click on the menu Tools->Macros->Visual Basic Editor (Alternatively press Alt-F11)
3 – If you don’t see a “Project” pane on the left hand side of the VB editor, click on the menu View->Project Explorer
4 – In the project pane, you should be able to see a high level item called “Normal”, under which there will be a subitem called “Modules”.
5 – If under “Modules”. you see a module called “NewMacros”, then double click on it to open it in the editor. If you don’t, then right click on “Modules”, and select the contextmenu item Insert->Module. Open the new module for editing.
6 – Paste the macro into the module, in the editor window.
7 – Save the file. Close word. Now the macro should be a permanent part of your MSWord and can be used on any word document you open in the future.
