- rinocp.zip
- fr.c2s.rinocp_0.0.1_all.ipk
- makeWebOS.bat
- RinoAPI
- RinoAzureService
- RinoAzureService.ccproj
- RinoAzureService.ccproj.user
- ServiceConfiguration.cscfg
- ServiceDefinition.csdef
- RinoCP.sln
- RinoTray
- RinoWebOS
- RinoWebRole
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using OneNote = Microsoft.Office.Interop.OneNote;
using System.Xml.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Runtime.Serialization;
namespace Rino
{
/// <summary>
/// Class for a page in a Notebook
/// </summary>
[DataContract]
public class Page : PageHeader
{
/// <summary>
/// Class to set HTML generation options
/// </summary>
public class Options
{
public bool FormatLine;
}
/// <summary>
/// Current options for generation
/// </summary>
private Options CurrentOptions;
/// <summary>
/// Content of the page as a raw XML string.
/// </summary>
/// <returns>content as a raw XML string</returns>
[DataMember]
public string Content { get; set; }
/// <summary>
/// Get a page in Microsoft OneNote.
/// </summary>
/// <param name="header">header of the page to read</param>
/// <returns>list of Notebook element found</returns>
public static Page LoadPageFromOneNote(PageHeader header)
{
// Call OneNote API to get content
string sPage;
OneNote.ApplicationClass onApp = new OneNote.ApplicationClass();
onApp.GetPageContent(header.ID, out sPage, OneNote.PageInfo.piAll);
// Create a page from the header
Page page = new Page();
page.ID = header.ID;
page.IsSubpage = header.IsSubpage;
page.Name = header.Name;
page.LastModifiedTime = header.LastModifiedTime;
page.Content = sPage;
return page;
}
/// <summary>
/// Get content of the page as simplified HTML using default generation settings.
/// </summary>
/// <returns>content as simplified HTML</returns>
public string ToHTML()
{
Options settings = new Options();
settings.FormatLine = true;
return ToHTML(settings);
}
/// <summary>
/// Get content of the page as simplified HTML.
/// </summary>
/// <param name="settings">generation settings</param>
/// <returns>content as simplified HTML</returns>
public string ToHTML(Options settings)
{
// Set options
if (settings == null)
return ToHTML();
CurrentOptions = settings;
// Get XML
XDocument page = XDocument.Parse(Content);
// Init visitor
output = new StringBuilder();
XMLVisitor visitor = new XMLVisitor();
InitVisitor(visitor);
// Launch generation
visitor.Visit(page);
// Return result
return output.ToString();
}
#region Generation visitor
/// <summary>
/// Max level for a paragraph
/// </summary>
private const int MaxTLevel = 16;
/// <summary>
/// Contextual variable
/// </summary>
private bool isInTitle;
private int currentOutline;
private bool[] levelIsList;
private bool[] previousIsList;
/// <summary>
/// Current output when generating
/// </summary>
private StringBuilder output;
/// <summary>
/// Do contextual initialization for visitor
/// </summary>
/// <param name="visitor">visitor to initialize</param>
private void InitVisitor(XMLVisitor visitor)
{
// Register templates
visitor.Register("Page", VisitPage);
visitor.Register("/Page", VisitSPage);
visitor.Register("Title", VisitTitle);
visitor.Register("Outline", VisitOutline);
visitor.Register("/Outline", VisitSOutline);
visitor.Register("T", VisitT);
visitor.Register("Bullet", VisitBullet);
visitor.Register("Number", VisitBullet);
visitor.Register("Table", VisitTable);
visitor.Register("/Table", VisitSTable);
visitor.Register("Row", VisitRow);
visitor.Register("/Row", VisitSRow);
visitor.Register("Cell", VisitCell);
visitor.Register("/Cell", VisitSCell);
visitor.RegisterDefault(VisitButIgnore);
// Init context
currentOutline = 0;
isInTitle = false;
levelIsList = new bool[MaxTLevel];
previousIsList = new bool[MaxTLevel];
for (int i = 0; i < MaxTLevel; i++)
{
levelIsList[i] = false;
previousIsList[i] = false;
}
}
/// <summary>
/// Visitor for Page tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitPage(XElement elem)
{
OutputLine("<html>");
}
/// <summary>
/// Visitor for /Page tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitSPage(XElement elem)
{
// Close page
OutputLine("</body>");
OutputLine("</html>");
}
/// <summary>
/// Visitor for Title tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitTitle(XElement elem)
{
isInTitle = true;
}
/// <summary>
/// Visitor for Outline tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitOutline(XElement elem)
{
// Not in title
isInTitle = false;
currentOutline++;
// Process begining tag
if (currentOutline == 1)
OutputLine("<body>");
OutputLine(String.Format("<div title='{0}'>", HttpUtility.HtmlEncode(Name))); // HACK: use Title attribute to force iPhone page title
}
/// <summary>
/// Visitor for /Outline tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitSOutline(XElement elem)
{
// Process ending tag
ComputeListLevel(elem.Ancestors().Count());
OutputLine("</div>");
}
/// <summary>
/// Visitor for T tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitT(XElement elem)
{
// Get value
string value = elem.Value;
// If in title, just generate title
if (isInTitle)
{
Output("<head><title>");
Output(value);
Output("</title></head>");
return;
}
// Paragraph or line ?
int level = elem.Ancestors().Count();
string tag = "p";
if (ComputeListLevel(level))
tag = "li";
// Indent
Indent(level);
// Empty line
if (value.Length == 0)
{
OutputLine("<br>");
return;
}
// Generate text
Output('<'); Output(tag); Output('>');
Output(value);
Output("</"); Output(tag); Output('>');
OutputLine();
}
/// <summary>
/// Compute tag for list level.
/// </summary>
/// <param name="level">current level</param>
/// <returns>true if the current level is in a list</returns>
private bool ComputeListLevel(int level)
{
// Close all the pending tag
for (int i = level+1; i < MaxTLevel; i++)
{
if (previousIsList[i])
{
Indent(i);
OutputLine("</ul>");
}
previousIsList[i] = false;
}
// Need to process the current as a list
bool currentIsList = levelIsList[level];
if (currentIsList)
{
if (!previousIsList[level])
{
Indent(level);
OutputLine("<ul>");
}
levelIsList[level] = false;
previousIsList[level] = true;
return true;
}
// Close the tag for previous level
if (!currentIsList && previousIsList[level])
{
Indent(level);
OutputLine("</ul>");
}
previousIsList[level] = false;
return false;
}
/// <summary>
/// Visitor for Bullet tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitBullet(XElement elem)
{
int level = elem.Ancestors().Count();
levelIsList[level - 1] = true;
}
/// <summary>
/// Visitor for Table tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitTable(XElement elem)
{
OutputLine("<table border='1'>");
}
/// <summary>
/// Visitor for /Table tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitSTable(XElement elem)
{
OutputLine("</table>");
}
/// <summary>
/// Visitor for Row tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitRow(XElement elem)
{
OutputLine("<tr>");
}
/// <summary>
/// Visitor for /Row tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitSRow(XElement elem)
{
OutputLine("</tr>");
}
/// <summary>
/// Visitor for Cell tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitCell(XElement elem)
{
OutputLine("<td>");
}
/// <summary>
/// Visitor for /Cell tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitSCell(XElement elem)
{
OutputLine("</td>");
}
/// <summary>
/// Visitor for all unknown tag.
/// </summary>
/// <param name="elem">element to process</param>
private void VisitButIgnore(XElement elem)
{
// Do nothing
}
#region Formating function
/// <summary>
/// Append text to output buffer.
/// </summary>
/// <param name="text">value to append</param>
private void Output(string text)
{
output.Append(text);
}
/// <summary>
/// Append character to output buffer.
/// </summary>
/// <param name="text">value to append</param>
private void Output(char character)
{
output.Append(character);
}
/// <summary>
/// Append newline to output buffer.
/// </summary>
private void OutputLine()
{
if (CurrentOptions.FormatLine)
output.AppendLine();
}
/// <summary>
/// Append text and newline to output buffer.
/// </summary>
/// <param name="text">value to append</param>
private void OutputLine(string text)
{
if (CurrentOptions.FormatLine)
output.AppendLine(text);
else
output.Append(text);
}
/// <summary>
/// Append an indent to output buffer.
/// </summary>
/// <param name="level">level to indent</param>
private void Indent(int level)
{
if (CurrentOptions.FormatLine)
output.Append(' ', level * 4);
}
#endregion
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Lionel is a software architect at
C2S, a software company based in France and subsidiary of the Bouygues group.
Lionel is also the author of
Liogo, an open-source Logo compiler for .NET.
Lionel is a contributor of
DotNetGuru and
Dr.Dobb's Journal.
Lionel is President and co-founder of
OLPC France.