• 9884阅读
  • 1回复

[转载]Syntax-Highlighting Experiments [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2013-07-13
转自:http://steckdenis.be/post-2013-07-01-syntax-highlighting-experiments.html


Syntax-Highlighting Experiments


Published on Mon 01 July 2013 inNepomuk,(0 Comments)


Sometimes, I’m very happy to work with Qt, because it provideseverything I need, and in a very clever way. Syntax-highlighting is oneof the many areas where Qt shines.High-level syntax-highlighting of programming languages and configuration files is easily done using KTextEditor (the component used by Kate, KWrite, Kile, KDevelop, I think). One has simply to write an XMLfile describing the language to highlight, and the editor does therest. Code-folding is also possible, as is every other feature everyoneloves in Kate and KDevelop.
For my Google Summer of Code project, such a full-fledged editor is abit overkill. What I need is a mean to syntax-highlight a one-line textedit. The highlighting itself is simple, because the “grammar” (if itreally is one) of the parser is simple.


A One-Line Text Edit



Yesterday, I started by implementing a small editor based on QPlainTextEdit, mimicking QLineEdit. I couldn’t directly use this class because it doesn’t allow syntax-highlighting, I need a QTextEdit subclass and a QTextDocument. I therefore tried to make QPlainTextEditlook like a simple line edit. This can be done by configuring itproperly (setting the size policy, disabling tabs, disabling the scrollbars and the word-wrap, etc) and by reimplementing its sizeHint() method. The reimplemented method behaves like the one of QLineEdit (original code from the Qt project FAQ):QSize QueryBuilder::sizeHint() const{QFontMetrics fm(font());QStyleOptionFrameV3 opt;QString text = document()->toPlainText();int h = qMax(fm.height(), 14) + 4;int w = fm.width(text) + 4;opt.initFrom(this);return style()->sizeFromContents(QStyle::CT_LineEdit,&opt,QSize(w, h).expandedTo(QApplication::globalStrut()),this);}
The method calculates the area of the displayed text (using QFontMetrics), and then asks the style to compute the size of the whole widget. By telling the style that the widget is a CT_LineEdit, the size returned is the exact same size a line edit would have. The illusion is perfect:





Choosing Colors



After having implemented the text editor, I started experimentingwith the syntax-highlighting itself. My idea was to have every ComparisonTermdisplayed in a different color, with the literal terms displayed inbold. During the development, I also thought that it would be nice tohave “type hints” (mails, photos, documents, files, contacts, etc)displayed in italics.My first idea was to follow the interface given by Ivan Čukić here.The problem was that I don’t even know how his “single-line edit withgrouped terms that can be removed by clicking on a cross” is officiallycalled. So, I’ve found nothing on Google that could help me to implementthat. I tried different solutions, but there were always problems (forinstance, a QLineEdit draws its white back-ground and its text in onestep, so I cannot draw boxes between the two). In order to still be ableto experiment things, I decided to use a simpler approach(syntax-highlighting) for now.
In the above image, you can see that every comparison term ishighlighted in a different color. The colors are coming from the Oxygenpalette, and are roughly all of the same luminosity. It is verydifficult to find colors that look well with each other, so if you haveideas, don’t hesitate to tell me. I have selected 8 colors, and thehighlighter cycles between them.I also tried to use HSV colors (Hue,Saturation, Value). Saturation and Value were forced to values oftenfound in Oxygen colors, and the hue was incremented by 71 degreesevery-time the color had to change. The result was ok, but not so nice.Sure, there was up to 360 different colors, but they were mostlybad-looking and difficult to read. I abandoned the idea and decided touse Oxygen colors, that were carefully crafted by the great designersof KDE.
I developed this experiment directly in the Nepomuk Widgets repository. As I have no KDE developer account yet, the repository can be found at http://public.steckdenis.be/git/nepomuk-widgets . My code is in the gsoc2013 branch. Feel free to experiment and to modify the colors (a table in ui/querysyntaxhighlighter.cpp).UPDATE:
Most users will never or very rarely use comparison terms. All theywant is a tool that returns a list of documents matching terms. Thesyntax-highlighter I presented in this blog post chooses a differentcolor for each comparison or literal terms. Queries like “cat dograbbit” therefore are highlighted using 3 different colors, every termbeing in bold. This is not really nice.So, I changed the highlighting a bit. Now, literal terms are nothighlighted at all, only comparison terms and resource type terms (typehints) are. For comparisons, the whole comparison is colored, and itspart that is not a literal term is also rendered in italics. So, “foobar sent by Jimmy” becomes “foo bar sent by Jimmy”:



Another modification is that nested queries are detected and underlined,so the user can see where it ends, and potentially why its query doesnot return the expected results:

二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线彩阳

只看该作者 1楼 发表于: 2013-07-13
代码的部分要是能够整理就好了。
上海Qt开发联盟,热忱地欢迎你的加入!
快速回复
限100 字节
 
上一个 下一个