<CharlieDigital/> Programming, Politics, and uhh…pineapples


Inserting HTML into Word Documents

Posted by Charles Chen

For a recent prototype, I was tasked with building a solution to allow authors to create "standard text" entries in SharePoint 2010 which could then be re-used by authors.

One of the challenges was trying to figure out the best way to store this type of content.  Word documents is one obvious solution, but I approached it differently: using SharePoint's HTML field type.

List wth standard text items.

You can see in the screen on the left, a list with a column called Default Text.  This is simply a multi-line text field set to either Rich text or Enhanced rich text.

SharePoint's rich text editor is fairly competent for most text formatting scenarios.

This design allows authors to create basic text bodies with formatting entirely in SharePoint

The next question is how to take advantage of this.

Add-in panel in Word 2010

In the authoring environment, Word 2010, an add-in was written to allow users to connect to SharePoint and browse the list contents with fully formatted text.

You can see the screenshot on the right.  The UI is a mish-mash of WPF and classic Windows Forms controls (specifically, the WebBrowser control) to render the HTML contents for preview.

The add-in uses the SharePoint web services to connect to a configured list to retrieve the items using the trusty old Lists web service (the tool was written to support both 2007 and 2010).

The next step is to figure out how to add the text to the body of the Word document and retain the formatting.  In all honesty, I figured that this would be the most complicated part.  In fact, it was the easiest part and accomplished with only a few meager lines of code.

The trick is to leverage the InsertFile function of the Range.  This allows us to insert arbitrary HTML strings by first saving them as files to a temporary location on disk.

/// <summary>
/// Saves the default text to a temporary .html file which can then be inserted.
/// </summary>
/// <returns>The path to the temporary .html file.</returns>
public string SaveToTemporaryFile()
    string htmlTempFile = Path.Combine(Path.GetTempPath(),
        string.Format("{0}.html", Path.GetRandomFileName()));

    using (StreamWriter writer = File.CreateText(htmlTempFile))
        string html = string.Format("<html>{0}</html>", Default);


    return htmlTempFile;

The only trick is that <html/> must be the root element of the document.

Once the temporary file is saved to the disk, we can insert it into the Word document:

private object _opt = Missing.Value;

/// <summary>
/// Inserts the standard text into the active selection range by creating a
/// temporary file and using the <c>InsertFile</c> method to inject HTML into a
/// Word document.
/// </summary>
/// <param name="standardText">The standard text.</param>
/// <param name="contentControl">The content control.</param>
public void InsertStandardText(StandardText standardText, ContentControl contentControl)
    object range = Application.Selection.Range;

    if (contentControl == null)
        contentControl =
            WdContentControlType.wdContentControlRichText, ref range);

    contentControl.Title = standardText.Title;

    string path = standardText.SaveToTemporaryFile();

    contentControl.Range.InsertFile(path, ref _opt, ref _opt, ref _opt, ref _opt);

    // Snipped for brevity...

HTML content inserted into the Word document

The screenshot to the left is an example of HTML content inserted into a Word document.

As you can see, it retained inherited the local formatting (fonts, font size) where no explicit font specification is made.  But otherwise, it faithfully rendered the HTML content entered in the list.

That's it.  I like it when things are simple yet powerful.  For server side (OpenXML manipulation), the story is a little bit different - we'll explore that some other time.


Commentary on “Frankenfish”

Posted by Charles Chen

The news media has recently been abuzz about about this so-called "Frankenfish".

It's been puzzling to me what the hullabaloo has been all about.  The fact of the matter is that humans have been altering the genetics of just about everything we eat for centuries (millennia?).

Those navel oranges you eat? They're all genetic clones of a single mutation that occurred in the 1800's and every navel orange since has been grown via cutting and grafting techniques. Most cultivars of avocados are also grown via cutting and grafting of a single plant with a desirable genetic mutation.  That bread you eat? It's probably made from wheat that's been bred and cross-bred for resistance to certain strains of fungi and resistance to insects.  The corn that you eat (and all of the byproducts made from that corn)? It's been bred, cross-bred, and selected for desirable traits for centuries.

Humans have been manipulating the genetics of the food that we eat and disrupting or enhancing the natural reproductive cycles of plants and animals alike to breed for desirable traits like pest resistance, drought resistance, fatter meat, leaner meat, tastier meat, greater milk production, faster growth, sweeter fruit, and so on. And when genetics aren't enough to get the desired results, humans aren't shy to rely on other aspects of science like artificial steroids, hormones, antibiotics, pesticides, fungicides, herbicides, and so on. All of which make it into our waterways and our digestive systems.  I'm not saying that these are "good", but that the food supply that you already eat from is hardly free from human intervention.

