Add support to cross out characters

- adds support for the command \xout of the LateX package ulem
- fileformat change
This commit is contained in:
Uwe Stöhr 2017-04-05 00:01:19 +02:00
parent d81deed121
commit e575e7eebd
21 changed files with 155 additions and 22 deletions

View File

@ -7,6 +7,11 @@ changes happened in particular if possible. A good example would be
-----------------------
2017-04-04 Uwe Stöhr <uwestoehr@web.de>
* Format incremented to 537: support for \xout.
Character style via ulem's \xout. New
LFUN_FONT_CROSSOUT
2017-04-04 Uwe Stöhr <uwestoehr@web.de>
* Format incremented to 536: support for Noto fonts.
- \usepackage[rm]{noto} > \font_roman "NotoSerif-TLF" "<nontexfont>"

View File

@ -26,15 +26,15 @@ import sys, os
from parser_tools import find_end_of, find_token_backwards, find_end_of_layout, \
find_token, find_end_of_inset, get_value, get_bool_value, \
get_containing_layout, get_quoted_value, del_token
get_containing_layout, get_quoted_value, del_token, find_re
# find_tokens, find_token_exact, is_in_inset, \
# check_token, get_option_value
from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert
from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, revert_font_attrs, \
insert_to_preamble
# get_ert, lyx2latex, \
# lyx2verbatim, length_in_bp, convert_info_insets
# insert_to_preamble, latex_length, revert_flex_inset, \
# revert_font_attrs, hex2ratio, str2bool
# latex_length, revert_flex_inset, hex2ratio, str2bool
####################################################################
# Private helper functions
@ -1960,6 +1960,16 @@ def revert_noto(document):
document.header[i] = document.header[i].replace("NotoMono-TLF", "default")
def revert_xout(document):
" Reverts \\xout font attribute "
changed = revert_font_attrs(document.body, "\\xout", "\\xout")
if changed == True:
insert_to_preamble(document, \
['% for proper cross-out',
'\\PassOptionsToPackage{normalem}{ulem}',
'\\usepackage{ulem}'])
##
# Conversion hub
#
@ -1993,10 +2003,12 @@ convert = [
[533, []],
[534, []],
[535, [convert_dashligatures]],
[536, []]
[536, []],
[537, []]
]
revert = [
[536, [revert_xout]],
[535, [revert_noto]],
[534, [revert_dashligatures]],
[533, [revert_chapterbib]],

View File

@ -166,8 +166,11 @@ docstring const stateText(FontInfo const & f)
os << bformat(_("Underline %1$s, "),
_(GUIMiscNames[f.underbar()]));
if (f.strikeout() != FONT_INHERIT)
os << bformat(_("Strikeout %1$s, "),
os << bformat(_("Strike out %1$s, "),
_(GUIMiscNames[f.strikeout()]));
if (f.xout() != FONT_INHERIT)
os << bformat(_("Cross out %1$s, "),
_(GUIMiscNames[f.xout()]));
if (f.uuline() != FONT_INHERIT)
os << bformat(_("Double underline %1$s, "),
_(GUIMiscNames[f.uuline()]));
@ -241,6 +244,9 @@ void Font::lyxWriteChanges(Font const & orgfont,
if (orgfont.fontInfo().strikeout() != bits_.strikeout()) {
os << "\\strikeout " << LyXMiscNames[bits_.strikeout()] << "\n";
}
if (orgfont.fontInfo().xout() != bits_.xout()) {
os << "\\xout " << LyXMiscNames[bits_.xout()] << "\n";
}
if (orgfont.fontInfo().uuline() != bits_.uuline()) {
os << "\\uuline " << LyXMiscNames[bits_.uuline()] << "\n";
}
@ -428,6 +434,11 @@ int Font::latexWriteStartChanges(odocstream & os, BufferParams const & bparams,
count += 9;
++runparams.inulemcmd;
}
if (f.xout() == FONT_ON) {
os << "\\xout{";
count += 9;
++runparams.inulemcmd;
}
if (f.uuline() == FONT_ON) {
os << "\\uuline{";
count += 11;
@ -507,6 +518,11 @@ int Font::latexWriteEndChanges(otexstream & os, BufferParams const & bparams,
++count;
--runparams.inulemcmd;
}
if (f.xout() == FONT_ON) {
os << '}';
++count;
--runparams.inulemcmd;
}
if (f.uuline() == FONT_ON) {
os << '}';
++count;
@ -569,6 +585,7 @@ string Font::toString(bool const toggle) const
<< "emph " << bits_.emph() << '\n'
<< "underbar " << bits_.underbar() << '\n'
<< "strikeout " << bits_.strikeout() << '\n'
<< "xout " << bits_.xout() << '\n'
<< "uuline " << bits_.uuline() << '\n'
<< "uwave " << bits_.uwave() << '\n'
<< "noun " << bits_.noun() << '\n'
@ -611,10 +628,10 @@ bool Font::fromString(string const & data, bool & toggle)
int const next = lex.getInteger();
bits_.setSize(FontSize(next));
} else if (token == "emph" || token == "underbar" ||
token == "noun" || token == "number" ||
token == "uuline" || token == "uwave" ||
token == "strikeout") {
} else if (token == "emph" || token == "underbar"
|| token == "noun" || token == "number"
|| token == "uuline" || token == "uwave"
|| token == "strikeout" || token == "xout") {
int const next = lex.getInteger();
FontState const misc = FontState(next);
@ -625,6 +642,8 @@ bool Font::fromString(string const & data, bool & toggle)
bits_.setUnderbar(misc);
else if (token == "strikeout")
bits_.setStrikeout(misc);
else if (token == "xout")
bits_.setXout(misc);
else if (token == "uuline")
bits_.setUuline(misc);
else if (token == "uwave")
@ -680,7 +699,12 @@ void Font::validate(LaTeXFeatures & features) const
if (bits_.strikeout() == FONT_ON) {
LYXERR(Debug::LATEX, "font.strikeout: " << bits_.strikeout());
features.require("ulem");
LYXERR(Debug::LATEX, "Strikeout enabled. Font: " << to_utf8(stateText(0)));
LYXERR(Debug::LATEX, "Strike out enabled. Font: " << to_utf8(stateText(0)));
}
if (bits_.xout() == FONT_ON) {
LYXERR(Debug::LATEX, "font.xout: " << bits_.xout());
features.require("ulem");
LYXERR(Debug::LATEX, "Cross out enabled. Font: " << to_utf8(stateText(0)));
}
if (bits_.uuline() == FONT_ON) {
LYXERR(Debug::LATEX, "font.uuline: " << bits_.uuline());
@ -752,6 +776,7 @@ ostream & operator<<(ostream & os, FontInfo const & f)
<< " emph " << f.emph()
<< " underbar " << f.underbar()
<< " strikeout " << f.strikeout()
<< " xout " << f.xout()
<< " uuline " << f.uuline()
<< " uwave " << f.uwave()
<< " noun " << f.noun()

View File

@ -70,6 +70,7 @@ FontInfo const sane_font(
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF,
FONT_OFF);
FontInfo const inherit_font(
@ -85,6 +86,7 @@ FontInfo const inherit_font(
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_INHERIT,
FONT_OFF);
FontInfo const ignore_font(
@ -100,6 +102,7 @@ FontInfo const ignore_font(
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE,
FONT_IGNORE);
@ -211,6 +214,8 @@ void FontInfo::reduce(FontInfo const & tmplt)
underbar_ = FONT_INHERIT;
if (strikeout_ == tmplt.strikeout_)
strikeout_ = FONT_INHERIT;
if (xout_ == tmplt.xout_)
xout_ = FONT_INHERIT;
if (uuline_ == tmplt.uuline_)
uuline_ = FONT_INHERIT;
if (uwave_ == tmplt.uwave_)
@ -253,6 +258,9 @@ FontInfo & FontInfo::realize(FontInfo const & tmplt)
if (strikeout_ == FONT_INHERIT)
strikeout_ = tmplt.strikeout_;
if (xout_ == FONT_INHERIT)
xout_ = tmplt.xout_;
if (uuline_ == FONT_INHERIT)
uuline_ = tmplt.uuline_;
@ -362,6 +370,7 @@ void FontInfo::update(FontInfo const & newfont, bool toggleall)
setEmph(setMisc(newfont.emph_, emph_));
setUnderbar(setMisc(newfont.underbar_, underbar_));
setStrikeout(setMisc(newfont.strikeout_, strikeout_));
setXout(setMisc(newfont.xout_, xout_));
setUuline(setMisc(newfont.uuline_, uuline_));
setUwave(setMisc(newfont.uwave_, uwave_));
setNoun(setMisc(newfont.noun_, noun_));
@ -385,8 +394,8 @@ bool FontInfo::resolved() const
&& shape_ != INHERIT_SHAPE && size_ != FONT_SIZE_INHERIT
&& emph_ != FONT_INHERIT && underbar_ != FONT_INHERIT
&& uuline_ != FONT_INHERIT && uwave_ != FONT_INHERIT
&& strikeout_ != FONT_INHERIT && noun_ != FONT_INHERIT
&& color_ != Color_inherit
&& strikeout_ != FONT_INHERIT && xout_ != FONT_INHERIT
&& noun_ != FONT_INHERIT && color_ != Color_inherit
&& background_ != Color_inherit);
}
@ -656,6 +665,8 @@ FontInfo lyxRead(Lexer & lex, FontInfo const & fi)
f.setUnderbar(FONT_OFF);
} else if (ttok == "no_strikeout") {
f.setStrikeout(FONT_OFF);
} else if (ttok == "no_xout") {
f.setXout(FONT_OFF);
} else if (ttok == "no_uuline") {
f.setUuline(FONT_OFF);
} else if (ttok == "no_uwave") {
@ -670,6 +681,8 @@ FontInfo lyxRead(Lexer & lex, FontInfo const & fi)
f.setUnderbar(FONT_ON);
} else if (ttok == "strikeout") {
f.setStrikeout(FONT_ON);
} else if (ttok == "xout") {
f.setXout(FONT_ON);
} else if (ttok == "uuline") {
f.setUuline(FONT_ON);
} else if (ttok == "uwave") {
@ -718,6 +731,10 @@ void lyxWrite(ostream & os, FontInfo const & f, string const & start, int level)
oss << indent << "\tMisc Strikeout\n";
else if (f.strikeout() == FONT_OFF)
oss << indent << "\tMisc No_Strikeout\n";
if (f.xout() == FONT_ON)
oss << indent << "\tMisc Xout\n";
else if (f.xout() == FONT_OFF)
oss << indent << "\tMisc No_Xout\n";
if (f.uuline() == FONT_ON)
oss << indent << "\tMisc Uuline\n";
else if (f.uuline() == FONT_OFF)

View File

@ -44,13 +44,14 @@ public:
FontState emph,
FontState underbar,
FontState strikeout,
FontState xout,
FontState uuline,
FontState uwave,
FontState noun,
FontState number)
: family_(family), series_(series), shape_(shape), size_(size),
style_(LM_ST_TEXT), color_(color), background_(background), emph_(emph),
underbar_(underbar), strikeout_(strikeout), uuline_(uuline),
underbar_(underbar), strikeout_(strikeout), xout_(xout), uuline_(uuline),
uwave_(uwave), noun_(noun), number_(number)
{}
@ -77,6 +78,8 @@ public:
void setUnderbar(FontState u) { underbar_ = u; }
FontState strikeout() const { return strikeout_; }
void setStrikeout(FontState s) { strikeout_ = s; }
FontState xout() const { return xout_; }
void setXout(FontState s) { xout_ = s; }
FontState uuline() const { return uuline_; }
void setUuline(FontState s) { uuline_ = s; }
FontState uwave() const { return uwave_; }
@ -180,6 +183,8 @@ private:
///
FontState strikeout_;
///
FontState xout_;
///
FontState uuline_;
///
FontState uwave_;
@ -201,6 +206,7 @@ inline bool operator==(FontInfo const & lhs, FontInfo const & rhs)
&& lhs.emph_ == rhs.emph_
&& lhs.underbar_ == rhs.underbar_
&& lhs.strikeout_ == rhs.strikeout_
&& lhs.xout_ == rhs.xout_
&& lhs.uuline_ == rhs.uuline_
&& lhs.uwave_ == rhs.uwave_
&& lhs.noun_ == rhs.noun_

View File

@ -431,6 +431,7 @@ enum FuncCode
LFUN_SECTION_SELECT, // vfr, 20090503
LFUN_FONT_UNDERLINE,
LFUN_FONT_STRIKEOUT,
LFUN_FONT_CROSSOUT, // uwestoehr 20170402
LFUN_FONT_UNDERUNDERLINE,
// 335
LFUN_FONT_UNDERWAVE,

View File

@ -1749,6 +1749,15 @@ void LyXAction::init()
*/
{ LFUN_FONT_STRIKEOUT, "font-strikeout", Noop, Layout },
/*!
* \var lyx::FuncCode lyx::LFUN_FONT_CROSSOUT
* \li Action: Toggles xout (cross-through) in the font (selection-wise).
* \li Syntax: font-crossout
* \li Origin: uwestoehr, 4 April 2017
* \endvar
*/
{ LFUN_FONT_CROSSOUT, "font-crossout", Noop, Layout },
/*!
* \var lyx::FuncCode lyx::LFUN_FONT_TYPEWRITER
* \li Action: Toggles the typewriter family font (selection-wise).

View File

@ -104,7 +104,7 @@ public:
/** inulemcmd > 0 means that the environment in which the
inset is typeset is part of a ulem command (\uline, \uuline,
\uwave, or \sout). Insets that output latex commands relying
\uwave, \sout or \xout). Insets that output latex commands relying
on local assignments (such as \cite) should enclose such
commands in \mbox{} in order to avoid breakage.
*/

View File

@ -2852,6 +2852,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
bool ubar_flag = false;
bool dbar_flag = false;
bool sout_flag = false;
bool xout_flag = false;
bool wave_flag = false;
// shape tags
bool shap_flag = false;
@ -2906,6 +2907,11 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
if (font_old.strikeout() != curstate)
doFontSwitch(tagsToOpen, tagsToClose, sout_flag, curstate, html::FT_SOUT);
// xout
curstate = font.fontInfo().xout();
if (font_old.xout() != curstate)
doFontSwitch(tagsToOpen, tagsToClose, xout_flag, curstate, html::FT_XOUT);
// double underbar
curstate = font.fontInfo().uuline();
if (font_old.uuline() != curstate)

View File

@ -464,6 +464,9 @@ void Text::readParToken(Paragraph & par, Lexer & lex,
} else if (token == "\\strikeout") {
lex.next();
font.fontInfo().setStrikeout(setLyXMisc(lex.getString()));
} else if (token == "\\xout") {
lex.next();
font.fontInfo().setXout(setLyXMisc(lex.getString()));
} else if (token == "\\uuline") {
lex.next();
font.fontInfo().setUuline(setLyXMisc(lex.getString()));

View File

@ -337,6 +337,8 @@ void Text::setFont(Cursor & cur, Font const & font, bool toggleall)
newfi.setUnderbar(oldfi.underbar() == FONT_OFF ? FONT_ON : FONT_OFF);
if (newfi.strikeout() == FONT_TOGGLE)
newfi.setStrikeout(oldfi.strikeout() == FONT_OFF ? FONT_ON : FONT_OFF);
if (newfi.xout() == FONT_TOGGLE)
newfi.setXout(oldfi.xout() == FONT_OFF ? FONT_ON : FONT_OFF);
if (newfi.uuline() == FONT_TOGGLE)
newfi.setUuline(oldfi.uuline() == FONT_OFF ? FONT_ON : FONT_OFF);
if (newfi.uwave() == FONT_TOGGLE)

View File

@ -2166,6 +2166,13 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
break;
}
case LFUN_FONT_CROSSOUT: {
Font font(ignore_font, ignore_language);
font.fontInfo().setXout(FONT_TOGGLE);
toggleAndShow(cur, this, font);
break;
}
case LFUN_FONT_UNDERUNDERLINE: {
Font font(ignore_font, ignore_language);
font.fontInfo().setUuline(FONT_TOGGLE);
@ -3203,6 +3210,7 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_FONT_STATE:
case LFUN_FONT_UNDERLINE:
case LFUN_FONT_STRIKEOUT:
case LFUN_FONT_CROSSOUT:
case LFUN_FONT_UNDERUNDERLINE:
case LFUN_FONT_UNDERWAVE:
case LFUN_TEXTSTYLE_APPLY:

View File

@ -158,7 +158,7 @@ public:
double pixelRatio() const { return pixel_ratio_; }
/// draw the underbar, strikeout, uuline and uwave font attributes
/// draw the underbar, strikeout, xout, uuline and uwave font attributes
virtual void textDecoration(FontInfo const & f, int x, int y, int width) = 0;
/**

View File

@ -85,7 +85,8 @@ static QList<BarPair> barData()
bars << BarPair(qt_("Underbar"), UNDERBAR_TOGGLE);
bars << BarPair(qt_("Double underbar"), UULINE_TOGGLE);
bars << BarPair(qt_("Wavy underbar"), UWAVE_TOGGLE);
bars << BarPair(qt_("Strikeout"), STRIKEOUT_TOGGLE);
bars << BarPair(qt_("Strike out"), STRIKEOUT_TOGGLE);
bars << BarPair(qt_("Cross out"), XOUT_TOGGLE);
bars << BarPair(qt_("Noun"), NOUN_TOGGLE);
bars << BarPair(qt_("Reset"), INHERIT);
return bars;
@ -319,6 +320,9 @@ static FontState getBar(FontInfo const & fi)
if (fi.strikeout() == FONT_TOGGLE)
return STRIKEOUT_TOGGLE;
if (fi.xout() == FONT_TOGGLE)
return XOUT_TOGGLE;
if (fi.uuline() == FONT_TOGGLE)
return UULINE_TOGGLE;
@ -344,6 +348,7 @@ static void setBar(FontInfo & fi, FontState val)
fi.setEmph(FONT_IGNORE);
fi.setUnderbar(FONT_IGNORE);
fi.setStrikeout(FONT_IGNORE);
fi.setXout(FONT_IGNORE);
fi.setUuline(FONT_IGNORE);
fi.setUwave(FONT_IGNORE);
fi.setNoun(FONT_IGNORE);
@ -364,6 +369,11 @@ static void setBar(FontInfo & fi, FontState val)
fi.setStrikeout(FONT_TOGGLE);
break;
case XOUT_TOGGLE:
setBar(fi, INHERIT);
fi.setXout(FONT_TOGGLE);
break;
case UULINE_TOGGLE:
setBar(fi, INHERIT);
fi.setUuline(FONT_TOGGLE);
@ -383,6 +393,7 @@ static void setBar(FontInfo & fi, FontState val)
fi.setEmph(FONT_INHERIT);
fi.setUnderbar(FONT_INHERIT);
fi.setStrikeout(FONT_INHERIT);
fi.setXout(FONT_INHERIT);
fi.setUuline(FONT_INHERIT);
fi.setUwave(FONT_INHERIT);
fi.setNoun(FONT_INHERIT);

View File

@ -39,6 +39,8 @@ enum FontState {
///
STRIKEOUT_TOGGLE,
///
XOUT_TOGGLE,
///
UULINE_TOGGLE,
///
UWAVE_TOGGLE,

View File

@ -543,6 +543,8 @@ void GuiPainter::textDecoration(FontInfo const & f, int x, int y, int width)
underline(f, x, y, width);
if (f.strikeout() == FONT_ON)
strikeoutLine(f, x, y, width);
if (f.xout() == FONT_ON)
crossoutLines(f, x, y, width);
if (f.uuline() == FONT_ON)
doubleUnderline(f, x, y, width);
if (f.uwave() == FONT_ON)
@ -665,6 +667,22 @@ void GuiPainter::strikeoutLine(FontInfo const & f, int x, int y, int width)
}
void GuiPainter::crossoutLines(FontInfo const & f, int x, int y, int width)
{
FontMetrics const & fm = theFontMetrics(f);
int const bottom = fm.underlinePos();
int const middle = fm.strikeoutPos();
// we draw several lines to fill the whole selection with strokes
// use 5 as diagonal width since this is close to the PDf output
// with normal font zoom levels
for(int x_current = x; x_current < x + width - 5; x_current = x_current + 5) {
line(x_current, y + bottom, x_current + 5, y - 2 * middle - 2 * bottom,
f.realColor(), line_solid, fm.lineWidth());
}
}
void GuiPainter::doubleUnderline(FontInfo const & f, int x, int y, int width)
{
FontMetrics const & fm = theFontMetrics(f);

View File

@ -169,6 +169,10 @@ private:
void strikeoutLine(FontInfo const & f,
int x, int y, int width);
/// check the font, and if set, draw cross-through lines
void crossoutLines(FontInfo const & f,
int x, int y, int width);
/// check the font, and if set, draw double underline
void doubleUnderline(FontInfo const & f,
int x, int y, int width);

View File

@ -172,6 +172,7 @@ string fontToTag(html::FontTypes type)
case FT_DBAR:
return "u";
case FT_SOUT:
case FT_XOUT:
return "del";
case FT_ITALIC:
return "i";
@ -211,6 +212,7 @@ string fontToAttribute(html::FontTypes type)
return "";
case FT_DBAR:
return "class='dline'";
case FT_XOUT:
case FT_SOUT:
return "class='strikeout'";
case FT_WAVE:

View File

@ -133,6 +133,7 @@ enum FontTypes {
FT_DBAR,
FT_WAVE,
FT_SOUT,
FT_XOUT,
// bold
FT_BOLD,
// shapes

View File

@ -3294,14 +3294,15 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
preamble.registerAutomaticallyLoadedPackage("ulem");
}
else if (t.cs() == "uuline" || t.cs() == "uwave" ||
t.cs() == "emph" || t.cs() == "noun") {
else if (t.cs() == "uuline" || t.cs() == "uwave"
|| t.cs() == "emph" || t.cs() == "noun"
|| t.cs() == "xout") {
context.check_layout(os);
os << "\n\\" << t.cs() << " on\n";
parse_text_snippet(p, os, FLAG_ITEM, outer, context);
context.check_layout(os);
os << "\n\\" << t.cs() << " default\n";
if (t.cs() == "uuline" || t.cs() == "uwave")
if (t.cs() == "uuline" || t.cs() == "uwave" || t.cs() == "xout")
preamble.registerAutomaticallyLoadedPackage("ulem");
}

View File

@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
#define LYX_FORMAT_LYX 536 // uwestoehr: support for Noto fonts
#define LYX_FORMAT_TEX2LYX 536
#define LYX_FORMAT_LYX 537 // uwestoehr: support for \\xout
#define LYX_FORMAT_TEX2LYX 537
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER