2002-09-25 14:26:13 +00:00
/**
2007-04-25 01:24:38 +00:00
* \ file InsetFloat . cpp
2002-09-25 14:26:13 +00:00
* This file is part of LyX , the document processor .
* Licence details can be found in the file COPYING .
2002-03-21 17:09:55 +00:00
*
2008-11-14 15:58:50 +00:00
* \ author Jürgen Vigna
* \ author Lars Gullik Bjønnes
* \ author Jürgen Spitzmüller
2002-03-21 17:09:55 +00:00
*
2003-08-23 00:17:00 +00:00
* Full author contact details are available in file CREDITS .
2002-09-25 14:26:13 +00:00
*/
2000-06-28 13:35:52 +00:00
2003-05-13 09:48:57 +00:00
# include <config.h>
2000-06-28 13:35:52 +00:00
2020-10-24 21:47:13 +00:00
# include "InsetFloat.h"
2020-06-08 21:27:49 +00:00
# include "InsetBox.h"
2008-03-02 11:30:50 +00:00
# include "InsetCaption.h"
2020-06-08 21:27:49 +00:00
# include "InsetGraphics.h"
# include "InsetLabel.h"
2003-03-05 19:46:08 +00:00
2007-04-26 04:41:58 +00:00
# include "Buffer.h"
# include "BufferParams.h"
2003-03-05 19:46:08 +00:00
# include "BufferView.h"
2007-08-12 21:43:58 +00:00
# include "Counters.h"
2007-04-26 14:56:30 +00:00
# include "Cursor.h"
2007-04-26 04:41:58 +00:00
# include "DispatchResult.h"
2003-03-05 19:46:08 +00:00
# include "Floating.h"
# include "FloatList.h"
2007-04-26 04:41:58 +00:00
# include "FuncRequest.h"
2005-04-22 08:57:22 +00:00
# include "FuncStatus.h"
2003-03-05 19:46:08 +00:00
# include "LaTeXFeatures.h"
2007-04-26 11:30:54 +00:00
# include "Lexer.h"
2020-07-11 10:30:14 +00:00
# include "xml.h"
2020-07-09 15:19:01 +00:00
# include "output_docbook.h"
2009-11-30 17:20:37 +00:00
# include "output_xhtml.h"
2008-03-02 11:30:50 +00:00
# include "ParIterator.h"
2016-06-19 02:39:38 +00:00
# include "TexRow.h"
# include "texstream.h"
2007-11-07 23:25:08 +00:00
# include "TextClass.h"
2019-05-09 23:35:40 +00:00
# include "InsetList.h"
2003-03-05 19:46:08 +00:00
2008-02-18 07:14:42 +00:00
# include "support/debug.h"
2008-06-18 18:54:31 +00:00
# include "support/docstream.h"
2008-02-18 07:14:42 +00:00
# include "support/gettext.h"
2001-07-30 11:56:00 +00:00
# include "support/lstrings.h"
2008-03-27 22:26:24 +00:00
# include "frontends/Application.h"
2004-07-24 10:55:30 +00:00
2007-12-12 10:16:00 +00:00
using namespace std ;
2010-02-10 17:33:39 +00:00
using namespace lyx : : support ;
2006-10-21 00:16:43 +00:00
2008-03-27 22:26:24 +00:00
namespace lyx {
2003-05-13 16:24:49 +00:00
2000-06-28 13:35:52 +00:00
// With this inset it will be possible to support the latex package
// float.sty, and I am sure that with this and some additional support
// classes we can support similar functionality in other formats
// (read DocBook).
// By using float.sty we will have the same handling for all floats, both
Run codespell on src/insets
Command was
codespell -w -i 3 -S Makefile.in -L mathed,afe,tthe,ue,fro,uint,larg,alph,te,thes,alle,Claus,pres,pass-thru src/insets/
2020-06-25 21:46:16 +00:00
// for those already in existence (table and figure) and all user created
2008-11-14 15:58:50 +00:00
// ones¹. So suddenly we give the users the possibility of creating new
2000-06-28 13:35:52 +00:00
// kinds of floats on the fly. (and with a uniform look)
//
// API to float.sty:
// \newfloat{type}{placement}{ext}[within]
// type - The "type" of the new class of floats, like program or
// algorithm. After the appropriate \newfloat, commands
// such as \begin{program} or \end{algorithm*} will be
// available.
// placement - The default placement for the given class of floats.
// They are like in standard LaTeX: t, b, p and h for top,
// bottom, page, and here, respectively. On top of that
// there is a new type, H, which does not really correspond
// to a float, since it means: put it "here" and nowhere else.
// Note, however that the H specifier is special and, because
// of implementation details cannot be used in the second
// argument of \newfloat.
// ext - The file name extension of an auxiliary file for the list
// of figures (or whatever). LaTeX writes the captions to
// this file.
// within - This (optional) argument determines whether floats of this
// class will be numbered within some sectional unit of the
// document. For example, if within is equal to chapter, the
2002-03-21 17:09:55 +00:00
// floats will be numbered within chapters.
2000-06-28 13:35:52 +00:00
// \floatstyle{style}
// style - plain, boxed, ruled
// \floatname{float}{floatname}
// float -
// floatname -
// \floatplacement{float}{placement}
// float -
// placement -
// \restylefloat{float}
// float -
// \listof{type}{title}
// title -
2008-11-14 15:58:50 +00:00
// ¹ the algorithm float is defined using the float.sty package. Like this
2000-06-28 13:35:52 +00:00
// \floatstyle{ruled}
// \newfloat{algorithm}{htbp}{loa}[<sect>]
// \floatname{algorithm}{Algorithm}
//
2001-03-11 03:20:44 +00:00
// The intention is that floats should be definable from two places:
// - layout files
// - the "gui" (i.e. by the user)
//
// From layout files.
// This should only be done for floats defined in a documentclass and that
// does not need any additional packages. The two most known floats in this
// category is "table" and "figure". Floats defined in layout files are only
// stored in lyx files if the user modifies them.
//
// By the user.
// There should be a gui dialog (and also a collection of lyxfuncs) where
// the user can modify existing floats and/or create new ones.
//
// The individual floats will also have some settable
// variables: wide and placement.
//
2000-06-28 13:35:52 +00:00
// Lgb
2010-02-08 22:09:40 +00:00
//FIXME: why do we set in stone the type here?
2019-09-15 22:43:35 +00:00
InsetFloat : : InsetFloat ( Buffer * buf , string const & params_str )
2015-09-02 18:53:13 +00:00
: InsetCaptionable ( buf )
2000-06-28 13:35:52 +00:00
{
2010-02-10 17:33:39 +00:00
string2params ( params_str , params_ ) ;
2015-09-02 18:53:13 +00:00
setCaptionType ( params_ . type ) ;
}
// Enforce equality of float type and caption type.
void InsetFloat : : setCaptionType ( std : : string const & type )
{
2017-07-03 17:53:14 +00:00
InsetCaptionable : : setCaptionType ( type ) ;
2015-09-02 18:53:13 +00:00
params_ . type = captionType ( ) ;
// check if the float type exists
if ( buffer ( ) . params ( ) . documentClass ( ) . floats ( ) . typeExist ( params_ . type ) )
2017-04-11 22:22:23 +00:00
setNewLabel ( ) ;
2015-09-02 18:53:13 +00:00
else
setLabel ( bformat ( _ ( " ERROR: Unknown float type: %1$s " ) , from_utf8 ( params_ . type ) ) ) ;
2000-06-28 13:35:52 +00:00
}
2011-03-28 22:33:04 +00:00
docstring InsetFloat : : layoutName ( ) const
2017-07-03 17:53:14 +00:00
{
2010-02-10 17:33:39 +00:00
return " Float: " + from_utf8 ( params_ . type ) ;
2008-11-05 15:35:02 +00:00
}
2008-04-10 09:22:49 +00:00
docstring InsetFloat : : toolTip ( BufferView const & bv , int x , int y ) const
{
2010-11-17 17:25:22 +00:00
if ( isOpen ( bv ) )
2015-09-02 18:53:13 +00:00
return InsetCaptionable : : toolTip ( bv , x , y ) ;
2008-04-27 14:47:07 +00:00
2008-04-10 09:22:49 +00:00
OutputParams rp ( & buffer ( ) . params ( ) . encoding ( ) ) ;
2008-08-29 00:38:51 +00:00
return getCaptionText ( rp ) ;
2008-04-10 09:22:49 +00:00
}
2007-04-26 14:56:30 +00:00
void InsetFloat : : doDispatch ( Cursor & cur , FuncRequest & cmd )
2000-06-28 13:35:52 +00:00
{
2010-04-09 19:00:42 +00:00
switch ( cmd . action ( ) ) {
2003-08-05 08:07:07 +00:00
2003-03-05 19:46:08 +00:00
case LFUN_INSET_MODIFY : {
2020-07-13 14:46:43 +00:00
if ( ! buffer ( ) . params ( ) . documentClass ( ) . floats ( ) . typeExist ( cmd . getArg ( 0 ) ) ) {
// not for us: pass further.
cur . undispatched ( ) ;
break ;
}
2003-03-05 19:46:08 +00:00
InsetFloatParams params ;
2008-03-27 22:26:24 +00:00
string2params ( to_utf8 ( cmd . argument ( ) ) , params ) ;
2015-03-12 14:57:29 +00:00
cur . recordUndoInset ( this ) ;
2008-08-19 14:56:12 +00:00
// placement, wide and sideways are not used for subfloats
if ( ! params_ . subfloat ) {
params_ . placement = params . placement ;
params_ . wide = params . wide ;
params_ . sideways = params . sideways ;
}
2018-05-10 18:15:11 +00:00
params_ . alignment = params . alignment ;
2009-07-13 12:56:20 +00:00
setNewLabel ( ) ;
2015-09-02 18:53:13 +00:00
if ( params_ . type ! = params . type )
setCaptionType ( params . type ) ;
2010-07-09 14:37:00 +00:00
// what we really want here is a TOC update, but that means
// a full buffer update
cur . forceBufferUpdate ( ) ;
2004-02-16 11:58:51 +00:00
break ;
2000-07-17 18:27:53 +00:00
}
2003-03-07 15:58:02 +00:00
case LFUN_INSET_DIALOG_UPDATE : {
2008-03-27 22:26:24 +00:00
cur . bv ( ) . updateDialog ( " float " , params2string ( params ( ) ) ) ;
2004-02-16 11:58:51 +00:00
break ;
2003-03-07 15:58:02 +00:00
}
2003-03-05 19:46:08 +00:00
default :
2015-09-02 18:53:13 +00:00
InsetCaptionable : : doDispatch ( cur , cmd ) ;
2004-02-16 11:58:51 +00:00
break ;
2001-05-31 16:48:26 +00:00
}
2003-03-05 17:56:47 +00:00
}
2002-03-21 17:09:55 +00:00
2007-04-26 14:56:30 +00:00
bool InsetFloat : : getStatus ( Cursor & cur , FuncRequest const & cmd ,
2005-04-22 08:57:22 +00:00
FuncStatus & flag ) const
{
2010-04-09 19:00:42 +00:00
switch ( cmd . action ( ) ) {
2005-04-22 08:57:22 +00:00
case LFUN_INSET_MODIFY :
2020-07-13 14:46:43 +00:00
if ( ! buffer ( ) . params ( ) . documentClass ( ) . floats ( ) . typeExist ( cmd . getArg ( 0 ) ) )
return Inset : : getStatus ( cur , cmd , flag ) ;
// fall through
2005-04-22 08:57:22 +00:00
case LFUN_INSET_DIALOG_UPDATE :
2008-05-29 15:14:00 +00:00
flag . setEnabled ( true ) ;
2005-04-22 09:16:28 +00:00
return true ;
2005-04-22 08:57:22 +00:00
2009-08-06 22:42:42 +00:00
case LFUN_INSET_SETTINGS :
2015-09-02 18:53:13 +00:00
if ( InsetCaptionable : : getStatus ( cur , cmd , flag ) ) {
2009-08-06 22:42:42 +00:00
flag . setEnabled ( flag . enabled ( ) & & ! params_ . subfloat ) ;
return true ;
} else
return false ;
2017-07-03 17:53:14 +00:00
2014-01-26 19:22:39 +00:00
case LFUN_NEWLINE_INSERT :
if ( params_ . subfloat ) {
flag . setEnabled ( false ) ;
return true ;
}
2017-08-12 07:06:29 +00:00
// no subfloat:
// fall through
2009-08-06 22:42:42 +00:00
2005-04-22 08:57:22 +00:00
default :
2015-09-02 18:53:13 +00:00
return InsetCaptionable : : getStatus ( cur , cmd , flag ) ;
2005-04-22 08:57:22 +00:00
}
}
2015-09-02 18:53:13 +00:00
bool InsetFloat : : hasSubCaptions ( ParIterator const & it ) const
2015-09-01 16:08:35 +00:00
{
2015-09-02 18:53:13 +00:00
return ( it . innerInsetOfType ( FLOAT_CODE ) | | it . innerInsetOfType ( WRAP_CODE ) ) ;
2007-08-12 21:43:58 +00:00
}
2018-05-11 13:31:04 +00:00
string InsetFloat : : getAlignment ( ) const
{
string alignment ;
string const buf_alignment = buffer ( ) . params ( ) . float_alignment ;
if ( params_ . alignment = = " document "
& & ! buf_alignment . empty ( ) ) {
alignment = buf_alignment ;
} else if ( ! params_ . alignment . empty ( )
& & params_ . alignment ! = " class "
& & params_ . alignment ! = " document " ) {
alignment = params_ . alignment ;
}
return alignment ;
}
2020-11-29 23:03:35 +00:00
CtObject InsetFloat : : getCtObject ( OutputParams const & ) const
{
return CtObject : : OmitObject ;
}
2018-05-11 13:31:04 +00:00
LyXAlignment InsetFloat : : contentAlignment ( ) const
{
LyXAlignment align = LYX_ALIGN_NONE ;
string alignment = getAlignment ( ) ;
if ( alignment = = " left " )
align = LYX_ALIGN_LEFT ;
else if ( alignment = = " center " )
align = LYX_ALIGN_CENTER ;
else if ( alignment = = " right " )
align = LYX_ALIGN_RIGHT ;
return align ;
}
2003-03-05 19:46:08 +00:00
void InsetFloatParams : : write ( ostream & os ) const
2003-03-05 17:56:47 +00:00
{
2015-09-02 18:53:13 +00:00
if ( type . empty ( ) ) {
// Better this than creating a parse error. This in fact happens in the
// parameters dialog via InsetFloatParams::params2string.
os < < " senseless " < < ' \n ' ;
} else
os < < type < < ' \n ' ;
2003-03-05 19:46:08 +00:00
2003-08-05 08:07:07 +00:00
if ( ! placement . empty ( ) )
2003-03-05 19:46:08 +00:00
os < < " placement " < < placement < < " \n " ;
2018-05-10 18:15:11 +00:00
if ( ! alignment . empty ( ) )
os < < " alignment " < < alignment < < " \n " ;
2003-08-05 08:07:07 +00:00
if ( wide )
2003-03-05 19:46:08 +00:00
os < < " wide true \n " ;
2003-08-05 08:07:07 +00:00
else
2003-03-05 19:46:08 +00:00
os < < " wide false \n " ;
2004-04-03 08:37:12 +00:00
2004-03-29 11:38:39 +00:00
if ( sideways )
os < < " sideways true \n " ;
else
os < < " sideways false \n " ;
2000-06-28 13:35:52 +00:00
}
2007-04-26 11:30:54 +00:00
void InsetFloatParams : : read ( Lexer & lex )
2000-06-28 13:35:52 +00:00
{
2008-04-05 10:34:29 +00:00
lex . setContext ( " InsetFloatParams::read " ) ;
2010-02-10 17:33:39 +00:00
lex > > type ;
2008-04-05 10:34:29 +00:00
if ( lex . checkFor ( " placement " ) )
2004-04-02 08:54:37 +00:00
lex > > placement ;
2018-05-10 18:15:11 +00:00
if ( lex . checkFor ( " alignment " ) )
lex > > alignment ;
2008-04-05 10:34:29 +00:00
lex > > " wide " > > wide ;
lex > > " sideways " > > sideways ;
2003-03-05 17:56:47 +00:00
}
2008-02-27 20:43:16 +00:00
void InsetFloat : : write ( ostream & os ) const
2003-03-05 19:46:08 +00:00
{
2010-02-08 22:09:40 +00:00
os < < " Float " ;
2003-03-05 19:46:08 +00:00
params_ . write ( os ) ;
2015-09-02 18:53:13 +00:00
InsetCaptionable : : write ( os ) ;
2003-03-05 19:46:08 +00:00
}
2008-02-27 20:43:16 +00:00
void InsetFloat : : read ( Lexer & lex )
2003-03-05 17:56:47 +00:00
{
2003-03-05 19:46:08 +00:00
params_ . read ( lex ) ;
2015-09-02 18:53:13 +00:00
InsetCaptionable : : read ( lex ) ;
setCaptionType ( params_ . type ) ;
2000-06-28 13:35:52 +00:00
}
2001-06-28 10:25:20 +00:00
void InsetFloat : : validate ( LaTeXFeatures & features ) const
2000-06-28 13:35:52 +00:00
{
2008-03-05 00:21:05 +00:00
if ( support : : contains ( params_ . placement , ' H ' ) )
2002-01-10 10:05:45 +00:00
features . require ( " float " ) ;
2004-04-03 08:37:12 +00:00
2004-03-29 11:38:39 +00:00
if ( params_ . sideways )
2008-01-11 18:56:53 +00:00
features . require ( " rotfloat " ) ;
2002-03-21 17:09:55 +00:00
2009-02-07 12:27:24 +00:00
if ( features . inFloat ( ) )
2008-03-02 11:30:50 +00:00
features . require ( " subfig " ) ;
2019-12-28 12:43:17 +00:00
if ( features . inDeletedInset ( ) ) {
features . require ( " tikz " ) ;
2019-12-27 08:50:11 +00:00
features . require ( " ct-tikz-object-sout " ) ;
2019-12-28 12:43:17 +00:00
}
2019-12-27 08:50:11 +00:00
2009-02-07 12:27:24 +00:00
features . useFloat ( params_ . type , features . inFloat ( ) ) ;
features . inFloat ( true ) ;
2015-09-02 18:53:13 +00:00
InsetCaptionable : : validate ( features ) ;
2009-02-07 12:27:24 +00:00
features . inFloat ( false ) ;
2000-06-28 13:35:52 +00:00
}
2019-05-09 23:35:40 +00:00
docstring InsetFloat : : xhtml ( XMLStream & xs , OutputParams const & rp ) const
2009-06-19 12:49:08 +00:00
{
FloatList const & floats = buffer ( ) . params ( ) . documentClass ( ) . floats ( ) ;
Floating const & ftype = floats . getType ( params_ . type ) ;
2009-11-30 17:08:56 +00:00
string const & htmltype = ftype . htmlTag ( ) ;
2010-01-07 17:32:04 +00:00
string const & attr = ftype . htmlAttrib ( ) ;
2009-06-19 12:49:08 +00:00
2009-11-30 17:20:37 +00:00
odocstringstream ods ;
2019-05-09 23:35:40 +00:00
XMLStream newxs ( ods ) ;
newxs < < xml : : StartTag ( htmltype , attr ) ;
2017-07-03 17:53:14 +00:00
InsetText : : XHTMLOptions const opts =
2009-11-30 17:20:37 +00:00
InsetText : : WriteLabel | InsetText : : WriteInnerTag ;
docstring deferred = InsetText : : insetAsXHTML ( newxs , rp , opts ) ;
2019-05-09 23:35:40 +00:00
newxs < < xml : : EndTag ( htmltype ) ;
2009-06-19 12:49:08 +00:00
2016-07-30 03:59:24 +00:00
if ( rp . inFloat = = OutputParams : : NONFLOAT ) {
2009-06-19 12:49:08 +00:00
// In this case, this float needs to be deferred, but we'll put it
// before anything the text itself deferred.
2009-11-30 17:20:37 +00:00
deferred = ods . str ( ) + ' \n ' + deferred ;
2016-07-30 03:59:24 +00:00
} else {
2009-06-19 12:49:08 +00:00
// In this case, the whole thing is already being deferred, so
// we can write to the stream.
2017-07-03 17:53:14 +00:00
// Note that things will already have been escaped, so we do not
2009-11-30 17:20:37 +00:00
// want to escape them again.
2019-05-09 23:35:40 +00:00
xs < < XMLStream : : ESCAPE_NONE < < ods . str ( ) ;
2016-07-30 03:59:24 +00:00
}
2009-11-30 17:20:37 +00:00
return deferred ;
2009-06-19 12:49:08 +00:00
}
2011-02-10 20:02:48 +00:00
void InsetFloat : : latex ( otexstream & os , OutputParams const & runparams_in ) const
2000-06-28 13:35:52 +00:00
{
2009-02-07 12:27:24 +00:00
if ( runparams_in . inFloat ! = OutputParams : : NONFLOAT ) {
2016-10-10 15:14:39 +00:00
if ( ! paragraphs ( ) . empty ( ) & & ! runparams_in . nice )
// improve TexRow precision in non-nice mode
os < < safebreakln ;
2009-02-07 12:27:24 +00:00
if ( runparams_in . moving_arg )
2008-03-02 11:30:50 +00:00
os < < " \\ protect " ;
os < < " \\ subfloat " ;
2014-12-04 16:27:56 +00:00
2009-02-07 12:27:24 +00:00
OutputParams rp = runparams_in ;
2014-12-04 16:27:56 +00:00
rp . moving_arg = true ;
2020-08-28 05:32:29 +00:00
rp . inFloat = OutputParams : : SUBFLOAT ;
2016-09-23 22:49:00 +00:00
os < < getCaption ( rp ) ;
2008-03-02 11:30:50 +00:00
os < < ' { ' ;
2015-02-20 10:51:40 +00:00
// The main argument is the contents of the float. This is not a moving argument.
rp . moving_arg = false ;
2011-02-10 20:02:48 +00:00
InsetText : : latex ( os , rp ) ;
2008-03-02 11:30:50 +00:00
os < < " } " ;
2014-12-04 16:27:56 +00:00
2011-02-10 20:02:48 +00:00
return ;
2008-03-02 11:30:50 +00:00
}
2009-02-07 12:27:24 +00:00
OutputParams runparams ( runparams_in ) ;
runparams . inFloat = OutputParams : : MAINFLOAT ;
2008-03-02 11:30:50 +00:00
2008-02-28 01:42:02 +00:00
FloatList const & floats = buffer ( ) . params ( ) . documentClass ( ) . floats ( ) ;
2008-01-11 18:56:53 +00:00
string tmptype = params_ . type ;
2015-05-22 16:59:17 +00:00
if ( params_ . sideways & & floats . allowsSideways ( params_ . type ) )
2008-01-11 18:56:53 +00:00
tmptype = " sideways " + params_ . type ;
2015-05-23 08:38:31 +00:00
if ( params_ . wide & & floats . allowsWide ( params_ . type )
2015-05-22 16:59:17 +00:00
& & ( ! params_ . sideways | |
params_ . type = = " figure " | |
params_ . type = = " table " ) )
2008-01-11 18:56:53 +00:00
tmptype + = " * " ;
2001-07-04 07:44:27 +00:00
// Figure out the float placement to use.
// From lowest to highest:
// - float default placement
// - document wide default placement
// - specific float placement
2015-05-22 08:37:14 +00:00
string tmpplacement ;
2008-02-27 20:43:16 +00:00
string const buf_placement = buffer ( ) . params ( ) . float_placement ;
2003-03-05 17:56:47 +00:00
string const def_placement = floats . defaultPlacement ( params_ . type ) ;
2018-05-10 18:15:11 +00:00
if ( params_ . placement = = " document "
& & ! buf_placement . empty ( )
& & buf_placement ! = def_placement ) {
2015-05-22 08:37:14 +00:00
tmpplacement = buf_placement ;
2018-05-10 18:15:11 +00:00
} else if ( ! params_ . placement . empty ( )
& & params_ . placement ! = " document "
& & params_ . placement ! = def_placement ) {
tmpplacement = params_ . placement ;
2015-05-22 08:37:14 +00:00
}
// Check if placement is allowed by this float
string const allowed_placement =
floats . allowedPlacement ( params_ . type ) ;
string placement ;
string : : const_iterator lit = tmpplacement . begin ( ) ;
string : : const_iterator end = tmpplacement . end ( ) ;
for ( ; lit ! = end ; + + lit ) {
if ( contains ( allowed_placement , * lit ) )
placement + = * lit ;
2001-07-04 07:44:27 +00:00
}
2002-03-21 17:09:55 +00:00
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
// Force \begin{<floatname>} to appear in a new line.
os < < breakln < < " \\ begin{ " < < from_ascii ( tmptype ) < < ' } ' ;
2011-03-12 01:40:01 +00:00
if ( runparams . lastid ! = - 1 )
os . texrow ( ) . start ( runparams . lastid , runparams . lastpos ) ;
2001-07-04 07:44:27 +00:00
// We only output placement if different from the def_placement.
2017-04-15 04:57:52 +00:00
// sidewaysfloats always use their own page,
// therefore don't output the p option that is always set
if ( ! placement . empty ( )
2019-09-15 22:43:35 +00:00
& & ( ! params_ . sideways | | from_ascii ( placement ) ! = " p " ) )
2006-10-21 00:16:43 +00:00
os < < ' [ ' < < from_ascii ( placement ) < < ' ] ' ;
2002-11-27 10:30:28 +00:00
os < < ' \n ' ;
2018-05-11 13:31:04 +00:00
2019-12-27 08:50:11 +00:00
if ( runparams . inDeletedInset ) {
2019-12-28 12:43:17 +00:00
// This has to be done manually since we need it inside the float
2020-11-29 23:03:35 +00:00
CtObject ctobject = runparams . ctObject ;
runparams . ctObject = CtObject : : DisplayObject ;
2019-12-28 12:43:17 +00:00
Changes : : latexMarkChange ( os , buffer ( ) . params ( ) , Change ( Change : : UNCHANGED ) ,
Change ( Change : : DELETED ) , runparams ) ;
runparams . ctObject = ctobject ;
2019-12-27 08:50:11 +00:00
}
2018-05-11 13:31:04 +00:00
string alignment = getAlignment ( ) ;
2018-05-10 18:15:11 +00:00
if ( alignment = = " left " )
os < < " \\ raggedright " < < breakln ;
else if ( alignment = = " center " )
os < < " \\ centering " < < breakln ;
else if ( alignment = = " right " )
os < < " \\ raggedleft " < < breakln ;
2002-03-21 17:09:55 +00:00
2011-02-10 20:02:48 +00:00
InsetText : : latex ( os , runparams ) ;
2002-05-05 15:15:51 +00:00
2019-12-27 08:50:11 +00:00
if ( runparams . inDeletedInset )
2019-12-28 12:43:17 +00:00
os < < " } " ;
2019-12-27 08:50:11 +00:00
Introduce a wrapper class for odocstream to help ensuring that no
blank lines may be inadvertently output. This is achieved by using two
special iomanip-like variables (breakln and safebreakln) in the lyx::
namespace. When they are inserted in the stream, a newline is output
only if not already at the beginning of a line. The difference between
breakln and safebreakln is that, if needed, the former outputs '\n'
and the latter "%\n".
In future, the new class will also be used for counting the number of
newlines issued. Even if the infractrure for doing that is already in
place, the counting is essentially still done the old way.
There are still places in the code where the functionality of the
class could be used, most probably. ATM, it is used for InsetTabular,
InsetListings, InsetFloat, and InsetText.
The Comment and GreyedOut insets required a special treatment and a
new InsetLayout parameter (Display) has been introduced. The default
for Display is "true", meaning that the corresponding latex
environment is of "display" type, i.e., it stands on its own, whereas
"false" means that the contents appear inline with the text. The
latter is the case for both Comment and GreyedOut insets.
Mostly, the only visible effects on latex exports should be the
disappearing of some redundant % chars and the appearing/disappearing
of null {} latex groups after a comment or lyxgreyedout environments
(they are related to the presence or absence of a space immediately
after those environments), as well as the fact that math environments
are now started on their own lines.
As a last thing, only the latex code between \begin{document} and
\end{document} goes through the new class, the preamble being directly
output through odocstream, as usual.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37360 a592a061-630c-0410-9148-cb99ea01b6c8
2011-01-29 02:41:13 +00:00
// Force \end{<floatname>} to appear in a new line.
os < < breakln < < " \\ end{ " < < from_ascii ( tmptype ) < < " } \n " ;
2000-06-28 13:35:52 +00:00
}
2013-03-08 19:52:18 +00:00
int InsetFloat : : plaintext ( odocstringstream & os , OutputParams const & runparams , size_t max_length ) const
2007-02-16 08:15:16 +00:00
{
2008-02-27 20:43:16 +00:00
os < < ' [ ' < < buffer ( ) . B_ ( " float " ) < < ' '
2009-07-13 12:56:20 +00:00
< < floatName ( params_ . type ) < < " : \n " ;
2013-03-08 19:52:18 +00:00
InsetText : : plaintext ( os , runparams , max_length ) ;
2007-02-16 08:15:16 +00:00
os < < " \n ] " ;
2007-02-20 17:52:41 +00:00
return PLAINTEXT_NEWLINE + 1 ; // one char on a separate line
2007-02-16 08:15:16 +00:00
}
2020-09-11 01:14:41 +00:00
std : : vector < const InsetCollapsible * > findSubfiguresInParagraph ( const Paragraph & par )
2020-06-08 21:27:49 +00:00
{
// Don't make the hypothesis that all subfigures are in the same paragraph.
// Similarly, there may be several subfigures in the same paragraph (most likely case, based on the documentation).
// Any box is considered as a subfigure, even though the most likely case is \minipage.
2020-09-11 01:14:41 +00:00
// Boxes are not required to make subfigures. The common root between InsetBox and InsetFLoat is InsetCollapsible.
std : : vector < const InsetCollapsible * > subfigures ;
2020-06-08 21:27:49 +00:00
for ( pos_type pos = 0 ; pos < par . size ( ) ; + + pos ) {
const Inset * inset = par . getInset ( pos ) ;
if ( ! inset )
continue ;
if ( const auto box = dynamic_cast < const InsetBox * > ( inset ) )
subfigures . push_back ( box ) ;
2020-09-11 01:14:41 +00:00
else if ( const auto fl = dynamic_cast < const InsetFloat * > ( inset ) )
subfigures . push_back ( fl ) ;
2020-06-08 21:27:49 +00:00
}
return subfigures ;
}
2020-09-11 22:39:23 +00:00
/// Takes an unstructured subfigure container (typically, an InsetBox) and find the elements within:
/// actual content (image or table), maybe a caption, maybe a label.
std : : tuple < InsetCode , const Inset * , const InsetCaption * , const InsetLabel * > docbookParseHopelessSubfigure ( const InsetText * subfigure )
{
InsetCode type = NO_CODE ;
const Inset * content = nullptr ;
const InsetCaption * caption = nullptr ;
const InsetLabel * label = nullptr ;
for ( const auto & it : subfigure - > paragraphs ( ) ) {
for ( pos_type posIn = 0 ; posIn < it . size ( ) ; + + posIn ) {
const Inset * inset = it . getInset ( posIn ) ;
if ( inset ) {
switch ( inset - > lyxCode ( ) ) {
case GRAPHICS_CODE :
case TABULAR_CODE :
if ( ! content ) {
content = inset ;
type = inset - > lyxCode ( ) ;
}
break ;
case CAPTION_CODE :
if ( ! caption ) {
caption = dynamic_cast < const InsetCaption * > ( inset ) ;
// A label often hides in a caption. Make a simplified version of the main loop.
if ( ! label ) {
for ( const auto & cit : caption - > paragraphs ( ) ) {
for ( pos_type cposIn = 0 ; cposIn < cit . size ( ) ; + + cposIn ) {
const Inset * cinset = cit . getInset ( posIn ) ;
if ( cinset & & cinset - > lyxCode ( ) = = LABEL_CODE ) {
label = dynamic_cast < const InsetLabel * > ( cinset ) ;
break ;
}
}
if ( label )
break ;
}
}
}
break ;
case LABEL_CODE :
if ( ! label )
label = dynamic_cast < const InsetLabel * > ( inset ) ;
break ;
default :
break ;
}
}
}
if ( content & & caption & & label )
break ;
}
return std : : make_tuple ( type , content , caption , label ) ;
}
2020-08-02 02:03:17 +00:00
void docbookSubfigures ( XMLStream & xs , OutputParams const & runparams , const InsetCaption * caption ,
2020-10-09 15:50:24 +00:00
const InsetLabel * label , std : : vector < const InsetCollapsible * > const & subfigures )
2020-06-08 21:27:49 +00:00
{
2020-08-02 02:03:17 +00:00
// Ensure there is no label output, it is supposed to be handled as xml:id.
OutputParams rpNoLabel = runparams ;
if ( label )
rpNoLabel . docbook_anchors_to_ignore . emplace ( label - > screenLabel ( ) ) ;
2020-06-08 21:27:49 +00:00
2020-08-02 02:03:17 +00:00
// First, open the formal group.
docstring attr = docstring ( ) ;
if ( label )
attr + = " xml:id= \" " + xml : : cleanID ( label - > screenLabel ( ) ) + " \" " ;
xs . startDivision ( false ) ;
xs < < xml : : StartTag ( " formalgroup " , attr ) ;
xs < < xml : : CR ( ) ;
2020-09-11 21:38:11 +00:00
xs < < xml : : StartTag ( " title " ) ; // Don't take attr here, the ID should only go in one place, not two.
2020-08-02 02:03:17 +00:00
if ( caption ) {
caption - > getCaptionAsDocBook ( xs , rpNoLabel ) ;
} else {
xs < < " No caption " ;
// No caption has been detected, but this tag is required for the document to be valid DocBook.
}
xs < < xml : : EndTag ( " title " ) ;
xs < < xml : : CR ( ) ;
// Deal with each subfigure individually. This should also deal with their caption and their label.
// This should be a recursive call to InsetFloat.
2020-09-11 22:39:23 +00:00
// An item in subfigure should either be an InsetBox containing an InsetFloat, or an InsetBox directly containing
// an image or a table, or directly an InsetFloat.
for ( const InsetCollapsible * subfigure : subfigures ) {
if ( subfigure = = nullptr )
continue ;
2020-09-11 01:14:41 +00:00
// The collapsible may already be a float (InsetFloat).
2020-09-11 22:39:23 +00:00
if ( dynamic_cast < const InsetFloat * > ( subfigure ) ) {
subfigure - > docbook ( xs , runparams ) ;
continue ;
}
2020-09-11 01:14:41 +00:00
2020-09-11 22:39:23 +00:00
// Subfigures are in boxes, then in InsetFloat.
{
bool foundInsetFloat = false ;
2020-09-11 01:14:41 +00:00
for ( const auto & it : subfigure - > paragraphs ( ) ) {
for ( pos_type posIn = 0 ; posIn < it . size ( ) ; + + posIn ) {
const Inset * inset = it . getInset ( posIn ) ;
2020-09-11 22:39:23 +00:00
if ( inset & & inset - > lyxCode ( ) = = FLOAT_CODE ) {
2020-09-11 01:14:41 +00:00
foundInsetFloat = true ;
2020-09-11 22:39:23 +00:00
inset - > docbook ( xs , runparams ) ;
2020-09-11 01:14:41 +00:00
break ;
}
2020-08-02 02:03:17 +00:00
}
2020-09-11 01:14:41 +00:00
if ( foundInsetFloat )
break ;
}
2020-09-11 22:39:23 +00:00
if ( foundInsetFloat )
continue ;
}
// Subfigures are in boxes, then directly an image or a table. In that case, generate the whole content of the
// InsetBox, but not the box container.
// Impose some model on the subfigure: at most a caption, at most a label, exactly one figure or one table.
{
InsetCode stype = NO_CODE ;
const Inset * scontent = nullptr ;
const InsetCaption * scaption = nullptr ;
const InsetLabel * slabel = nullptr ;
std : : tie ( stype , scontent , scaption , slabel ) = docbookParseHopelessSubfigure ( subfigure ) ;
// If there is something, generate it. This is very much like docbookNoSubfigures, but many things
// must be coded differently because there is no float.
// TODO: some code is identical to Floating, like Floating::docbookTag or Floating::docbookCaption. How to reuse that code?
if ( scontent ) {
// Floating::docbookCaption()
string docbook_caption = " caption " ; // This is already correct for tables.
if ( stype = = GRAPHICS_CODE )
docbook_caption = " title " ;
// Floating::docbookTag() with hasTitle = true, as we are in formalgroup.
string stag = " float " ;
if ( stype = = GRAPHICS_CODE )
stag = " figure " ;
else if ( stype = = TABULAR_CODE )
stag = " table " ;
// Ensure there is no label output, it is supposed to be handled as xml:id.
if ( slabel )
rpNoLabel . docbook_anchors_to_ignore . emplace ( slabel - > screenLabel ( ) ) ;
// Ensure the float does not output its caption, as it is handled here (DocBook mandates a specific place for
// captions, they cannot appear at the end of the float, albeit LyX is happy with that).
OutputParams rpNoTitle = runparams ;
rpNoTitle . docbook_in_float = true ;
if ( stype = = TABULAR_CODE )
rpNoTitle . docbook_in_table = true ;
// Organisation: <float> <title if any/> <contents without title/> </float>.
docstring sattr = docstring ( ) ;
if ( slabel )
sattr + = " xml:id= \" " + xml : : cleanID ( slabel - > screenLabel ( ) ) + " \" " ;
// No layout way of adding attributes, unlike the normal code path.
xs < < xml : : StartTag ( stag , sattr ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : StartTag ( docbook_caption ) ;
if ( scaption )
scaption - > getCaptionAsDocBook ( xs , rpNoLabel ) ;
else // Mandatory in formalgroup.
xs < < " No caption detected " ;
xs < < xml : : EndTag ( docbook_caption ) ;
xs < < xml : : CR ( ) ;
scontent - > docbook ( xs , rpNoTitle ) ;
xs < < xml : : EndTag ( stag ) ;
xs < < xml : : CR ( ) ;
// This subfigure could be generated.
continue ;
}
2020-06-08 21:27:49 +00:00
}
2020-09-11 22:39:23 +00:00
// If there is no InsetFloat in the inset, output a warning.
xs < < XMLStream : : ESCAPE_NONE < < " Error: no float found in the box. "
" To use subfigures in DocBook, elements must be wrapped in a float "
" inset and have a title/caption. " ;
2020-08-02 02:03:17 +00:00
// TODO: could also output a table, that would ensure that the document is correct and *displays* correctly (but without the right semantics), instead of just an error.
2020-09-11 22:39:23 +00:00
// Recurse to generate as much content as possible (avoid any loss).
2020-08-02 02:03:17 +00:00
subfigure - > docbook ( xs , runparams ) ;
2020-06-08 21:27:49 +00:00
}
2020-08-02 02:03:17 +00:00
// Every subfigure is done: close the formal group.
xs < < xml : : EndTag ( " formalgroup " ) ;
xs < < xml : : CR ( ) ;
xs . endDivision ( ) ;
}
2020-11-27 22:44:48 +00:00
void docbookGenerateFillerMedia ( XMLStream & xs )
{
xs < < xml : : StartTag ( " mediaobject " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : StartTag ( " textobject " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : StartTag ( " phrase " ) ;
xs < < " This figure is empty. " ;
xs < < xml : : EndTag ( " phrase " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : EndTag ( " textobject " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : EndTag ( " mediaobject " ) ;
xs < < xml : : CR ( ) ;
}
void docbookGenerateFillerTable ( XMLStream & xs , BufferParams : : TableOutput format )
{
switch ( format ) {
case BufferParams : : HTMLTable :
xs < < xml : : StartTag ( " tr " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : StartTag ( " td " ) ;
xs < < " This table is empty. " ;
xs < < xml : : EndTag ( " td " ) ;
xs < < xml : : CR ( ) ;
xs < < xml : : EndTag ( " tr " ) ;
xs < < xml : : CR ( ) ;
break ;
case BufferParams : : CALSTable :
// CALS tables allow for <mediaobject>, use that instead.
docbookGenerateFillerMedia ( xs ) ;
break ;
}
}
2020-08-02 02:03:17 +00:00
void docbookNoSubfigures ( XMLStream & xs , OutputParams const & runparams , const InsetCaption * caption ,
2021-12-26 01:24:06 +00:00
const InsetLabel * label , Floating const & ftype , const InsetFloat * thisFloat ) {
2020-06-08 21:27:49 +00:00
// Ensure there is no label output, it is supposed to be handled as xml:id.
OutputParams rpNoLabel = runparams ;
if ( label )
rpNoLabel . docbook_anchors_to_ignore . emplace ( label - > screenLabel ( ) ) ;
// Ensure the float does not output its caption, as it is handled here (DocBook mandates a specific place for
// captions, they cannot appear at the end of the float, albeit LyX is happy with that).
OutputParams rpNoTitle = runparams ;
rpNoTitle . docbook_in_float = true ;
2020-09-02 22:48:55 +00:00
if ( ftype . docbookFloatType ( ) = = " table " )
2020-08-02 02:03:17 +00:00
rpNoTitle . docbook_in_table = true ;
2020-06-08 21:27:49 +00:00
2020-11-27 04:19:27 +00:00
// Generate the contents of the float (to check for emptiness).
2021-12-24 00:08:24 +00:00
odocstringstream osFloatContent ;
2021-12-26 01:24:06 +00:00
bool hasFloat = false ;
if ( thisFloat ) {
XMLStream xsFloatContent ( osFloatContent ) ;
thisFloat - > InsetText : : docbook ( xsFloatContent , rpNoTitle ) ;
hasFloat = ! osFloatContent . str ( ) . empty ( ) ;
}
2021-12-24 00:08:24 +00:00
// Do the same for the caption.
odocstringstream osCaptionContent ;
2021-12-26 01:24:06 +00:00
bool hasCaption = false ;
if ( caption ! = nullptr ) {
XMLStream xsCaptionContent ( osCaptionContent ) ;
caption - > getCaptionAsDocBook ( xsCaptionContent , rpNoLabel ) ;
hasCaption = ! osCaptionContent . str ( ) . empty ( ) ;
}
2020-11-27 04:19:27 +00:00
2020-08-02 02:03:17 +00:00
// Organisation: <float> <title if any/> <contents without title/> </float>.
2021-12-24 00:08:24 +00:00
// - Generate the attributes for the float tag.
2020-06-08 21:27:49 +00:00
docstring attr = docstring ( ) ;
if ( label )
attr + = " xml:id= \" " + xml : : cleanID ( label - > screenLabel ( ) ) + " \" " ;
if ( ! ftype . docbookAttr ( ) . empty ( ) ) {
if ( ! attr . empty ( ) )
attr + = " " ;
attr + = from_utf8 ( ftype . docbookAttr ( ) ) ;
}
2020-11-27 22:44:48 +00:00
// - Open the float tag.
2021-12-24 00:08:24 +00:00
xs < < xml : : StartTag ( ftype . docbookTag ( hasCaption ) , attr ) ;
2020-06-08 21:27:49 +00:00
xs < < xml : : CR ( ) ;
2020-11-27 22:44:48 +00:00
// - Generate the caption.
2021-12-24 00:08:24 +00:00
if ( hasCaption ) {
2020-11-27 22:44:48 +00:00
string const & titleTag = ftype . docbookCaption ( ) ;
2020-06-08 21:27:49 +00:00
xs < < xml : : StartTag ( titleTag ) ;
2021-12-24 00:08:24 +00:00
xs < < XMLStream : : ESCAPE_NONE < < osCaptionContent . str ( ) ;
2020-06-08 21:27:49 +00:00
xs < < xml : : EndTag ( titleTag ) ;
xs < < xml : : CR ( ) ;
}
2020-11-27 04:19:27 +00:00
2021-12-24 00:08:24 +00:00
// - Output the actual content of the float or some dummy content (to ensure that the output
// document is valid).
if ( hasFloat )
xs < < XMLStream : : ESCAPE_NONE < < osFloatContent . str ( ) ;
2020-11-27 22:44:48 +00:00
else if ( ftype . docbookFloatType ( ) = = " table " )
docbookGenerateFillerTable ( xs , thisFloat - > buffer ( ) . params ( ) . docbook_table_output ) ;
else
docbookGenerateFillerMedia ( xs ) ;
2020-11-27 04:19:27 +00:00
2020-11-27 22:44:48 +00:00
// - Close the float.
2021-12-24 00:08:24 +00:00
xs < < xml : : EndTag ( ftype . docbookTag ( hasCaption ) ) ;
2020-06-08 21:27:49 +00:00
xs < < xml : : CR ( ) ;
2001-03-23 08:37:44 +00:00
}
2020-08-02 02:03:17 +00:00
void InsetFloat : : docbook ( XMLStream & xs , OutputParams const & runparams ) const
{
2020-11-15 02:03:16 +00:00
const InsetCaption * caption = getCaptionInset ( ) ;
const InsetLabel * label = getLabelInset ( ) ;
2020-08-02 02:03:17 +00:00
2020-11-15 02:03:16 +00:00
// Determine whether the float has subfigures.
std : : vector < const InsetCollapsible * > subfigures ;
2020-08-02 02:03:17 +00:00
auto end = paragraphs ( ) . end ( ) ;
for ( auto it = paragraphs ( ) . begin ( ) ; it ! = end ; + + it ) {
2020-09-11 01:14:41 +00:00
std : : vector < const InsetCollapsible * > foundSubfigures = findSubfiguresInParagraph ( * it ) ;
2020-08-02 02:03:17 +00:00
if ( ! foundSubfigures . empty ( ) ) {
subfigures . reserve ( subfigures . size ( ) + foundSubfigures . size ( ) ) ;
subfigures . insert ( subfigures . end ( ) , foundSubfigures . begin ( ) , foundSubfigures . end ( ) ) ;
}
}
// Gather a few things from global environment that are shared between all following cases.
2020-11-27 04:19:27 +00:00
FloatList const & floats = buffer ( ) . params ( ) . documentClass ( ) . floats ( ) ;
Floating const & ftype = floats . getType ( params_ . type ) ;
2020-08-02 02:03:17 +00:00
// Switch on subfigures.
if ( ! subfigures . empty ( ) )
docbookSubfigures ( xs , runparams , caption , label , subfigures ) ;
else
docbookNoSubfigures ( xs , runparams , caption , label , ftype , this ) ;
}
2007-10-13 09:04:52 +00:00
bool InsetFloat : : insetAllowed ( InsetCode code ) const
2001-07-12 14:35:38 +00:00
{
2017-07-03 17:53:14 +00:00
// The case that code == FLOAT_CODE is handled in Text3.cpp,
2009-07-21 20:04:52 +00:00
// because we need to know what type of float is meant.
switch ( code ) {
case WRAP_CODE :
case FOOT_CODE :
case MARGIN_CODE :
return false ;
default :
2015-09-02 18:53:13 +00:00
return InsetCaptionable : : insetAllowed ( code ) ;
2009-07-21 20:04:52 +00:00
}
2000-06-28 13:35:52 +00:00
}
2000-07-04 19:16:35 +00:00
2009-07-13 12:56:20 +00:00
void InsetFloat : : setWide ( bool w , bool update_label )
2000-07-15 23:51:46 +00:00
{
2015-05-22 16:59:17 +00:00
if ( ! buffer ( ) . params ( ) . documentClass ( ) . floats ( ) . allowsWide ( params_ . type ) )
params_ . wide = false ;
else
params_ . wide = w ;
2008-08-19 14:56:12 +00:00
if ( update_label )
2009-07-13 12:56:20 +00:00
setNewLabel ( ) ;
2000-07-15 23:51:46 +00:00
}
2009-07-13 12:56:20 +00:00
void InsetFloat : : setSideways ( bool s , bool update_label )
2004-03-29 11:38:39 +00:00
{
2015-05-22 16:59:17 +00:00
if ( ! buffer ( ) . params ( ) . documentClass ( ) . floats ( ) . allowsSideways ( params_ . type ) )
params_ . sideways = false ;
else
params_ . sideways = s ;
2008-08-19 14:56:12 +00:00
if ( update_label )
2009-07-13 12:56:20 +00:00
setNewLabel ( ) ;
2004-03-29 11:38:39 +00:00
}
2009-07-13 12:56:20 +00:00
void InsetFloat : : setSubfloat ( bool s , bool update_label )
2008-03-02 11:30:50 +00:00
{
params_ . subfloat = s ;
2008-08-19 14:56:12 +00:00
if ( update_label )
2009-07-13 12:56:20 +00:00
setNewLabel ( ) ;
2008-08-19 14:56:12 +00:00
}
2009-07-13 12:56:20 +00:00
void InsetFloat : : setNewLabel ( )
2008-08-19 14:56:12 +00:00
{
2021-01-03 19:38:49 +00:00
docstring lab = _ ( " Float: " ) ;
2008-08-19 14:56:12 +00:00
2008-11-23 14:46:33 +00:00
if ( params_ . subfloat )
2021-01-03 19:38:49 +00:00
lab = _ ( " Subfloat: " ) ;
2008-08-19 14:56:12 +00:00
2009-07-13 12:56:20 +00:00
lab + = floatName ( params_ . type ) ;
2008-08-19 14:56:12 +00:00
2015-05-22 16:59:17 +00:00
FloatList const & floats = buffer ( ) . params ( ) . documentClass ( ) . floats ( ) ;
if ( params_ . wide & & floats . allowsWide ( params_ . type ) )
2008-08-19 14:56:12 +00:00
lab + = ' * ' ;
2015-05-22 16:59:17 +00:00
if ( params_ . sideways & & floats . allowsSideways ( params_ . type ) )
2008-08-19 14:56:12 +00:00
lab + = _ ( " (sideways) " ) ;
2008-03-02 11:30:50 +00:00
setLabel ( lab ) ;
}
2013-03-22 21:23:38 +00:00
bool InsetFloat : : allowsCaptionVariation ( std : : string const & newtype ) const
{
2016-03-25 18:22:57 +00:00
return ! params_ . subfloat & & newtype ! = " Unnumbered " ;
2013-03-22 21:23:38 +00:00
}
2016-09-23 22:49:00 +00:00
TexString InsetFloat : : getCaption ( OutputParams const & runparams ) const
2015-10-13 22:51:50 +00:00
{
2009-06-19 12:18:38 +00:00
InsetCaption const * ins = getCaptionInset ( ) ;
if ( ins = = 0 )
2016-09-23 22:49:00 +00:00
return TexString ( ) ;
2015-10-13 22:51:50 +00:00
2016-09-23 22:49:00 +00:00
otexstringstream os ;
2015-10-13 22:51:50 +00:00
ins - > getArgs ( os , runparams ) ;
2009-06-19 12:18:38 +00:00
2016-10-10 15:14:39 +00:00
if ( ! runparams . nice )
// increase TexRow precision in non-nice mode
os < < safebreakln ;
2015-10-13 22:51:50 +00:00
os < < ' [ ' ;
2016-09-04 02:21:19 +00:00
otexstringstream os2 ;
ins - > getArgument ( os2 , runparams ) ;
TexString ts = os2 . release ( ) ;
docstring & arg = ts . str ;
2011-02-02 11:05:56 +00:00
// Protect ']'
if ( arg . find ( ' ] ' ) ! = docstring : : npos )
arg = ' { ' + arg + ' } ' ;
2016-09-04 02:21:19 +00:00
os < < move ( ts ) ;
2015-10-13 22:51:50 +00:00
os < < ' ] ' ;
2016-10-10 15:14:39 +00:00
if ( ! runparams . nice )
os < < safebreakln ;
2016-09-23 22:49:00 +00:00
return os . release ( ) ;
2008-03-02 11:30:50 +00:00
}
2008-03-27 22:26:24 +00:00
void InsetFloat : : string2params ( string const & in , InsetFloatParams & params )
2003-03-05 19:46:08 +00:00
{
params = InsetFloatParams ( ) ;
2003-04-24 20:02:49 +00:00
if ( in . empty ( ) )
return ;
2003-05-21 21:20:50 +00:00
2003-09-15 11:00:00 +00:00
istringstream data ( in ) ;
2008-04-02 23:06:22 +00:00
Lexer lex ;
2003-03-07 14:08:10 +00:00
lex . setStream ( data ) ;
2008-04-05 10:34:29 +00:00
lex . setContext ( " InsetFloat::string2params " ) ;
2003-12-11 15:23:15 +00:00
params . read ( lex ) ;
2003-03-05 19:46:08 +00:00
}
2008-03-27 22:26:24 +00:00
string InsetFloat : : params2string ( InsetFloatParams const & params )
2003-03-05 19:46:08 +00:00
{
ostringstream data ;
params . write ( data ) ;
2003-09-15 11:00:00 +00:00
return data . str ( ) ;
2003-03-05 19:46:08 +00:00
}
2006-10-21 00:16:43 +00:00
} // namespace lyx