[Tex/LaTex] Defining a Lyx-inset, that always has full line width in the editor

lyxlyx-layouts

Correction: In the original text I wrote that floats are displayed full-width. This was an error; Just like the "flexi-insets" created with InsetLayout they are only displayed in full-width when they contain more than one line. Hence the workaround also doesn't work as intended.

In LyX there are some builtin layouts in Resources/layouts/stdlayouts.inc that when inserted fill the full width of the editor. This behaviour applies to the prototype layout Box and the Box:<SpecificName> family of layouts. Similar behaviour applies to floats.

I wanted to define a local layout that encloses a paragraph into the widetext environment. The layout

InsetLayout WideText 
    LyXType          Custom
    LabelString      WideText
    LatexType        environment
    LatexName        widetext
    Decoration       classic
    LabelFont        
        Color        blue
        Size         Small
    EndFont
    MultiPar         true
    OptionalArgs     0
    Preamble
        \RequirePackage{widetext}
    EndPreamble 
End

does this, but in LyX the inset will be displayed only as wide as its contents — which is a poor representation of the actual environment. I'd prefer my inset to be displayed in the Style of boxes and floats, without being either: Boxes always include a minipage environment (which is undesirable) and floats cause undesirable changes to the preamble unless supressed by a hack (which hence may break in future versions of LyX).

As a workaround I am using the layout

Float
    Type         widetext
    GuiName      widetext
    IsPredefined true
End 

where IsPredefine supresses an entry in the preamble, that clashes with the definition of the widetext environment. The inset is then listed in Insert → Float The results look like this

Widetext Inset vs pseudo-float
and the compiled behaviour is correct in both cases.

But is there a clean solution to obtain the desired behaviour without the float-hack?

Best Answer

From what I understand, this is not possible for Flex insets.

Looking at the source code, we see that Inset.h has the following

/// Is the width forced to some value?
virtual bool hasFixedWidth() const { return false; }

In the inheritance chain to InsetFlex, this member function is never overriden.

Boxes have the following (see InsetBox.cpp):

bool InsetBox::hasFixedWidth() const
{
    return !params_.width.empty();
}

If you change that return to be return false;, then they will not have the full page width that you're talking about either.

Note that when I copy/paste your definition into Document > Settings > Local Layout, I get the following output on my terminal:

insets/InsetLayout.cpp (206): Flex insets must have names of the form `Flex:<name>'.
This one has the name `WideText'
Ignoring LyXType declaration.
LyX: Unknown InsetLayout tag [around line 2 of file  current token: 'Custom' context: '']
LyX: Unknown InsetLayout tag [around line 11 of file  current token: 'OptionalArgs' context: '']
LyX: Unknown InsetLayout tag [around line 12 of file  current token: '0' context: '']
frontends/qt4/GuiDocument.cpp (571): Format 49
InsetLayout "Flex:WideText"
    LyXType          Custom
    LabelString      WideText
    LatexType        environment
    LatexName        widetext
    Decoration       classic
    LabelFont        
        Color        blue
        Size         Small
    EndFont
    MultiPar         true
    ResetArgs   1
    Preamble
        \RequirePackage{widetext}
    EndPreamble 
    ResetsFont true
End

You might want to correct these errors.

Finally, note that I have little experience with layouts in LyX, so any of the above could be off. You should join our mailing list at lyx-users@lists.lyx.org and post further questions there. The experts there know more than I do.

Related Question