On Mon, 2006-10-16 at 15:49 +0200, Juergen Spitzmueller wrote:
> On the way towards a charstyles gui, several things still need to be done.
> One is that currently char style definitions are only really possible by 
> means 
> of manual preamble definitions.
> 
> I.e., if I want to have a char style "keyword" that is roman, red and bold in 
> the output, I'll need to define:
> 
> CharStyle Keyword
>       LatexType             Command
>       LatexName             keyword
>       Font
>         Family                Roman
>         Color         red
>         Series                bold
>       EndFont
>       Preamble
>               \usepackage{color}
>               \newcommand\keyword[1]{\textrm{\textbf{\textcolor{red}{#1}}}}
>       EndPreamble
> End
> 
> The "Font" param defines the screen font only, not the output font. This is 
> very inconventient and will have to change in order to define char styles 
> with a gui.
> 
> The attached patch is a proof-of-concept trial that changes the behaviour, so 
> that the preamble definition is automatically created from the Font 
> informations _if_ there exists no manual Preamble entry. The Preamble entry 
> is the place for advanced and fancy stuff.
> 
> So for the above charstyle, the definition would only need to be
> 
> CharStyle Keyword
>       LatexType             Command
>       LatexName             keyword
>       Font
>         Family                Roman
>         Color         red
>         Series                bold
>       EndFont
> End
> 
> The patch works quite well, but I have a few questions:
> - is LyXTextClass::readCharStyle a good place for the preamble generation?
> - in order to avoid conflicts with older definitions, should we leave Font 
> untouched and introduce a new "OutputFont" param? I am not sure, because 
> older char style definitions did not work without a Preamble definition, and 
> if one is there, it is kept.
> 
> Please comment, as I'd like to put something like this in sooner or later.
> 
> The remaining milestones on the way to a gui are:
> - All used charstyles definitions will have to be included in the document, 
> because currently, a document with self defined charstyles is not portable.
> - currently, charstyle definitions are only possible in layout files, and 
> thus 
> bound to document classes. Additionally, we'll have to provide (1) charstyles 
> that are valid for a given document only (and hence only included in the 
> document) and (2) general charstyles that are selectable always (and defined 
> in some general file). Only these two types can be set up with the gui (the 
> user will be able to select the "scope" in the gui and change the scope of a 
> given charstyle).
> 
> I don't know if I'll have enough time to do all this myself, so if somebody 
> wants to help, I'll be most grateful.
> 
> Jürgen

I did some work on this ages ago, and attach a diff saved from then.
Feel free to cannibalize... I have no free time right now to work on it.

I don't precisely remember how it was supposed to work, but I do
remember that there were two different types of charstyles:

1) the classical type, programmed in layout files; and
2) "fontstyles", which take the screen font at the cursor (insert)
location and turn it into a charstyle. (It also got the LaTeX output
font more or less right!). These travel with the document.

I hope you get this decyphered :-)

- Martin

Index: insets/insetcharstyle.C
===================================================================
--- insets/insetcharstyle.C	(revision 13327)
+++ insets/insetcharstyle.C	(working copy)
@@ -48,7 +48,7 @@
 	setInsetName("CharStyle");
 	setInlined();
 	setDrawFrame(false);
-	has_label_ = true;
+	has_label_ = params_.latextype != "fontstyle";
 }
 
 
