Happy stress free coding

Sep 14, 2008

Writing the blog with Word 2007

Writing the blog in word posed some challenges. One I stumbled upon 2 minutes after I started was that code and xml I pasted in looked like shit.

Maybe there is an easily available workaround that I have not found, but then again, if I cannot find it you might not either.

I researched how to format code and xml in word to get it to look ok in blogger, more precise to keep the indentations in blogger in an earlier post.

So I took on the task to write a plugin that lets you paste in code and xml, select it and then press a button to format it by enclosing it in a table, that in turns hold tables to get the indentations correct.

Of course this has proven to take more time that I would have guessed. Anyone using word as a host for anything will know why… You just cannot trust the application to behave logical. It's more like a crazy horse, you think your friends but then you get kicked in the butt…

Even now as I write this I trying to figure out how to keep this crazy animal sane long enough so that I can do my thing.

 
 

private Office.CommandBar AddToolBar()

 

{

 

// Create the toolbar

  
 

Office.CommandBar toolbar = this.Application.CommandBars.Add(TOOLBAR, MsoBarPosition.msoBarTop, missing, false);

 

// Add a button to it

 

Office.CommandBarButton button = (Office.CommandBarButton)

 

toolbar.Controls.Add(MsoControlType.msoControlButton, missing,

 

missing, missing, false);

  
 

// Set the button's style

 

button.Style = Office.MsoButtonStyle.msoButtonCaption;

  
 

// Set the button's caption

 

button.Caption = "Code and XML Format for web publish";

 

button.Click += new _CommandBarButtonEvents_ClickEventHandler(CodeAndXmlFormat);

  
 

// Ensure the toolbar is visible, by default it won't be

 

toolbar.Visible = true;

  
 

// Return the newly created toolbar

 

return toolbar;

 

}

 

The active part of the code comes here:

 
 

void CodeAndXmlFormat(CommandBarButton Ctrl, ref bool CancelDefault)

 

{

 

if (this.Application.Selection.Tables.Count != 0)

 

{

 

MessageBox.Show("There are a some tables in the selection, so I cannot do anything for you...");

 

return;

 

}

  
 

Application.ScreenUpdating=false;

 

Try

 

{

 

List<Paragraph> ps = new List<Paragraph>();

 

List<int> indents = new List<int>();

 

bool started=false;

 

int smallestwidth=int.MaxValue;

 

// Run thru the selection

 

foreach (Paragraph p in this.Application.Selection.Paragraphs)

 

{

 

if (started || p.Range.Text != "\r") // skip leading empties

 

{

 

started=true;

 

ps.Add(p);

 

int width = 0;

 

// count leading spaces and tabs

 

for (int i = 1; i < p.Range.Characters.Count + 1; i++)

 

{

 

string s = p.Range.Characters[i].Text;

 

if (s == " ")

 

width++;

 

else if (s == "\t")

 

width+=4;

 

else

 

break;

 

}

 

indents.Add(width);

 

if (width<smallestwidth)

 

smallestwidth=width;

  
 

}

 

}

  
 

// Now build the new table

 

Range r3=Application.Selection.Range.Duplicate;

 

r3.End++;

 

r3.Start=r3.End;

 

object paramMissing2 = Type.Missing;

 

Table t=r3.Tables.Add(r3,ps.Count+1,1,ref paramMissing2,ref paramMissing2);

 

for (int i=ps.Count-1;i>=0;i--)

 

{

 

Paragraph p=ps[i];

 

DoOneRowAsSubTable(t.Rows[i + 2], p, indents[i] - smallestwidth/*detuct initial space*/ );

 

}

  
 

// The oldest and best trick in the book when doing word developement; record a macro of what you need to do, then steal the code:

 

this.Application.Selection.SetRange(t.Range.Start,t.Range.End);

 

this.Application.Selection.Font.Size = 8;

  
  
 

// Delete old

 

for (int i = ps.Count - 1; i >= 0; i--)

 

{

 

Paragraph p = ps[i];

 

object numtodel = 1;

 

p.Range.Delete(ref paramMissing2, ref numtodel);

 

}

 

}

 

finally

 

{

 

Application.ScreenUpdating=true;

 

}

 

}

  

 

This code depends on this method that wraps one row in a sub table with two cells that fix up the indentation:

 
 

private void DoOneRowAsSubTable(Row row, Paragraph p, int width)

 

{

 

object paramMissing2 = Type.Missing;

 

Table t=row.Cells[1].Range.Tables.Add(row.Cells[1].Range,1,2,ref paramMissing2, ref paramMissing2);

 

Application.ActiveDocument.UndoClear();

 

//Application.ScreenRefresh();

 

float totwidth=t.Rows[1].Cells[1].Width+t.Rows[1].Cells[2].Width;

 

t.Rows[1].Cells[1].Width=Math.Max(15,width*7);

 

t.Rows[1].Cells[2].Width = Math.Min(row.Cells[1].Width, totwidth - t.Rows[1].Cells[1].Width);

  
  
 

Range r=p.Range.Duplicate;

 

// drop leading spaceses

 

while (r.Characters.Count > 1 && (r.Characters[1].Text == " " || r.Characters[1].Text == "\t"))

 

{

 

r.Start+=1;

 

}

 

while (r.End > r.Start && (r.Characters[r.Characters.Count].Text == "\r" || r.Characters[r.Characters.Count].Text == "\a"))

 

{

 

r.End-=1;

 

}

 

if (r.Start<r.End)

 

{

 

r.Copy();

 

t.Rows[1].Cells[2].Range.Paste();

 

//t.Rows[1].Cells[2].Range.InsertXML(r.WordOpenXML,ref paramMissing2);

 

}

 

}

  

 

And that's it. Now I can use Word2007 to post code and xaml. I still need to mark the snippets and push an add in button to wrap in a table. And Yes, the table thing is not optimal in anyway, but it is good enough for me.

To be honest I also made some small changes to the css part of the blogger style sheet. I made the main area wider and also added a style to make table rows 9 pixels high.

 
 

table {

 

line-height:9px;

 

background-color:#eeeeee;

 

}

  
 

#main-wrapper {

 

width: 660px;

 

float: $startSide;

 

word-wrap: break-word; /* fix for long text breaking sidebar float in IE */

 

overflow: hidden; /* fix for long non-text content breaking IE sidebar float */

 

}

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home