using System; using System.Collections.Generic; using System.Linq; using System.Text; using ScrewTurn.Wiki.PluginFramework; using System.Text.RegularExpressions; namespace ScrewTurn.Wiki.Plugins.PluginPack { /// /// Implements a footnotes plugin. /// public class Footnotes : IFormatterProviderV30 { // Kindly contributed by Jens Felsner private static readonly ComponentInformation info = new ComponentInformation("Footnotes Plugin", "Threeplicate Srl", "3.0.1.471", "http://www.screwturn.eu", "http://www.screwturn.eu/Version/PluginPack/RssFeedDisplay.txt"); private static readonly Regex ReferencesRegex = new Regex("(<[ ]*references[ ]*/[ ]*>|<[ ]*references[ ]*>.*?<[ ]*/[ ]*references[ ]*>)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex RefRegex = new Regex("<[ ]*ref[ ]*>.*?<[ ]*/[ ]*ref[ ]*>", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex RefRemovalRegex = new Regex("(<[ ]*ref[ ]*>|<[ ]*/[ ]*ref[ ]*>)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private IHostV30 host = null; private string config = ""; /// /// Initializes the Storage Provider. /// /// The Host of the Component. /// The Configuration data, if any. /// If or are null. /// If is not valid or is incorrect. public void Init(IHostV30 host, string config) { this.host = host; this.config = config != null ? config : ""; } // Replaces the first occurence of 'find' in 'input' with 'replace' private static string ReplaceFirst(string input, string find, string replace) { return input.Substring(0, input.IndexOf(find)) + replace + input.Substring(input.IndexOf(find) + find.Length); } /// /// Performs a Formatting phase. /// /// The raw content to Format. /// The Context information. /// The Phase. /// The Formatted content. public string Format(string raw, ContextInformation context, FormattingPhase phase) { // Match all * MatchCollection mc = RefRegex.Matches(raw); // No ref-tag found, nothing to do if(mc.Count == 0) return raw; // No references tag if(ReferencesRegex.Matches(raw).Count == 0) { return raw + "
Reference Error! Missing element <references/>"; } string output = raw; string ref_string = ""; int footnoteCounter = 0; // For each ... replace it with Footnote, append it to ref-section foreach(Match m in mc) { footnoteCounter++; output = ReplaceFirst(output, m.Value, "" + footnoteCounter.ToString() + ""); ref_string += ""; } ref_string += "
" + footnoteCounter.ToString() + "" + RefRemovalRegex.Replace(m.Value, "") + "
"; // Replace with ref-section output = ReferencesRegex.Replace(output, ref_string); return output; } #region IFormatterProviderV30 Member /// /// Specifies whether or not to execute Phase 1. /// public bool PerformPhase1 { get { return false; } } /// /// Specifies whether or not to execute Phase 2. /// public bool PerformPhase2 { get { return true; } } /// /// Specifies whether or not to execute Phase 3. /// public bool PerformPhase3 { get { return false; } } /// /// Gets the execution priority of the provider (0 lowest, 100 highest). /// public int ExecutionPriority { get { return 50; } } /// /// Prepares the title of an item for display (always during phase 3). /// /// The input title. /// The context information. /// The prepared title (no markup allowed). public string PrepareTitle(string title, ContextInformation context) { return title; } #endregion #region IProviderV30 Member /// /// Method invoked on shutdown. /// /// This method might not be invoked in some cases. public void Shutdown() { } /// /// Gets the Information about the Provider. /// public ComponentInformation Information { get { return info; } } /// /// Gets a brief summary of the configuration string format, in HTML. Returns null if no configuration is needed. /// public string ConfigHelpHtml { get { return null; } } #endregion } }