Index: konversation/src/Makefile.am =================================================================== --- konversation/src/Makefile.am (revision 792988) +++ konversation/src/Makefile.am (working copy) @@ -3,7 +3,7 @@ METASOURCES = AUTO bin_PROGRAMS = konversation -bin_SCRIPTS = konversationircprotocolhandler +bin_SCRIPTS = konversationircprotocolhandler konversation_latexconvert.sh konversation_SOURCES = konviface.skel konviconfigdialog.cpp konversationstatusbar.cpp \ konvisettingsdialog.cpp konversationmainwindow.cpp valuelistviewitem.cpp urlcatcher.cpp \ @@ -37,7 +37,7 @@ autoreplace_preferencesui.ui autoreplace_preferences.cpp viewcontainer.cpp viewtree.cpp \ viewtreeitem.cpp servergroupdialogui.ui dcctransfer.cpp dcctransfermanager.cpp \ dcctransferdetailedinfopanelui.ui dcctransferdetailedinfopanel.cpp dcccommon.cpp \ - queuetunerbase.ui queuetuner.cpp ircqueue.cpp + queuetunerbase.ui queuetuner.cpp ircqueue.cpp latex.cpp konversation_COMPILE_FIRST = config/preferences_base.h konversation_LDADD = $(LIB_KIO) $(LIB_KABC) $(LIB_KIMIFACE) linkaddressbook/liblinkaddressbookui.la blowfish/libblowfish.la config/libkonversationconfig.la Index: konversation/src/latex.cpp =================================================================== --- konversation/src/latex.cpp (revision 0) +++ konversation/src/latex.cpp (revision 0) @@ -0,0 +1,147 @@ +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +/* + Copyright (C) 2007 Bourdon Pierre + + This code was mostly copied from the KopeTeX plugin source code. + Copyright (c) 2004 by Duncan Mac-Vicar Prett + Copyright (c) 2004-2005 by Olivier Goffart + Kopete (c) 2001-2004 by the Kopete developers +*/ + +#include "latex.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "konversationapplication.h" +#include "konversationmainwindow.h" +#include "config/preferences.h" + +namespace Konversation +{ + LaTeXFormula* LaTeXFormula::s_self = 0; + static KStaticDeleter staticLaTeXFormulaDeleter; + + LaTeXFormula* LaTeXFormula::self() + { + if(!s_self) + staticLaTeXFormulaDeleter.setObject(s_self, new LaTeXFormula()); + return s_self; + } + + LaTeXFormula::LaTeXFormula() + { + s_self = this; + m_magickNotFoundShown = false; + m_convScript = KStandardDirs::findExe("konversation_latexconvert.sh"); + } + + LaTeXFormula::~LaTeXFormula() + { + if(s_self == this) + staticLaTeXFormulaDeleter.setObject(s_self, 0, false); + } + + bool LaTeXFormula::securityCheck(const QString& latexFormula) + { + return !latexFormula.contains(QRegExp("\\\\(def|let|futurelet|newcommand" + "|chardef|catcode|makeatletter|noexpand|toksdef|every|errhelp|errorstopmode" + "|scrollmode|nonstopmode|batchmode|read|csname|newhelp|relax|afterground" + "|afterassignment|expandafter|noexpand|special|command|loop|repeat|toks" + "|providecommand|renewcommand" + "|output|line|mathcode|name|item|section|mbox|DeclareRobustCommand)[^a-zA-Z]")); + } + + QString LaTeXFormula::handleLatex(const QString& latexFormula) + { + KTempFile* tmpFile = new KTempFile(locateLocal("tmp", "konversationlatex-"), ".png"); + tmpFile->setAutoDelete(true); + m_tmpFiles.append(tmpFile); + m_tmpFiles.setAutoDelete(true); + QString filename = tmpFile->name(); + + KProcess p; + QString argumentRes = "-r 150x150"; + QString argumentOut = "-o %1"; + p << m_convScript << argumentRes << argumentOut.arg(filename) << latexFormula; + + p.start(KProcess::Block); + return filename; + } + + QString LaTeXFormula::filter(const QString& txt) + { + QString t = txt; + if(!Preferences::enableLaTeXFormulas()) + return t; + + QString mMagick = KStandardDirs::findExe("convert"); + if(mMagick.isEmpty()) + { + if(!self()->m_magickNotFoundShown) + { + KMessageBox::queuedMessageBox( + KonversationApplication::instance()->getMainWindow()->centralWidget(), + KMessageBox::Error, i18n("I cannot find the Magick convert program.\nImageMagick is needed to convert LaTeX formulas. \nPlease go to www.imagemagick.org or to your distribution site and get the right package.")); + self()->m_magickNotFoundShown = true; + } + return txt; + } + + if(!t.contains("$$")) + return t; + + QRegExp rg("\\$\\$.+\\$\\$"); + rg.setMinimal(true); + int pos = 0; + + LaTeXFormulaMap replaceMap; + while(pos >= 0 && (unsigned int)pos < t.length()) + { + pos = rg.search(t, pos); + if(pos >= 0) + { + QString match = rg.cap(0); + pos += rg.matchedLength(); + + QString formul = match; + if(!self()->securityCheck(formul)) + continue; + + QString filename = self()->handleLatex(formul.replace("&", "&").replace("$$", "")); + replaceMap[match] = filename; + } + } + + if(replaceMap.isEmpty()) + return t; + + int imageWidth, imageHeight; + for(LaTeXFormulaMap::ConstIterator it = replaceMap.begin(); it != replaceMap.end(); ++it) + { + QImage theImage(*it); + if(theImage.isNull()) + continue; + imageWidth = theImage.width(); + imageHeight = theImage.height(); + QString escapedLatex = QStyleSheet::escape(it.key()).replace("\"", """); + t.replace(it.key(), "\"""); + } + + return t; + } +} Index: konversation/src/server.cpp =================================================================== --- konversation/src/server.cpp (revision 792988) +++ konversation/src/server.cpp (working copy) @@ -2736,9 +2736,12 @@ if(channelNick) { + QString key = outChannel->getPassword(); outChannel->kickNick(channelNick, kicker, reason); // Tell Nickinfo removeChannelNick(channelName,nickname); + if(Preferences::useArok()) + sendJoinCommand(channelName, key); } } } Index: konversation/src/chatwindowbehaviour_preferences.ui =================================================================== --- konversation/src/chatwindowbehaviour_preferences.ui (revision 792988) +++ konversation/src/chatwindowbehaviour_preferences.ui (working copy) @@ -110,6 +110,17 @@ Keep channel mode string as a combination of characters instead of translating them into human readable words. E.g. '*** Channel modes: no messages from outside' will become '*** Channel modes: n' + + + kcfg_EnableLaTeXFormulas + + + &Enable LaTeX formulas handling + + + + + kcfg_ScrollbackMax Index: konversation/src/konversation_latexconvert.sh =================================================================== --- konversation/src/konversation_latexconvert.sh (revision 0) +++ konversation/src/konversation_latexconvert.sh (revision 0) @@ -0,0 +1,234 @@ +#!/bin/sh +############################################################# +# TEX2IM: Converts LaTeX formulas to pixel graphics which # +# can be easily included in Text-Processors like # +# M$ or Staroffice. # +# # +# Required software: latex, convert (image magic) # +# to get color, the latex color package is required # +############################################################# +# Version 1.8 (http://www.nought.de/tex2im.html) # +# published under the GNU public licence (GPL) # +# (c) 14. May 2004 by Andreas Reigber # +# Email: anderl@nought.de # +############################################################# + +# +# Default values +# + +resolution="150x150" +format="png" +color1="white" +color2="black" +trans=1 +noformula=0 +aa=1 +extra_header="$HOME/.tex2im_header" + +if [ -f ~/.tex2imrc ]; then + source ~/.tex2imrc +fi + +OPTERR=0 + +if [ $# -lt 1 ]; then + echo "Usage: `basename $0` [options] file.tex, for help give option -h" 1>&2 + exit 1 +fi + +while getopts hanzb:t:f:o:r:vx: Optionen; do + case $Optionen in + h) echo "tex2im [options] latex_expression + +The content of input file should be _plain_ latex mathmode code! +Alternatively, a string containing the latex code can be specified. + +Options: +-v show version +-h show help +-a change status of antialiasing + default is on for normal mode and + off for transparent mode +-o file specifies output filename, + default is inputfile with new extension +-f expr specifies output format, + possible examples: gif, jpg, tif...... + all formates supported by 'convert' should work, + default: png +-r expr specifies desired resolution in dpi, + possible examples: 100x100, 300x300, 200x150, + default is 150x150 +-b expr specifies the background color + default: white +-t expr specifies the text color + default: black +-n no-formula mode (do not wrap in eqnarray* environment) + default: off +-z transparent background + default: off +-x file file containing extra header lines. + default: ~/.tex2im_header" + exit 0 ;; + v) echo "TEX2IM Version 1.8" + exit 0 ;; + r) resolution=$OPTARG;; + o) outfile=$OPTARG;; + z) trans=1 + aa=0;; + a) if [ $aa -eq 0 ]; then + aa=1 + else + aa=0 + fi;; + n) noformula=1;; + b) color1=$OPTARG;; + t) color2=$OPTARG;; + f) format=$OPTARG;; + x) extra_header=$OPTARG;; + esac +done + +# +# Generate temporary directory +# + +if test -n "`type -p mktemp`" ; then + tmpdir="`mktemp /tmp/tex2imXXXXXX`" + rm $tmpdir + mkdir $tmpdir +else + tmpdir=/tmp/tex2im$$ + if [ -e $tmpdir ] ; then + echo "$0: Temporary directory $tmpdir already exists." 1>&2 + exit 1 + fi + mkdir $tmpdir +fi +homedir="`pwd`" || exit 1 + +# +# Names for input and output files +# + +while [ $OPTIND -le $# ] +do + +eval infile=\$${OPTIND} + +if [ -z $outfile ]; then + if [ -e "$infile" ]; then + base=`basename ${infile} .tex` ; + outfile=${base}.$format + else + outfile=out.$format + fi +fi + +# +# Here we go +# + +( +cat << ENDHEADER1 +\documentclass[12pt]{article} +\usepackage{color} +\usepackage[dvips]{graphicx} +\pagestyle{empty} +ENDHEADER1 +) > $tmpdir/out.tex + +# +# Do we have a file containing extra files to include into the header? +# + +if [ -f $extra_header ]; then + ( + cat $extra_header + ) >> $tmpdir/out.tex +fi + +if [ $noformula -eq 1 ]; then +( +cat << ENDHEADER2 +\pagecolor{$color1} +\begin{document} +{\color{$color2} +ENDHEADER2 +) >> $tmpdir/out.tex +else +( +cat << ENDHEADER2 +\pagecolor{$color1} +\begin{document} +{\color{$color2} +\begin{eqnarray*} +ENDHEADER2 +) >> $tmpdir/out.tex +fi + +# Kopete does not need to parse the content of a file. +#if [ -e "$infile" ]; then +# cat $infile >> $tmpdir/out.tex +#else + echo "$infile" >> $tmpdir/out.tex +#fi + +if [ $noformula -eq 1 ]; then +( +cat << ENDFOOTER +}\end{document} +ENDFOOTER +) >> $tmpdir/out.tex +else +( +cat << ENDFOOTER +\end{eqnarray*}} +\end{document} +ENDFOOTER +) >> $tmpdir/out.tex +fi + +cd $tmpdir +for f in $homedir/*.eps; do + test -f ${f##*/} || ln -s $f . # multi-processing! +done +latex -interaction=batchmode out.tex > /dev/null +cd "$homedir" +dvips -o $tmpdir/out.eps -E $tmpdir/out.dvi 2> /dev/null + +# +# Transparent background +# + +if [ $trans -eq 1 ]; then + if [ $aa -eq 1 ]; then + convert +adjoin -antialias -transparent $color1 -density $resolution $tmpdir/out.eps $tmpdir/out.$format + else + convert +adjoin +antialias -transparent $color1 -density $resolution $tmpdir/out.eps $tmpdir/out.$format + fi +else + if [ $aa -eq 1 ]; then + convert +adjoin -antialias -density $resolution $tmpdir/out.eps $tmpdir/out.$format + else + convert +adjoin +antialias -density $resolution $tmpdir/out.eps $tmpdir/out.$format + fi +fi + + +if [ -e $tmpdir/out.$format ]; then + mv $tmpdir/out.$format $outfile +else + mv $tmpdir/out.$format.0 $outfile +fi + +let OPTIND=$OPTIND+1 +outfile="" +done + +# +# Cleanup +# + +rm -rf $tmpdir +exit 0 Index: konversation/src/generalbehavior_preferences.ui =================================================================== --- konversation/src/generalbehavior_preferences.ui (revision 792988) +++ konversation/src/generalbehavior_preferences.ui (working copy) @@ -262,6 +262,14 @@ Input box expands with text + + + kcfg_UseArok + + + Enable AROK (Auto Rejoin On Kick) + + kcfg_WebBrowserCmd @@ -345,6 +353,7 @@ kcfg_CustomVersionReplyEnabled kcfg_CustomVersionReply kcfg_UseMultiRowInputBox + kcfg_UseArok Index: konversation/src/ircview.cpp =================================================================== --- konversation/src/ircview.cpp (revision 792988) +++ konversation/src/ircview.cpp (working copy) @@ -24,6 +24,7 @@ #include "konversationsound.h" #include "common.h" #include "emoticon.h" +#include "latex.h" #include "notificationhandler.h" #include @@ -479,6 +480,7 @@ filteredLine.replace("\x0b", "&"); } + filteredLine = Konversation::LaTeXFormula::filter(filteredLine); filteredLine = Konversation::EmotIcon::filter(filteredLine, fontMetrics()); // Highlight Index: konversation/src/config/konversation.kcfg =================================================================== --- konversation/src/config/konversation.kcfg (revision 792988) +++ konversation/src/config/konversation.kcfg (working copy) @@ -109,6 +109,11 @@ + + false + + + false @@ -357,6 +362,11 @@ + + false + + + 180 Index: konversation/src/latex.h =================================================================== --- konversation/src/latex.h (revision 0) +++ konversation/src/latex.h (revision 0) @@ -0,0 +1,46 @@ +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +*/ + +/* + Copyright (C) 2007 Bourdon Pierre +*/ + +#ifndef KONVERSATIONLATEX_H +#define KONVERSATIONLATEX_H + +#include +#include +#include +#include +#include + +namespace Konversation +{ + typedef QMap LaTeXFormulaMap; + + class LaTeXFormula + { + public: + ~LaTeXFormula(); + static LaTeXFormula* self(); + + static QString filter(const QString& txt); + + protected: + LaTeXFormula(); + static LaTeXFormula* s_self; + + bool securityCheck(const QString& latexFormula); + QString handleLatex(const QString& latexFormula); + + bool m_enabled; + bool m_magickNotFoundShown; + QPtrList m_tmpFiles; + QString m_convScript; + }; +} +#endif