HtmlTags.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:14k
源码类别:

Email服务器

开发平台:

Delphi

  1. unit HtmlTags;
  2. interface
  3. uses
  4.   Classes, DomCore;
  5. const
  6.   MAX_TAGS_COUNT  = 128;
  7.   MAX_FLAGS_COUNT = 32;
  8. type
  9.   THtmlTagSet = set of 0..MAX_TAGS_COUNT - 1;
  10.   THtmlTagFlags = set of 0..MAX_FLAGS_COUNT - 1;
  11.   THtmlTag = class
  12.   private
  13.     FName: TDomString;
  14.     FNumber: Integer;
  15.     FParserFlags: THtmlTagFlags;
  16.     FFormatterFlags: THtmlTagFlags;
  17.   public
  18.     constructor Create(const AName: TDomString; ANumber: Integer; AParserFlags, AFormatterFlags: THtmlTagFlags);
  19.     property Name: TDomString read FName;
  20.     property Number: Integer read FNumber;
  21.     property ParserFlags: THtmlTagFlags read FParserFlags;
  22.     property FormatterFlags: THtmlTagFlags read FFormatterFlags;
  23.   end;
  24.   TCompareTag = function(Tag: THtmlTag): Integer of object;
  25.   THtmlTagList = class
  26.   private
  27.     FList: TList;
  28.     FUnknownTag: THtmlTag;
  29.     FSearchName: WideString;
  30.     FSearchNumber: Integer;
  31.     function CompareName(Tag: THtmlTag): Integer;
  32.     function CompareNumber(Tag: THtmlTag): Integer;
  33.     function GetTag(Compare: TCompareTag): THtmlTag;
  34.   public
  35.     constructor Create;
  36.     destructor Destroy; override;
  37.     function GetTagByName(const Name: TDomString): THtmlTag;
  38.     function GetTagByNumber(Number: Integer): THtmlTag;
  39.   end;
  40.   TURLSchemes = class(TStringList)
  41.   private
  42.     FMaxLen: Integer;
  43.   public
  44.     function Add(const S: String): Integer; override;
  45.     function IsURL(const S: String): Boolean;
  46.     function GetScheme(const S: String): String;
  47.     property MaxLen: Integer read FMaxLen;
  48.   end;
  49. var
  50.   HtmlTagList: THtmlTagList;
  51.   URLSchemes: TURLSchemes;
  52. const
  53.   UNKNOWN_TAG    = 0;
  54.   A_TAG          = 1;
  55.   ABBR_TAG       = 2;
  56.   ACRONYM_TAG    = 3;
  57.   ADDRESS_TAG    = 4;
  58.   APPLET_TAG     = 5;
  59.   AREA_TAG       = 6;
  60.   B_TAG          = 7;
  61.   BASE_TAG       = 8;
  62.   BASEFONT_TAG   = 9;
  63.   BDO_TAG        = 10;
  64.   BIG_TAG        = 11;
  65.   BLOCKQUOTE_TAG = 12;
  66.   BODY_TAG       = 13;
  67.   BR_TAG         = 14;
  68.   BUTTON_TAG     = 15;
  69.   CAPTION_TAG    = 16;
  70.   CENTER_TAG     = 17;
  71.   CITE_TAG       = 18;
  72.   CODE_TAG       = 19;
  73.   COL_TAG        = 20;
  74.   COLGROUP_TAG   = 21;
  75.   DD_TAG         = 22;
  76.   DEL_TAG        = 23;
  77.   DFN_TAG        = 24;
  78.   DIR_TAG        = 25;
  79.   DIV_TAG        = 26;
  80.   DL_TAG         = 27;
  81.   DT_TAG         = 28;
  82.   EM_TAG         = 29;
  83.   FIELDSET_TAG   = 30;
  84.   FONT_TAG       = 31;
  85.   FORM_TAG       = 32;
  86.   FRAME_TAG      = 33;
  87.   FRAMESET_TAG   = 34;
  88.   H1_TAG         = 35;
  89.   H2_TAG         = 36;
  90.   H3_TAG         = 37;
  91.   H4_TAG         = 38;
  92.   H5_TAG         = 39;
  93.   H6_TAG         = 40;
  94.   HEAD_TAG       = 41;
  95.   HR_TAG         = 42;
  96.   HTML_TAG       = 43;
  97.   I_TAG          = 44;
  98.   IFRAME_TAG     = 45;
  99.   IMG_TAG        = 46;
  100.   INPUT_TAG      = 47;
  101.   INS_TAG        = 48;
  102.   ISINDEX_TAG    = 49;
  103.   KBD_TAG        = 50;
  104.   LABEL_TAG      = 51;
  105.   LEGEND_TAG     = 52;
  106.   LI_TAG         = 53;
  107.   LINK_TAG       = 54;
  108.   MAP_TAG        = 55;
  109.   MENU_TAG       = 56;
  110.   META_TAG       = 57;
  111.   NOFRAMES_TAG   = 58;
  112.   NOSCRIPT_TAG   = 59;
  113.   OBJECT_TAG     = 60;
  114.   OL_TAG         = 61;
  115.   OPTGROUP_TAG   = 62;
  116.   OPTION_TAG     = 63;
  117.   P_TAG          = 64;
  118.   PARAM_TAG      = 65;
  119.   PRE_TAG        = 66;
  120.   Q_TAG          = 67;
  121.   S_TAG          = 68;
  122.   SAMP_TAG       = 69;
  123.   SCRIPT_TAG     = 70;
  124.   SELECT_TAG     = 71;
  125.   SMALL_TAG      = 72;
  126.   SPAN_TAG       = 73;
  127.   STRIKE_TAG     = 74;
  128.   STRONG_TAG     = 75;
  129.   STYLE_TAG      = 76;
  130.   SUB_TAG        = 77;
  131.   SUP_TAG        = 78;
  132.   TABLE_TAG      = 79;
  133.   TBODY_TAG      = 80;
  134.   TD_TAG         = 81;
  135.   TEXTAREA_TAG   = 82;
  136.   TFOOT_TAG      = 83;
  137.   TH_TAG         = 84;
  138.   THEAD_TAG      = 85;
  139.   TITLE_TAG      = 86;
  140.   TR_TAG         = 87;
  141.   TT_TAG         = 88;
  142.   U_TAG          = 89;
  143.   UL_TAG         = 90;
  144.   VAR_TAG        = 91;
  145.   BlockTags               = [ADDRESS_TAG, BLOCKQUOTE_TAG, CENTER_TAG, DIV_TAG, DL_TAG, FIELDSET_TAG, {FORM_TAG,} H1_TAG, H2_TAG, H3_TAG, H4_TAG, H5_TAG, H6_TAG, HR_TAG, NOSCRIPT_TAG, OL_TAG, PRE_TAG, TABLE_TAG, UL_TAG];
  146.   BlockParentTags         = [ADDRESS_TAG, BLOCKQUOTE_TAG, CENTER_TAG, DIV_TAG, DL_TAG, FIELDSET_TAG, H1_TAG, H2_TAG, H3_TAG, H4_TAG, H5_TAG, H6_TAG, HR_TAG, LI_TAG, NOSCRIPT_TAG, OL_TAG, PRE_TAG, TD_TAG, TH_TAG, UL_TAG];
  147.   HeadTags                = [BASE_TAG, LINK_TAG, META_TAG, SCRIPT_TAG, STYLE_TAG, TITLE_TAG];
  148.   {Elements forbidden from having an end tag, and therefore are empty; from HTML 4.01 spec}
  149.   EmptyTags               = [AREA_TAG, BASE_TAG, BASEFONT_TAG, BR_TAG, COL_TAG, FRAME_TAG, HR_TAG, IMG_TAG, INPUT_TAG, ISINDEX_TAG, LINK_TAG, META_TAG, PARAM_TAG];
  150.   PreserveWhiteSpaceTags  = [PRE_TAG];
  151.   NeedFindParentTags      = [COL_TAG, COLGROUP_TAG, DD_TAG, DT_TAG, LI_TAG, OPTION_TAG, P_TAG, TABLE_TAG, TBODY_TAG, TD_TAG, TFOOT_TAG, TH_TAG, THEAD_TAG, TR_TAG];
  152.   ListItemParentTags      = [DIR_TAG, MENU_TAG, OL_TAG, UL_TAG];
  153.   DefItemParentTags       = [DL_TAG];
  154.   TableSectionParentTags  = [TABLE_TAG];
  155.   ColParentTags           = [COLGROUP_TAG];
  156.   RowParentTags           = [TABLE_TAG, TBODY_TAG, TFOOT_TAG, THEAD_TAG];
  157.   CellParentTags          = [TR_TAG];
  158.   OptionParentTags        = [OPTGROUP_TAG, SELECT_TAG];
  159. implementation
  160. uses
  161.   SysUtils;
  162. constructor THtmlTag.Create(const AName: TDomString; ANumber: Integer; AParserFlags, AFormatterFlags: THtmlTagFlags);
  163. begin
  164.   inherited Create;
  165.   FName := AName;
  166.   FNumber := ANumber
  167. end;
  168. constructor THtmlTagList.Create;
  169. begin
  170.   inherited Create;
  171.   FList := TList.Create;
  172.   FList.Capacity := MAX_TAGS_COUNT;
  173.   FList.Add(THtmlTag.Create('a',          A_TAG,          [], []));
  174.   FList.Add(THtmlTag.Create('abbr',       ABBR_TAG,       [], []));
  175.   FList.Add(THtmlTag.Create('acronym',    ACRONYM_TAG,    [], []));
  176.   FList.Add(THtmlTag.Create('address',    ADDRESS_TAG,    [], []));
  177.   FList.Add(THtmlTag.Create('applet',     APPLET_TAG,     [], []));
  178.   FList.Add(THtmlTag.Create('area',       AREA_TAG,       [], []));
  179.   FList.Add(THtmlTag.Create('b',          B_TAG,          [], []));
  180.   FList.Add(THtmlTag.Create('base',       BASE_TAG,       [], []));
  181.   FList.Add(THtmlTag.Create('basefont',   BASEFONT_TAG,   [], []));
  182.   FList.Add(THtmlTag.Create('bdo',        BDO_TAG,        [], []));
  183.   FList.Add(THtmlTag.Create('big',        BIG_TAG,        [], []));
  184.   FList.Add(THtmlTag.Create('blockquote', BLOCKQUOTE_TAG, [], []));
  185.   FList.Add(THtmlTag.Create('body',       BODY_TAG,       [], []));
  186.   FList.Add(THtmlTag.Create('br',         BR_TAG,         [], []));
  187.   FList.Add(THtmlTag.Create('button',     BUTTON_TAG,     [], []));
  188.   FList.Add(THtmlTag.Create('caption',    CAPTION_TAG,    [], []));
  189.   FList.Add(THtmlTag.Create('center',     CENTER_TAG,     [], []));
  190.   FList.Add(THtmlTag.Create('cite',       CITE_TAG,       [], []));
  191.   FList.Add(THtmlTag.Create('code',       CODE_TAG,       [], []));
  192.   FList.Add(THtmlTag.Create('col',        COL_TAG,        [], []));
  193.   FList.Add(THtmlTag.Create('colgroup',   COLGROUP_TAG,   [], []));
  194.   FList.Add(THtmlTag.Create('dd',         DD_TAG,         [], []));
  195.   FList.Add(THtmlTag.Create('del',        DEL_TAG,        [], []));
  196.   FList.Add(THtmlTag.Create('dfn',        DFN_TAG,        [], []));
  197.   FList.Add(THtmlTag.Create('dir',        DIR_TAG,        [], []));
  198.   FList.Add(THtmlTag.Create('div',        DIV_TAG,        [], []));
  199.   FList.Add(THtmlTag.Create('dl',         DL_TAG,         [], []));
  200.   FList.Add(THtmlTag.Create('dt',         DT_TAG,         [], []));
  201.   FList.Add(THtmlTag.Create('em',         EM_TAG,         [], []));
  202.   FList.Add(THtmlTag.Create('fieldset',   FIELDSET_TAG,   [], []));
  203.   FList.Add(THtmlTag.Create('font',       FONT_TAG,       [], []));
  204.   FList.Add(THtmlTag.Create('form',       FORM_TAG,       [], []));
  205.   FList.Add(THtmlTag.Create('frame',      FRAME_TAG,      [], []));
  206.   FList.Add(THtmlTag.Create('frameset',   FRAMESET_TAG,   [], []));
  207.   FList.Add(THtmlTag.Create('h1',         H1_TAG,         [], []));
  208.   FList.Add(THtmlTag.Create('h2',         H2_TAG,         [], []));
  209.   FList.Add(THtmlTag.Create('h3',         H3_TAG,         [], []));
  210.   FList.Add(THtmlTag.Create('h4',         H4_TAG,         [], []));
  211.   FList.Add(THtmlTag.Create('h5',         H5_TAG,         [], []));
  212.   FList.Add(THtmlTag.Create('h6',         H6_TAG,         [], []));
  213.   FList.Add(THtmlTag.Create('head',       HEAD_TAG,       [], []));
  214.   FList.Add(THtmlTag.Create('hr',         HR_TAG,         [], []));
  215.   FList.Add(THtmlTag.Create('html',       HTML_TAG,       [], []));
  216.   FList.Add(THtmlTag.Create('i',          I_TAG,          [], []));
  217.   FList.Add(THtmlTag.Create('iframe',     IFRAME_TAG,     [], []));
  218.   FList.Add(THtmlTag.Create('img',        IMG_TAG,        [], []));
  219.   FList.Add(THtmlTag.Create('input',      INPUT_TAG,      [], []));
  220.   FList.Add(THtmlTag.Create('ins',        INS_TAG,        [], []));
  221.   FList.Add(THtmlTag.Create('isindex',    ISINDEX_TAG,    [], []));
  222.   FList.Add(THtmlTag.Create('kbd',        KBD_TAG,        [], []));
  223.   FList.Add(THtmlTag.Create('label',      LABEL_TAG,      [], []));
  224.   FList.Add(THtmlTag.Create('legend',     LEGEND_TAG,     [], []));
  225.   FList.Add(THtmlTag.Create('li',         LI_TAG,         [], []));
  226.   FList.Add(THtmlTag.Create('link',       LINK_TAG,       [], []));
  227.   FList.Add(THtmlTag.Create('map',        MAP_TAG,        [], []));
  228.   FList.Add(THtmlTag.Create('menu',       MENU_TAG,       [], []));
  229.   FList.Add(THtmlTag.Create('meta',       META_TAG,       [], []));
  230.   FList.Add(THtmlTag.Create('noframes',   NOFRAMES_TAG,   [], []));
  231.   FList.Add(THtmlTag.Create('noscript',   NOSCRIPT_TAG,   [], []));
  232.   FList.Add(THtmlTag.Create('object',     OBJECT_TAG,     [], []));
  233.   FList.Add(THtmlTag.Create('ol',         OL_TAG,         [], []));
  234.   FList.Add(THtmlTag.Create('optgroup',   OPTGROUP_TAG,   [], []));
  235.   FList.Add(THtmlTag.Create('option',     OPTION_TAG,     [], []));
  236.   FList.Add(THtmlTag.Create('p',          P_TAG,          [], []));
  237.   FList.Add(THtmlTag.Create('param',      PARAM_TAG,      [], []));
  238.   FList.Add(THtmlTag.Create('pre',        PRE_TAG,        [], []));
  239.   FList.Add(THtmlTag.Create('q',          Q_TAG,          [], []));
  240.   FList.Add(THtmlTag.Create('s',          S_TAG,          [], []));
  241.   FList.Add(THtmlTag.Create('samp',       SAMP_TAG,       [], []));
  242.   FList.Add(THtmlTag.Create('script',     SCRIPT_TAG,     [], []));
  243.   FList.Add(THtmlTag.Create('select',     SELECT_TAG,     [], []));
  244.   FList.Add(THtmlTag.Create('small',      SMALL_TAG,      [], []));
  245.   FList.Add(THtmlTag.Create('span',       SPAN_TAG,       [], []));
  246.   FList.Add(THtmlTag.Create('strike',     STRIKE_TAG,     [], []));
  247.   FList.Add(THtmlTag.Create('strong',     STRONG_TAG,     [], []));
  248.   FList.Add(THtmlTag.Create('style',      STYLE_TAG,      [], []));
  249.   FList.Add(THtmlTag.Create('sub',        SUB_TAG,        [], []));
  250.   FList.Add(THtmlTag.Create('sup',        SUP_TAG,        [], []));
  251.   FList.Add(THtmlTag.Create('table',      TABLE_TAG,      [], []));
  252.   FList.Add(THtmlTag.Create('tbody',      TBODY_TAG,      [], []));
  253.   FList.Add(THtmlTag.Create('td',         TD_TAG,         [], []));
  254.   FList.Add(THtmlTag.Create('textarea',   TEXTAREA_TAG,   [], []));
  255.   FList.Add(THtmlTag.Create('tfoot',      TFOOT_TAG,      [], []));
  256.   FList.Add(THtmlTag.Create('th',         TH_TAG,         [], []));
  257.   FList.Add(THtmlTag.Create('thead',      THEAD_TAG,      [], []));
  258.   FList.Add(THtmlTag.Create('title',      TITLE_TAG,      [], []));
  259.   FList.Add(THtmlTag.Create('tr',         TR_TAG,         [], []));
  260.   FList.Add(THtmlTag.Create('tt',         TT_TAG,         [], []));
  261.   FList.Add(THtmlTag.Create('u',          U_TAG,          [], []));
  262.   FList.Add(THtmlTag.Create('ul',         UL_TAG,         [], []));
  263.   FList.Add(THtmlTag.Create('var',        VAR_TAG,        [], []));
  264.   FUnknownTag := THtmlTag.Create('', UNKNOWN_TAG, [], [])
  265. end;
  266. destructor THtmlTagList.Destroy;
  267. var
  268.   I: Integer;
  269. begin
  270.   for I := FList.Count - 1 downto 0 do
  271.     THtmlTag(FList[I]).Free;
  272.   FList.Free;
  273.   FUnknownTag.Free;
  274.   inherited Destroy
  275. end;
  276. function THtmlTagList.GetTag(Compare: TCompareTag): THtmlTag;
  277. var
  278.   I, Low, High, Rel: Integer;
  279. begin
  280.   Low := -1;
  281.   High := FList.Count - 1;
  282.   while High - Low > 1 do
  283.   begin
  284.     I := (High + Low) div 2;
  285.     Result := FList[I];
  286.     Rel := Compare(Result);
  287.     if Rel < 0 then
  288.       High := I
  289.     else
  290.     if Rel > 0 then
  291.       Low := I
  292.     else
  293.       Exit
  294.   end;
  295.   if High >= 0 then
  296.   begin
  297.     Result := FList[High];
  298.     if Compare(Result) = 0 then
  299.       Exit
  300.   end;
  301.   Result := nil
  302. end;
  303. function THtmlTagList.CompareName(Tag: THtmlTag): Integer;
  304. begin
  305.   Result := CompareStr(FSearchName, Tag.Name)
  306. end;
  307. function THtmlTagList.CompareNumber(Tag: THtmlTag): Integer;
  308. begin
  309.   Result := FSearchNumber - Tag.Number
  310. end;
  311. function THtmlTagList.GetTagByName(const Name: TDomString): THtmlTag;
  312. begin
  313.   FSearchName := Name;
  314.   Result := GetTag(CompareName);
  315.   if Result = nil then
  316.     Result := FUnknownTag
  317. end;
  318. function THtmlTagList.GetTagByNumber(Number: Integer): THtmlTag;
  319. begin
  320.   FSearchNumber := Number;
  321.   Result := GetTag(CompareNumber)
  322. end;
  323. function TURLSchemes.Add(const S: String): Integer;
  324. begin
  325.   if Length(S) > FMaxLen then
  326.     FMaxLen := Length(S);
  327.   Result := inherited Add(S)
  328. end;
  329. function TURLSchemes.IsURL(const S: String): Boolean;
  330. begin
  331.   Result := IndexOf(LowerCase(S)) >= 0
  332. end;
  333. function TURLSchemes.GetScheme(const S: String): String;
  334. const
  335.   SchemeChars = [Ord('A')..Ord('Z'), Ord('a')..Ord('z')];
  336. var
  337.   I: Integer;
  338. begin
  339.   Result := '';
  340.   for I := 1 to MaxLen + 1 do
  341.   begin
  342.     if I > Length(S) then
  343.       Exit;
  344.     if S[I] = ':' then
  345.     begin
  346.       if IsURL(Copy(S, 1, I - 1)) then
  347.         Result := Copy(S, 1, I - 1);
  348.       Exit
  349.     end
  350.   end
  351. end;
  352. initialization
  353.   HtmlTagList := THtmlTagList.Create;
  354.   URLSchemes := TURLSchemes.Create;
  355.   URLSchemes.Add('http');
  356.   URLSchemes.Add('https');
  357.   URLSchemes.Add('ftp');
  358.   URLSchemes.Add('mailto');
  359.   URLSchemes.Add('news');
  360.   URLSchemes.Add('nntp');
  361.   URLSchemes.Add('gopher');
  362. finalization
  363.   HtmlTagList.Free;
  364.   URLSchemes.Free
  365. end.