[Solved] Paragraph style to set first words in small-caps

Discuss the word processor
Post Reply
User avatar
CannedMan
Posts: 225
Joined: Wed Aug 04, 2010 12:06 am

[Solved] Paragraph style to set first words in small-caps

Post by CannedMan »

(I am currently using LibreOffice, due to its complete support for OpenType; if this has been added to OpenOffice now, I would happily switch back again.)

Creating my styles for my thesis, I would like to add a set of styles to change the format of the first words of a paragraph. I know well how to style the first letter (the initial), which I use below chapter headings, but in addition to this, I would like to add either the option to have the first whole line or the first n words set in petit. (EB Garamond has a stylistic subset allowing petit, which works better for longer sections of text than small-caps.)

Presently, I have found no other way to do this than to create a character style and manually applying this wherever needed. What I would prefer, is to find an option to create a paragraph style which either set the whole first line in petit, or – preferably – the first few words. In other words:
  • First paragraph first line petit: one word
  • First paragraph first line petit: two words
  • First paragraph first line petit: three words
  • etc.
  • First paragraph first line petit: whole line
Do anyone know of any way to achieve this?
Last edited by CannedMan on Fri Feb 26, 2021 12:05 am, edited 1 time in total.
Apache OpenOffice 4.1.5 / LibreOffice 7.0.0.3 on Windows 10 (x64)
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

A paragraph style doesn't have that feature.

You can create your paragraph styles and then write a macro that goes through every paragraph already written and formats the first words or line appropriately but it won't be dynamic... you'll have to run it when you've finished your document and again once you've made changes that affect the formattiing.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
RoryOF
Moderator
Posts: 34618
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Paragraph style to set first words in small-caps/petite

Post by RoryOF »

I can recollect a macro written, I think by Lupp, to do just that. No time to search for it at present.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

EDIT 2021-01-30: Added another parameter for the word count. Default is 1.
EDIT 2021-02-03: Wrapped slighly modified code in Writer document with installer. Scroll down.
Last edited by Villeroy on Wed Feb 03, 2021 6:04 pm, edited 4 times in total.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

If you try the conditional one, you may stumble upon the problem that the actual style names differ from the ones shown in the GUI.
The following Basic snippet reports the name of the para style name at cursor:

Code: Select all

Msgbox ThisComponent.CurrentSelection.getByIndex(0).ParaStyleName
Same with character style name:

Code: Select all

Msgbox ThisComponent.CurrentSelection.getByIndex(0).CharStyleName
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

I'm not altogether clear what you're asking for here but here is a basic macro that can be used instead of when you'd press the enter key to start a new paragraph:
It shows a popup menu with a list of numbers 1- 10
and then changes whichever number of words you select at the start of your current paragraph to small caps
then inserts the enter key to start the new paragraph

Code: Select all

sub smallcapwordsEnter()
	vc = thiscomponent.currentcontroller.viewcursor
	res = showpopup3(Thiscomponent.currentcontroller.componentwindow,"1*2*3*4*5*6*7*8*9*10",0,0)
	if res<>"" then
		tc = vc.text.createtextcursorbyrange(vc)
		tc.gotostartofparagraph(false)
		for i = 1 to val(res)
			tc.gotoNextWord(true)
		next
		tc.charcasemap = 4
	end if
	thiscomponent.Text.insertControlCharacter(vc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)
end sub

function showpopup3(window,st as string,x,y) as string
	'split by *
	'separator_
	'note ~ identifies accelerator
	dim sts() as string,c as long

	aRect = CreateUnoStruct("com.sun.star.awt.Rectangle")
	'        aRect.X =oEvt.x + scontrol.PosSize.X +1
	'       aRect.Y = oEvt.y + scontrol.PosSize.y+1


	oPopup = CreateUnoService("stardiv.vcl.PopupMenu")'"com.sun.star.awt.PopupMenu")

	sts = split(st,"*")

	for i = 0 to ubound(sts)
		c =c+1
		if sts(i) ="_" then
			oPopup.insertSeparator(c)
		else
			oPopup.insertItem(c, sts(i),0, c)
			oPopup.setCommand(c, sts(i))
		end if
	next
	n = oPopup.execute( window, aRect, com.sun.star.awt.PopupMenuDirection.EXECUTE_DEFAULT)
	If n > 0 Then
		showpopup3 = oPopup.getCommand(n)
	end if

End function






Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
CannedMan
Posts: 225
Joined: Wed Aug 04, 2010 12:06 am

Re: Paragraph style to set first words in small-caps/petite

Post by CannedMan »

The skill level of the people of this forum never ceases to amaze me. I have no knowledge of how to write macros (a skill I hope to one day be able to learn), but I think I might be able to decipher what is going on.

@Jeje: Is it the line