The rampant and unjustified fear around genetically modified food is symptomatic of a culturally ingrained distrust of science (maybe it stems from religiosity...) and a general ignorance about agriculture and the long history of selection and crossbreeding for genetic traits. Certainly, we can't simply take AquaBounty's word, but we can approach this rationally and study the science and study the data to ensure that indeed, the inserted genes do not have an undesirable side effect in humans and that the environmental impact will be safe.

In the big picture, this type of science is needed if we wish to responsibly address the growing population of the Earth. Our natural resources aren't getting any more bountiful, yet the human population continues to grow, devour, want, and so on. If genetic modification can help yield greater harvests from the same land, if genetic modification and result in the decreased use of pesticides or fungicides or herbicides or fertilizer, if genetic modification can make farm raised fish profitable and thus help the recovery of wild salmon stocks, if genetic modification can help feed the growing population of the Earth and decrease famine and hunger, then I ask why should we not embrace this science and find solutions that work?

It recalls the criticism that Norman Borlaug's work received:

Borlaug's name is nearly synonymous with the Green Revolution, against which many criticisms  have been mounted over the decades by environmentalists, nutritionists, progressives, and economists. Throughout his years of research, Borlaug's programs often faced opposition by people who consider genetic crossbreeding to be unnatural or to have negative effects.

And yet, Borlaug's work has arguably saved billions of lives:

Borlaug received his Ph.D. in plant pathology and genetics from the University of Minnesota in 1942. He took up an agricultural research position in Mexico, where he developed semi-dwarf, high-yield, disease-resistant wheat varieties.

During the mid-20th century, Borlaug led the introduction of these high-yielding varieties combined with modern agricultural production techniques to Mexico, Pakistan, and India. As a result, Mexico became a net exporter of wheat by 1963. Between 1965 and 1970, wheat yields nearly doubled in Pakistan and India, greatly improving the food security in those nations.  These collective increases in yield have been labeled the Green Revolution, and Borlaug is often credited with saving over a billion people worldwide from starvation.

Of course, there are many that decry humanitarianism as being far from the objectives of AquaBounty; they say that AquaBounty is only in it for greed, for money, for profit.  But then I have to ask: what commercial fishing or farming operation isn't in it for money and profit?  Even that mom & pop organic farm down the street is in it for profit.  It's the very basis of the capitalistic system: do more, cheaper, faster, more efficiently.  There's no such thing as food production that doesn't follow this basis (with few exceptions like the production of fine liquors or wines, for example).

Certainly, there are pitfalls and certainly, there are dangers. However, the reality is that many wild fish populations are being fished to the edge of extinction or will be fished to the brink of extinction if we don't take responsible action today. That includes developing better systems of quotas and monitoring of natural populations, decreasing pollution in our waterways, and developing alternatives that can alleviate the strain that commercial fisheries place on these populations.  In the broader picture, if we also consider land based crop farming, improving efficiency through genetic engineering may be necessary to curb deforestation and the continued destruction of natural habitat while still meeting the nutritional needs of a growing population.  Borlaug developed a hypothesis with regards to the importance of increasing yields through science:

The large role he played in both increasing crop yields and promoting this view has led to this methodology being called by agricultural economists the "Borlaug hypothesis", namely that increasing the productivity of agriculture on the best farmland can help control deforestation by reducing the demand for new farmland. According to this view, assuming that global food demand is on the rise, restricting crop usage to traditional low-yield methods would also require at least one of the following: the world population to decrease, either voluntarily or as a result of mass starvations; or the conversion of forest land into crop land. It is thus argued that high-yield techniques are ultimately saving ecosystems from destruction.

I deem these fish safe until the science tells me otherwise. For all intents and purposes, they've only inserted genes from two other fish species (one of them being another type of salmon!) for their desirable traits; hardly worth the shock response and uproar over these GM salmon. The "Frankenfish" label is completely based on ignorance and stoking the fears of the ignorant.


Presenting at the Tri-State Code Camp 2010.2!

Posted by Charles Chen

The session is titled "Object Oriented Development and Practices in SharePoint":

Building maintainable solutions on the SharePoint platform can be a challenge (and that might be putting it mildly). Code interspersed with CAML strings, rampant code duplication, hundred (thousand?) line methods, inconsistent code quality, and so on.  How can a dev/technical lead address these problems that arise when a team of individuals with diverse experience and skill levels embarks on designing and building a solution on the SharePoint platform?

