DocSpace-client/common/ASC.Textile/Blocks/PhraseBlockModifier.cs

97 lines
4.0 KiB
C#

#region License Statement
// Copyright (c) L.A.B.Soft. All rights reserved.
//
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license.
//
// You must not remove this notice, or any other, from this software.
#endregion
#region Using Statements
using System.Text.RegularExpressions;
#endregion
namespace Textile.Blocks
{
public abstract class PhraseBlockModifier : BlockModifier
{
protected PhraseBlockModifier()
{
}
protected string PhraseModifierFormat(string input, string modifier, string tag)
{
// All phrase modifiers are one character, or a double character. Sometimes,
// there's an additional escape character for the regex ('\').
var compressedModifier = modifier;
if (modifier.Length == 4)
{
compressedModifier = modifier.Substring(0, 2);
}
else if (modifier.Length == 2)
{
if (modifier[0] != '\\')
compressedModifier = modifier[0].ToString();
//else: compressedModifier = modifier;
}
//else: compressedModifier = modifier;
// We try to remove the Textile tag used for the formatting from
// the punctuation pattern, so that we match the end of the formatted
// zone correctly.
var punctuationPattern = Globals.PunctuationPattern.Replace(compressedModifier, "");
// Now we can do the replacement.
var pmme = new PhraseModifierMatchEvaluator(tag);
var res = Regex.Replace(input,
@"(?<=\s|" + punctuationPattern + @"|[{\(\[]|^)" +
modifier +
Globals.BlockModifiersPattern +
@"(:(?<cite>(\S+)))?" +
@"(?<content>[^" + compressedModifier + "]*)" +
@"(?<end>" + punctuationPattern + @"*)" +
modifier +
@"(?=[\]\)}]|" + punctuationPattern + @"+|\s|$)",
new MatchEvaluator(pmme.MatchEvaluator)
);
return res;
}
private class PhraseModifierMatchEvaluator
{
readonly string m_tag;
public PhraseModifierMatchEvaluator(string tag)
{
m_tag = tag;
}
public string MatchEvaluator(Match m)
{
if (m.Groups["content"].Length == 0)
{
// It's possible that the "atts" match groups eats the contents
// when the user didn't want to give block attributes, but the content
// happens to match the syntax. For example: "*(blah)*".
if (m.Groups["atts"].Length == 0)
return m.ToString();
return "<" + m_tag + ">" + m.Groups["atts"].Value + m.Groups["end"].Value + "</" + m_tag + ">";
}
var atts = BlockAttributesParser.ParseBlockAttributes(m.Groups["atts"].Value, m_tag);
if (m.Groups["cite"].Length > 0)
atts += " cite=\"" + m.Groups["cite"] + "\"";
var res = "<" + m_tag + atts + ">" +
m.Groups["content"].Value + m.Groups["end"].Value +
"</" + m_tag + ">";
return res;
}
}
}
}