Code: Select all

tc.charcasemap = 4
that changes the font to small caps? Are you calling for true small caps found via functions or the fake small caps found via effects? If the latter, is there a way to use your macro to call the OpenType function ss=02?
@Villeroy: I take it that the lines

Code: Select all

CharStyleName = 'Strong Emphasis'
is where one would insert the style name one has for the small caps / petits?
Apache OpenOffice 4.1.5 / LibreOffice 7.0.0.3 on Windows 10 (x64)
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

I know nothing about OpenType function ss=02 and whether OpenOffice supports that I'm afraid.

charcasemap = 4 is the same smallcaps in the format menu/character/font effects/effects/small capitals

You can change that line to tc.charstylename = whatever
or any other character property of a range of text.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
CannedMan
Posts: 225
Joined: Wed Aug 04, 2010 12:06 am

Re: Paragraph style to set first words in small-caps/petite

Post by CannedMan »

That would be fake caps, in that case. Allow me to make a bold statement.
True small caps versus fake small caps
True small caps versus fake small caps
Given how you fetch the caps, there should be no reason why you couldn’t simply call the caps via this different function, or? I am asking because I truly don’t know and am quite ignorant when it comes to these things. Type, however, I know fairly well.
JeJe wrote:charcasemap = 4 is the same smallcaps in the format menu/character/font effects/effects/small capitals

You can change that line to tc.charstylename = whatever
or any other character property of a range of text.
That would solve it then, I would presume.
Apache OpenOffice 4.1.5 / LibreOffice 7.0.0.3 on Windows 10 (x64)
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

CannedMan wrote: @Villeroy: I take it that the lines

Code: Select all

CharStyleName = 'Strong Emphasis'
is where one would insert the style name one has for the small caps / petits?
Yes, you should add your own routines (and possibly remove mine). The code is just is a plain text file in your profile folder. Writer can handle that, Notepad almost as well if you obey one thing: Python is the only(?) programming language where white space has a meaning. Every indentation level is 4 white spaces wide.
If you write your custom routine, copy one of mine, change the name after "def", specify your 3 arguments.
The attached Writer document installs my code to [My Macros] > pyWriter > FirstWordCharStyle.py
Use Ctrl+F10 to watch the indentations of 4,8,12 white spaces and push the button to install the code. An embedded Basic macro will store the plain document text to the right location where it will be detected as a Python macro. I use to store my Python macros in folders named pyWriter, pyCalc etc. in order to distinguish them from the Basic macros which can be edited in the Basic GUI only.

Python code is editable in any application that can handle text, preferably some kind of code editor but Writer or Windows Notepad will do.

Code: Select all

def First_3_Words_Emphasis_Conditional(*args):
    CharStyleName = 'Strong Emphasis'
    WordCount = 3
    ParaStyeNames = ('Standard', 'Text body indent',)
    FormatParagraphsFirstWord(CharStyleName, WordCount, ParaStyeNames)
First_3_Words_Emphasis_Conditional can be called directly from a dialog or button without any arguments. (*args) is a blank placeholder to take and ignore any passed arguments. The office sometimes passes over some info about the calling button which is not important here but raises an error when not handled this way.

This routine calls FormatParagraphsFirstWord which is the working routine actually performing the job.
First argument to FormatParagraphsFirstWord is the character style name to be applied.
Second argument (3) is the count of words.
Third argument is an optional list of paragraph style names.
The working routine ignores any paragraph styles that are not in this list. If you leave out that list, all paragraphs are treated equally. This way you create one working routine which can be called easily by very simple routines. In the calling routines you declare the gory details as argument and pass them over to the working routine.
The working routine FormatParagraphsFirstWord appears together with the calling routines in the macro dialogs although it can not be called directly from there. Nothing bad will happen if you try, just an error message.
Attachments
FirstWordCharStyle.odt
Python macro to apply a char style to the first x words of given paragraph styles (or all paragraphs)
(28.21 KiB) Downloaded 136 times
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
MrProgrammer
Moderator
Posts: 4907
Joined: Fri Jun 04, 2010 7:57 pm
Location: Wisconsin, USA

Re: Paragraph style to set first words in small-caps/petite

Post by MrProgrammer »

Villeroy wrote:Python is the only(?) programming language where white space has a meaning.
You may enjoy learning about the Whitespace language, where white space has meaning and everything else is ignored. Here is Hello World in Whitespace with tabs in light grey, and spaces in darker grey. This makes the LF characters recognizable. Python is mentioned in the link. I find many clever ideas in the Esoteric programming language article. Piet seems particularly fun.
Whitespace Hello World.png
And I must tell you, Villeroy, how much I enjoyed your droll comment about uploading confidential data to Facebook's servers in topic 104343. I laughed.
Mr. Programmer
AOO 4.1.7 Build 9800, MacOS 13.6.3, iMac Intel.   The locale for any menus or Calc formulas in my posts is English (USA).
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

