Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » How to generate/serialize pretty printed HTML-output
How to generate/serialize pretty printed HTML-output [message #1715672] Wed, 25 November 2015 08:07 Go to next message
Bernd Hofner is currently offline Bernd HofnerFriend
Messages: 68
Registered: July 2009
Member
Hello,

I generate an HTML page from my DSL.
Some sections of the generated HTML should look identical to the DSL text entered in the XText editor - including spaces and indentation. I'd also like to do syntax highlighting for the keywords of the DSL and generate hyperlinks for the cross references.

The model produced by the parser has lost some of the input information that I like to reproduce in my generated content: which keywords, whitespaces, indentations and line breaks were used in the input ("the token stream").

Example-DSL input:

Für alle x : ClassX
mit: x.wert < "100"
gilt: x.kategorie = "teuer"


The desired html output should look somewhat like this:

<div>
  <span class="keyword">Für alle</span>
  <span class="whitespace"> </span>
  <span class="identifier">x</span>
  <span class="whitespace"> </span>
  <span class="keyword">:</span>
  <span class="whitespace"> </span>
  <span class="type"><a href="link to declaration">ClassX</a></span>
  <br>
...
</div>


I wonder how to approach this?
Whould it be a good idea to create a specialized Serializer?

I would appreciate some hints to point me in the right direction,

Bernd
Re: How to generate/serialize pretty printed HTML-output [message #1715679 is a reply to message #1715672] Wed, 25 November 2015 08:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
starting with an XtextResource you can access the node model (resource.getParseResult().getRootNode)
you can traverse the node model for its node. the nodes can be inspected for there grammar elements and the semantic elements.
i did such an html export about 3 years ago (unfortunately closed source) but it should be doable in about 200 lines of code


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to generate/serialize pretty printed HTML-output [message #1715776 is a reply to message #1715679] Thu, 26 November 2015 06:51 Go to previous messageGo to next message
Bernd Hofner is currently offline Bernd HofnerFriend
Messages: 68
Registered: July 2009
Member
Good morning Christian,

Thank you for the hint. The puzzle pieces seem to be all there, but I still have problems to stick them together.

I had a closer look at the node tree and dumped a sample of it to the console. I have some difficulties to understand what I see.

First - it seems that the tree had a terrible radiation accident:

It contains two tree hierarchies at the same time, as a CompositeNode can have children AND leaves at the same time. To make matters worse to understand, a LeafNode can itself contain further leaves - these branching leaves must be a mutation due to too much radiation exposure.

In which order to I have to traverse - when to I go down the child hierarchy and when to step into the leaves hierarchy?

Next - the tree seems to contain the same information multiple times - in the parsed example file, the keyword "condition:" is contained once, but the dumped tree contains it four or five times. How to decide when to pick up the information in a node for serialization and when to ignore it?

I stumpled across a class NodeUtil - could it help to make sense of the tree?

Ciao, Bernd

[Updated on: Thu, 26 November 2015 06:53]

Report message to a moderator

Re: How to generate/serialize pretty printed HTML-output [message #1715777 is a reply to message #1715776] Thu, 26 November 2015 07:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
simple use INode.getAsTreeIterable on the root. it will to the traversal for you

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to generate/serialize pretty printed HTML-output [message #1715779 is a reply to message #1715777] Thu, 26 November 2015 07:50 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
here is a very basic statring point

def private CharSequence handleResource(XtextResource resource) {
'''
<html>«resource.parseResult?.rootNode.handle»</html>'''
}

def private dispatch CharSequence handle(ICompositeNode n)
'''«FOR c : n.children»«c.handle»«ENDFOR»'''

def private dispatch CharSequence handle(ILeafNode n)
'''«n.text.replaceAll("\n\r?","<br/>")»'''


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: How to generate/serialize pretty printed HTML-output [message #1715781 is a reply to message #1715779] Thu, 26 November 2015 08:24 Go to previous messageGo to next message
Bernd Hofner is currently offline Bernd HofnerFriend
Messages: 68
Registered: July 2009
Member
This got me considerable forward.
Now I can iterate in the right order over the tree:

XtextResource resource= (XtextResource)me.eResource();
CompositeNode rootNode= resource.getParseResult().getRootNode();
			
Iterable<AbstractNode> nodes= NodeUtil.getAllContents(rootNode);
for(AbstractNode n : nodes) {
   if (node instanceof LeafNode) {
      TextFragment t= new TextFragment((LeafNode)node);
      t.seralize();
   }
}

And identify a lot of sematic data for each node:
public class TextFragment {
	public String text;
	boolean isKeyword= false;
	boolean isWhitespace= false;
	boolean isComment= false;
	
	public TextFragment(LeafNode node) {
		text= node.getText();
		
		if (node.getGrammarElement() instanceof CrossReference) {
			CrossReference ref = (CrossReference) node.getGrammarElement();
                        // TODO: The targets seem not to be filled
		} else if (node.getGrammarElement() instanceof RuleCall) {
			RuleCall rc = (RuleCall) node.getGrammarElement();
                        // TODO: some of the rule calls should be cross references...			
		} else if (node.getGrammarElement() instanceof Keyword) {
			Keyword kw= (Keyword)node.getGrammarElement();
			isKeyword= true;
		} else if (node.getGrammarElement() instanceof TerminalRule) {
			TerminalRule term= (TerminalRule)node.getGrammarElement();
			if(term.getName().equals("WS")) {
				isWhitespace= true;
			}
			else if(   term.getName().equals("ML_COMMENT")
					|| term.getName().equals("SL_COMMENT")) 
			{
				isComment= true;
			}
		}
	}
}


Resolving the cross references now seems to be the next hurdle.
It seems that the results of the linking are not reflected in the node tree.
What I mean is when I inspect the a node representing a cross reference,
the targets are empty - the reference references nothing?:
CrossReference ref = (CrossReference) node.getGrammarElement();
EList<EObject> targets= ref.eCrossReferences();


[Updated on: Thu, 26 November 2015 08:31]

Report message to a moderator

Re: How to generate/serialize pretty printed HTML-output [message #1715785 is a reply to message #1715781] Thu, 26 November 2015 09:00 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
Nodemodelutil and eobjectatoffsethelper. You schould resolve anything beforehand anyway

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:Generate production artifacts with 2.9
Next Topic:Tweak InternalDSLParser in order to recover from Mismatched tokens
Goto Forum:
  


Current Time: Sun Sep 22 22:46:15 GMT 2024

Powered by FUDForum. Page generated in 0.03981 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top