@@ -104,6 +104,7 @@
 void InsetCharStyle::setDefined(CharStyles::iterator cs)
 {
 	params_.latextype = cs->latextype;
+	has_label_ = params_.latextype != "fontstyle";
 	params_.latexname = cs->latexname;
 	params_.latexparam = cs->latexparam;
 	params_.font = cs->font;
@@ -261,15 +262,26 @@
 int InsetCharStyle::latex(Buffer const & buf, ostream & os,
 		     OutputParams const & runparams) const
 {
-	if (!undefined()) {
-		os << "\\" << params_.latexname;
-		if (!params_.latexparam.empty())
-			os << params_.latexparam;
-		os << "{";
+	int i = 0;
+	if (params_.latextype == "fontstyle") {
+		params_.font.latexWriteStartChanges(os, 
+			LyXFont(LyXFont::ALL_SANE), 
+			LyXFont(LyXFont::ALL_SANE));
+		i = InsetText::latex(buf, os, runparams);
+		params_.font.latexWriteEndChanges(os, 
+			LyXFont(LyXFont::ALL_SANE),
+			LyXFont(LyXFont::ALL_SANE));
+	} else if (params_.latextype == "command") {
+		if (!undefined()) {
+			os << "\\" << params_.latexname;
+			if (!params_.latexparam.empty())
+				os << params_.latexparam;
+			os << "{";
+		}
+		i = InsetText::latex(buf, os, runparams);
+		if (!undefined())
+			os << "}";
 	}
-	int i = InsetText::latex(buf, os, runparams);
-	if (!undefined())
-		os << "}";
 	return i;
 }
 
@@ -327,6 +339,8 @@
 {
 	// Force inclusion of preamble snippet in layout file
 	features.require(params_.type);
+	if (params_.font.color() !=  LColor::none)
+		features.require("color");
 	InsetText::validate(features);
 }
 
Index: factory.C
===================================================================
--- factory.C	(revision 13312)
+++ factory.C	(working copy)
@@ -90,8 +90,28 @@
 		CharStyles::iterator found_cs = tclass.charstyle(s);
 		if (found_cs != tclass.charstyles().end())
 			return new InsetCharStyle(params, found_cs);
-		else
-			return new InsetCharStyle(params, s);
+		else {
+			found_cs = params.charstyle(s);
+			if (found_cs != params.charstyles().end())
+				return new InsetCharStyle(params, found_cs);
+			else if (s[0] == '_') {
+				// Insert here new buffer style into list...
+				InsetCharStyle * inset = 
+					new InsetCharStyle(params, s);
+				CharStyle cs;
+				cs.name = s;
+				cs.latexname = s;
+				cs.latextype = "fontstyle";
+				cs.font = bv->cursor().getFont();
+				CharStyles & css = const_cast<CharStyles &>(params.charstyles());
+				if (params.charstyle(cs.name) == css.end())
+					css.push_back(cs);
+				//inset->setDefined(css.end() - 1);
+				inset->setDefined(params.charstyle(cs.name));
+				return inset;
+			} else
+				return new InsetCharStyle(params, s);
+		}
 	}
 
 	case LFUN_INSERT_NOTE: {
@@ -410,8 +430,15 @@
 			if (found_cs != tclass.charstyles().end())
 				inset.reset(new InsetCharStyle(buf.params(), found_cs));
 			else {
+				CharStyles::iterator found_cs 
+					= buf.params().charstyle(s);
+				if (found_cs != buf.params().charstyles().end())
+					inset.reset(new InsetCharStyle(buf.params(), found_cs));
+				else {
+				
 				// "Undefined" inset
 				inset.reset(new InsetCharStyle(buf.params(), s));
+				}
 			}
 		} else if (tmptok == "Branch") {
 			inset.reset(new InsetBranch(buf.params(),
Index: CutAndPaste.C
===================================================================
--- CutAndPaste.C	(revision 13339)
+++ CutAndPaste.C	(working copy)
@@ -388,26 +389,28 @@
 		if (it->lyxCode() == InsetBase::CHARSTYLE_CODE) {
 			InsetCharStyle & inset =
 				static_cast<InsetCharStyle &>(*it);
-			string const name = inset.params().type;
-			CharStyles::iterator const found_cs =
-				tclass2.charstyle(name);
-			if (found_cs == tclass2.charstyles().end()) {
-				// The character style is undefined in tclass2
-				inset.setUndefined();
-				string const s = bformat(_(
-					"Character style %1$s is "
-					"undefined because of class "
-					"conversion from\n%2$s to %3$s"),
-					 name, tclass1.name(), tclass2.name());
-				// To warn the user that something had to be done.
-				errorlist.push_back(ErrorItem(
-						_("Undefined character style"),
-						s, it.paragraph().id(),
-						it.pos(), it.pos() + 1));
-			} else if (inset.undefined()) {
-				// The character style is undefined in
-				// tclass1 and is defined in tclass2
-				inset.setDefined(found_cs);
+			// Ignore per-document charstyles:
+			if (inset.params().latextype != "fontstyle") {
+				string const name = inset.params().type;
+				CharStyles::iterator const found_cs = tclass2.charstyle(name);
+				if (found_cs == tclass2.charstyles().end()) {
+					// The character style is undefined in tclass2
+					inset.setUndefined();
+					string const s = bformat(_(
+						"Character style %1$s is "
+						"undefined because of class "
+						"conversion from\n%2$s to %3$s"),
+						 name, tclass1.name(), tclass2.name());
+					// To warn the user that something had to be done.
+					errorlist.push_back(ErrorItem(
+							_("Undefined character style"),
+							s, it.paragraph().id(),
+							it.pos(), it.pos() + 1));
+				} else if (inset.undefined()) {
+					// The character style is undefined in
+					// tclass1 and is defined in tclass2
+					inset.setDefined(found_cs);
+				}
 			}
 		}
 	}
Index: bufferparams.C
===================================================================
--- bufferparams.C	(revision 13312)
+++ bufferparams.C	(working copy)
@@ -245,6 +245,9 @@
 
 	AuthorList authorlist;
 	BranchList branchlist;
+	/// CharStyles defined in this buffer
+	CharStyles charstyles;
+
 	boost::array<Bullet, 4> temp_bullets;
 	boost::array<Bullet, 4> user_defined_bullets;
 	Spacing spacing;
@@ -344,6 +347,32 @@
 }
 
 
+CharStyles & BufferParams::charstyles()
+{
+	return pimpl_->charstyles;
+}
+
+
+CharStyles const & BufferParams::charstyles() const
+{
+	return pimpl_->charstyles;
+}
+
+
+CharStyles::iterator BufferParams::charstyle(string const & s) const
+{
+	CharStyles::iterator cs = 
+		const_cast<CharStyles &>(charstyles()).begin(); 
+	CharStyles::iterator csend = 
+		const_cast<CharStyles &>(charstyles()).end(); 
+	for (; cs != csend; ++cs) { 
+		if (cs->name == s) 
+			return cs; 
+	} 
+	return csend; 
+}
+
+
 Bullet & BufferParams::temp_bullet(lyx::size_type const index)
 {
 	BOOST_ASSERT(index < 4);
@@ -488,6 +517,15 @@
 
 			}
 		}
+	} else if (token == "\\charstyle") {
+		lex.next();
+		CharStyle cs;
+		cs.name = lex.getString();
+		cs.latextype = "fontstyle";
+		cs.latexname = cs.name;
+		cs.font.lyxRead(lex);
+		if (charstyle(cs.name) == charstyles().end())
+			charstyles().push_back(cs);
 	} else if (token == "\\author") {
 		lex.eatLine();
 		istringstream ss(lex.getString());
@@ -605,7 +643,15 @@
 		   << "\n\\end_branch"
 		   << "\n";
 	}
-
+	CharStyles::const_iterator cit = charstyles().begin();
+	CharStyles::const_iterator cend = charstyles().end();
+	for (; cit != cend; ++cit) {
+		os << "\\charstyle " << cit->name;
+		// Output font info here
+		cit->font.lyxWriteChanges(LyXFont(LyXFont::ALL_SANE), os);
+		os << "\\endfont"
+		   << "\n";
+	}	
 	if (!paperwidth.empty())
 		os << "\\paperwidth "
 		   << VSpace(paperwidth).asLyXCommand() << '\n';
Index: text3.C
===================================================================
--- text3.C	(revision 13328)
+++ text3.C	(working copy)
@@ -1665,8 +1665,7 @@
 		break;
 	case LFUN_INSERT_CHARSTYLE:
 		code = InsetBase::CHARSTYLE_CODE;
-		if (cur.buffer().params().getLyXTextClass().charstyles().empty())
-			enable = false;
+		enable = true;
 		break;
 	case LFUN_INSERT_BOX:
 		code = InsetBase::BOX_CODE;
Index: bufferparams.h
===================================================================
--- bufferparams.h	(revision 13312)
+++ bufferparams.h	(working copy)
@@ -161,6 +161,11 @@
 	/// BranchList:
 	BranchList & branchlist();
 	BranchList const & branchlist() const;
+	/// CharStyles:
+	CharStyles & charstyles();
+	CharStyles const & charstyles() const;
+	/// Retrieve element of name s:
+	CharStyles::iterator charstyle(std::string const & s) const;
 	///
 	std::string inputenc;
 	///
Index: lyxfont.C
===================================================================
--- lyxfont.C	(revision 13312)
+++ lyxfont.C	(working copy)
@@ -628,7 +628,9 @@
 	bool finished = false;
 	while (!finished && lex.isOK() && !error) {
 		lex.next();
-		string const tok = ascii_lowercase(lex.getString());
+		string tok = ascii_lowercase(lex.getString());
+		if (tok[0] == '\\')
+			tok = tok.substr(1);
 
 		if (tok.empty()) {
 			continue;
Index: MenuBackend.C
===================================================================
--- MenuBackend.C	(revision 13312)
+++ MenuBackend.C	(working copy)
@@ -601,6 +601,17 @@
 				    FuncRequest(LFUN_INSERT_CHARSTYLE,
 						cit->name)), view);
 	}
+	tomenu.add(MenuItem(MenuItem::Separator));
+	CharStyles & charstyles2 = view->buffer()->params().charstyles();
+	cit = charstyles2.begin();
+	end = charstyles2.end();
+	for (; cit != end; ++cit) {
+		string const label = cit->name;
+		tomenu.add(MenuItem(MenuItem::Command, label,
+				    FuncRequest(LFUN_INSERT_CHARSTYLE,
+						cit->name)), view);
+	}
+
 }
 
 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to