epublishing/ePublishing/Archive.xba

1165 lines
No EOL
35 KiB
XML

<?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="Archive" script:language="StarBasic" script:moduleType="normal">Sub archMark26
End Sub
Public Const MAX_CHAR_KERNING = 15
Public Const MIN_CHAR_KERNING = -10
Public Const MIN_SPACING_TO_SHRINK = 500
Sub resetNotesStyle
Dim oDescriptor As Object
Dim dispatcher As Object
Dim x As Integer
Dim oViewCursor As Object
Dim document As Object
Dim allNotes As Object
Dim aNote As Object
Dim oEnum As Object
Dim oCurPar As Object
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
document = ThisComponent.CurrentController.Frame
oViewCursor = ThisComponent.CurrentController.getViewCursor()
allNotes = thisComponent.FootNotes
for x = 0 to allNotes.Count -1
aNote = allNotes.getByIndex(x)
aNote.Anchor.CharStyleName=&quot;Footnote anchor&quot;
oEnum = aNote.Text.createEnumeration()
Do While oEnum.hasMoreElements()
oCurPar = oEnum.nextElement()
oCurPar.ParaStyleName = &quot;Footnote&quot;
Loop
Next
End Sub
Sub createBidirectLink
Dim oSelections As Object
Dim oAnchor1 As Object
Dim oAnchor2 As Object
Dim oAnchor1Name As String
Dim oAnchor2Name As String
If IsNull(ThisComponent) Then
MsgBox getTranslation(&quot;bidirectLinkSuggestion&quot;)
Exit Sub
End If
oSelections = ThisComponent.getCurrentSelection()
If IsNull(oSelections) Then
MsgBox getTranslation(&quot;bidirectLinkSuggestion&quot;)
Exit Sub
End If
objectsCount = oSelections.getCount() - 1
If objectsCount &lt; 2 OR objectsCount &gt; 2 Then
MsgBox getTranslation(&quot;bidirectLinkSuggestion&quot;)
Exit Sub
End If
oAnchor1 = oSelections.getByIndex(1)
oAnchor2 = oSelections.getByIndex(2)
If isAnchorEmpty(oAnchor1) Or isAnchorEmpty(oAnchor2) Then
MsgBox getTranslation(&quot;bidirectLinkSuggestion&quot;)
Exit Sub
EndIf
oAnchor1Name = RND_String()
oAnchor2Name = RND_String()
createAnchor(oAnchor1,oAnchor1Name)
createAnchor(oAnchor2,oAnchor2Name)
createLink(oAnchor1,oAnchor1.String,oAnchor2Name)
createLink(oAnchor2,oAnchor2.String,oAnchor1Name)
End Sub
Function isAnchorEmpty(anchor As Object) As Boolean
Dim anchorName As String
anchorName = trim(anchor.String)
If Len(anchorName) = 0 Then
isAnchorEmpty = true
Exit Function
EndIf
If Len(anchorName) = 1 AND Chr(10) = anchorName Then
isAnchorEmpty = true
Exit Function
EndIf
isAnchorEmpty = false
End Function
Sub disposeBookmark(bookmarkName As String)
Dim bookmarks As Object
Dim bookmark As Object
Dim elementName As String
elementName = ThisComponent.Links.ElementNames(6)
bookmarks = ThisComponent.Links.getByName(elementName)
If bookmarks.hasByName(bookmarkName) Then
bookmark = bookmarks.getByName(bookmarkName)
bookmark.dispose()
EndIf
End Sub
Sub createAnchor(targetRange as Object,anchorName as String)
dim oViewCursor as object
dim document as object
dim dispatcher as Object
disposeBookMark(anchorName)
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.gotoRange(targetRange,false)
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = &quot;Bookmark&quot;
args1(0).Value = anchorName
dispatcher.executeDispatch(document, &quot;.uno:InsertBookmark&quot;, &quot;&quot;, 0, args1())
End Sub
Sub createLink(targetRange as Object,linkName as String,linkURL as String)
dim oViewCursor as object
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.gotoRange(targetRange,false)
&apos;Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
&apos;Mri oViewCursor
oViewCursor.HyperlinkURL = &quot;#&quot; &amp; linkURL
oViewCursor.HyperLinkName = linkName
&apos;dim args2(4) as new com.sun.star.beans.PropertyValue
&apos;args2(0).Name = &quot;Hyperlink.Text&quot;
&apos;args2(0).Value = linkName
&apos;args2(1).Name = &quot;Hyperlink.URL&quot;
&apos;args2(1).Value = &quot;#&quot;+linkURL
&apos;args2(2).Name = &quot;Hyperlink.Target&quot;
&apos;args2(2).Value = &quot;&quot;
&apos;args2(3).Name = &quot;Hyperlink.Name&quot;
&apos;args2(3).Value = linkName
&apos;args2(4).Name = &quot;Hyperlink.Type&quot;
&apos;args2(4).Value = 1
&apos;dispatcher.executeDispatch(document, &quot;.uno:SetHyperlink&quot;, &quot;&quot;, 0, args2())
End Sub
Function RND_String
Dim OutputString As String
Dim TempString As String
Dim i as Long
OutputString=&quot;&quot;
randomize
For i = 1 to 20
Select Case i
Case 5, 8, 11, 14
OutputString=OutputString+&quot;-&quot;
Case Else
TempString=Hex(int(rnd*256))
If len(TempString) &lt; 2 Then
TempString=TempString+&quot;0&quot;
EndIf
OutputString=OutputString+TempString
End Select
next i
RND_String = OutputString
End Function
sub convertIndesignPageBreaks
Dim description As String
Dim pageBreakMarker As String
pageBreakMarker = &quot;---XYXYX---&quot;
description = getTranslation(&quot;convertIndesignPageBreaksConfirmation&quot;)
If NOT confirm(description) Then
Exit Sub
EndIf
turnOffTracking()
balanceFootNotes()
Dim oViewCursor As Object
oViewCursor = thisComponent.getCurrentController.getViewCursor
oViewCursor.jumpToFirstPage
Dim oSearch As Object
Dim oTextCursor As Object
Dim testCurs As Object
Dim firstLowercase As Boolean
Dim firstBreak As Boolean
firstBreak = true
Dim charNum As Long
Dim prevParaLastCharacter As String
Dim oFound As Object
Dim pageNumber As Integer
Dim prevPageNumber As Integer
Dim nextPara As Object
Dim prevPara As Object
Dim nextParaFirstCharacter As String
Dim stringContents As String
firstLowercase = false
oSearch = ThisComponent.createSearchDescriptor()
oSearch.SearchString = pageBreakMarker
oSearch.SearchRegularExpression=True
oSearch.searchAll=True
oFound = ThisComponent.findFirst(oSearch)
Do While Not IsNull(oFound)
oTextCursor = oFound.Text.createTextCursor()
oTextCursor.gotoRange(oFound,false)
oTextCursor.gotoStartOfParagraph(false)
oTextCursor.gotoEndOfParagraph(true)
testCurs = oTextCursor.Text.createTextCursorByRange(oTextCursor.End)
testCurs.goRight(1,false)
testCurs.gotoEndOfParagraph(true)
&apos;In case two page breaks go together
stringContents = testCurs.String
If stringContents &lt;&gt; pageBreakMarker Then
oTextCursor.goRight(1,true)
EndIf
oTextCursor.String = &quot;&quot;
oTextCursor.BreakType = com.sun.star.style.BreakType.PAGE_BEFORE
&apos;Go to Start of new paragraph to shrink prev page if necessary
oViewCursor.goToRange(oTextCursor.End,false)
oViewCursor.goLeft(1,false)
&apos;
Wait 100
pageNumber = getPageNumber(oTextCursor.Text.createTextCursorByRange(oTextCursor.End))
If firstBreak Then
firstBreak = false
prevPageNumber = pageNumber
EndIf
If pageNumber - prevPageNumber &gt; 1 Then
shrinkPageContent
Wait 100
pageNumber = getPageNumber(oTextCursor.Text.createTextCursorByRange(oTextCursor.End))
EndIf
&apos;check first character
oTextCursor.goRight(1,true)
nextPara = oTextCursor.End
nextParaFirstCharacter = oTextCursor.getString()
If (isLowerCase(nextParaFirstCharacter)) Then
adjustFirstLine(nextPara)
firstLowercase = true
End If
&apos;check last character
oTextCursor.goLeft(2,false)
prevPara = oTextCursor.Start
oTextCursor.goLeft(1,true)
prevParaLastCharacter = oTextCursor.getString()
If (prevParaLastCharacter = &quot; &quot;) Then
&apos; oTextCursor.String=&quot;&quot;
&apos;last paragraph
adjustLastLine(prevPara)
adjustFirstLine(nextPara)
EndIf
If (isLowerCase(prevParaLastCharacter)) Then
If firstLowercase Then
oTextCursor.collapseToEnd()
oTextCursor.setString(&quot;-&quot;)
oTextCursor.collapseToEnd()
adjustLastLine(prevPara)
adjustFirstLine(nextPara)
EndIf
End If
If pageNumber - prevPageNumber &lt; 2 Then
&apos;stretchPrevPage(prevPara)
EndIf
prevPageNumber = pageNumber
oFound = ThisComponent.findNext(oFound.End, oSearch)
Loop
setUniqPageStyles
MsgBox getTranslation(&quot;convertIndesignPageBreaksFinish&quot;)
end Sub
Sub configureHeadings
configureArchiveHeading1
configureArchiveHeadings()
End Sub
Sub configureArchiveHeading1
Dim outline1() As Object
Dim oViewCursor As Object
Dim oSavePosition As Object
Dim initPosition As Object
Dim initPageNum As Integer
fixViewCursor()
oViewCursor = thisComponent.getCurrentController.getViewCursor
oSavePosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
outline1 = getHeadingWithLevel(1)
Dim startViewPageNum As Integer
Dim pageNumberCursor As Object
Dim i As Integer
Dim j As Integer
For i = LBound(outline1) To UBound(outline1)
oViewCursor.goToRange(outline1(i), false)
oViewCursor.jumpToEndOfPage()
initPosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
initPageNum = oViewcursor.getPage()
Do While Not isContentPageChanged(initPosition, initPageNum) AND outline1(i).ParaBottomMargin &lt; 10000
outline1(i).ParaBottomMargin = outline1(i).ParaBottomMargin + 100
Loop
Do While isContentPageChanged(initPosition, initPageNum)
If outline1(i).ParaBottomMargin &lt; 0 Then
Exit Do
EndIf
outline1(i).ParaBottomMargin = outline1(i).ParaBottomMargin - 100
Loop
Next i
oViewCursor.goToRange(oSavePosition,false)
End Sub
Sub configureArchiveHeadings()
Dim outline1() As Object
Dim oViewCursor As Object
Dim initPosition As Object
Dim initPageNum As Integer
Dim savePosition As Object
fixViewCursor()
oViewCursor = thisComponent.getCurrentController.getViewCursor
savePosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
Dim pageNumberCursor As Object
Dim i As Integer
Dim j As Integer
Dim initialPageCount As Integer
initialPageCount = ThisComponent.currentController.pageCount
For j = 2 To 10
outline1 = getHeadingWithLevel(j)
For i = LBound(outline1) To UBound(outline1)
If outline1(i).BreakType &lt;&gt; 4 Then
oViewCursor.goToRange(outline1(i), false)
oViewCursor.jumpToEndOfPage()
initPosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
initPageNum = oViewcursor.getPage()
Do While Not isContentPageChanged(initPosition, initPageNum)
outline1(i).ParaTopMargin = outline1(i).ParaTopMargin + 100
If (outline1(i).ParaTopMargin &gt; outline1(i).ParaBottomMargin) Then
Exit Do
EndIf
Loop
Do While isContentPageChanged(initPosition, initPageNum)
If outline1(i).ParaBottomMargin &lt; 0 Then
Exit Do
EndIf
outline1(i).ParaTopMargin = outline1(i).ParaTopMargin - 100
Loop
EndIf
Next i
Next j
oViewCursor.goToRange(savePosition,false)
End Sub
Sub stretchPrevPage()
&apos;Assumption hard breaks at start of stretching page and at start of next page
Dim pageCount As Integer
Dim curViewPageNum As Integer
Dim startViewPageNum As Integer
Dim successOperation As Boolean
Dim paragraphs() As Object
Dim outline1() As Object
Dim outline2() As Object
initialPageCount = thiscomponent.currentController.pageCount
Dim oViewCursor As Object
Dim textCursor As Object
Dim pageNumberCursor As Object
Dim oSavePosition As Object
Dim pageStartPosition As Object
Dim i As Integer
Dim curPara As Object
oViewCursor = thisComponent.getCurrentController.getViewCursor
oSavePosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
&apos;oViewCursor.goToStartOfLine(false)
pageNumberCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
pageNumberCursor.goToStartOfWord(false)
&apos;Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
&apos;MRI pageNumberCursor
oViewCursor.jumpToStartOfPage()
startViewPageNum = getPageNumber(pageNumberCursor)
textCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
Do While oViewCursor.getPage() = startViewPageNum
curPara = textCursor.textParagraph
If curPara.outlineLevel = 1 Then
addToArray(outline1, curPara)
ElseIf curPara.outlineLevel = 2 Then
addToArray(outline2, curPara)
Else
addToArray(paragraphs, curPara)
EndIf
successOperation = textCursor.goToNextParagraph(false)
If NOT successOperation Then
Exit Do
EndIf
oViewCursor.goToRange(textCursor,false)
Loop
If UBound(outline1) &gt; -1 Then
Do While startViewPageNum = getPageNumber(pageNumberCursor)
For i = LBound(outline1) To UBound(outline1)
outline1(i).ParaTopMargin = outline1(i).ParaTopMargin + 100
Next i
Loop
For i = LBound(outline1) To UBound(outline1)
If outline1(i).ParaTopMargin &gt;= 100 Then
outline1(i).ParaTopMargin = outline1(i).ParaTopMargin - 100
EndIf
Next i
Exit Sub
EndIf
If UBound(outline2) &gt; -1 Then
Do While startViewPageNum = getPageNumber(pageNumberCursor)
For i = LBound(outline2) To UBound(outline2)
outline2(i).ParaTopMargin = outline2(i).ParaTopMargin + 100
If outline2(i).ParaTopMargin &gt; outline2(i).ParaBottomMargin Then
Exit Do
EndIf
Next i
Loop
For i = LBound(outline2) To UBound(outline2)
If outline2(i).ParaTopMargin &gt;= 100 Then
outline2(i).ParaTopMargin = outline2(i).ParaTopMargin - 100
EndIf
Next i
Exit Sub
EndIf
&apos;Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
&apos;Mri curPara
Dim paraLineSpacing As Object
Dim tmpPageNum As Integer
tmpPageNum = getPageNumber(pageNumberCursor)
If UBound(paragraphs) &gt; -1 Then
Dim iterations As Integer
iterations = 0
Do While startViewPageNum = getPageNumber(pageNumberCursor)
For i = LBound(paragraphs) To UBound(paragraphs)
paraLineSpacing = paragraphs(i).paraLineSpacing
paraLineSpacing.Height = paraLineSpacing.Height + 5
paragraphs(i).paraLineSpacing = paraLineSpacing
Next i
iterations = iterations + 1
If iterations &gt; 4 Then
Exit Do
EndIf
tmpPageNum = getPageNumber(pageNumberCursor)
Loop
For i = LBound(paragraphs) To UBound(paragraphs)
paraLineSpacing = paragraphs(i).paraLineSpacing
paraLineSpacing.Height = paraLineSpacing.Height - 5
paragraphs(i).paraLineSpacing = paraLineSpacing
Next i
Exit Sub
EndIf
oViewCursor.goToRange(oSavePosition,false)
End Sub
Sub adjustLastLineCurPara()
Dim oViewCursor As Object
Dim oTextCursor As Object
Dim paraEnd As Object
Dim success As Boolean
Dim adjustType As Integer
Dim hyph As Boolean
fixViewCursor()
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oTextCursor = oViewCursor.Text.CreateTextCursorByRange(oViewCursor)
paraEnd = getParaEnd(oTextCursor)
oTextCursor.goToRange(paraEnd,false)
oTextCursor.goLeft(1,true)
If (oTextCursor.String = &quot; &quot;) Then
oTextCursor.String = &quot;&quot;
EndIf
adjustType = oTextCursor.ParaAdjust
hyph = oTextCursor.ParaIsHyphenation
oTextCursor.ParaIsHyphenation = true
success = balanceParaTail(oTextCursor.Start)
If success And adjustType = 2 Then
oTextCursor.ParaLastLineAdjust = 2
Else
oTextCursor.ParaIsHyphenation = hyph
EndIf
End Sub
Sub balanceFootNotes()
Dim allNotes As Object
Dim aNote As Object
Dim x As Long
allNotes = ThisComponent.FootNotes
For x = 0 to allNotes.Count -1
aNote = allNotes.getByIndex(x)
balanceFootNote(aNote)
Next
End Sub
Sub balanceFootNote(textElement As Object)
Dim enum1Element As Object
Dim enum1 As Object
Dim oViewCursor As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
enum1 = textElement.createEnumeration()
While enum1.hasMoreElements
enum1Element = enum1.nextElement
If enum1Element.supportsService(&quot;com.sun.star.text.Paragraph&quot;) Then
oViewCursor.goToRange(enum1Element,false)
adjustLastLineCurPara()
EndIf
Wend
End Sub
Sub adjustLastLine(anchor As Object)
Dim oViewCursor As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.goToRange(anchor,false)
adjustLastLineCurPara()
End Sub
Sub adjustFirstLine(anchor As Object)
anchor.ParaFirstLineIndent = 0
End Sub
Function isLowerCase(character As String) As Boolean
Dim charNum As Long
If (character = &quot;&quot;) Then
charNum = ASC(&quot;&quot;+0)
Else
charNum = ASC(character)
End If
If ((charNum &gt; 1071 AND charNum &lt; 1120) Or (charNum &gt; 96 AND charNum &lt; 123)) Then
isLowerCase = true
Exit Function
EndIf
isLowerCase = false
End Function
Function balanceParaTail(targetPara As Object) As Boolean
Dim oViewCursor As Object
Dim oTextCursor As Object
Dim oContent As Object
Dim oContentStart As Object
Dim oContentEnd As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.goToRange(targetPara, false)
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
oContentStart = getParaStart(oTextCursor)
oContentEnd = getParaEnd(oTextCursor)
oContent = getParaSelected(oContentStart,oContentEnd)
balanceParaTail = balanceContentTail(oContent)
End Function
Function balanceContentTail(oContent As Object) As Boolean
&apos; Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
balanceContentTail = false
Dim oViewCursor As Object
Dim paraLen As Integer
Dim lineCount As Integer
Dim initialLineCount As Integer
Dim lineLen As Integer
Dim minLastLineLength As Integer
Dim medianLen As Integer
Dim paraLines() As Object
Dim decreaseKerningFailed As Boolean
Dim increaseKerningFailed As Boolean
Dim fallBackSuccess As Boolean
fallBackSuccess = false
decreaseKerningFailed = false
increaseKerningFailed = false
oViewCursor = ThisComponent.CurrentController.getViewCursor()
paraLen = Len(oContent.String)
paraLines = getContentLines(oContent)
initialLineCount = getParaLinesCount(paraLines)
lineLen = getParaLineLength(paraLines, 0)
medianLen = calculateMedianParaLen(oContent)
minLastLineLength = medianLen * 0.93
If Not IsEmpty(oContent.CharKerning) Then
initialCharKerning = oContent.CharKerning
Else
initialCharKerning = 0
End If
If initialLineCount &lt; 2 Then
Exit Function
EndIf
Do While lastLineIsNotBalanced(lineLen, minLastLineLength)
decreaseCharKerning(oContent)
paraLines = getContentLines(oContent)
lineCount = getParaLinesCount(paraLines)
lineLen = getParaLineLength(paraLines,0)
If (lineCount &lt; initialLineCount ) OR (oContent.CharKerning &lt; MIN_CHAR_KERNING) Then
&apos;Tightened last line but it is still smaller than we need
fallBackSuccess = tryExpandPrevLines(oContent, minLastLineLength)
If Not fallBackSuccess Then
oContent.CharKerning = initialCharKerning
oViewCursor.collapseToEnd()
balanceContentTail = false
Exit Function
EndIf
Exit Do
EndIf
Loop
oViewCursor.collapseToEnd()
balanceContentTail = true
End Function
Function shrinkContentWithKerning(oContent As Object) As Boolean
&apos; Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
shrinkContentWithKerning = false
Dim paraLen As Integer
Dim lineCount As Integer
Dim saveLineCount As Integer
Dim initialLineCount As Integer
Dim contentLines() As Object
Dim kerningValue As Integer
contentLines = getContentLines(oContent)
initialLineCount = getParaLinesCount(contentLines)
saveLineCount = initialLineCount
If Not IsEmpty(oContent.CharKerning) Then
initialCharKerning = oContent.CharKerning
Else
initialCharKerning = 0
End If
kerningValue = initialCharKerning
&apos;Reduce kerning is useless if content is less than 2 lines long
If initialLineCount &lt; 2 Then
Exit Function
EndIf
Do While oContent.CharKerning &gt; MIN_CHAR_KERNING
decreaseCharKerning(oContent)
contentLines = getContentLines(oContent)
lineCount = getParaLinesCount(contentLines)
If lineCount &lt; saveLineCount Then
kerningValue = oContent.CharKerning
saveLineCount = lineCount
EndIf
Loop
&apos;If decrease kerning didn&apos;t reduce lines then retreat to latest value that changed lines count
If kerningValue &lt;&gt; oContent.CharKerning Then
oContent.CharKerning = kerningValue
EndIf
If initialCharKerning &lt;&gt; kerningValue Then
shrinkContentWithKerning = true
EndIf
End Function
Function tryExpandPrevLines(oPara As Object, minLastLineLength As Integer) As Boolean
Dim lineCount As Integer
Dim initialLineCount As Integer
Dim paraLine As Object
Dim lineNum As Integer
Dim failedLines() As Integer
paraLines = getContentLines(oPara)
lineLen = getParaLineLength(paraLines,0)
initialLineCount = getParaLinesCount(paraLines)
lineCount = initialLineCount
lineNum = 0
Do While lineCount = initialLineCount And lastLineIsNotBalanced(lineLen, minLastLineLength)
If (lineNum + 1 &lt; lineCount And Not IsInArray(failedLines, lineNum + 1)) Then
lineNum = lineNum + 1
EndIf
paraLine = paraLines(UBound(paraLines) - lineNum)
increaseCharKerning(paraLine)
paraLines = getContentLines(oPara)
lineCount = getParaLinesCount(paraLines)
lineLen = getParaLineLength(paraLines,0)
If lineNum &gt; 1 And (lineCount &lt;&gt; initialLineCount Or paraLine.CharKerning &gt; MAX_CHAR_KERNING) Then
AddToArray(failedLines, lineNum)
decreaseCharKerning(paraLine)
paraLines = getContentLines(oPara)
lineCount = getParaLinesCount(paraLines)
lineLen = getParaLineLength(paraLines,0)
lineNum = 0
ElseIf lineNum = 1 And paraLine.CharKerning &gt; MAX_CHAR_KERNING Then
tryExpandPrevLines = false
Exit Function
EndIf
Loop
If Not lastLineIsNotBalanced(lineLen, minLastLineLength) And lineCount = initialLineCount Then
tryExpandPrevLines = true
Else
tryExpandPrevLines = false
EndIf
End Function
Function getParaLinesCount(paraLines() As Object) As Integer
getParaLinesCount = UBound(paraLines) + 1
End Function
Function getParaLineLength(paraLines() As Object, lineNumber As Integer) As Integer
Dim arrIndex As Integer
arrIndex = UBound(paraLines) - lineNumber
If (arrIndex &gt;= 0) Then
getParaLineLength = Len(paraLines(arrIndex).String)
Else
&apos;Throw an error?
getParaLineLength = 0
EndIf
End Function
Function getContentLines(oContent As Object) As Variant
Dim oTextCursor As Object
Dim oViewCursor As Object
Dim paraLine As Object
Dim paraLines() As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
&apos;initial value is 1 As paragraph can&apos;t be 0 lines long
oTextCursor = oContent.Text.createTextCursorByRange(oContent)
oTextCursor.collapseToStart()
oViewCursor.goToRange(oTextCursor,false)
While NOT oTextCursor.isEndOfParagraph()
oViewCursor.gotoEndOfLine(true)
If (Len(oViewCursor.String) = 0) Then
oTextCursor.goToRange(oViewCursor,false)
oTextCursor.goRight(1,false)
oViewCursor.goToRange(oTextCursor,false)
oViewCursor.gotoEndOfLine(true)
EndIf
If (Len(oViewCursor.String) &gt; 0) Then
paraLine = oViewCursor.Text.createTextCursorByRange(oViewCursor)
AddToArray(paraLines, paraLine)
EndIf
oViewCursor.collapseToEnd()
oTextCursor.goToRange(oViewCursor,false)
Wend
getContentLines = paraLines
End Function
Sub decreaseCharKerning(oPara As Object)
Dim initialCharKerning As Integer
Dim textExcerpts As Object
Dim textExcerpt As Object
initialCharKerning = MIN_CHAR_KERNING + 2
If Not (IsEmpty(oPara.CharKerning)) Then
initialCharKerning = oPara.CharKerning
EndIf
If (initialCharKerning &gt;= MIN_CHAR_KERNING) Then
oPara.CharKerning = initialCharKerning - 2
EndIf
End Sub
Sub increaseCharKerning(oPara As Object)
Dim initialCharKerning As Integer
Dim textExcerpts As Object
Dim textExcerpt As Object
initialCharKerning = MAX_CHAR_KERNING - 2
If Not (IsEmpty(oPara.CharKerning)) Then
initialCharKerning = oPara.CharKerning
EndIf
oPara.CharKerning = initialCharKerning + 2
End Sub
Function lastLineIsNotBalanced(lineLen As Integer,minLastLineLength As Integer) As Boolean
lastLineIsNotBalanced = true
If lineLen = 0 Then
lastLineIsNotBalanced = false
Exit Function
EndIf
If lineLen &gt;= minLastLineLength Then
lastLineIsNotBalanced = false
EndIf
End Function
Function getParaStart(oTextCursor As Object) As Object
If NOT oTextCursor.isStartOfParagraph() Then
oTextCursor.gotoStartOfParagraph(false)
EndIf
getParaStart = oTextCursor.getStart()
End Function
Function getParaEnd(oTextCursor As Object) As Object
If NOT oTextCursor.isEndOfParagraph() Then
oTextCursor.gotoEndOfParagraph(false)
EndIf
getParaEnd = oTextCursor.getEnd()
End Function
Function getParaSelected(oParaStart As Object,oParaEnd As Object) As Object
Dim oPara As Object
oPara = oParaStart.Text.createTextCursorByRange(oParaStart)
oPara.goToRange(oParaEnd,true)
getParaSelected = oPara
End Function
Function calculateMedianParaLen(oPara As Object) As Integer
Dim oTextCursor As Object
Dim oViewCursor As Object
Dim lineCount As Integer
Dim lineLen As Integer
Dim linesLen As Integer
linesLen = 0
calculateMedianParaLen = 0
lineCount = 0
lineLen = 0
If (Len (oPara.String) = 0) Then
Exit Function
EndIf
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.goToRange(oPara, false)
oViewCursor.collapseToStart()
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
oParaStart = getParaStart(oTextCursor)
oViewCursor.goToRange(oParaStart,false)
While NOT oTextCursor.isEndOfParagraph()
oViewCursor.gotoEndOfLine(true)
lineLen = Len(oViewCursor.getString())
If lineLen &gt; 0 Then
linesLen = linesLen + lineLen
lineCount = lineCount + 1
oViewCursor.collapseToEnd()
oTextCursor.goToRange(oViewCursor,false)
Else
oTextCursor.goToRange(oViewCursor,false)
oTextCursor.goRight(1,false)
oViewCursor.goToRange(oTextCursor,false)
EndIf
Wend
If lineCount &gt; 0 Then
calculateMedianParaLen = linesLen / lineCount
EndIf
End Function
Sub convertBookmarksToFootnotes()
Dim description As String
description = getTranslation(&quot;convertIndesignFoonotesConfirmation&quot;)
If NOT confirm(description) Then
Exit Sub
EndIf
Dim bookmarks as Object
Dim bookmarkName as String
Dim bookmarkNames() As String
Dim strStart As Integer
Dim linkPrefix As String
Dim backLinkSuffix As String
Dim backwardLink As String
Dim forwardLink As String
Dim forward As Object
Dim backward As Object
linkPrefix = &quot;footnote-&quot;
backLinkSuffix = &quot;-backlink&quot;
Dim i As Integer
bookmarkName = ThisComponent.Links.ElementNames(6)
bookmarks = ThisComponent.Links.getByName(bookmarkName)
bookmarkNames = bookmarks.getElementNames()
For i = LBound(bookmarkNames) To Ubound(bookmarkNames)
bookmarkName = bookmarkNames(i)
If InStr(bookmarkName, linkPrefix) = 1 Then
forwardLink = &quot;&quot;
backwardLink = &quot;&quot;
If InStr(bookmarkName, backLinkSuffix) &gt; 0 Then
forwardLink = Left(bookmarkName,Len(bookmarkName) - Len(backLinkSuffix))
backwardLink = bookmarkName
Else
forwardLink = bookmarkName
backwardLink = bookmarkName + backLinkSuffix
EndIf
convertLinkToFootnote(forwardLink,backwardLink)
EndIf
Next i
resetNotesStyle
MsgBox getTranslation(&quot;convertIndesignFootnotesFinish&quot;)
End Sub
Sub convertLinkToFootnote(forwardLink,backwardLink)
Dim bookMarkName As String
bookmarkName = ThisComponent.Links.ElementNames(6)
Dim bookmarks As Object
bookmarks = ThisComponent.Links.getByName(bookmarkName)
Dim forward As Object
Dim backward As Object
Dim oViewCursor As Object
Dim footNoteSign As String
oViewCursor = ThisComponent.CurrentController.getViewCursor()
Dim oTextCursor As Object
If NOT bookmarks.hasByName(forwardLink) OR NOT bookmarks.hasByName(backwardLink) Then
exit sub
&apos;If msgbox( &quot;NO SuCH LINK&quot;, 36 ) = 6 Then Stop
EndIf
forward = bookmarks.getByName(forwardLink)
backward = bookmarks.getByName(backwardLink)
oViewCursor.goToRange(forward.Anchor,false)
footNoteSign = getTextInFootnote
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
oTextCursor.gotoEndOfParagraph(false)
oTextCursor.gotoStartOfParagraph(true)
oViewCursor.goToRange(oTextCursor,true)
unoCut()
SendRM
oViewCursor.goToRange(backward.Anchor,false)
removeFootnoteSignInText
createFootnote
unoPaste()
oViewCursor.getText.setLabel(footNoteSign)
forward.dispose()
backward.dispose()
End Sub
Function getTextInFootnote As String
Dim oViewCursor As Object
Dim oTextCursor As Object
Dim character As String
getTextInFootnote = &quot;&quot;
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
oTextCursor.goToStartOfParagraph(false)
oViewCursor.goToRange(oTextCursor,false)
oViewCursor.goRight(1,true)
character = oViewCursor.String
Do While isLinkCharacter(character)
If IsNumeric(character) Then
getTextInFootnote = getTextInFootnote &amp; character
EndIf
oViewCursor.String = &quot;&quot;
oViewCursor.goRight(1,true)
character = oViewCursor.String
Loop
If oViewCursor.String = &quot; &quot; Then
oViewCursor.String = &quot;&quot;
Else
oViewCursor.goLeft(1,false)
EndIf
End Function
Sub removeFootnoteSignInText
Dim oViewCursor As Object
Dim character As String
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.String = &quot;&quot;
oViewCursor.goLeft(1,true)
character = oViewCursor.String
Do While isLinkCharacter(character)
oViewCursor.String = &quot;&quot;
oViewCursor.goLeft(1,true)
character = oViewCursor.String
Loop
oViewCursor.goRight(1,true)
End Sub
Function isLinkCharacter(character As String) As Boolean
Select Case character
Case &quot;[&quot;
isLinkCharacter = true
Exit Function
Case &quot;]&quot;
isLinkCharacter = true
Exit Function
Case &quot;0&quot;
isLinkCharacter = true
Exit Function
Case &quot;1&quot;
isLinkCharacter = true
Exit Function
Case &quot;2&quot;
isLinkCharacter = true
Exit Function
Case &quot;3&quot;
isLinkCharacter = true
Exit Function
Case &quot;4&quot;
isLinkCharacter = true
Exit Function
Case &quot;5&quot;
isLinkCharacter = true
Exit Function
Case &quot;6&quot;
isLinkCharacter = true
Exit Function
Case &quot;7&quot;
isLinkCharacter = true
Exit Function
Case &quot;8&quot;
isLinkCharacter = true
Exit Function
Case &quot;9&quot;
isLinkCharacter = true
Exit Function
Case Else
isLinkCharacter = false
End Select
End Function
sub unoCut
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
dispatcher.executeDispatch(document, &quot;.uno:Cut&quot;, &quot;&quot;, 0, Array())
end sub
sub unoPaste
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
dispatcher.executeDispatch(document, &quot;.uno:Paste&quot;, &quot;&quot;, 0, Array())
end sub
sub createFootnote
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
dispatcher.executeDispatch(document, &quot;.uno:InsertFootnote&quot;, &quot;&quot;, 0, Array())
end Sub
Dim oDialog
Sub onSelectMenuItem(oEvent)
oDialog.endExecute()
oDialog.model.Tag = oEvent.ActionCommand
End Sub
Sub replaceParaStyle
dim oldStyleName As String
dim oldStyle As Object
dim newStyleName As String
dim paragraphStyles As Object
dim userInput As Integer
Dim listBox As Object
Dim paraStyle As Object
Dim oViewCursor As Object
Dim enum1 As Object
Dim oTextCursor As Object
Dim i As Integer
oStyles = ThisComponent.StyleFamilies
paraStyles = oStyles.getByName(oStyles.elementNames(1))
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oldStyleName = oViewCursor.ParaStyleName
paraStyleNames = paraStyles.ElementNames
Dim displayParaStyleNames(Ubound(paraStyleNames))
Dim sortedDPSN(Ubound(paraStyleNames))
displayParaStyleNames = paraStyleNames
Redim Preserve displayParaStyleNames(Ubound(paraStyleNames))
For i = LBound(displayParaStyleNames) To Ubound(displayParaStyleNames)
paraStyle = paraStyles.getByName(displayParaStyleNames(i))
displayParaStyleNames(i) = paraStyle.displayName
Next i
sortedDPSN = displayParaStyleNames
Redim Preserve sortedDPSN(Ubound(paraStyleNames))
subShellSort(sortedDPSN)
DialogLibraries.LoadLibrary(&quot;ePublishing&quot;)
oDialog = CreateUnoDialog( DialogLibraries.ePublishing.replaceParaStyle )
listBox = oDialog.getControl(&quot;ListBox1&quot;)
listBox.addItems(sortedDPSN , 0)
oDialog.Title = getTranslation(&quot;replaceParaStyleDialogTitle&quot;)
oDialog.Execute()
newStyleName = oDialog.model.Tag
If newStyleName=&quot;0&quot; or newStyleName=&quot;&quot; Then
Exit sub
EndIf
foundIndex = getIndex(displayParaStyleNames, newStyleName)
&apos;set style system name instead of display name
newStyleName = paraStyleNames(foundIndex)
If newStyleName = oldStyleName Then
MsgBox getTranslation(&quot;replaceParaStyleStylesEqualsNotification&quot;)
Exit sub
EndIf
If oldStyleName &lt;&gt; &quot;&quot; Then
oldStyle = paraStyles.getByName(oldStyleName)
If NOT oldStyle.isUserDefined Then
MsgBox getTranslation(&quot;replaceParaStyleCurrentStyleIsStandard&quot;)
Exit sub
EndIf
oldStyle.ParentStyle = newStyleName
paraStyles.removeByName(oldStyleName)
EndIf
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
enum1 = oTextCursor.createEnumeration()
While enum1.hasMoreElements
enum1Element = enum1.nextElement
If enum1Element.supportsService(&quot;com.sun.star.text.Paragraph&quot;) Then
If enum1Element.ParaStyleName &lt;&gt; newStyleName Then
oldStyle = paraStyles.getByName(enum1Element.ParaStyleName)
oldStyle.ParentStyle = newStyleName
paraStyles.removeByName(enum1Element.ParaStyleName)
EndIf
EndIf
Wend
End Sub
Function getIndex(array As variant, value As variant) As Integer
Dim id As Integer
Dim nRight As Integer
Dim nLen As Integer
id = 0
nRight = uBound(array)
nLen = len(value)
while id &lt;= nRight
If array(id) = value Then
getIndex = id
exit Function
Else
id = id + 1
end if
wend
getIndex = -1
End Function
Sub subShellSort(mArray)
Dim n As Integer
Dim h As Integer
Dim i As Integer
Dim j As Integer
Dim t As String
Dim Ub As Integer
Dim LB As Integer
Lb = lBound(mArray)
Ub = uBound(mArray)
&apos; compute largest increment
n = Ub - Lb + 1
h = 1
If n &gt; 14 then
do while h &lt; n
h = 3 * h + 1
loop
h = h \ 3
h = h \ 3
End If
Do While h &gt; 0
For i = Lb + h to Ub
t = mArray(i)
For j = i - h to Lb step -h
If strComp(mArray(j), t, 0) &lt; 1 then
Exit For
EndIf
mArray(j + h) = mArray(j)
Next j
mArray(j + h) = t
Next i
h = h \ 3
Loop
End Sub
</script:module>