LyX file-format changes
-----------------------
+2003-05-20 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
+
+ * Added new space insets:
+ \SpecialChar ~ is now \InsetSpace ~
+ ERT: "\ " could be converted to InsetSpace \<space>
+ ERT: "\," could be converted to InsetSpace \,
+
2003-03-12 John Levon <levon@movementarian.org>
* Added \\end_header to signify the end of the header in a
+2003-05-21 José Matos <jamatos@fep.up.pt>
+
+ * lyx2lyx/lyxconvert_221.py: convert \SpecialChar ~
+
+2003-05-20 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
+
+ * bind/cua.bind:
+ * bind/emacs.bind:
+ * bind/yemacs.bind:
+ * bind/latinkeys.bind:
+ * ui/stdmenus.ui: new space insets
+
2003-05-20 John Levon <levon@movementarian.org>
* ui/stdtoolbars.ui: s/Paragraph Style/Paragraph Settings/
\bind "M-Return" "break-paragraph-keep-layout"
\bind "C-Return" "break-line"
\bind "C-k" "line-delete-forward"
-\bind "C-space" "protected-space-insert"
+\bind "C-space" "space-insert protected"
+\bind "C-M-space" "space-insert normal"
+\bind "S-C-space" "space-insert thin"
\bind "C-period" "end-of-sentence-period-insert"
\bind "M-period" "dots-insert"
\bind "Escape" "cancel"
\bind "M-Return" "break-paragraph-keep-layout"
\bind "C-Return" "break-line"
\bind "C-S-L" "ligature-break-insert"
-\bind "C-space" "protected-space-insert"
+\bind "C-space" "space-insert protected"
+\bind "C-M-space" "space-insert normal"
+\bind "S-C-space" "space-insert thin"
\bind "C-period" "end-of-sentence-period-insert"
\bind "M-period" "dots-insert"
\bind "M-w" "copy"
\bind "braceright" "self-insert"
\bind "asciitilde" "self-insert"
-\bind "nobreakspace" "protected-space-insert"
+\bind "nobreakspace" "space-insert protected"
\bind "exclamdown" "self-insert"
\bind "cent" "self-insert"
\bind "sterling" "self-insert"
\bind "M-Return" "break-paragraph-keep-layout"
\bind "C-Return" "break-line"
\bind "C-S-L" "ligature-break-insert"
-\bind "C-space" "protected-space-insert"
+\bind "C-space" "space-insert protected"
+\bind "C-M-space" "space-insert normal"
+\bind "S-C-space" "space-insert thin"
\bind "C-period" "end-of-sentence-period-insert"
\bind "M-period" "dots-insert"
\bind "M-w" "copy"
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+import string
+
def add_end(header):
header.append("\\end_header");
+def convert_spaces(lines):
+ for i in range(len(lines)):
+ lines[i] = string.replace(lines[i],"\\SpecialChar ~","\\InsetSpace ~")
+
def convert(header, body):
add_end(header)
+ convert_spaces(body)
if __name__ == "__main__":
pass
Item "Horizontal Fill|H" "hfill-insert"
Item "Hyphenation Point|P" "hyphenation-point-insert"
Item "Ligature Break|k" "ligature-break-insert"
- Item "Protected Blank|B" "protected-space-insert"
+ Item "Protected Space|r" "space-insert protected"
+ Item "Force normal Space|n" "space-insert normal"
+ Item "Thin Space|T" "space-insert thin"
Item "Linebreak|L" "break-line"
Item "Ellipsis|i" "dots-insert"
Item "End of Sentence|E" "end-of-sentence-period-insert"
Item "Insert table" "tabular-insert 4 4"
End
-Toolbar "Extra" "off,top"
+Toolbar "Extra" "on,top"
Item "Numbered list" "layout Enumerate"
Item "Itemized list" "layout Itemize"
Item "List" "layout List"
Item "Thesaurus" "thesaurus-entry"
End
-Toolbar "Table" "off,bottom"
+Toolbar "Table" "table,bottom"
Item "Add row" "tabular-feature append-row"
Item "Add column" "tabular-feature append-column"
Item "Delete row" "tabular-feature delete-row"
Item "Set multi-column" "tabular-feature multicolumn"
End
-Toolbar "Math" "off,bottom"
+Toolbar "Math" "math,bottom"
Item "Show math panel" "math-panel"
Item "Set display mode" "math-display"
Item "Subscript" "math-subscript"
Item "Delete column" "tabular-feature delete-column"
End
-Toolbar "Command Buffer" "off,bottom"
+Toolbar "Command Buffer" "on,bottom"
Minibuffer
End
+2003-05-20 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
+
+ * LyXAction.C: new lfun space-insert, kill protected-space-insert
+ * lfuns.h: new LFUN_SPACE
+ * lyxfunc.C: protected space has a new lfun
+ * paragraph_funcs.C: read new space insets
+ * text3.C:
+ * factory.C: handle new space insets
2003-05-22 André Pönitz <poenitz@gmx.net>
{ LFUN_DIALOG_PREFERENCES, "dialog-preferences", NoBuffer },
{ LFUN_SAVEPREFERENCES, "preferences-save", NoBuffer },
{ LFUN_PASTESELECTION, "primary-selection-paste", Noop },
- { LFUN_PROTECTEDSPACE, "protected-space-insert", Noop },
{ LFUN_QUOTE, "quote-insert", Noop },
{ LFUN_RECONFIGURE, "reconfigure", NoBuffer },
{ LFUN_REDO, "redo", Noop },
{ LFUN_PRIORSEL, "screen-up-select", ReadOnly },
{ LFUN_SCROLL_INSET, "inset-scroll", ReadOnly },
{ LFUN_SELFINSERT, "self-insert", Noop },
+ { LFUN_SPACE_INSERT, "space-insert", Noop },
{ LFUN_CHARATCURSOR, "server-char-after", ReadOnly },
{ LFUN_GETFONT, "server-get-font", ReadOnly },
{ LFUN_GETLAYOUT, "server-get-layout", ReadOnly },
#include "insets/insetoptarg.h"
#include "insets/insetparent.h"
#include "insets/insetref.h"
+#include "insets/insetspace.h"
#include "insets/insettabular.h"
#include "insets/insettext.h"
#include "insets/insettoc.h"
return new InsetUrl(icp);
}
}
+
+ case LFUN_SPACE_INSERT: {
+ string const name = cmd.argument;
+ if (name == "normal")
+ return new InsetSpace(InsetSpace::NORMAL);
+ else if (name == "protected")
+ return new InsetSpace(InsetSpace::PROTECTED);
+ else if (name == "thin")
+ return new InsetSpace(InsetSpace::THIN);
+ else if (name == "quad")
+ return new InsetSpace(InsetSpace::QUAD);
+ else if (name == "qquad")
+ return new InsetSpace(InsetSpace::QQUAD);
+ else if (name == "enspace")
+ return new InsetSpace(InsetSpace::ENSPACE);
+ else if (name == "enskip")
+ return new InsetSpace(InsetSpace::ENSKIP);
+ else if (name == "negthinspace")
+ return new InsetSpace(InsetSpace::NEGTHIN);
+ else if (name.empty())
+ lyxerr << "LyX function 'space' needs an argument." << endl;
+ else
+ lyxerr << "Wrong argument for LyX function 'space'." << endl;
+ }
+
break;
default:
inset = new InsetEnvironment(buf.params, lex.getString());
} else if (tmptok == "ERT") {
inset = new InsetERT(buf.params);
+ } else if (tmptok == "InsetSpace") {
+ inset = new InsetSpace;
} else if (tmptok == "Tabular") {
inset = new InsetTabular(buf);
} else if (tmptok == "Text") {
+2003-05-20 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
+
+ * insetspace.[Ch]: added (new space insets)
+ * Makefile.am:
+ * inset.h: handle new space insets
+
2003-05-21 Lars Gullik Bjønnes <larsbj@gullik.net>
* insetfloat.C (addToToc): adjust
insetquotes.h \
insetref.C \
insetref.h \
+ insetspace.C \
+ insetspace.h \
insetspecialchar.C \
insetspecialchar.h \
insettabular.C \
///
MINIPAGE_CODE,
///
+ SPACE_CODE,
+ ///
SPECIALCHAR_CODE, // 25
///
TABULAR_CODE,
--- /dev/null
+/**
+ * \file insetspace.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Asger Alstrup Nielsen
+ * \author Jean-Marc Lasgouttes
+ * \author Lars Gullik Bjønnes
+ * \author Juergen Spitzmueller
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#include <config.h>
+
+#include "insetspace.h"
+
+#include "debug.h"
+#include "dimension.h"
+#include "LaTeXFeatures.h"
+#include "BufferView.h"
+#include "frontends/Painter.h"
+#include "frontends/font_metrics.h"
+#include "lyxlex.h"
+#include "lyxfont.h"
+
+using std::ostream;
+using std::max;
+
+
+InsetSpace::InsetSpace(Kind k)
+ : kind_(k)
+{}
+
+
+InsetSpace::Kind InsetSpace::kind() const
+{
+ return kind_;
+}
+
+
+void InsetSpace::dimension(BufferView *, LyXFont const & font,
+ Dimension & dim) const
+{
+ dim.a = font_metrics::maxAscent(font);
+ dim.d = font_metrics::maxDescent(font);
+
+ switch (kind_) {
+ case THIN:
+ case NEGTHIN:
+ dim.w = font_metrics::width("x", font) / 3;
+ break;
+ case PROTECTED:
+ case NORMAL:
+ dim.w = font_metrics::width("x", font);
+ break;
+ case QUAD:
+ dim.w = 20;
+ break;
+ case QQUAD:
+ dim.w = 40;
+ break;
+ case ENSPACE:
+ case ENSKIP:
+ dim.w = 10;
+ break;
+ }
+}
+
+
+void InsetSpace::draw(BufferView * bv, LyXFont const & f,
+ int baseline, float & x) const
+{
+ Painter & pain = bv->painter();
+ LyXFont font(f);
+
+ float w = width(bv, font);
+ int h = font_metrics::ascent('x', font);
+ int xp[4], yp[4];
+
+ xp[0] = int(x); yp[0] = baseline - max(h / 4, 1);
+ if (kind_ == NORMAL) {
+ xp[1] = int(x); yp[1] = baseline;
+ xp[2] = int(x + w); yp[2] = baseline;
+ } else {
+ xp[1] = int(x); yp[1] = baseline + max(h / 4, 1);
+ xp[2] = int(x + w); yp[2] = baseline + max(h / 4, 1);
+ }
+ xp[3] = int(x + w); yp[3] = baseline - max(h / 4, 1);
+
+ if (kind_ == PROTECTED || kind_ == ENSPACE || kind_ == NEGTHIN)
+ pain.lines(xp, yp, 4, LColor::latex);
+ else
+ pain.lines(xp, yp, 4, LColor::special);
+ x += w;
+}
+
+
+void InsetSpace::write(Buffer const *, ostream & os) const
+{
+ string command;
+ switch (kind_) {
+ case NORMAL:
+ command = "\\space";
+ break;
+ case PROTECTED:
+ command = "~";
+ break;
+ case THIN:
+ command = "\\,";
+ break;
+ case QUAD:
+ command = "\\quad{}";
+ break;
+ case QQUAD:
+ command = "\\qquad{}";
+ break;
+ case ENSPACE:
+ command = "\\enspace{}";
+ break;
+ case ENSKIP:
+ command = "\\enskip{}";
+ break;
+ case NEGTHIN:
+ command = "\\negthinspace{}";
+ break;
+ }
+ os << "\\InsetSpace " << command << "\n";
+}
+
+
+// This function will not be necessary when lyx3
+void InsetSpace::read(Buffer const *, LyXLex & lex)
+{
+ lex.nextToken();
+ string const command = lex.getString();
+
+ if (command == "\\space")
+ kind_ = NORMAL;
+ else if (command == "~")
+ kind_ = PROTECTED;
+ else if (command == "\\,")
+ kind_ = THIN;
+ else if (command == "\\quad{}")
+ kind_ = QUAD;
+ else if (command == "\\qquad{}")
+ kind_ = QQUAD;
+ else if (command == "\\enspace{}")
+ kind_ = ENSPACE;
+ else if (command == "\\enskip{}")
+ kind_ = ENSKIP;
+ else if (command == "\\negthinspace{}")
+ kind_ = NEGTHIN;
+ else
+ lex.printError("InsetSpace: Unknown kind: `$$Token'");
+}
+
+
+int InsetSpace::latex(Buffer const *, ostream & os, bool /*fragile*/,
+ bool free_space) const
+{
+ switch (kind_) {
+ case NORMAL:
+ os << (free_space ? " " : "\\ ");
+ break;
+ case PROTECTED:
+ os << (free_space ? ' ' : '~');
+ break;
+ case THIN:
+ os << (free_space ? " " : "\\,");
+ break;
+ case QUAD:
+ os << (free_space ? " " : "\\quad{}");
+ break;
+ case QQUAD:
+ os << (free_space ? " " : "\\qquad{}");
+ break;
+ case ENSPACE:
+ os << (free_space ? " " : "\\enspace{}");
+ break;
+ case ENSKIP:
+ os << (free_space ? " " : "\\enskip{}");
+ break;
+ case NEGTHIN:
+ os << (free_space ? " " : "\\negthinspace{}");
+ break;
+ }
+ return 0;
+}
+
+
+int InsetSpace::ascii(Buffer const *, ostream & os, int) const
+{
+ switch (kind_) {
+ case NORMAL:
+ case PROTECTED:
+ case THIN:
+ case QUAD:
+ case QQUAD:
+ case ENSPACE:
+ case ENSKIP:
+ case NEGTHIN:
+ os << ' ';
+ break;
+ }
+ return 0;
+}
+
+
+int InsetSpace::linuxdoc(Buffer const *, ostream & os) const
+{
+ switch (kind_) {
+ // fixme: correct?
+ case NORMAL:
+ case QUAD:
+ case QQUAD:
+ case ENSKIP:
+ os << " ";
+ break;
+ case PROTECTED:
+ case ENSPACE:
+ case THIN:
+ case NEGTHIN:
+ os << " ";
+ break;
+ }
+ return 0;
+}
+
+
+int InsetSpace::docbook(Buffer const *, ostream & os, bool) const
+{
+ switch (kind_) {
+ // fixme: correct?
+ case NORMAL:
+ case QUAD:
+ case QQUAD:
+ case ENSKIP:
+ os << " ";
+ break;
+ case PROTECTED:
+ case ENSPACE:
+ case THIN:
+ case NEGTHIN:
+ os << " ";
+ break;
+ }
+ return 0;
+}
+
+
+Inset * InsetSpace::clone(Buffer const &, bool) const
+{
+ return new InsetSpace(kind_);
+}
+
+
+bool InsetSpace::isChar() const
+{
+ return true;
+}
+
+bool InsetSpace::isLetter() const
+{
+ return false;
+}
+
+bool InsetSpace::isSpace() const
+{
+ return true;
+}
+
+bool InsetSpace::isLineSeparator() const
+{
+ return false;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file InsetSpace.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Asger Alstrup Nielsen
+ * \author Jean-Marc Lasgouttes
+ * \author Lars Gullik Bjønnes
+ * \author Juergen Spitzmueller
+ *
+ * Full author contact details are available in file CREDITS
+ */
+
+#ifndef INSET_SPACE_H
+#define INSET_SPACE_H
+
+
+#include "inset.h"
+#include "LString.h"
+
+struct LaTeXFeatures;
+
+/// Used to insert different kinds of spaces
+class InsetSpace : public Inset {
+public:
+
+ /// The different kinds of spaces we support
+ enum Kind {
+ /// Normal space ('\ ')
+ NORMAL,
+ /// Protected (no break) space ('~')
+ PROTECTED,
+ /// Thin space ('\,')
+ THIN,
+ /// \quad (1em)
+ QUAD,
+ /// \qquad (2em)
+ QQUAD,
+ /// \enspace (0.5em unbreakable)
+ ENSPACE,
+ /// \enspace (0.5em breakable)
+ ENSKIP,
+ /// Negative thin space ('\negthinspace')
+ NEGTHIN
+ };
+
+ ///
+ InsetSpace() {}
+ ///
+ explicit
+ InsetSpace(Kind k);
+ ///
+ Kind kind() const;
+ ///
+ void dimension(BufferView *, LyXFont const &, Dimension &) const;
+ ///
+ void draw(BufferView *, LyXFont const &, int, float &) const;
+ ///
+ void write(Buffer const *, std::ostream &) const;
+ /// Will not be used when lyxf3
+ void read(Buffer const *, LyXLex & lex);
+ ///
+ int latex(Buffer const *, std::ostream &,
+ bool fragile, bool free_spc) const;
+ ///
+ int ascii(Buffer const *, std::ostream &, int linelen) const;
+ ///
+ int linuxdoc(Buffer const *, std::ostream &) const;
+ ///
+ int docbook(Buffer const *, std::ostream &, bool mixcont) const;
+ ///
+ virtual Inset * clone(Buffer const &, bool same_id = false) const;
+ ///
+ Inset::Code lyxCode() const { return Inset::SPACE_CODE; }
+ /// We don't need \begin_inset and \end_inset
+ bool directWrite() const { return true; }
+
+ // should this inset be handled like a normal charater
+ bool isChar() const;
+ /// is this equivalent to a letter?
+ bool isLetter() const;
+ /// is this equivalent to a space (which is BTW different from
+ // a line separator)?
+ bool isSpace() const;
+ // should we break lines after this inset?
+ bool isLineSeparator() const;
+private:
+ /// And which kind is this?
+ Kind kind_;
+};
+
+#endif // INSET_SPACE_H
case END_OF_SENTENCE: s = "."; break;
case LDOTS: s = ". . ."; break;
case MENU_SEPARATOR: s = " x "; break;
- case PROTECTED_SEPARATOR: s = "x"; break;
+ case HYPHENATION: s = "-"; break;
}
dim.w = font_metrics::width(s, font);
if (kind_ == HYPHENATION && dim.w > 5)
x += width(bv, font);
break;
}
- case PROTECTED_SEPARATOR:
- {
- float w = width(bv, font);
- int h = font_metrics::ascent('x', font);
- int xp[4], yp[4];
-
- xp[0] = int(x);
- yp[0] = baseline - max(h / 4, 1);
-
- xp[1] = int(x);
- yp[1] = baseline;
-
- xp[2] = int(x + w);
- yp[2] = baseline;
-
- xp[3] = int(x + w);
- yp[3] = baseline - max(h / 4, 1);
-
- pain.lines(xp, yp, 4, LColor::special);
- x += w;
- break;
- }
}
}
case MENU_SEPARATOR:
command = "\\menuseparator";
break;
- case PROTECTED_SEPARATOR:
- command = "~";
- break;
}
os << "\\SpecialChar " << command << "\n";
}
kind_ = LDOTS;
else if (command == "\\menuseparator")
kind_ = MENU_SEPARATOR;
- else if (command == "~")
- kind_ = PROTECTED_SEPARATOR;
else
lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
}
case MENU_SEPARATOR:
os << "\\lyxarrow{}";
break;
- case PROTECTED_SEPARATOR:
- os << (free_space ? ' ' : '~');
- break;
}
return 0;
}
case MENU_SEPARATOR:
os << "->";
break;
- case PROTECTED_SEPARATOR:
- os << ' ';
- break;
}
return 0;
}
case MENU_SEPARATOR:
os << "&lyxarrow;";
break;
- case PROTECTED_SEPARATOR:
- os << " ";
- break;
}
return 0;
}
case MENU_SEPARATOR:
os << "&lyxarrow;";
break;
- case PROTECTED_SEPARATOR:
- os << " ";
- break;
}
return 0;
}
bool InsetSpecialChar::isSpace() const
{
- return kind_ == PROTECTED_SEPARATOR;
+ return false;
}
END_OF_SENTENCE,
/// Menu separator
MENU_SEPARATOR,
- /// Protected Separator
- PROTECTED_SEPARATOR
};
///
// 60
LFUN_BEGINNINGBUFSEL,
LFUN_ENDBUFSEL,
- LFUN_PROTECTEDSPACE,
+ LFUN_SPACE_INSERT, // JSpitzm 20030520
LFUN_SETMARK,
LFUN_DELETE,
// 65
case LFUN_END_OF_SENTENCE:
code = Inset::SPECIALCHAR_CODE;
break;
- case LFUN_PROTECTEDSPACE:
+ case LFUN_SPACE_INSERT:
// slight hack: we know this is allowed in math mode
if (!mathcursor)
- code = Inset::SPECIALCHAR_CODE;
+ code = Inset::SPACE_CODE;
break;
default:
break;
break;
}
- case LFUN_PROTECTEDSPACE:
+ case LFUN_SPACE_INSERT:
case LFUN_MATH_SPACE:
bv->lockedInsetStoreUndo(Undo::EDIT);
mathcursor->insert(MathAtom(new MathSpaceInset(",")));
#include "insets/insetoptarg.h"
#include "insets/insetcommandparams.h"
#include "insets/insetbibitem.h"
+#include "insets/insetspace.h"
#include "insets/insetspecialchar.h"
#include "insets/insetlatexaccent.h"
#include "insets/insettabular.h"
} else if (token == "\\color") {
lex.next();
font.setLyXColor(lex.getString());
- } else if (token == "\\SpecialChar") {
+ } else if (token == "\\InsetSpace" || token == "\\SpecialChar") {
LyXLayout_ptr const & layout = par.layout();
// Insets don't make sense in a free-spacing context! ---Kayvan
if (layout->free_spacing || par.isFreeSpacing()) {
- if (lex.isOK()) {
+ if (token == "\\InsetSpace")
+ par.insertChar(par.size(), ' ', font, change);
+ else if (lex.isOK()) {
lex.next();
string const next_token = lex.getString();
- if (next_token == "\\-") {
+ if (next_token == "\\-")
par.insertChar(par.size(), '-', font, change);
- } else if (next_token == "~") {
- par.insertChar(par.size(), ' ', font, change);
- } else {
+ else {
lex.printError("Token `$$Token' "
"is in free space "
"paragraph layout!");
}
}
} else {
- Inset * inset = new InsetSpecialChar;
+ Inset * inset = 0;
+ if (token == "\\SpecialChar" )
+ inset = new InsetSpecialChar;
+ else
+ inset = new InsetSpace;
inset->read(&buf, lex);
par.insertInset(par.size(), inset, font, change);
}
bv->switchKeyMap();
break;
- case LFUN_PROTECTEDSPACE:
+ case LFUN_SPACE_INSERT:
if (cursor.par()->layout()->free_spacing) {
insertChar(' ');
update();
} else {
- specialChar(this, bv, InsetSpecialChar::PROTECTED_SEPARATOR);
+ doInsertInset(this, cmd, false, false);
}
moveCursorUpdate(bv, false);
break;