Yep. Programming is a cultural technique like literature or music.

Let's spread some simple tunes.
@CannedMan,
if variable names are irritating you (particularly the misspelled ones), the above def First_3_Words_Emphasis_Conditional can be written in 2 lines with "hard coded" values instead of variables. It's just a matter of readability and style.

Code: Select all

def First_3_Words_Emphasis_Conditional(*args):
    FormatParagraphsFirstWord('Strong Emphasis', 3, ('Standard', 'Text body indent',))
The declaration line is the same. The second line calls the working routine with 3 directly entered argument values. One quoted string (char style), one number (the word count) and a list of quoted para style names in braces.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

You need to change that line in my above code to.

Code: Select all

      tc.CHARFONTNAME = "EB Garamond:c2pc"
(It doesn't work in OpenOffice only LibreOffice)
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

JeJe's code works with both OpenOffice and Libreoffice if you replace

Code: Select all

   res = showpopup3(Thiscomponent.currentcontroller.componentwindow,"1*2*3*4*5*6*7*8*9*10",0,0)
with

Code: Select all

res = inputbox("How many words to small caps?","macro smallcapwordsEnter",3)
However, the LibreOffice drop down menu looks more impressive than the inputbox borrowed from VBA of the 90ies.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

Villeroy:

?

My code worked fine for me in both OpenOffice and LibreOffice

The only thing that doesn't work is OpenOffice doesn't seem to support all the font features that LibreOffice does = that's not related to my popup menu though which is fine in both for me at least.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Paragraph style to set first words in small-caps/petite

Post by JeJe »

Apart from its appearance the input box needs an extra key press - the return key after entering the number. Unless in a hurry I use a custom dialog instead of the input box.

Another approach (appearance wise) based on my menu one is to hide the popup menu off screen and use the status bar to display the choices.

Code: Select all



sub smallcapwordsEnter()
   vc = thiscomponent.currentcontroller.viewcursor

oBar = thiscomponent.CurrentController.getStatusIndicator()

oBar.start ("Small caps for first: 1 word, 2 words, 3 words, 4 words, 5 words, 6 words, 7 words, 8 words, 9 words, Escape key to cancel",0)


   res = showpopup3(Thiscomponent.currentcontroller.componentwindow,"1*2*3*4*5*6*7*8*9*10",-1000,0)

   if res<>"" then
      tc = vc.text.createtextcursorbyrange(vc)
      tc.gotostartofparagraph(false)
      for i = 1 to val(res)
         tc.gotoNextWord(true)
      next
      tc.CHARFONTNAME = "EB Garamond:c2pc"
'      tc.charcasemap = 4
   end if
   thiscomponent.Text.insertControlCharacter(vc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)

obar.end

end sub

function showpopup3(window,st as string,x,y) as string
   'split by *
   'separator_
   'note ~ identifies accelerator
   dim sts() as string,c as long

   aRect = CreateUnoStruct("com.sun.star.awt.Rectangle")
   '        aRect.X =oEvt.x + scontrol.PosSize.X +1
   '       aRect.Y = oEvt.y + scontrol.PosSize.y+1
 aRect.X =x
 arect.y = y

   oPopup = CreateUnoService("stardiv.vcl.PopupMenu")'"com.sun.star.awt.PopupMenu")

   sts = split(st,"*")

   for i = 0 to ubound(sts)
      c =c+1
      if sts(i) ="_" then
         oPopup.insertSeparator(c)
      else
         oPopup.insertItem(c, sts(i),0, c)
         oPopup.setCommand(c, sts(i))
      end if
   next
   n = oPopup.execute( window, aRect, com.sun.star.awt.PopupMenuDirection.EXECUTE_DEFAULT)
   If n > 0 Then
      showpopup3 = oPopup.getCommand(n)
   end if

End function





Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Villeroy
Volunteer
Posts: 31279
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Paragraph style to set first words in small-caps/petite

Post by Villeroy »

Oh, I thought the pop up would be the new thing. I'm not fond of fonts.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
CannedMan
Posts: 225
Joined: Wed Aug 04, 2010 12:06 am

Re: Paragraph style to set first words in small-caps/petite

Post by CannedMan »

I cannot stress how impressed I am with the skill level of you guys. I am soon to embark on this journey of self-inflicted academic pain and suffering; I will try to remember to check back to tell you guys how awesome your replies have been and how much it has helped me. Until then, I will mark this as solved. Stay safe and healthy!
Apache OpenOffice 4.1.5 / LibreOffice 7.0.0.3 on Windows 10 (x64)
Post Reply