This session introduces a series of practices, tools, libraries, and techniques to support an object-oriented approach to building sustainable and maintainable solutions on the SharePoint platform.  It offers an innovative approach to solving complex solution and development problems through embracing simplicity and leveraging the capabilities of the .NET Framework to build a framework for highly object-oriented, patterns based solutions.

Technologies: SharePoint 2007, Visual Studio 2010, C#, .NET, XSLT (Saxon)

Audience: SharePoint developers, SharePoint technical architects, SharePoint technical leads, .NET developers

Level: Intermediate/Advanced.  Audiences with experience in design patterns, reflection, delegates, anonymous functions, and XSLT will be able to follow along and extract the most value from this session.

To expand on that, the plan is to cover some of the lessons I've learned from being deep in the code on a handful of large SharePoint projects.  These lessons I've encapsulated in a framework of sorts which was designed to help:

  1. Accelerate development of solutions for SharePoint
  2. Increase developer productivity while still maintaining high levels of code consistency
  3. Increase adherence to the DRY (Don't Repeat Yourself) principle by leveraging patterns and object-oriented code
  4. Decrease the entry barrier for ASP.NET developers transitioning to SharePoint

It won't be for everyone; however, for any team that's deep into the SharePoint APIs and building custom solutions (web parts, event receivers, web pages, layout pages, and so on), I promise this will be a great session to attend.  My hope is that attendees will be able to walk away with some ideas on how to make their teams more productive and to help teams write better code.

The event will take place on Saturday, October 9th at the DeVry campus in Fort Washington, PA (great campus, good presenters, free lunch!).  Details here: http://codecamp.phillydotnet.org/2010-2/default.aspx

I'd be lying if I said I wasn't a bit anxious over the whole thing.

I plan on putting together a monster post before the event with the outline, details, and materials of the stuff I plan to cover.  See you there (and wish me luck)!


A New Euphemism for Bad Code

Posted by Charles Chen

Ant Death Spiral (via Cynical-C).

This is one of my favorite things about ants -- the ant death spiral. Actually, it's a circular mill, first described in army ants by Schneirla (1944). A circle of army ants, each one following the ant in front, becomes locked into a circular mill. They will continue to circle each other until they all die. How crazy is that?

This is the perfect description for bad code and bad programmers (and poorly run companies!).  Each development cycle that builds on bad code just compounds the problem until you're locked into a code death spiral of "we don't have time to clean it up" or "it'll take too much effort to refactor it" or "this is just how we do it here".  Instead, each member of the team begrudgingly (or even worse, dutifully and mindlessly marching like ants) continues to use the bad code, copy and paste the bad code, and build on top of the bad code thereby creating more bad code and more dependencies on the bad code that become inexorably difficult to refactor and extract.


In programming and software development, Paul Graham captures this concept perfectly in his essay on the failure of Yahoo! and why they fell to Microsoft and Google:

In technology, once you have bad programmers, you're doomed. I can't think of an instance where a company has sunk into technical mediocrity and recovered. Good programmers want to work with other good programmers. So once the quality of programmers at your company starts to drop, you enter a death spiral from which there is no recovery.

But not all hope is lost,

Sometimes they escape, though. Beebe (1921) described a circular mill he witnessed in Guyana. It measured 1200 feet in circumference and had a 2.5 hour circuit time per ant. The mill persisted for two days, "with ever increasing numbers of dead bodies littering the route as exhaustion took its toll, but eventually a few workers straggled from the trail thus breaking the cycle, and the raid marched off into the forest."

Avoid the ant death spiral!  As Fred Brooks suggests in The Mythical Man Month,

Programming managers have long recognized wide productivity variations between good programmers and poor ones.  But the actual measured magnitudes have astounded all of us.  In one set of their studies, Sackman, Erickson, and Grant were measuring performances of a group of experienced programmers.  Within just this group the ratios between best and worst performances averaged about 10:1 on productivity measurements and an amazing 5:1 on program speed and space requirements!  In short the $20,000/year programmer may well be 10 times as productive as the $10,000/year one.  The converse may be true, too.  The data showed no correlation whatsoever between experience and performance. (I doubt if that is universally true.)

Take the effort to find, work with, hire, or -- better yet -- count yourself among those programmers that can help teams avoid walking into the ant death spiral in the first place.  Address lingering issues and inefficiencies as soon as possible; fixing bad code early can yield huge gains in agility and flexibility down the line.  Never be afraid to break the cycle and call out bad code and poor practices.

Filed under: DevLife 2 Comments