<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Michael Wolbert's Blog &#187; Intellipad</title>
	<atom:link href="http://michaelwolbert.nl/blog/tag/intellipad/feed/" rel="self" type="application/rss+xml" />
	<link>http://michaelwolbert.nl/blog</link>
	<description></description>
	<lastBuildDate>Thu, 06 May 2010 12:44:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using a Makefile to launch Oslo&#8217;s executables from Intellipad</title>
		<link>http://michaelwolbert.nl/blog/2009/03/using-a-makefile-to-launch-oslos-executables-from-intellipad/</link>
		<comments>http://michaelwolbert.nl/blog/2009/03/using-a-makefile-to-launch-oslos-executables-from-intellipad/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 15:30:17 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Microsoft Oslo]]></category>
		<category><![CDATA[Study]]></category>
		<category><![CDATA[Intellipad]]></category>
		<category><![CDATA[Makefile]]></category>
		<category><![CDATA[MGrammar]]></category>

		<guid isPermaLink="false">http://michaelwolbert.nl/blog/?p=178</guid>
		<description><![CDATA[In my previous post I mentioned Bryan Sumter&#8217;s GUI tool, which executes the right command from the configuration of the GUI. Sometimes I love my keyboard more than I love my mouse, so I decided to have a try on integrating the tool&#8217;s functionality into Intellipad using a Makefile to configure the commands. (Scroll down [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://michaelwolbert.nl/blog/2009/03/oslotool-a-gui-on-top-of-mexe-mxexe-mgexe-and-mgxexe/" target="_self">previous</a> post I mentioned Bryan Sumter&#8217;s GUI tool, which executes the right command from the configuration of the GUI. Sometimes I love my keyboard more than I love my mouse, so I decided to have a try on integrating the tool&#8217;s functionality into Intellipad using a Makefile to configure the commands. (Scroll down for download!)</p>
<p><strong>Developing:<br />
</strong>First of a snippet from the input Makefile:</p>
<pre>
<div class="codesnip-container" >######################################
# m builds
+m #executable
    @All #target
        files 	= m\*.m
	out	= bin\mx\Image.mx
	package = Image

    @AllToRepository
	files 	= m\*.m
	out	= bin\sql\ImageRep.sql
	target 	= Repository

    @AllToTsql
	files 	= m\*.m
	out	= bin\sql\ImageTsql.sql
	target	= Tsql10</div>
</pre>
<p>After specifying the input file, we continue..</p>
<ul>
<li><strong>Create MGrammar</strong> to parse Makefile to a graph.</li>
<li><strong>Compile MGrammar</strong> to Mgx or MgxResource to use in the runtime.</li>
<li><strong>Build a runtime</strong>: at first I wanted to build a runtime in Intellipads scriptengine (IronPython), but I encountered errors on DynamicParser.Parse(), which I couldn&#8217;t resolve. Since IronPython was no use for me at the moment, I used the .NET 3.5 Console Application (<em>mmake.exe &lt;executable&gt;.&lt;target&gt;</em>) to parse the graph and execute the build command with the proper parameters from the graph.</li>
<li><strong>Create a new Minibuffer command</strong> in IronPython which takes a <em>&lt;executable&gt;.&lt;target&gt;</em> as parameter (eg m.All). A new process will be created to call <em>mmake.exe m.All</em> and its stdout will be redirected to a new BufferView in Intellipad.</li>
</ul>
<p><strong>Python Magic</strong></p>
<p>FindHelper.py</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">from</span> Microsoft.<span class="me1">Intellipad</span>.<span class="me1">Host</span> <span class="kw1">import</span> HostWindow
<span class="kw1">from</span> System.<span class="me1">Windows</span> <span class="kw1">import</span> MessageBox, MessageBoxButton, MessageBoxImage
<span class="kw1">from</span> System.<span class="me1">Diagnostics</span> <span class="kw1">import</span> Process, ProcessStartInfo
<span class="kw1">from</span> System.<span class="me1">IO</span> <span class="kw1">import</span> Directory, Path
...
<span class="kw1">def</span> BuildImpl<span class="br0">&#40;</span>activeView, target<span class="br0">&#41;</span>:
&nbsp; &nbsp; filePath = GetFriendlyFilePath<span class="br0">&#40;</span>activeView.<span class="me1">Buffer</span>.<span class="me1">Uri</span>.<span class="me1">AbsolutePath</span><span class="br0">&#41;</span> &nbsp; &nbsp;

&nbsp; &nbsp; <span class="kw1">if</span> filePath.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&quot;Makefile&quot;</span><span class="br0">&#41;</span> &gt;= <span class="nu0">0</span>:
&nbsp; &nbsp; &nbsp; &nbsp; hostWindow = HostWindow.<span class="me1">GetHostWindowForBufferView</span><span class="br0">&#40;</span>activeView<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; buildBuffer = Common.<span class="me1">BufferManager</span>.<span class="me1">GetBuffer</span><span class="br0">&#40;</span>System.<span class="me1">Uri</span><span class="br0">&#40;</span><span class="st0">'transient://build'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Common.<span class="me1">Clear</span><span class="br0">&#40;</span>buildBuffer<span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; view = Common.<span class="me1">GetView</span><span class="br0">&#40;</span>hostWindow, buildBuffer<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> view <span class="kw1">is</span> <span class="kw2">None</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hostWindow.<span class="me1">ShowInRoot</span><span class="br0">&#40;</span>buildBuffer, <span class="nu0">40.0</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; fileDir = Path.<span class="me1">GetDirectoryName</span><span class="br0">&#40;</span>filePath<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>exitCode, stdout, stderr<span class="br0">&#41;</span> = RunBuildCommand<span class="br0">&#40;</span><span class="st0">&quot;mmake&quot;</span>, fileDir, target<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Common.<span class="me1">Write</span><span class="br0">&#40;</span>buildBuffer, stdout + <span class="st0">&quot;<span class="es0">\n</span>&quot;</span> + stderr<span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">else</span>:
&nbsp; &nbsp; &nbsp; &nbsp; message = <span class="st0">&quot;Error: Makefile needs to be in the active buffer.&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; MessageBox.<span class="me1">Show</span><span class="br0">&#40;</span>message, IntellipadMessageBoxTitle , MessageBoxButton.<span class="me1">OK</span>,
&nbsp;MessageBoxImage.<span class="me1">Information</span><span class="br0">&#41;</span>

<span class="kw1">def</span> GetFriendlyFilePath<span class="br0">&#40;</span>fileUri<span class="br0">&#41;</span>:
&nbsp; &nbsp; path = <span class="kw2">str</span><span class="br0">&#40;</span>fileUri<span class="br0">&#41;</span>.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">'%20'</span>, <span class="st0">' '</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">return</span> path.<span class="me1">replace</span><span class="br0">&#40;</span><span class="st0">'/'</span>, <span class="st0">'<span class="es0">\\</span>'</span><span class="br0">&#41;</span>

<span class="kw1">def</span> RunBuildCommand<span class="br0">&#40;</span><span class="kw3">cmd</span>, <span class="kw3">pwd</span>, args<span class="br0">&#41;</span>:
&nbsp; &nbsp; processStartInfo = ProcessStartInfo<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; processStartInfo.<span class="me1">WorkingDirectory</span> = <span class="kw3">pwd</span>
&nbsp; &nbsp; processStartInfo.<span class="me1">FileName</span> = <span class="kw3">cmd</span>
&nbsp; &nbsp; processStartInfo.<span class="me1">Arguments</span> = args
&nbsp; &nbsp; processStartInfo.<span class="me1">UseShellExecute</span> = <span class="kw2">False</span>
&nbsp; &nbsp; processStartInfo.<span class="me1">RedirectStandardOutput</span> = <span class="kw2">True</span>
&nbsp; &nbsp; processStartInfo.<span class="me1">RedirectStandardError</span> = <span class="kw2">True</span>

&nbsp; &nbsp; process = Process<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; process.<span class="me1">StartInfo</span> = processStartInfo
&nbsp; &nbsp; process.<span class="me1">Start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; process.<span class="me1">WaitForExit</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; stdout = process.<span class="me1">StandardOutput</span>.<span class="me1">ReadToEnd</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; stderr = process.<span class="kw2">StandardError</span>.<span class="me1">ReadToEnd</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">return</span> process.<span class="me1">ExitCode</span>, stdout, stderr</div>
</div>
</pre>
<p>MiniBufferCommandSetup.py</p>
<pre>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">def</span> Build<span class="br0">&#40;</span>target<span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; FindHelper.<span class="me1">BuildImpl</span><span class="br0">&#40;</span>MiniBufferHelper.<span class="me1">GetActiveView</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, target<span class="br0">&#41;</span></div>
</div>
</pre>
<p><strong>Running the Makefile:<br />
</strong>When I use Intellipad to work on my grammars and models, I have the following directory setup:</p>
<p><a href="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/projectdir.jpg"><img class="size-medium wp-image-181 aligncenter" title="projectdir" src="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/projectdir-262x300.jpg" alt="" width="206" height="236" /></a></p>
<p>Now open up the Makefile in Intellipad:<br />
<span style="color: #ff0000;">Note: All paths specified in the Makefile are relative to the path of the Makefile.</span></p>
<p style="text-align: center;"><a href="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/makefilemanytomany.jpg"><img class="size-medium wp-image-182 aligncenter" title="makefilemanytomany" src="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/makefilemanytomany-300x167.jpg" alt="" width="329" height="182" /></a></p>
<p>Hit Ctrl+/ to bring up the Minibuffer and type: Build(&#8217;&lt;executable&gt;.&lt;target&gt;&#8217;)<br />
<span style="color: #ff0000;">Note: Intellipad needs to know what directory the Makefile is in, so the Makefile buffer should be active (selected) before bringing up the Minibuffer.</span></p>
<p style="text-align: center;"><a href="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/minibufferbuildcommand.jpg"><img class="size-medium wp-image-183 aligncenter" title="minibufferbuildcommand" src="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/minibufferbuildcommand-300x168.jpg" alt="" width="326" height="181" /></a></p>
<p>Command will run and output to a new BufferView:</p>
<p style="text-align: center;"><a href="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/commandexecuted.jpg"><img class="size-medium wp-image-185 aligncenter" title="commandexecuted" src="http://michaelwolbert.nl/blog/wp-content/uploads/2009/03/commandexecuted-300x168.jpg" alt="" width="330" height="184" /></a></p>
<p><strong><br />
Download:<br />
</strong></p>
<ul>
<li><a href="http://michaelwolbert.nl/projects/Oslo/mmake/project_sample.zip" target="_self">Sample project directory</a> (Makefile and samples from Oslo SDK 1.0 for sample builds).</li>
<li><a href="http://michaelwolbert.nl/projects/Oslo/mmake/mmake-0.1.zip" target="_self">mmake</a> (1 runtime, 1 mgx and 2 .py): <span style="color: #ff0000;">Extract archive in %PATH_TO_OSLO_SDK%\Bin</span></li>
</ul>
<p><span style="color: #ff0000;"><span style="color: #000000;"><strong>Install notes:<br />
</strong></span></span></p>
<ul>
<li><span style="color: #ff0000;">Add </span><span style="color: #ff0000;">%PATH_TO_OSLO_SDK%\Bin to system var: PATH</span></li>
<li>Backup .py files in case Intellipad stops working: FindHelper.py and MiniBufferCommandSetup.<br />
<span style="color: #000000;">%PATH_TO_OSLO_SDK%\</span>Bin\Intellipad\FindHelper.py<br />
<span style="color: #000000;">%PATH_TO_OSLO_SDK%\</span>Bin\Intellipad\Components\Microsoft.Intellipad.Scripting\PrivateScripts</li>
<li>Write permission errors on %PATH_TO_OSLO_SDK%: fix directory settings.</li>
</ul>
<p><strong>What&#8217;s next?</strong></p>
<ul>
<li>Hyperlinks on buildtargets in Intellipad: click to compile.</li>
<li>Resolving IronPython issues with DynamicParser.Parse().</li>
<li>Build a horizontal DSL instead of a vertical DSL for Makefiles.</li>
</ul>
<p><strong>Bugs and errors:<br />
</strong>Post bugs or suggestions in the comments or drop me a line via email. :-)</p>
<p><strong>References:</strong></p>
<ul>
<li><a href="http://blogs.msdn.com/Intellipad/" target="_self">http://blogs.msdn.com/Intellipad/</a></li>
<li><a href="http://www.ironpython.info/index.php/Contents" target="_self">http://www.ironpython.info/index.php/Contents</a></li>
<li><a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2256">http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2256</a></li>
</ul>
<p><span style="color: #ff0000;"><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://michaelwolbert.nl/blog/2009/03/using-a-makefile-to-launch-oslos-executables-from-intellipad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

