Oberon/A2/Oberon.HTMLDocs.Mod
(* ETH Oberon,版权所有 2001 ETH Zuerich Institut fuer Computersysteme,ETH Zentrum,CH-8092 Zuerich。
请参阅“通用 ETH Oberon 系统源代码许可证”合同,可从以下地址获取:http://www.oberon.ethz.ch/ *)
MODULE HTMLDocs IN Oberon; (** 可移植 *) (* ejz,希腊语和数学支持由 afi 提供 *)
(* 检查 ISOToOberon 的索引是否超过 255。ple,2005-05-08。 *)
- IMPORT Objects, Input, Strings, Display, Display3, Fonts, HyperDocs, Texts, Gadgets, Documents, HTTPDocs0, TextDocs,
- Oberon, TextGadgets, Lists, Attributes, Desktops, Links, Streams, TextStreams;
- Oberon, TextGadgets, Lists, Attributes, Desktops, Links, Streams, TextStreams;
- CONST
- (* 类 *)
- WhiteSpace* = 0; OpenTag* = 1; OpenEndTag* = 2; CloseTag* = 3; CharRef* = 4; Character* = 5; Value* = 6; Undef* = 7;
- (* 状态 *)
- TextPlain* = 1; TextHtml* = 2; InTag* = 3; End* = 4;
- (* 列表类型 *)
- DefList = 0; DescList = 1; OrderedList = 2;
- Menu = "Desktops.Copy[复制] HyperDocs.Back[后退] HyperDocs.Reload[重新加载] TextDocs.Search[搜索] Desktops.StoreDoc[存储]";
- GreekCap = "0013143516173415192134222324252728202931323337372636180000000000";
- GreekMin = "004546674849664751536654555657596052616364656969586850";
- (* 类 *)
- ASCIIBullets = TRUE;
- ASCIIBullets = TRUE;
- TYPE
- Integer = LONGINT;
- DocURL* = POINTER TO DocURLDesc;
- DocURLDesc* = RECORD (HyperDocs.DefURLDesc)
- dockey*: LONGINT
- dockey*: LONGINT
- END;
- TextAttrs = POINTER TO TextAttrsDesc;
- TextAttrsDesc = RECORD
- lib: Objects.Library;
- style: TextGadgets.Style;
- col, voff: SHORTINT;
- next: TextAttrs
- lib: Objects.Library;
- END;
- Page* = POINTER TO PageDesc;
- Scanner* = RECORD
- page*: Page;
- S*: Streams.Stream;
- class*, state*: INTEGER;
- value*: ARRAY 1024 OF CHAR;
- pre*, end*: BOOLEAN;
- ch*, next*, char*: CHAR;
- avail: LONGINT
- page*: Page;
- END;
- List = POINTER TO ListDesc;
- ListDesc = RECORD
- style: TextGadgets.Style;
- kind, nesting, itemNr: INTEGER;
- dtok: BOOLEAN;
- next: List
- style: TextGadgets.Style;
- END;
- Form* = POINTER TO FormDesc;
- FormDesc* = RECORD (TextGadgets.ControlDesc)
- elems*: HTTPDocs0.ObjList
- elems*: HTTPDocs0.ObjList
- END;
- PageDesc* = RECORD (Gadgets.ObjDesc)
- W*, Ws*: Texts.Writer;
- textAttrs: TextAttrs;
- T*, source*: Texts.Text;
- D*: Documents.Document;
- alink*, clink: Objects.Object;
- style: TextGadgets.Style;
- base*: DocURL;
- orgLabel: ARRAY 64 OF CHAR;
- lists: List;
- orgPos, linkkey*, headerLen, docKey*: LONGINT;
- next*: Page;
- task: Oberon.Task;
- textC*, linkC*, oldLinkC*, textbackC*, lines*: INTEGER;
- left*, blank*, head, cacheSource*: BOOLEAN
- W*, Ws*: Texts.Writer;
- END;
- Item* = POINTER TO ItemDesc;
- ItemDesc* = RECORD (Lists.ItemDesc)
- value*: ARRAY 64 OF CHAR;
- oldSel*, hasVal*: BOOLEAN
- value*: ARRAY 64 OF CHAR;
- END;
- TagHandler* = PROCEDURE (VAR S: Scanner; on: BOOLEAN);
- ExtTag* = POINTER TO ExtTagDesc;
- ExtTagDesc* = RECORD
- tag: ARRAY 32 OF CHAR;
- handle*: TagHandler;
- start*, stop*: PROCEDURE (P: Page);
- next: ExtTag
- tag: ARRAY 32 OF CHAR;
- END;
- TagAttr* = POINTER TO TagAttrDesc;
- TagAttrDesc* = RECORD
- name: ARRAY 64 OF CHAR;
- value*: ARRAY 512 OF CHAR;
- next: TagAttr
- name: ARRAY 64 OF CHAR;
- END;
- Task = POINTER TO TaskDesc;
- TaskDesc = RECORD (Oberon.TaskDesc)
- S: Scanner;
- P: Page
- S: Scanner;
- END;
- Integer = LONGINT;
- VAR
- bullets: ARRAY 2 OF RECORD
- f: Fonts.Font;
- c: CHAR
- f: Fonts.Font;
- END;
- Wr*, Wq: Texts.Writer;
- imgs*: BOOLEAN;
- extTags, newTag*: ExtTag;
- entities*: ARRAY 69, 7 OF CHAR;
- entityEncoding*: ARRAY 69 OF CHAR;
- pages*: Page;
- searchAttr: ARRAY 32 OF CHAR;
- mono: Fonts.Font;
- found: BOOLEAN;
- dispW: INTEGER;
- GreekTab: ARRAY 128 OF CHAR;
- bullets: ARRAY 2 OF RECORD
- PROCEDURE WriteLn*(P: Page);
- BEGIN
- INC(P.lines);
- IF P.lines < 3 THEN
- Texts.WriteLn(P.W); P.blank := FALSE
- Texts.WriteLn(P.W); P.blank := FALSE
- END
- INC(P.lines);
- END WriteLn;
- PROCEDURE WriteSpace*(P: Page);
- BEGIN
- IF P.blank THEN
- Texts.Write(P.W, " "); P.blank := FALSE
- Texts.Write(P.W, " "); P.blank := FALSE
- END
- IF P.blank THEN
- END WriteSpace;
- PROCEDURE WriteObj*(P: Page; obj: Objects.Object);
- BEGIN
- Texts.WriteObj(P.W, obj);
- IF (obj IS Display.Frame) & (obj(Display.Frame).W >= (HyperDocs.docW-16)) THEN
- INC(P.lines); P.blank := FALSE
- INC(P.lines); P.blank := FALSE
- ELSIF obj IS TextGadgets.Style THEN
- P.blank := FALSE
- P.blank := FALSE
- ELSIF ~(obj IS TextGadgets.Control) THEN
- P.lines := 0; P.blank := TRUE
- P.lines := 0; P.blank := TRUE
- END
- Texts.WriteObj(P.W, obj);
- END WriteObj;
- PROCEDURE InitTabs(style: TextGadgets.Style);
- VAR i: LONGINT;
- VAR i: LONGINT;
- BEGIN
- style.W := ((dispW DIV 8) * 5)-24; style.width := style.W;
- style.noTabs := 32;
- FOR i := 0 TO 31 DO
- style.tab[i] := SHORT(32+i*32)
- style.tab[i] := SHORT(32+i*32)
- END
- style.W := ((dispW DIV 8) * 5)-24; style.width := style.W;
- END InitTabs;
- PROCEDURE NewStyle(): TextGadgets.Style;
- VAR style: TextGadgets.Style;
- VAR style: TextGadgets.Style;
- BEGIN
- style := TextGadgets.newStyle();
- InitTabs(style);
- Attributes.SetBool(style, "FrameW", TRUE);
- RETURN style
- style := TextGadgets.newStyle();
- END NewStyle;
- PROCEDURE Syntax(size: INTEGER; attr: CHAR): Fonts.Font;
- VAR
- name: ARRAY 32 OF CHAR;
- sizeS: ARRAY 4 OF CHAR;
- name: ARRAY 32 OF CHAR;
- VAR
- BEGIN
- name := "Default";
- IF dispW < 800 THEN DEC(size, 2) END;
- IF size <= 8 THEN size := 8
- ELSIF size <= 10 THEN size := 10
- ELSIF size <= 12 THEN size := 12
- ELSIF size <= 14 THEN size := 14
- ELSIF size <= 16 THEN size := 16
- ELSIF size <= 20 THEN size := 20
- ELSE size := 24
- END;
- Strings.IntToStr(size, sizeS);
- IF attr = 0X THEN (* 跳过 *)
- ELSIF attr = "i" THEN (* 跳过 *)
- ELSIF attr = "m" THEN attr := "b"
- ELSIF attr = "b" THEN (* 跳过 *)
- ELSE attr := 0X
- END;
- Strings.Append(name, sizeS); Strings.AppendCh(name, attr); Strings.Append(name, ".Scn.Fnt");
- RETURN Fonts.This(name)
- name := "Default";
- END Syntax;
- PROCEDURE PushTextAttrs*(P: Page);
- VAR attr: TextAttrs;
- VAR attr: TextAttrs;
- BEGIN
- NEW(attr);
- attr.lib := P.W.lib; attr.col := P.W.col; attr.voff := P.W.voff;
- attr.style := P.style;
- attr.next := P.textAttrs; P.textAttrs := attr
- NEW(attr);
- END PushTextAttrs;
- PROCEDURE PopTextAttrs*(P: Page);
- VAR
- style: TextGadgets.Style;
- M: Objects.CopyMsg;
- style: TextGadgets.Style;
- VAR
- BEGIN
- IF P.textAttrs # NIL THEN
- Texts.SetFont(P.W, P.textAttrs.lib);
- Texts.SetColor(P.W, P.textAttrs.col);
- Texts.SetOffset(P.W, P.textAttrs.voff);
- style := P.textAttrs.style;
- IF (P.style.mode # style.mode) OR (P.style.leftM # style.leftM) OR (P.style.width # style.width) THEN
- M.id := Objects.shallow; Objects.Stamp(M); M.obj := NIL; M.dlink := NIL;
- style.handle(style, M); style := M.obj(TextGadgets.Style);
- P.style := style; WriteObj(P, style)
- M.id := Objects.shallow; Objects.Stamp(M); M.obj := NIL; M.dlink := NIL;
- END;
- P.textAttrs := P.textAttrs.next
- Texts.SetFont(P.W, P.textAttrs.lib);
- ELSE
- Texts.SetFont(P.W, Syntax(12, 0X));
- Texts.SetColor(P.W, SHORT(P.textC));
- Texts.SetOffset(P.W, 0);
- style := NewStyle();
- IF (P.style.mode # style.mode) OR (P.style.leftM # style.leftM) OR (P.style.width # style.width) THEN
- P.style := style; WriteObj(P, style)
- P.style := style; WriteObj(P, style)
- END
- Texts.SetFont(P.W, Syntax(12, 0X));
- END
- IF P.textAttrs # NIL THEN
- END PopTextAttrs;
- PROCEDURE SplitFontName(f: Fonts.Font; VAR family: ARRAY OF CHAR; VAR size: INTEGER; VAR attr: CHAR);
- VAR
- val: LONGINT;
- i: INTEGER;
- val: LONGINT;
- VAR
- BEGIN
- i := 0;
- WHILE (f.name[i] # 0X) & ~Strings.IsDigit(f.name[i]) DO
- INC(i)
- INC(i)
- END;
- COPY(f.name, family); family[i] := 0X;
- Strings.StrToIntPos(f.name, val, i); size := SHORT(val);
- IF Strings.IsAlpha(f.name[i]) THEN
- attr := f.name[i]
- attr := f.name[i]
- ELSE
- attr := 0X
- attr := 0X
- END
- i := 0;
- END SplitFontName;
- PROCEDURE FontSize(f: Fonts.Font; VAR size: INTEGER);
- VAR
- family: ARRAY 64 OF CHAR;
- attr: CHAR;
- family: ARRAY 64 OF CHAR;
- VAR
- BEGIN
- SplitFontName(f, family, size, attr)
- SplitFontName(f, family, size, attr)
- END FontSize;
- PROCEDURE GetFontSize*(P: Page): INTEGER;
- VAR size: INTEGER;
- VAR size: INTEGER;
- BEGIN
- FontSize(P.W.lib(Fonts.Font), size);
- IF dispW < 800 THEN
- INC(size, 2)
- INC(size, 2)
- END;
- IF size <= 8 THEN
- size := 1
- size := 1
- ELSIF size <= 10 THEN
- size := 2
- size := 2
- ELSIF size <= 12 THEN
- size := 3
- size := 3
- ELSIF size <= 14 THEN
- size := 4
- size := 4
- ELSIF size <= 16 THEN
- size := 5
- size := 5
- ELSIF size <= 20 THEN
- size := 6
- size := 6
- ELSE
- size := 7
- size := 7
- END;
- RETURN size
- FontSize(P.W.lib(Fonts.Font), size);
- END GetFontSize;
- PROCEDURE ChangeFontAttr(f: Fonts.Font; attr: CHAR): Fonts.Font;
- VAR
- family: ARRAY 64 OF CHAR;
- str: ARRAY 4 OF CHAR;
- size: INTEGER;
- oldattr: CHAR;
- family: ARRAY 64 OF CHAR;
- VAR
- BEGIN
- IF attr = "m" THEN attr := "b" END;
- SplitFontName(f, family, size, oldattr);
- IF oldattr # attr THEN
- Strings.IntToStr(size, str); Strings.Append(family, str);
- IF attr # 0X THEN
- Strings.AppendCh(family, attr)
- Strings.AppendCh(family, attr)
- END;
- Strings.Append(family, ".Scn.Fnt");
- RETURN Fonts.This(family)
- Strings.IntToStr(size, str); Strings.Append(family, str);
- ELSE
- RETURN f
- RETURN f
- END
- IF attr = "m" THEN attr := "b" END;
- END ChangeFontAttr;
- PROCEDURE ChangeFontSize(f: Fonts.Font; size: INTEGER): Fonts.Font;
- VAR
- family: ARRAY 64 OF CHAR;
- str: ARRAY 4 OF CHAR;
- oldsize: INTEGER;
- attr: CHAR;
- family: ARRAY 64 OF CHAR;
- VAR
- BEGIN
- IF dispW < 800 THEN
- DEC(size, 2)
- DEC(size, 2)
- END;
- SplitFontName(f, family, oldsize, attr);
- IF oldsize # size THEN
- Strings.IntToStr(size, str); Strings.Append(family, str);
- IF attr # 0X THEN
- Strings.AppendCh(family, attr)
- Strings.AppendCh(family, attr)
- END;
- Strings.Append(family, ".Scn.Fnt");
- RETURN Fonts.This(family)
- Strings.IntToStr(size, str); Strings.Append(family, str);
- ELSE
- RETURN f
- RETURN f
- END
- IF dispW < 800 THEN
- END ChangeFontSize;
- PROCEDURE SetFontSize*(P: Page; size: INTEGER);
- VAR fnt: Fonts.Font;
- VAR fnt: Fonts.Font;
- BEGIN
- fnt := P.W.lib(Fonts.Font);
- IF size < 1 THEN
- size := 1
- size := 1
- ELSIF size > 9 THEN
- size := 9
- size := 9
- END;
- PushTextAttrs(P);
- CASE size OF
- 1: Texts.SetFont(P.W, ChangeFontSize(fnt, 8))
- |2: Texts.SetFont(P.W, ChangeFontSize(fnt, 10))
- |3: Texts.SetFont(P.W, ChangeFontSize(fnt, 12))
- |4: Texts.SetFont(P.W, ChangeFontSize(fnt, 14))
- |5: Texts.SetFont(P.W, ChangeFontSize(fnt, 16))
- |6: Texts.SetFont(P.W, ChangeFontSize(fnt, 20))
- |7: Texts.SetFont(P.W, ChangeFontSize(fnt, 24))
- |8: fnt := ChangeFontSize(fnt, 24);
- Texts.SetFont(P.W, ChangeFontAttr(fnt, "m"))
- Texts.SetFont(P.W, ChangeFontAttr(fnt, "m"))
- |9: fnt := ChangeFontSize(fnt, 24);
- Texts.SetFont(P.W, ChangeFontAttr(fnt, "b"))
- Texts.SetFont(P.W, ChangeFontAttr(fnt, "b"))
- 1: Texts.SetFont(P.W, ChangeFontSize(fnt, 8))
- END
- fnt := P.W.lib(Fonts.Font);
- END SetFontSize;
- PROCEDURE HorzRule*(P: Page; w, h: INTEGER);
- VAR obj: Objects.Object;
- VAR obj: Objects.Object;
- BEGIN
- IF P.lines <= 0 THEN
- WriteLn(P)
- WriteLn(P)
- END;
- h := 2*h;
- IF h < 4 THEN
- h := 4
- h := 4
- END;
- obj := Gadgets.CreateObject("BasicFigures.NewRect3D");
- Attributes.SetBool(obj, "Filled", TRUE);
- Attributes.SetInt(obj, "Color", P.textbackC);
- Gadgets.ModifySize(obj(Display.Frame), w, h);
- WriteObj(P, obj); P.lines := 1; WriteLn(P)
- IF P.lines <= 0 THEN
- END HorzRule;
- PROCEDURE TextAlign*(CONST align: ARRAY OF CHAR): TextGadgets.Style;
- VAR style: TextGadgets.Style;
- VAR style: TextGadgets.Style;
- BEGIN
- style := NewStyle(); EXCL(style.mode, TextGadgets.left);
- CASE CAP(align[0]) OF
- |"L": INCL(style.mode, TextGadgets.left)
- |"R": INCL(style.mode, TextGadgets.right)
- |"C", "J": INCL(style.mode, TextGadgets.middle)
- |"L": INCL(style.mode, TextGadgets.left)
- ELSE (* BLEED... *)
- CASE CAP(align[5]) OF
- "L": INCL(style.mode, TextGadgets.left)
- |"R": INCL(style.mode, TextGadgets.right)
- |"C", "J": INCL(style.mode, TextGadgets.middle)
- "L": INCL(style.mode, TextGadgets.left)
- ELSE
- RETURN NIL
- RETURN NIL
- END
- CASE CAP(align[5]) OF
- END;
- RETURN style
- style := NewStyle(); EXCL(style.mode, TextGadgets.left);
- END TextAlign;
- PROCEDURE CloseA*(P: Page);
- BEGIN
- IF P.alink # NIL THEN
- WriteObj(P, P.alink); P.alink := NIL;
- WHILE (P.W.col = SHORT(P.linkC)) OR (P.W.col = SHORT(P.oldLinkC)) DO
- PopTextAttrs(P);
- IF P.textAttrs = NIL THEN RETURN END
- PopTextAttrs(P);
- END
- WriteObj(P, P.alink); P.alink := NIL;
- END
- IF P.alink # NIL THEN
- END CloseA;
- PROCEDURE OpenList(P: Page; kind: INTEGER);
- VAR list: List;
- VAR list: List;
- BEGIN
- PushTextAttrs(P);
- NEW(list); list.itemNr := 0;
- list.style := NewStyle();
- IF P.lists = NIL THEN
- list.nesting := 0;
- WriteLn(P); WriteLn(P)
- list.nesting := 0;
- ELSE
- list.nesting := P.lists.nesting+1
- list.nesting := P.lists.nesting+1
- END;
- P.style := list.style; WriteObj(P, list.style);
- list.dtok := FALSE; list.kind := kind;
- list.next := P.lists; P.lists := list
- PushTextAttrs(P);
- END OpenList;
- PROCEDURE CloseList(P: Page);
- BEGIN
- IF P.lists # NIL THEN
- IF P.lists.itemNr = 0 THEN
- P.lists.style.leftM := 32
- P.lists.style.leftM := 32
- END;
- P.lists := P.lists.next
- IF P.lists.itemNr = 0 THEN
- END;
- PopTextAttrs(P);
- IF P.lists = NIL THEN
- WriteLn(P); WriteLn(P)
- WriteLn(P); WriteLn(P)
- END
- IF P.lists # NIL THEN
- END CloseList;
- PROCEDURE FindFormObj*(form: Form; CONST name: ARRAY OF CHAR): Objects.Object;
- VAR
- ol: HTTPDocs0.ObjList;
- oname: ARRAY 64 OF CHAR;
- obj: Objects.Object;
- ol: HTTPDocs0.ObjList;
- VAR
- BEGIN
- obj := NIL;
- ol := form.elems;
- WHILE ol # NIL DO
- Attributes.GetString(ol.obj, "Name", oname);
- IF oname = name THEN
- obj := ol.obj
- obj := ol.obj
- END;
- ol := ol.next
- Attributes.GetString(ol.obj, "Name", oname);
- END;
- RETURN obj
- obj := NIL;
- END FindFormObj;
- PROCEDURE RememberValue*(obj: Objects.Object);
- VAR A: Objects.AttrMsg;
- VAR A: Objects.AttrMsg;
- BEGIN
- A.id := Objects.get; A.name := "Value"; A.class := Objects.Inval;
- obj.handle(obj, A);
- A.id := Objects.set; A.name := "IniValue";
- obj.handle(obj, A)
- A.id := Objects.get; A.name := "Value"; A.class := Objects.Inval;
- END RememberValue;
- 过程 AddFormObj*(P: 页面; form: 表单; obj: 对象.对象; CONST name: 字符数组; storeVal, write: 布尔);
- VAR ol, op: HTTPDocs0.对象列表;
- VAR ol, op: HTTPDocs0.对象列表;
- BEGIN
- NEW(ol); ol.obj := obj; ol.next := NIL;
- op := form.elems;
- WHILE (op # NIL) & (op.next # NIL) DO
- op := op.next
- op := op.next
- END;
- IF op # NIL THEN
- op.next := ol
- op.next := ol
- ELSE
- form.elems := ol
- form.elems := ol
- END;
- IF storeVal THEN
- 记住值(obj)
- 记住值(obj)
- END;
- IF name # "" THEN
- 小工具.命名对象(obj, name)
- 小工具.命名对象(obj, name)
- END;
- IF write THEN
- 写入对象(P, obj)
- 写入对象(P, obj)
- END
- NEW(ol); ol.obj := obj; ol.next := NIL;
- 结束 AddFormObj;
- 过程 FindA(CONST name: 字符数组);
- BEGIN
- IF name = searchAttr THEN
- found := TRUE
- found := TRUE
- END
- IF name = searchAttr THEN
- 结束 FindA;
- 过程 HasA(obj: 对象.对象; CONST name : 字符数组): 布尔;
- VAR A: Objects.AttrMsg;
- VAR A: Objects.AttrMsg;
- BEGIN
- found := FALSE; COPY(name, searchAttr);
- A.id := 对象.枚举; COPY(name, A.name); A.res := -1;
- A.枚举 := FindA;
- obj.handle(obj, A);
- RETURN found
- found := FALSE; COPY(name, searchAttr);
- 结束 HasA;
- 过程 重置值(form: 表单);
- VAR
- A: 对象.属性消息;
- ol: HTTPDocs0.ObjList;
- item: 项目;
- A: 对象.属性消息;
- VAR
- BEGIN
- ol := form.elems;
- WHILE ol # NIL DO
- IF HasA(ol.obj, "IniValue") THEN
- A.id := 对象.获取; A.name := "IniValue"; A.class := 对象.无效;
- ol.obj.处理(ol.obj, A);
- A.id := 对象.设置; A.name := "Value";
- ol.obj.处理(ol.obj, A);
- 小工具.更新(ol.obj)
- A.id := 对象.获取; A.name := "IniValue"; A.class := 对象.无效;
- ELSIF ol.obj IS 列表.列表 THEN
- item := ol.obj(列表.列表).items(项目);
- WHILE item # NIL DO
- item.sel := item.oldSel;
- IF item.next # NIL THEN
- item := item.next(项目)
- item := item.next(项目)
- ELSE
- item := NIL
- item := NIL
- END
- item.sel := item.oldSel;
- END;
- 小工具.更新(ol.obj)
- item := ol.obj(列表.列表).items(项目);
- END;
- ol := ol.next
- IF HasA(ol.obj, "IniValue") THEN
- END
- ol := form.elems;
- 结束 重置值;
- 过程 GetText*(view: 对象.对象): 文本.文本;
- VAR model: 对象.对象;
- VAR model: 对象.对象;
- BEGIN
- IF view # NIL THEN
- 链接.获取链接(view, "Model", model);
- IF (model # NIL) & (model IS 文本.文本) THEN
- RETURN model(文本.文本)
- RETURN model(文本.文本)
- ELSE
- RETURN NIL
- RETURN NIL
- END
- 链接.获取链接(view, "Model", model);
- ELSE
- RETURN NIL
- RETURN NIL
- END
- IF view # NIL THEN
- 结束 GetText;
(** HTMLDocs.定位标签
- 用于同一页面内的超链接。 *)
- 用于同一页面内的超链接。 *)
- 过程 定位*;
- VAR
- S: 属性.扫描器;
- F: 文本.查找器;
- pos: 长整型;
- obj: Objects.Object;
- name: ARRAY 32 OF CHAR;
- curDoc: 文档.文档;
- node: 超文档.节点;
- text: 文本.文本;
- S: 属性.扫描器;
- VAR
- BEGIN
- curDoc := 桌面.当前文档(小工具.上下文);
- node := 超文档.节点由文档(curDoc);
- text := GetText(小工具.上下文);
- IF (curDoc # NIL) & (text # NIL) THEN
- 属性.打开扫描器(S, 奥伯龙.Par.text, 奥伯龙.Par.pos);
- 属性.扫描(S);
- IF (S.class = 属性.字符串) OR (S.class = 属性.名称) THEN
- 文本.打开查找器(F, text, 0);
- pos := F.pos; 文本.查找对象(F, obj);
- WHILE ~F.eot DO
- IF obj IS 小工具.框架 THEN
- 属性.获取字符串(obj, "Name", name);
- IF S.s = name THEN
- IF node # NIL THEN
- 超文档.记住组织(curDoc.dsc(文本小工具.框架).org, node, node);
- 超文档.链接节点到文档(curDoc, node)
- 超文档.记住组织(curDoc.dsc(文本小工具.框架).org, node, node);
- END;
- 超文档.滚动到(curDoc.dsc(文本小工具.框架), pos);
- RETURN
- IF node # NIL THEN
- END
- 属性.获取字符串(obj, "Name", name);
- END;
- pos := F.pos; 文本.查找对象(F, obj)
- IF obj IS 小工具.框架 THEN
- END
- 文本.打开查找器(F, text, 0);
- END
- 属性.打开扫描器(S, 奥伯龙.Par.text, 奥伯龙.Par.pos);
- END
- curDoc := 桌面.当前文档(小工具.上下文);
- 结束 定位;
(** HTMLDocs.执行下一个
- 由可点击的图像用于激活周围的超链接。 *)
- 由可点击的图像用于激活周围的超链接。 *)
- 过程 执行下一个*;
- VAR
- F: 文本.查找器;
- exec, obj: 对象.对象;
- text: 文本.文本;
- F: 文本.查找器;
- VAR
- BEGIN
- exec := 小工具.执行者对象;
- text := GetText(小工具.上下文);
- IF (text # NIL) & (exec # NIL) THEN
- 文本.打开查找器(F, text, 0);
- 文本.查找对象(F, obj);
- WHILE ~F.eot DO
- IF obj = exec THEN
- exec := NIL
- exec := NIL
- ELSIF (exec = NIL) & (obj IS 文本小工具.控件) THEN
- 小工具.执行属性(obj(文本小工具.控件), "Cmd", 小工具.上下文, NIL, NIL);
- RETURN
- 小工具.执行属性(obj(文本小工具.控件), "Cmd", 小工具.上下文, NIL, NIL);
- END;
- 文本.查找对象(F, obj)
- IF obj = exec THEN
- END
- 文本.打开查找器(F, text, 0);
- END
- exec := 小工具.执行者对象;
- 结束 执行下一个;
- 过程 当前表单(context: 对象.对象): 表单;
- VAR
- F: 文本.查找器;
- exec, obj: 对象.对象;
- ol: HTTPDocs0.ObjList;
- text: 文本.文本;
- F: 文本.查找器;
- VAR
- BEGIN
- IF context # NIL THEN
- exec := 小工具.执行者对象; text := GetText(context);
- IF text # NIL THEN
- 文本.打开查找器(F, text, 0);
- 文本.查找对象(F, obj);
- WHILE ~F.eot DO
- IF obj IS 表单 THEN
- ol := obj(表单).elems;
- WHILE (ol # NIL) & (ol.obj # exec) DO
- ol := ol.next
- ol := ol.next
- END;
- IF ol # NIL THEN
- RETURN obj(表单)
- RETURN obj(表单)
- END
- ol := obj(表单).elems;
- END;
- 文本.查找对象(F, obj)
- IF obj IS 表单 THEN
- END
- 文本.打开查找器(F, text, 0);
- END;
- RETURN 当前表单(context.dlink)
- exec := 小工具.执行者对象; text := GetText(context);
- END;
- RETURN NIL
- IF context # NIL THEN
- 结束 当前表单;
(** HTMLDocs.重置
- 由表单中的 "重置" 按钮使用。 *)
- 由表单中的 "重置" 按钮使用。 *)
- 过程 重置*;
- BEGIN
- 重置值(当前表单(小工具.上下文))
- 重置值(当前表单(小工具.上下文))
- 结束 重置;
- 过程 复制表单(VAR M: 对象.复制消息; from, to: 表单);
- BEGIN
- 文本小工具.复制控件(M, from, to);
- 文本小工具.复制控件(M, from, to);
to.elems := from.elems
- 结束 复制表单;
- 过程 表单处理程序(F: 对象.对象; VAR M: 对象.对象消息);
- VAR
- ol: HTTPDocs0.ObjList;
- obj, action: 对象.对象;
- key: 长整型;
- F1: 表单;
- ol: HTTPDocs0.ObjList;
- VAR
- BEGIN
- WITH F: 表单 DO
- IF M IS 对象.属性消息 THEN
- WITH M: 对象.属性消息 DO
- IF (M.id = 对象.获取) & (M.name = "Gen") THEN
- M.class := 对象.字符串;
- M.s := "HTMLDocs.新建表单";
- M.res := 0
- M.class := 对象.字符串;
- ELSE
- 文本小工具.控件处理程序(F, M)
- 文本小工具.控件处理程序(F, M)
- END
- IF (M.id = 对象.获取) & (M.name = "Gen") THEN
- END
- WITH M: 对象.属性消息 DO
- ELSIF M IS 对象.文件消息 THEN
- WITH M: 对象.文件消息 DO
- 文本小工具.控件处理程序(F, M);
- IF M.id = 对象.加载 THEN
- 超文档.加载链接(M.R, key);
- action := 小工具.创建对象("基本小工具.新建整数");
- 属性.设置整数(action, "Value", key);
- 小工具.命名对象(action, "@ACTION");
- NEW(F.elems);
- F.elems.obj := action;
- F.elems.next := NIL;
- 小工具.读取引用(M.R, F.lib, obj);
- WHILE obj # NIL DO
- NEW(ol);
- ol.next := F.elems;
- F.elems := ol;
- ol.obj := obj;
- 小工具.读取引用(M.R, F.lib, obj)
- NEW(ol);
- END
- 超文档.加载链接(M.R, key);
- ELSIF M.id = 对象.存储 THEN
- action := 查找表单对象(F, "@ACTION");
- 属性.获取整数(action, "Value", key);
- 超文档.存储链接(M.R, key);
- ol := F.elems;
- WHILE ol # NIL DO
- IF ol.obj # action THEN
- 小工具.写入引用(M.R, F.lib, ol.obj)
- 小工具.写入引用(M.R, F.lib, ol.obj)
- END;
- ol := ol.next
- IF ol.obj # action THEN
- END;
- 小工具.写入引用(M.R, F.lib, NIL)
- action := 查找表单对象(F, "@ACTION");
- END
- 文本小工具.控件处理程序(F, M);
- END
- WITH M: 对象.文件消息 DO
- ELSIF M IS 对象.复制消息 THEN
- WITH M: 对象.复制消息 DO
- IF M.stamp = F.stamp THEN
- M.obj := F.dlink
- M.obj := F.dlink
- ELSE
- NEW(F1);
- F.stamp := M.stamp; F.dlink := F1;
- 复制表单(M, F, F1);
- M.obj := F1
- NEW(F1);
- END
- IF M.stamp = F.stamp THEN
- END
- WITH M: 对象.复制消息 DO
- ELSIF M IS 对象.绑定消息 THEN
- ol := F.elems;
- WHILE ol # NIL DO
- ol.obj.处理(ol.obj, M);
- ol := ol.next
- ol.obj.处理(ol.obj, M);
- END
- ol := F.elems;
- ELSE
- 文本小工具.控件处理程序(F, M)
- 文本小工具.控件处理程序(F, M)
- END
- IF M IS 对象.属性消息 THEN
- END
- WITH F: 表单 DO
- 结束 表单处理程序;
- 过程 新建表单*;
- VAR form: 表单;
- VAR form: 表单;
- BEGIN
- NEW(form);
- form.W := 0; form.H := 0;
- form.elems := NIL;
- form.处理 := 表单处理程序;
- 对象.新建对象 := form
- NEW(form);
- 结束 新建表单;
- 过程 十六进制数字(i: 整型): 字符;
- BEGIN
- IF i < 10 THEN
- RETURN CHR(i+ORD("0"))
- RETURN CHR(i+ORD("0"))
- ELSE
- RETURN CHR(i-10+ORD("A"))
- RETURN CHR(i-10+ORD("A"))
- END
- IF i < 10 THEN
- 结束 十六进制数字;
- 过程 映射坐标(obj: 对象.对象; VAR x, y: 整型);
- VAR M: 显示.定位消息;
- VAR M: 显示.定位消息;
- BEGIN
- M.F := NIL; M.loc := NIL; M.res := -1;
- M.X := 奥伯龙.鼠标.X; M.Y := 奥伯龙.鼠标.Y;
- 显示.广播(M);
- IF M.loc = obj THEN
- x := M.u; y := -M.v
- x := M.u; y := -M.v
- ELSE
- x := 0; y := 0
- x := 0; y := 0
- END
- M.F := NIL; M.loc := NIL; M.res := -1;
- 结束 映射坐标;
- 过程 组成查询(form: 表单; exec: 对象.对象; VAR query: 文本.文本);
- VAR
- ol: HTTPDocs0.ObjList;
- x, y: 整型;
- obj: Objects.Object;
- text: 文本.文本;
- name: 对象.名称;
- str: 字符数组 64; (* LEN(对象.属性消息.s) *)
- item: 项目;
- A: 对象.属性消息;
- R: 文本.读取器;
- ch: 字符;
- multisel, done: 布尔;
- ol: HTTPDocs0.ObjList;
- 过程 写入转义字符(ch: 字符);
- BEGIN
- ch := 字符串.奥伯龙到 ISO[ORD(ch)];
- IF (ch < 020X) OR (ch = "+") OR(ch = "&") OR (ch = "=") OR (ch = "?") OR (ch = "%") OR (ch = "$") OR
- (ch = ";") OR (ch = "/") OR (ch = "#") OR (ch = ":") THEN
- 文本.写入(Wr, "%");
- 文本.写入(Wr, 十六进制数字(ORD(ch) DIV 16));
- 文本.写入(Wr, 十六进制数字(ORD(ch) MOD 16))
- (ch = ";") OR (ch = "/") OR (ch = "#") OR (ch = ":") THEN
- ELSIF ch = 020X THEN
- 文本.写入(Wr, "+");
- 文本.写入(Wr, "+");
- ELSIF ch >= CHR(128) THEN
- 文本.写入(Wr, "%");
- 文本.写入(Wr, 十六进制数字(ORD(ch) DIV 16));
- 文本.写入(Wr, 十六进制数字(ORD(ch) MOD 16))
- 文本.写入(Wr, "%");
- ELSE
- 文本.写入(Wr, ch)
- 文本.写入(Wr, ch)
- END
- ch := 字符串.奥伯龙到 ISO[ORD(ch)];
- 结束 写入转义字符;
- 过程 整型属性(i: 长整型);
- BEGIN
- 文本.写入字符串(Wr, name);
- 文本.写入(Wr, "=");
- 文本.写入整型(Wr, i, 0);
- 文本.写入(Wr, "&")
- 文本.写入字符串(Wr, name);
- 结束 整型属性;
- 过程 字符串属性(CONST s: 字符数组);
- VAR i: 整型;
- VAR i: 整型;
- BEGIN
- 文本.写入字符串(Wr, name);
- 文本.写入(Wr, "=");
- i := 0;
- WHILE s[i] # 0X DO
- 写入转义字符(s[i]);
- INC(i)
- 写入转义字符(s[i]);
- END;
- 文本.写入(Wr, "&")
- 文本.写入字符串(Wr, name);
- 结束 字符串属性;
- 过程 实数属性(y: 长实数; l: 整型);
- BEGIN
- 文本.写入字符串(Wr, name);
- 文本.写入(Wr, "=");
- 文本.写入长实数(Wr, y, l);
- 文本.写入(Wr, "&")
- 文本.写入字符串(Wr, name);
- 结束 实数属性;
- VAR
- BEGIN
- NEW(query);
- 文本.打开(query, "");
- ol := form.elems;
- WHILE ol # NIL DO
- obj := ol.obj;
- 小工具.获取对象名称(obj, name);
- IF (name # "") & (name[0] # "@") THEN
- IF HasA(obj, "FormElem") THEN
- 属性.获取字符串(obj, "FormElem", str);
- IF (str = "IMAGE") & (exec = obj) THEN
- 映射坐标(obj, x, y);
- 字符串.追加(name, ".x");
- 整型属性(x);
- 小工具.获取对象名称(obj, name);
- 字符串.追加(name, ".y");
- 整型属性(y)
- 映射坐标(obj, x, y);
- ELSIF str = "SELECT" THEN
- done := FALSE;
- 属性.获取布尔值(obj, "MultiSel", multisel);
- item := obj(列表.列表).items(项目);
- WHILE (item # NIL) & (~done OR multisel) DO
- IF item.sel THEN
- done := TRUE;
- IF item.hasVal THEN
- 字符串属性(item.value)
- 字符串属性(item.value)
- ELSE
- 字符串属性(item.s)
- 字符串属性(item.s)
- END
- done := TRUE;
- END;
- IF item.next # NIL THEN
- item := item.next(项目)
- item := item.next(项目)
- ELSE
- item := NIL
- item := NIL
- END
- IF item.sel THEN
- END;
- IF ~done THEN
- 字符串属性("")
- 字符串属性("")
- END
- done := FALSE;
- ELSIF str = "TEXTAREA" THEN
- 文本.写入字符串(Wr, name);
- 文本.写入(Wr, "=");
- text := GetText(obj);
- IF text # NIL THEN
- 文本.打开读取器(R, text, 0);
- 文本.读取(R, ch);
- WHILE ~R.eot DO
- IF ch = 字符串.CR THEN
- (* 发送文本 -> CRLF *)
- 文本.写入行(Wr)
- (* 发送文本 -> CRLF *)
- ELSE
- 写入转义字符(ch)
- 写入转义字符(ch)
- END;
- 文本.读取(R, ch)
- IF ch = 字符串.CR THEN
- END
- 文本.打开读取器(R, text, 0);
- END;
- 文本.写入(Wr, "&")
- 文本.写入字符串(Wr, name);
- ELSIF str = "PASSWORD" THEN
- 属性.获取字符串(obj, "Value", A.s);
- 字符串属性(A.s)
- 属性.获取字符串(obj, "Value", A.s);
- END
- 属性.获取字符串(obj, "FormElem", str);
- ELSIF HasA(obj, "YesVal") THEN
- 属性.获取布尔值(obj, "Value", A.b);
- IF A.b THEN
- 属性.获取字符串(obj, "YesVal", str);
- 字符串属性(str)
- 属性.获取字符串(obj, "YesVal", str);
- ELSIF HasA(obj, "SubmitVal") & (obj = exec) THEN
- 属性.获取字符串(obj, "SubmitVal", str);
- 字符串属性(str)
- 属性.获取字符串(obj, "SubmitVal", str);
- END
- 属性.获取布尔值(obj, "Value", A.b);
- ELSIF HasA(obj, "Value") THEN
- IF HasA(obj, "MaxLen") THEN
- 属性.获取整数(obj, "MaxLen", A.i);
- x := SHORT(A.i)
- 属性.获取整数(obj, "MaxLen", A.i);
- ELSE
- x := -1
- x := -1
- END;
- A.id := 对象.获取;
- A.name := "Value";
- A.class := 对象.无效;
- A.res := -1;
- obj.handle(obj, A);
- CASE A.class OF
- 对象.整型: 整型属性(A.i);
- |对象.字符串: IF (x >= 0) & (x < LEN(A.s)) THEN
- A.s[x] := 0X
- A.s[x] := 0X
- END;
- 字符串属性(A.s)
- |对象.实数: IF x > 0 THEN
- 实数属性(A.x, x)
- 实数属性(A.x, x)
- ELSE
- 实数属性(A.x, 15)
- 实数属性(A.x, 15)
- END
- |对象.长实数: IF x > 0 THEN
- 实数属性(A.y, x)
- 实数属性(A.y, x)
- ELSE
- 实数属性(A.y, 15)
- 实数属性(A.y, 15)
- END
- 对象.整型: 整型属性(A.i);
- ELSE
- END
- IF HasA(obj, "MaxLen") THEN
- END
- IF HasA(obj, "FormElem") THEN
- END;
- ol := ol.next
- obj := ol.obj;
- END;
- 文本.追加(query, Wr.buf);
- 文本.删除(query, query.len-1, query.len)
- NEW(query);
- 结束 组成查询;
(** HTMLDocs.提交查询
- 由表单中的 "提交" 按钮使用。 *)
- 由表单中的 "提交" 按钮使用。 *)
- 过程 提交查询*;
- VAR
- exec, obj: 对象.对象;
- attr, qury: 字符数组 32;
- key, mkey: 长整型;
- docname: 字符数组 1024;
- query: 文本.文本;
- form: 表单;
- x, y: 整型;
- cont: HTTPDocs0.上下文;
- doc: 文档.文档;
- clearCache: 布尔;
- exec, obj: 对象.对象;
- VAR
- BEGIN
- query := NIL;
- exec := 小工具.执行者对象;
- IF HasA(exec, "Query") & HasA(exec, "Method") THEN
- clearCache := TRUE;
- form := 当前表单(小工具.上下文);
- obj := 查找表单对象(form, "@ACTION");
- Attributes.GetInt(obj, "Value", key);
- HyperDocs.DocNameByKey(docname, key);
- Attributes.GetString(exec, "Query", qury);
- IF qury = "ISINDEX" THEN
- obj := FindFormObj(CurForm(Gadgets.context), "QUERY");
- Attributes.GetString(obj, "Value", attr);
- NEW(query);
- 文本.打开(query, "");
- Texts.WriteString(Wq, attr);
- Texts.Append(query, Wq.buf);
- attr := "GET"
- obj := FindFormObj(CurForm(Gadgets.context), "QUERY");
- ELSIF qury = "ISMAP" THEN
- IF HasA(exec, "UseMapKey") THEN
- clearCache := FALSE;
- query := NIL; Attributes.GetInt(exec, "UseMapKey", mkey)
- clearCache := FALSE;
- ELSE
- mkey := HyperDocs.UndefKey
- mkey := HyperDocs.UndefKey
- END;
- IF mkey = HyperDocs.UndefKey THEN
- NEW(query);
- 文本.打开(query, "");
- MapCoord(exec, x, y);
- Texts.WriteInt(Wq, x, 0);
- Texts.Write(Wq, ",");
- Texts.WriteInt(Wq, y, 0);
- Texts.Append(query, Wq.buf)
- NEW(query);
- ELSE
- query := NIL; key := mkey
- query := NIL; key := mkey
- END;
- attr := "GET"
- IF HasA(exec, "UseMapKey") THEN
- ELSIF qury = "FORM" THEN
- ComposeQuery(form, exec, query);
- Attributes.GetString(exec, "Method", attr)
- ComposeQuery(form, exec, query);
- ELSE
- Texts.WriteString(Wr, "未知的查询类型 ");
- Texts.WriteString(Wr, qury);
- Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf);
- RETURN
- Texts.WriteString(Wr, "未知的查询类型 ");
- END;
- IF (attr = "GET") OR (attr = "POST") THEN
- NEW(cont);
- cont.query := query;
- COPY(attr, cont.method);
- cont.user := ""; cont.passwd := "";
- IF clearCache THEN
- HyperDocs.CacheDoc(key, NIL);
- HyperDocs.CacheText(key, NIL)
- HyperDocs.CacheDoc(key, NIL);
- END;
- HyperDocs.FollowKeyLink(cont, key)
- NEW(cont);
- ELSIF attr = "Authorization" THEN
- NEW(cont); cont.query := NIL;
- cont.method := "GET";
- obj := FindFormObj(form, "Username");
- Attributes.GetString(obj, "Value", cont.user);
- obj := FindFormObj(form, "Password");
- Attributes.GetString(obj, "Value", cont.passwd);
- HyperDocs.FollowKeyLink(cont, key)
- NEW(cont); cont.query := NIL;
- ELSIF attr = "MAILTO" THEN
- NEW(cont);
- cont.curDoc := NIL; cont.new := NIL;
- cont.replace := FALSE; cont.history := FALSE;
- cont.old := HyperDocs.NodeByDoc(Desktops.CurDoc(Gadgets.context));
- HyperDocs.context := cont;
- HyperDocs.RetrieveLink(key, docname);
- doc := Documents.Open(docname);
- HyperDocs.context := NIL;
- IF (doc # NIL) & (doc.dsc # NIL) THEN
- IF (query # NIL) & (doc.dsc IS TextGadgets.Frame) THEN
- Texts.WriteLn(Wr); Texts.Insert(query, 0, Wr.buf);
- Texts.WriteLn(Wr); Texts.Append(query, Wr.buf);
- Texts.Save(query, 0, query.len, Wr.buf);
- Texts.Append(doc.dsc(TextGadgets.Frame).text, Wr.buf)
- Texts.WriteLn(Wr); Texts.Insert(query, 0, Wr.buf);
- END;
- Desktops.ShowDoc(doc)
- IF (query # NIL) & (doc.dsc IS TextGadgets.Frame) THEN
- ELSIF query # NIL THEN
- TextDocs.ShowText("mailto 查询", query, HyperDocs.docW, HyperDocs.docH)
- TextDocs.ShowText("mailto 查询", query, HyperDocs.docW, HyperDocs.docH)
- END
- NEW(cont);
- ELSE
- Texts.WriteString(Wr, "未知的查询方法 ");
- Texts.WriteString(Wr, attr);
- Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf);
- RETURN
- Texts.WriteString(Wr, "未知的查询方法 ");
- END
- clearCache := TRUE;
- END
- query := NIL;
- END SubmitQuery;
- PROCEDURE HREF(P: Page; VAR href, cmd: ARRAY OF CHAR; VAR key: LONGINT);
- VAR i, j: LONGINT;
- VAR i, j: LONGINT;
- BEGIN
- key := -1; COPY("", cmd); i := 0;
- WHILE (href[i] # 0X) & (href[i] <= " ") DO
- INC(i)
- INC(i)
- END;
- IF href[i] = "#" THEN
- COPY("HTMLDocs.Locate ", cmd); href[0] := " ";
- Strings.Append(cmd, href); cmd[16] := 022X;
- Strings.AppendCh(cmd, 022X)
- COPY("HTMLDocs.Locate ", cmd); href[0] := " ";
- ELSE
- WHILE (href[i] # 0X) & (href[i] # "#") DO
- INC(i)
- INC(i)
- END;
- IF href[i] = "#" THEN
- DEC(i); j := 0;
- WHILE P.base.path[j] # 0X DO
- INC(j)
- INC(j)
- END; DEC(j);
- WHILE (i > 0) & (j > 0) & (href[i] = P.base.path[j]) DO
- DEC(i); DEC(j)
- DEC(i); DEC(j)
- END;
- IF i = 0 THEN
- COPY("HTMLDocs.Locate ", cmd);
- j := 0;
- WHILE cmd[j] # 0X DO
- INC(j)
- INC(j)
- END;
- cmd[j] := 022X; INC(j);
- WHILE (href[i] # 0X) & (href[i] # "#") DO
- INC(i)
- INC(i)
- END; INC(i);
- WHILE href[i] # 0X DO
- cmd[j] := href[i]; INC(j); INC(i)
- cmd[j] := href[i]; INC(j); INC(i)
- END;
- cmd[j] := 022X; cmd[j+1] := 0X;
- RETURN
- COPY("HTMLDocs.Locate ", cmd);
- END
- DEC(i); j := 0;
- END;
- key := HyperDocs.BuildKey(P.base, href);
- IF key = HyperDocs.UndefKey THEN
- Texts.WriteString(Wr, href);
- Texts.WriteString(Wr, " 链接类型不支持");
- Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf)
- Texts.WriteString(Wr, href);
- END
- WHILE (href[i] # 0X) & (href[i] # "#") DO
- END
- key := -1; COPY("", cmd); i := 0;
- END HREF;
- PROCEDURE Read*(VAR S: Scanner);
- VAR St: Streams.Stream;
- VAR St: Streams.Stream;
- BEGIN
- St := S.S; S.ch := S.next;
- IF St.eos & (St.Available(St) <= 0) THEN
- S.avail := 0; S.next := 0X; S.end := TRUE
- S.avail := 0; S.next := 0X; S.end := TRUE
- ELSE
- TextStreams.Read(St, S.next); DEC(S.avail);
- Texts.Write(S.page.Ws, S.next);
- IF S.ch = Strings.CR THEN
- IF S.next = Strings.LF THEN
- TextStreams.Read(St, S.next); DEC(S.avail);
- Texts.Write(S.page.Ws, S.next)
- TextStreams.Read(St, S.next); DEC(S.avail);
- END;
- S.ch := Strings.CR
- IF S.next = Strings.LF THEN
- ELSIF S.ch = Strings.LF THEN
- S.ch := Strings.CR
- S.ch := Strings.CR
- END
- TextStreams.Read(St, S.next); DEC(S.avail);
- END
- St := S.S; S.ch := S.next;
- END Read;
- PROCEDURE ChangeFontFamily(f: Fonts.Font; CONST newfamily: ARRAY OF CHAR): Fonts.Font;
- VAR
- family: ARRAY 64 OF CHAR;
- str: ARRAY 4 OF CHAR;
- size: INTEGER;
- attr: CHAR;
- family: ARRAY 64 OF CHAR;
- VAR
- BEGIN
- SplitFontName(f, family, size, attr);
- IF family # newfamily THEN
- COPY(newfamily, family);
- Strings.IntToStr(size, str); Strings.Append(family, str);
- IF attr # 0X THEN
- Strings.AppendCh(family, attr)
- Strings.AppendCh(family, attr)
- END;
- Strings.Append(family, ".Scn.Fnt");
- RETURN Fonts.This(family)
- COPY(newfamily, family);
- ELSE
- RETURN f
- RETURN f
- END
- SplitFontName(f, family, size, attr);
- END ChangeFontFamily;
- PROCEDURE WriteCharRef*(P: Page; VAR S: Scanner);
- VAR
- i, j, k: LONGINT;
- entity: ARRAY 64 OF CHAR; istr: ARRAY 4 OF CHAR;
- lib: Objects.Library;
- obj: Objects.Object;
- fnt: Fonts.Font;
- ref: INTEGER;
- i, j, k: LONGINT;
- VAR
- BEGIN
- IF S.ch = "#" THEN
- (* Texts.WriteString(Wr, "Numeric character reference pending."); Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf); *)
- Read(S);
- IF Strings.IsDigit(S.ch) THEN
- i := 0;
- WHILE ~S.end & (i < 9100) & Strings.IsDigit(S.ch) DO
- i := 10*i+ORD(S.ch)-ORD("0"); Read(S)
- i := 10*i+ORD(S.ch)-ORD("0"); Read(S)
- END;
- IF S.ch = ";" THEN
- Read(S)
- Read(S)
- END;
- CASE i OF
- 169: Texts.WriteString(P.W, "(c)")
- |174: Texts.WriteString(P.W, "(R)")
- |188: Texts.WriteString(P.W, " 1/4")
- |189: Texts.WriteString(P.W, " 1/2")
- |190: Texts.WriteString(P.W, " 3/4")
- 169: Texts.WriteString(P.W, "(c)")
- ELSE
- fnt := P.W.lib(Fonts.Font);
- IF (i >= 913) & (i <= 982) THEN (* Greek character *)
- Strings.IntToStr(i - 900, istr);
- k := 0;
- WHILE ((istr[0] # GreekTab[k]) OR (istr[1] # GreekTab[k+1])) & (k < 120) DO
- k := k + 2
- k := k + 2
- END;
- k := k DIV 2;
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Greek"));
- Texts.Write(P.W, CHR(k + ORD("@")));
- Texts.SetFont (P.W, fnt);
- Strings.IntToStr(i - 900, istr);
- ELSIF (i >= 8501) & (i <= 9002) THEN (* Math character *)
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- CASE i OF (* glyph TeX name *)
- 9001: Texts.Write(P.W, "a") (* a langle *)
- (* b *) (* b vdash *)
- (* c *) (* c models *)
- (* d *) (* d dashv *)
- | 8721: Texts.Write(P.W, "e") (* e sum *)
- (* f *) (* f ll *)
- (* g *) (* g gg *)
- | 8968: Texts.Write(P.W, "h") (* h lceil *)
- | 8969: Texts.Write(P.W, "i") (* i rceil *)
- | 8970: Texts.Write(P.W, "j") (* j lfloor *)
- | 8971: Texts.Write(P.W, "k") (* k rfloor *)
- (* l *) (* l Vert *)
- (* m *) (* m mp *)
- (* n *) (* n prec *)
- (* o *) (* o succ *)
- | 8776: Texts.Write(P.W, "p") (* p simeq *)
- | 9002: Texts.Write(P.W, "q") (* q rangle *)
- (* r *) (* r not supset *)
- | 8629: Texts.Write(P.W, "s") (* s (carriage return) *)
- (* t *) (* t ?? *)
- (* u *) (* u ?? *)
- (* v - moved down *) (* v S *)
- (* w *) (* w ?? *)
- | 8747: Texts.Write(P.W, "x") (* x int *)
- (* y *) (* y oint *)
- (* z *) (* z because *)
- (* C *) (* C wp *)
- (* D *) (* D oslash *)
- | 8853: Texts.Write(P.W, "E") (* E oplus *)
- | 8709: Texts.Write(P.W, "F") (* F emptyset *)
- | 8745: Texts.Write(P.W, "G") (* G cap *)
- | 8746: Texts.Write(P.W, "H") (* H cup *)
- | 8835: Texts.Write(P.W, "I") (* I supset *)
- | 8839: Texts.Write(P.W, "J") (* J supseteq *)
- | 8836: Texts.Write(P.W, "K") (* K not subset *)
- | 8834: Texts.Write(P.W, "L") (* L subset *)
- | 8838: Texts.Write(P.W, "M") (* M subseteq *)
- | 8712: Texts.Write(P.W, "N") (* N in *)
- | 8713: Texts.Write(P.W, "O") (* O not in *)
- | 8736: Texts.Write(P.W, "P") (* P angle *)
- | 8711: Texts.Write(P.W, "Q") (* Q nabla *)
- | 8704: Texts.Write(P.W, "R") (* R forall *)
- | 8707: Texts.Write(P.W, "S") (* S exists *)
- | 8715: Texts.Write(P.W, "T") (* T owns *)
- (* U *) (* U sqcap *)
- | 8730: Texts.Write(P.W, "V") (* V surb *)
- | 8901: Texts.Write(P.W, "W") (* W cdot *)
- (* X *) (* X lnot *)
- | 8869: Texts.Write(P.W, "Y") (* Y land *)
- | 8870: Texts.Write(P.W, "Z") (* Z lor *)
- (* 0 - moved down *) (* 0 deg *)
- (* 1 - moved down *) (* 1 pm *)
- | 8805: Texts.Write(P.W, "3") (* 3 geq *)
- (* 4 *) (* 4 times *)
- | 8733: Texts.Write(P.W, "5") (* 5 propto *)
- | 8706: Texts.Write(P.W, "6") (* 6 partial *)
- (* 7 - moved down *) (* 7 bullet *)
- (* 8 - moved down *) (* 8 div *)
- | 8800: Texts.Write(P.W, "9") (* 9 not= *)
- (* ) *) (* ) swarrow *)
- (* ! *) (* ! mathbb R ?? *)
- | 8501: Texts.Write(P.W, "@") (* @ aleph *)
- | 8804: Texts.Write(P.W, "#") (* # leq *)
- (* $ - moved down *) (* $ / *)
- | 8734: Texts.Write(P.W, "%") (* % infty *)
- | 8658: Texts.Write(P.W, "^") (* ^ Rightarrow *)
- (* & *) (* & >> *)
- (* * *) (* * searrow *)
- (* ( *) (* ( nwarrow *)
- | 8592: Texts.Write(P.W, ",") (* , gets *)
- | 8594: Texts.Write(P.W, ".") (* . to *)
- | 8773: Texts.Write(P.W, ";") (* ; approx *)
- (* ' *) (* ' nearrow *)
- (* ` *) (* ` ?? *)
- | 8593: Texts.Write(P.W, "-") (* - uparrow *)
- (* = *) (* = vert *)
- | 8595: Texts.Write(P.W, "/") (* / downarrow *)
- | 8656: Texts.Write(P.W, "\") (* \ Leftarrow *)
- | 8660: Texts.Write(P.W, "[") (* [ Leftrightarrow *)
- | 8657: Texts.Write(P.W, "]") (* ] Uparrow *)
- (* < - moved down *) (* < dots *)
- | 8722: Texts.Write(P.W, ">") (* > (minus sign) *)
- | 8801: Texts.Write(P.W, ":") (* : equiv *)
- (* " - moved down *) (* " prime *)
- (* ~ - moved down *) (* ~ cents *)
- | 8659: Texts.Write(P.W, "_") (* _ Downarrow *)
- | 8596: Texts.Write(P.W, "+") (* + leftrightarrow *)
- 9001: Texts.Write(P.W, "a") (* a langle *)
- ELSE
- END;
- Texts.SetFont (P.W, fnt);
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- ELSIF (i >= 8201) & (i <= 8500) THEN (* Math character *)
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- CASE i OF (* glyph TeX name *)
- 8465: Texts.Write(P.W, "A") (* A Im *)
- | 8476: Texts.Write(P.W, "B") (* B Re *)
- | 8243: Texts.Write(P.W, "2") (* 2 (double prime) *)
- | 8226: Texts.Write(P.W, "7") (* 7 bullet *)
- | 8260: Texts.Write(P.W, "$") (* $ / *)
- | 8230: Texts.Write(P.W, "<") (* < dots *)
- | 8242: Texts.Write(P.W, '"') (* " prime *)
- | 8224: Texts.Write(P.W, "}") (* } dagger *)
- 8465: Texts.Write(P.W, "A") (* A Im *)
- ELSE
- END;
- Texts.SetFont (P.W, fnt);
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- (*
- ELSIF (i >= 160) & (i <= 250) THEN (* Math character *)
- *)
- ELSIF (i = 167) OR (i = 176) OR (i = 177) OR (i = 162) OR (i = 247) THEN (* Math character *)
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- CASE i OF (* glyph TeX name *)
- 167: Texts.Write(P.W, "v") (* v S *)
- | 176: Texts.Write(P.W, "0") (* 0 deg *)
- | 177: Texts.Write(P.W, "1") (* 1 pm *)
- | 247: Texts.Write(P.W, "8") (* 8 div *)
- | 162: Texts.Write(P.W, "~") (* ~ cents *)
- 167: Texts.Write(P.W, "v") (* v S *)
- ELSE
- END;
- Texts.SetFont (P.W, fnt);
- Texts.SetFont (P.W, ChangeFontFamily(fnt, "Math"));
- fnt := P.W.lib(Fonts.Font);
- i := 0;
- (* Texts.WriteString(Wr, "Numeric character reference pending."); Texts.WriteLn(Wr);
- IF S.ch = "#" THEN
(* ISOToOberon 是一个包含 256 个字符的数组,而 HTML 可以
引用任意 65536 个字符,� .. 。检查 i 是否
是 ISOToOberon 的有效索引。 *)
- ELSIF (i < 256) THEN
- Texts.Write(P.W, Strings.ISOToOberon[i])
- Texts.Write(P.W, Strings.ISOToOberon[i])
- ELSE (* 该字符在 ETH Oberon / PC Native 中不可用。 *)
- Texts.Write(P.W, CHR(0)) (* 生成一个空字符。 *)
- Texts.Write(P.W, CHR(0)) (* 生成一个空字符。 *)
- END
- ELSIF (i < 256) THEN
- END
- ELSE (* 错误的 HTML 字符引用。 *)
- Texts.WriteString(P.W, "&#")
- Texts.WriteString(P.W, "&#")
- END
- ELSE
- (* Texts.WriteString(Wr, "Named character entity pending."); Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf); *)
- i := 0;
- WHILE ~S.end & Strings.IsAlpha(S.ch) & (i < 63) DO
- entity[i] := S.ch; INC(i); entity[i] := 0X;
- j := 0;
- WHILE (j < LEN(entities)) & (entities[j] # entity) DO
- INC(j)
- INC(j)
- END;
- IF j < LEN(entities) THEN
- i := 63
- i := 63
- END;
- Read(S)
- entity[i] := S.ch; INC(i); entity[i] := 0X;
- END;
- entity[i] := 0X;
- (* Texts.WriteString(Wr, "Entity name = "); Texts.WriteString(Wr, entity); Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf); *)
- i := 0;
- WHILE (i < LEN(entities)) & (entities[i] # entity) DO
- INC(i)
- INC(i)
- END;
- IF i < LEN(entities) THEN
- Texts.Write(P.W, entityEncoding[i])
- Texts.Write(P.W, entityEncoding[i])
- ELSIF entity = "trade" THEN
- PushTextAttrs(P); Texts.SetOffset(P.W, 4);
- Texts.WriteString(P.W, "TM");
- PopTextAttrs(P)
- PushTextAttrs(P); Texts.SetOffset(P.W, 4);
- ELSIF entity = "reg" THEN
- Texts.WriteString(P.W, "(R)")
- Texts.WriteString(P.W, "(R)")
- ELSIF entity = "copy" THEN
- Texts.WriteString(P.W, "(c)")
- Texts.WriteString(P.W, "(c)")
- ELSE
- lib := Objects.ThisLibrary("HTMLIcons.Lib");
- Objects.GetRef(lib.dict, entity, ref);
- IF ref >= 0 THEN
- lib.GetObj(lib, ref, obj); WriteObj(P, obj)
- lib.GetObj(lib, ref, obj); WriteObj(P, obj)
- ELSE
- Texts.Write(P.W, "&"); Texts.WriteString(P.W, entity); RETURN
- Texts.Write(P.W, "&"); Texts.WriteString(P.W, entity); RETURN
- END
- lib := Objects.ThisLibrary("HTMLIcons.Lib");
- END;
- IF S.ch = ";" THEN
- Read(S)
- Read(S)
- END
- (* Texts.WriteString(Wr, "Named character entity pending."); Texts.WriteLn(Wr);
- END
- END WriteCharRef;
- PROCEDURE CharRefStr*(P: Page; VAR S: Scanner; VAR str: ARRAY OF CHAR);
- VAR
- i, j: LONGINT;
- entity: ARRAY 64 OF CHAR;
- i, j: LONGINT;
- VAR
- BEGIN
- COPY("", str);
- IF S.ch = "#" THEN
- Read(S);
- IF Strings.IsDigit(S.ch) THEN
- i := 0;
- WHILE ~S.end & (i < 256) & Strings.IsDigit(S.ch) DO
- i := 10*i+ORD(S.ch)-ORD("0"); Read(S)
- i := 10*i+ORD(S.ch)-ORD("0"); Read(S)
- END;
- IF S.ch = ";" THEN
- Read(S)
- Read(S)
- END;
- CASE i OF
- 169: Strings.Append(str, "(c)")
- |174: Strings.Append(str, "(R)")
- |188: Strings.Append(str, " 1/4")
- |189: Strings.Append(str, " 1/2")
- |190: Strings.Append(str, " 3/4")
- 169: Strings.Append(str, "(c)")
- ELSE
- IF (i < 256) THEN
- Strings.AppendCh(str, Strings.ISOToOberon[i])
- ELSE (* 该字符在 ETH Oberon / PC Native 05.01.2003 中不可用。 *)
- Strings.AppendCh(str, CHR(0)) (* 生成一个空字符。 *)
- Strings.AppendCh(str, CHR(0)) (* 生成一个空字符。 *)
- END
- END
- i := 0;
- ELSE (* 错误的 HTML 字符引用。 *)
- Strings.Append(str, "&#")
- Strings.Append(str, "&#")
- END
- Read(S);
- ELSIF Strings.IsAlpha(S.ch) THEN
- i := 0;
- WHILE ~S.end & Strings.IsAlpha(S.ch) & (i < 63) DO
- entity[i] := S.ch; INC(i); entity[i] := 0X;
- j := 0;
- WHILE (j < LEN(entities)) & (entities[j] # entity) DO
- INC(j)
- INC(j)
- END;
- IF j < LEN(entities) THEN
- i := 63
- i := 63
- END;
- Read(S)
- entity[i] := S.ch; INC(i); entity[i] := 0X;
- END;
- entity[i] := 0X;
- i := 0;
- WHILE (i < LEN(entities)) & (entities[i] # entity) DO
- INC(i)
- INC(i)
- END;
- IF i < LEN(entities) THEN
- Strings.AppendCh(str, entityEncoding[i])
- Strings.AppendCh(str, entityEncoding[i])
- ELSIF entity = "trade" THEN
- Strings.Append(str, "TM")
- Strings.Append(str, "TM")
- ELSIF entity = "reg" THEN
- Strings.Append(str, "(R)")
- Strings.Append(str, "(R)")
- ELSIF entity = "copy" THEN
- Strings.Append(str, "(c)")
- Strings.Append(str, "(c)")
- ELSE
- Strings.AppendCh(str, "&"); Strings.Append(str, entity); RETURN
- Strings.AppendCh(str, "&"); Strings.Append(str, entity); RETURN
- END;
- IF S.ch = ";" THEN
- Read(S)
- Read(S)
- END
- i := 0;
- ELSE
- COPY("&", str)
- COPY("&", str)
- END
- COPY("", str);
- END CharRefStr;
- PROCEDURE Next*(VAR S: Scanner);
- VAR i, l: LONGINT;
- VAR i, l: LONGINT;
- BEGIN
- CASE S.state OF
- TextHtml
- IF S.ch = "<" THEN
- Read(S);
- IF Strings.IsAlpha(S.ch) OR (S.ch = "/") OR (S.ch = "!") THEN
- S.class := OpenTag
- S.class := OpenTag
- ELSE
- S.char := S.ch; S.class := Character
- S.char := S.ch; S.class := Character
- END
- Read(S);
- ELSIF S.ch = "&" THEN
- Read(S); S.class := CharRef
- Read(S); S.class := CharRef
- ELSIF (S.ch <= " ") & (S.ch # 0X) & ~S.pre THEN
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF (S.ch = "<") & (S.class = CloseTag) THEN
- Read(S);
- IF Strings.IsAlpha(S.ch) OR (S.ch = "/") OR (S.ch = "!") THEN
- S.class := OpenTag
- S.class := OpenTag
- ELSE
- S.char := S.ch; S.class := Character
- S.char := S.ch; S.class := Character
- END
- Read(S);
- ELSIF S.end THEN
- S.class := Undef; S.state := End
- S.class := Undef; S.state := End
- ELSE
- S.class := WhiteSpace
- S.class := WhiteSpace
- END
- WHILE ~S.end & (S.ch <= " ") DO
- ELSIF ~S.end THEN
- S.char := S.ch; Read(S); S.class := Character(*; S.skipWS := FALSE*)
- S.char := S.ch; Read(S); S.class := Character(*; S.skipWS := FALSE*)
- ELSE
- S.class := Undef; S.state := End
- S.class := Undef; S.state := End
- END
- IF S.ch = "<" THEN
- |TextPlain
- IF S.ch # 0X THEN
- S.char := S.ch; Read(S); S.class := Character
- S.char := S.ch; Read(S); S.class := Character
- ELSE
- S.class := Undef; S.state := End
- S.class := Undef; S.state := End
- END
- IF S.ch # 0X THEN
- |InTag
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF S.ch = "/" THEN
- Read(S); S.class := OpenEndTag
- Read(S); S.class := OpenEndTag
- ELSIF S.ch = ">" THEN
- Read(S); S.class := CloseTag
- Read(S); S.class := CloseTag
- ELSIF S.ch = "&" THEN
- Read(S); S.class := CharRef
- Read(S); S.class := CharRef
- ELSIF Strings.IsAlpha(S.ch) THEN
- i := 0; l := LEN(S.value)-1;
- WHILE ~S.end & (Strings.IsAlpha(S.ch) OR Strings.IsDigit(S.ch)) DO
- IF i < l THEN
- S.value[i] := S.ch; INC(i)
- S.value[i] := S.ch; INC(i)
- END;
- Read(S)
- IF i < l THEN
- END;
- S.value[i] := 0X; S.class := Value;
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF S.ch = "<" THEN
- Read(S);
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- Read(S);
- IF Strings.IsAlpha(S.ch) THEN
- i := 0; l := LEN(S.value)-1;
- WHILE ~S.end & (Strings.IsAlpha(S.ch) OR Strings.IsDigit(S.ch)) DO
- IF i < l THEN
- S.value[i] := S.ch; INC(i)
- S.value[i] := S.ch; INC(i)
- END;
- Read(S)
- IF i < l THEN
- END
- i := 0; l := LEN(S.value)-1;
- END
- i := 0; l := LEN(S.value)-1;
- END
- WHILE ~S.end & (S.ch <= " ") DO
- ELSIF ~S.end THEN
- S.char := S.ch; Read(S); S.class := Character
- S.char := S.ch; Read(S); S.class := Character
- ELSE
- S.class := Undef; S.state := End
- S.class := Undef; S.state := End
- END
- TextHtml
- ELSE
- S.class := Undef; S.state := End
- S.class := Undef; S.state := End
- END
- CASE S.state OF
- END Next;
- PROCEDURE NextAttr*(VAR S: Scanner; VAR name: ARRAY OF CHAR): BOOLEAN;
- VAR
- i, l: LONGINT;
- charRef: ARRAY 16 OF CHAR;
- quoted: BOOLEAN;
- i, l: LONGINT;
- VAR
- BEGIN
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF (S.ch = ",") OR (S.ch = ";") THEN
- Read(S);
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END
- Read(S);
- END;
- i := 0; l := LEN(name)-1;
- WHILE ~S.end & Strings.IsAlpha(S.ch) DO
- IF i < l THEN
- name[i] := CAP(S.ch); INC(i)
- name[i] := CAP(S.ch); INC(i)
- END;
- Read(S)
- IF i < l THEN
- END;
- name[i] := 0X;
- IF i > 0 THEN
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF S.ch = "=" THEN
- Read(S);
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF S.ch = 022X THEN
- Read(S); quoted := TRUE
- Read(S); quoted := TRUE
- ELSE
- quoted := FALSE
- quoted := FALSE
- END;
- i := 0; l := LEN(S.value)-1;
- WHILE ~S.end & ( (~quoted & (S.ch > " ") & (S.ch # ">")) OR (quoted & (S.ch # 022X)) ) DO
- IF i < l THEN
- IF S.ch = "&" THEN
- Read(S); CharRefStr(S.page, S, charRef);
- S.value[i] := 0X; Strings.Append(S.value, charRef);
- i := Strings.Length(S.value)
- Read(S); CharRefStr(S.page, S, charRef);
- ELSIF (S.ch >= " ") OR (S.ch = Strings.Tab) THEN
- S.value[i] := S.ch; INC(i); Read(S)
- S.value[i] := S.ch; INC(i); Read(S)
- ELSE
- Read(S)
- Read(S)
- END
- IF S.ch = "&" THEN
- ELSE
- Read(S)
- Read(S)
- END
- IF i < l THEN
- END;
- IF S.ch = 022X THEN
- Read(S)
- Read(S)
- END;
- WHILE ~quoted & (i > 0) & (S.value[i-1] <= " ") DO
- S.value[i-1] := 0X; DEC(i)
- S.value[i-1] := 0X; DEC(i)
- END;
- S.value[i] := 0X
- Read(S);
- ELSE
- COPY("", S.value)
- COPY("", S.value)
- END;
- S.class := Value; RETURN TRUE
- WHILE ~S.end & (S.ch <= " ") DO
- END;
- COPY("", name); COPY("", S.value); RETURN FALSE
- WHILE ~S.end & (S.ch <= " ") DO
- END NextAttr;
- PROCEDURE GetAttrs*(VAR S: Scanner; VAR attrs: TagAttr);
- VAR attr: TagAttr;
- VAR attr: TagAttr;
- BEGIN
- attrs := NIL; NEW(attr);
- WHILE NextAttr(S, attr.name) DO
- attr.next := attrs; attrs := attr;
- COPY(S.value, attr.value);
- NEW(attr)
- attr.next := attrs; attrs := attr;
- END
- attrs := NIL; NEW(attr);
- END GetAttrs;
- PROCEDURE FindAttr*(attrs: TagAttr; CONST name: ARRAY OF CHAR): TagAttr;
- VAR attr: TagAttr;
- VAR attr: TagAttr;
- BEGIN
- attr := attrs;
- WHILE (attr # NIL) & (attr.name # name) DO
- attr := attr.next
- attr := attr.next
- END;
- RETURN attr
- attr := attrs;
- END FindAttr;
- PROCEDURE OpenScanner*(VAR S: Scanner; St: Streams.Stream);
- BEGIN
- (*S.skipWS := FALSE; S.genWS := FALSE;*)
- S.ch := 0X; S.next := 0X; S.end := FALSE;
- S.S := St; S.class := Undef; S.state := TextHtml; S.pre := FALSE;
- Read(S)
- (*S.skipWS := FALSE; S.genWS := FALSE;*)
- END OpenScanner;
- PROCEDURE A(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- obj: Objects.Object;
- isRef, newDoc: BOOLEAN;
- P: Page;
- VAR
- BEGIN
- P := S.page; CloseA(P); P.linkkey := HyperDocs.UndefKey;
- IF on THEN
- isRef := FALSE; newDoc := FALSE;
- WHILE NextAttr(S, attr) DO
- IF attr = "HREF" THEN
- isRef := TRUE; HREF(P, S.value, attr, P.linkkey);
- IF P.linkkey # HyperDocs.UndefKey THEN
- P.alink := HyperDocs.LinkControl(P.linkkey)
- P.alink := HyperDocs.LinkControl(P.linkkey)
- ELSE
- P.alink := Gadgets.CreateObject("TextGadgets.NewControl");
- Attributes.SetString(P.alink, "Cmd", attr)
- P.alink := Gadgets.CreateObject("TextGadgets.NewControl");
- END
- isRef := TRUE; HREF(P, S.value, attr, P.linkkey);
- ELSIF (attr = "NAME") OR (attr = "ID") THEN
- IF S.value = P.orgLabel THEN
- Texts.Append(P.T, P.W.buf); P.orgPos := P.T.len
- Texts.Append(P.T, P.W.buf); P.orgPos := P.T.len
- END;
- obj := Gadgets.CreateObject("TextGadgets.NewControl");
- WriteObj(P, obj); Attributes.SetString(obj, "Name", S.value)
- IF S.value = P.orgLabel THEN
- ELSIF attr = "TARGET" THEN
- newDoc := TRUE
- newDoc := TRUE
- END
- IF attr = "HREF" THEN
- END;
- IF isRef THEN
- IF newDoc THEN
- Attributes.SetString(P.alink, "Opt", "New")
- Attributes.SetString(P.alink, "Opt", "New")
- END;
- IF ~HyperDocs.Visited(P.linkkey) THEN
- PushTextAttrs(P); Texts.SetColor(P.W, SHORT(P.linkC))
- PushTextAttrs(P); Texts.SetColor(P.W, SHORT(P.linkC))
- ELSE
- PushTextAttrs(P); Texts.SetColor(P.W, SHORT(P.oldLinkC))
- PushTextAttrs(P); Texts.SetColor(P.W, SHORT(P.oldLinkC))
- END
- IF newDoc THEN
- END
- isRef := FALSE; newDoc := FALSE;
- END
- P := S.page; CloseA(P); P.linkkey := HyperDocs.UndefKey;
- END A;
- PROCEDURE Address(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, Syntax(12, "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END Address;
- PROCEDURE B(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "b"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END B;
- PROCEDURE SplitHostPort*(VAR url, host: ARRAY OF CHAR; VAR port: INTEGER);
- VAR
- i, j: INTEGER;
- val: LONGINT;
- i, j: INTEGER;
- VAR
- BEGIN
- i := 0;
- WHILE (url[i] # 0X) & (url[i] # "/") DO
- INC(i)
- INC(i)
- END;
- WHILE url[i] = "/" DO
- INC(i)
- INC(i)
- END;
- j := 0;
- WHILE (url[j] # 0X) & (url[j] # "@") DO
- INC(j)
- INC(j)
- END;
- IF url[j] = "@" THEN
- i := j+1
- i := j+1
- END;
- j := 0;
- WHILE (url[i] # 0X) & (url[i] # "/") & (url[i] # ":") DO
- host[j] := url[i]; INC(i); INC(j)
- host[j] := url[i]; INC(i); INC(j)
- END;
- host[j] := 0X;
- IF url[i] = ":" THEN
- INC(i); Strings.StrToIntPos(url, val, i);
- port := SHORT(val)
- INC(i); Strings.StrToIntPos(url, val, i);
- ELSE
- port := 0
- port := 0
- END
- i := 0;
- END SplitHostPort;
- PROCEDURE BASE(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr, label: ARRAY 64 OF CHAR;
- s: HyperDocs.LinkScheme;
- key: 长整型;
- port: INTEGER;
- P: Page;
- VAR
- BEGIN
- IF on THEN
- P := S.page;
- WHILE NextAttr(S, attr) DO
- IF attr = "HREF" THEN
- P.base.key := HyperDocs.BuildKey(P.base, S.value);
- s := HyperDocs.LinkSchemeByKey(P.base.key);
- IF s = NIL THEN
- s := HyperDocs.LinkSchemeByPrefix("file")
- s := HyperDocs.LinkSchemeByPrefix("file")
- END;
- COPY(s.prefix, P.base.prefix);
- HyperDocs.RetrieveLink(P.base.key, S.value);
- IF P.base.prefix = "http" THEN
- P.base.key := HTTPDocs0.SplitHTTPAdr(S.value, P.base.host, P.base.path, label, P.base.port)
- P.base.key := HTTPDocs0.SplitHTTPAdr(S.value, P.base.host, P.base.path, label, P.base.port)
- ELSIF P.base.prefix = "file" THEN
- P.base.key := HyperDocs.SplitFileAdr(S.value, P.base.path, label);
- P.base.host := ""; P.base.port := 0
- P.base.key := HyperDocs.SplitFileAdr(S.value, P.base.path, label);
- ELSE (* proxy *)
- SplitHostPort(S.value, P.base.host, P.base.port);
- key := HTTPDocs0.SplitHTTPAdr(S.value, P.base.host, P.base.path, label, port)
- SplitHostPort(S.value, P.base.host, P.base.port);
- END
- P.base.key := HyperDocs.BuildKey(P.base, S.value);
- END
- IF attr = "HREF" THEN
- END
- P := S.page;
- END
- IF on THEN
- END BASE;
- PROCEDURE HexVal(ch: CHAR): INTEGER;
- BEGIN
- IF (ch >= "0") & (ch <= "9") THEN
- RETURN ORD(ch)-ORD("0")
- RETURN ORD(ch)-ORD("0")
- ELSIF (ch >= "A") & (ch <= "F") THEN
- RETURN ORD(ch)-ORD("A")+10
- RETURN ORD(ch)-ORD("A")+10
- ELSIF (ch >= "a") & (ch <= "f") THEN
- RETURN ORD(ch)-ORD("a")+10
- RETURN ORD(ch)-ORD("a")+10
- ELSE
- RETURN 256
- RETURN 256
- END
- IF (ch >= "0") & (ch <= "9") THEN
- END HexVal;
- PROCEDURE Color(CONST val: ARRAY OF CHAR; VAR col: INTEGER);
- VAR
- r, g, b, rr, gg, bb, i, bestC: INTEGER;
- diff, mdiff: REAL;
- r, g, b, rr, gg, bb, i, bestC: INTEGER;
- VAR
- BEGIN
- IF val = "white" THEN
- col := 0; RETURN
- col := 0; RETURN
- ELSIF val = "red" THEN
- col := 1; RETURN
- col := 1; RETURN
- ELSIF val = "green" THEN
- col := 2; RETURN
- col := 2; RETURN
- ELSIF val = "blue" THEN
- col := 3; RETURN
- col := 3; RETURN
- ELSIF val = "black" THEN
- col := 15; RETURN
- col := 15; RETURN
- ELSIF val[0] = "#" THEN
- r := 16*HexVal(val[1])+HexVal(val[2]);
- g := 16*HexVal(val[3])+HexVal(val[4]);
- b := 16*HexVal(val[5])+HexVal(val[6])
- r := 16*HexVal(val[1])+HexVal(val[2]);
- ELSE
- r := 16*HexVal(val[0])+HexVal(val[1]);
- g := 16*HexVal(val[2])+HexVal(val[3]);
- b := 16*HexVal(val[4])+HexVal(val[5])
- r := 16*HexVal(val[0])+HexVal(val[1]);
- END;
- IF (r > 255) OR (g > 255) OR (b > 255) THEN
- RETURN
- RETURN
- END;
- mdiff := MAX(REAL); bestC := 0;
- i := 0;
- WHILE (i < 256) & (mdiff > 0.0) DO
- Display.GetColor(i, rr, gg, bb);
- diff := LONG(rr-r)*LONG(rr-r);
- diff := diff+LONG(gg-g)*LONG(gg-g);
- diff := diff+LONG(bb-b)*LONG(bb-b);
- IF diff < mdiff THEN
- bestC := i; mdiff := diff
- bestC := i; mdiff := diff
- END;
- INC(i)
- Display.GetColor(i, rr, gg, bb);
- END;
- col := bestC
- IF val = "white" THEN
- END Color;
- PROCEDURE BASEFONT(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- val: LONGINT;
- size, i: INTEGER;
- col: BOOLEAN;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- col := FALSE; size := GetFontSize(P);
- WHILE NextAttr(S, attr) DO
- IF attr = "SIZE" THEN
- i := 1;
- IF S.value[0] = "-" THEN
- Strings.StrToIntPos(S.value, val, i);
- size := size-SHORT(val)
- Strings.StrToIntPos(S.value, val, i);
- ELSIF S.value[0] = "+" THEN
- Strings.StrToIntPos(S.value, val, i);
- size := size+SHORT(val)
- Strings.StrToIntPos(S.value, val, i);
- ELSE
- i := 0;
- Strings.StrToIntPos(S.value, val, i);
- size := SHORT(val)
- i := 0;
- END
- i := 1;
- ELSIF attr = "COLOR" THEN
- Color(S.value, P.textC); col := TRUE
- Color(S.value, P.textC); col := TRUE
- END
- IF attr = "SIZE" THEN
- END;
- SetFontSize(P, size);
- IF col THEN
- Texts.SetColor(P.W, SHORT(P.textC))
- Texts.SetColor(P.W, SHORT(P.textC))
- END
- col := FALSE; size := GetFontSize(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END BASEFONT;
- PROCEDURE BIG(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- SetFontSize(P, GetFontSize(P)+2)
- SetFontSize(P, GetFontSize(P)+2)
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END BIG;
- PROCEDURE BLINK(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetColor(P.W, SHORT(Display3.red))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END BLINK;
- PROCEDURE BLOCKQUOTE(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- P.style := NewStyle();
- WriteObj(P, P.style);
- Texts.SetFont(P.W, Syntax(12, "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END BLOCKQUOTE;
- PROCEDURE ChangeColors(P: Page; from, to: SHORTINT);
- VAR tattr: TextAttrs;
- VAR tattr: TextAttrs;
- BEGIN
- IF P.W.col = from THEN
- Texts.SetColor(P.W, to)
- Texts.SetColor(P.W, to)
- END;
- tattr := P.textAttrs;
- WHILE tattr # NIL DO
- IF tattr.col = from THEN
- tattr.col := to
- tattr.col := to
- END;
- tattr := tattr.next
- IF tattr.col = from THEN
- END
- IF P.W.col = from THEN
- END ChangeColors;
- PROCEDURE BODY(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- key: 长整型;
- doc: 文档.文档;
- BackE: HTTPDocs0.Entry;
- col: INTEGER;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- Texts.Append(P.T, P.W.buf);
- WHILE NextAttr(S, attr) DO
- IF attr = "BGCOLOR" THEN
- Color(S.value, P.textbackC); Attributes.SetInt(P.D.dsc, "Color", P.textbackC)
- Color(S.value, P.textbackC); Attributes.SetInt(P.D.dsc, "Color", P.textbackC)
- ELSIF attr = "TEXT" THEN
- col := P.textC; Color(S.value, col);
- ChangeColors(P, SHORT(P.textC), SHORT(col));
- P.textC := col
- col := P.textC; Color(S.value, col);
- ELSIF attr = "LINK" THEN (* 超文本链接 *)
- col := P.linkC; Color(S.value, col);
- ChangeColors(P, SHORT(P.linkC), SHORT(col));
- P.linkC := col; Attributes.SetInt(P.D.dsc, "LinkColor", P.linkC)
- col := P.linkC; Color(S.value, col);
- ELSIF attr = "VLINK" THEN (* 已访问的超文本链接 *)
- col := P.oldLinkC; Color(S.value, col);
- ChangeColors(P, SHORT(P.oldLinkC), SHORT(col));
- P.oldLinkC := col; Attributes.SetInt(P.D.dsc, "OldLinkColor", P.oldLinkC)
- col := P.oldLinkC; Color(S.value, col);
- ELSIF attr = "BACKGROUND" THEN
- key := HyperDocs.BuildKey(P.base, S.value);
- IF imgs THEN
- NEW(BackE);
- BackE.basekey := P.base.dockey; BackE.ol := NIL; BackE.attrs := NIL; BackE.text := P.T;
- BackE.pos := -1; BackE.key := HyperDocs.UndefKey; BackE.obj := P.D;
- NEW(doc); HyperDocs.DocNameByKey(doc.name, key); doc.handle := NIL; doc.dsc := NIL;
- HTTPDocs0.RequestDoc(doc, HTTPDocs0.httpProxy, key, "GET", FALSE, BackE, NIL)
- NEW(BackE);
- END
- key := HyperDocs.BuildKey(P.base, S.value);
- END
- IF attr = "BGCOLOR" THEN
- END
- Texts.Append(P.T, P.W.buf);
- END
- P := S.page;
- END BODY;
- PROCEDURE BR(VAR S: Scanner; on: BOOLEAN);
- BEGIN
- IF on THEN
- WriteLn(S.page)(*; S.page.lines := 0*)
- WriteLn(S.page)(*; S.page.lines := 0*)
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END BR;
- PROCEDURE ExecAttrs*;
- VAR
- exec, cont: Objects.Object;
- name, nr: ARRAY 32 OF CHAR;
- i: LONGINT;
- exec, cont: Objects.Object;
- VAR
- BEGIN
- cont := Gadgets.context; exec := Gadgets.executorObj;
- IF exec # NIL THEN
- i := 1; name := "Cmd";
- Strings.IntToStr(i, nr);
- Strings.Append(name, nr);
- WHILE Attributes.FindAttr(name, exec(Gadgets.Frame).attr) # NIL DO
- Gadgets.ExecuteAttr(exec(Gadgets.Frame), name, cont, NIL, NIL);
- INC(i); name := "Cmd";
- Strings.IntToStr(i, nr);
- Strings.Append(name, nr)
- Gadgets.ExecuteAttr(exec(Gadgets.Frame), name, cont, NIL, NIL);
- END
- i := 1; name := "Cmd";
- END
- cont := Gadgets.context; exec := Gadgets.executorObj;
- END ExecAttrs;
- PROCEDURE CALL(VAR S: Scanner; on: BOOLEAN);
- (* ejz *)
- VAR
- P: Page;
- name, attr: ARRAY 32 OF CHAR;
- i: LONGINT;
- P: Page;
- (* ejz *)
- BEGIN
- P := S.page; CloseA(P);
- IF on THEN
- P.clink := Gadgets.CreateObject("TextGadgets.NewControl");
- i := 0;
- WHILE NextAttr(S, attr) DO
- IF attr = "CMD" THEN
- INC(i); name := "Cmd";
- Strings.IntToStr(i, attr);
- Strings.Append(name, attr);
- Attributes.SetString(P.clink, name, S.value)
- INC(i); name := "Cmd";
- END
- IF attr = "CMD" THEN
- END;
- IF i = 0 THEN
- P.clink := NIL
- P.clink := NIL
- ELSE
- Attributes.SetString(P.clink, "Cmd", "HTMLDocs.ExecAttrs")
- Attributes.SetString(P.clink, "Cmd", "HTMLDocs.ExecAttrs")
- END;
- PushTextAttrs(P);
- Texts.SetColor(P.W, SHORT(Display3.red))
- P.clink := Gadgets.CreateObject("TextGadgets.NewControl");
- ELSE
- IF P.clink # NIL THEN
- WriteObj(P, P.clink)
- WriteObj(P, P.clink)
- END;
- P.clink := NIL; PopTextAttrs(P)
- IF P.clink # NIL THEN
- END
- P := S.page; CloseA(P);
- END CALL;
- PROCEDURE CENTER(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- P.style := NewStyle();
- EXCL(P.style.mode, TextGadgets.left); INCL(P.style.mode, TextGadgets.middle);
- WriteObj(P, P.style)
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END CENTER;
- PROCEDURE CITE(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END CITE;
- PROCEDURE CODEx(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono)
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END CODEx;
- PROCEDURE DD(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- (* IF (P.lists.dtok) THEN
- Texts.WriteString(Wr, "P.lists.dtok = TRUE"); Texts.WriteLn(Wr); Texts.Append(Oberon.Log, Wr.buf)
- Texts.WriteString(Wr, "P.lists.dtok = TRUE"); Texts.WriteLn(Wr); Texts.Append(Oberon.Log, Wr.buf)
- END; *)
- (* <DL> and <DD> can exist with <DT> absent. *)
- IF (P.lists # NIL) & (P.lists.kind = DescList) (* & P.lists.dtok *) THEN
- Texts.Write(P.W, Strings.Tab)
- Texts.Write(P.W, Strings.Tab)
- ELSE
- IF P.lists # NIL THEN
- INC(P.lists.itemNr);
- IF P.lists.itemNr > 1 THEN
- WriteLn(P)
- WriteLn(P)
- END
- INC(P.lists.itemNr);
- ELSE
- WriteLn(P)
- WriteLn(P)
- END
- IF P.lists # NIL THEN
- END
- (* IF (P.lists.dtok) THEN
- END;
- P.blank := FALSE
- (*S.skipWS := TRUE*)
- P := S.page;
- END DD;
- PROCEDURE DFN(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END DFN;
- PROCEDURE DIR(VAR S: Scanner; on: BOOLEAN);
- BEGIN
- IF on THEN
- OpenList(S.page, DefList)
- OpenList(S.page, DefList)
- ELSE
- CloseList(S.page)
- CloseList(S.page)
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END DIR;
- PROCEDURE DIVI(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 32 OF CHAR;
- style: TextGadgets.Style;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- style := NIL;
- WHILE NextAttr(S, attr) DO
- IF attr = "ALIGN" THEN
- style := TextAlign(S.value)
- style := TextAlign(S.value)
- END
- IF attr = "ALIGN" THEN
- END;
- IF style # NIL THEN
- P.style := style; WriteObj(P, P.style)
- P.style := style; WriteObj(P, P.style)
- END
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END DIVI;
- PROCEDURE DL(VAR S: Scanner; on: BOOLEAN);
- BEGIN
- IF on THEN
- OpenList(S.page, DescList)
- OpenList(S.page, DescList)
- ELSE
- CloseList(S.page)
- CloseList(S.page)
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END DL;
- PROCEDURE DT(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- IF P.lists # NIL THEN
- INC(P.lists.itemNr);
- IF P.lists.itemNr > 1 THEN
- WriteLn(P)
- WriteLn(P)
- END;
- IF P.lists.kind = DescList THEN
- P.lists.dtok := TRUE;
- Texts.Write(P.W, Strings.Tab)
- P.lists.dtok := TRUE;
- END
- INC(P.lists.itemNr);
- ELSE
- WriteLn(P)
- WriteLn(P)
- END
- IF P.lists # NIL THEN
- END;
- P.blank := FALSE
- (*S.skipWS := TRUE*)
- P := S.page;
- END DT;
- PROCEDURE EM(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END EM;
- PROCEDURE FRAME(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- P: Page;
- VAR
- BEGIN
- P := S.page; CloseA(P); P.linkkey := HyperDocs.UndefKey;
- IF on THEN
- WHILE NextAttr(S, attr) DO
- IF (attr = "SRC") OR (attr = "HREF") THEN
- P.lines := 0; WriteLn(P); WriteLn(P); Texts.WriteString(P.W, "FRAME Reference: ");
- HREF(P, S.value, attr, P.linkkey);
- IF P.linkkey # HyperDocs.UndefKey THEN
- P.alink := HyperDocs.LinkControl(P.linkkey);
- HyperDocs.RetrieveLink(P.linkkey, S.value);
- Attributes.SetString(P.alink, "Opt", "N")
- P.alink := HyperDocs.LinkControl(P.linkkey);
- ELSE
- P.alink := Gadgets.CreateObject("TextGadgets.NewControl");
- Attributes.SetString(P.alink, "Cmd", attr)
- P.alink := Gadgets.CreateObject("TextGadgets.NewControl");
- END;
- PushTextAttrs(P); Texts.SetColor(P.W, SHORT(P.linkC));
- Texts.WriteString(P.W, S.value); WriteObj(P, P.alink);
- P.alink := NIL; P.linkkey := HyperDocs.UndefKey;
- PopTextAttrs(P); WriteLn(P)
- P.lines := 0; WriteLn(P); WriteLn(P); Texts.WriteString(P.W, "FRAME Reference: ");
- END
- IF (attr = "SRC") OR (attr = "HREF") THEN
- END
- WHILE NextAttr(S, attr) DO
- END
- P := S.page; CloseA(P); P.linkkey := HyperDocs.UndefKey;
- END FRAME;
- PROCEDURE FONT(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- val: LONGINT;
- size, i, textC: INTEGER;
- col: BOOLEAN;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- col := FALSE; size := GetFontSize(P);
- WHILE NextAttr(S, attr) DO
- IF attr = "SIZE" THEN
- i := 1;
- IF S.value[0] = "-" THEN
- Strings.StrToIntPos(S.value, val, i);
- size := size-SHORT(val)
- Strings.StrToIntPos(S.value, val, i);
- ELSIF S.value[0] = "+" THEN
- Strings.StrToIntPos(S.value, val, i);
- size := size+SHORT(val)
- Strings.StrToIntPos(S.value, val, i);
- ELSE
- i := 0;
- Strings.StrToIntPos(S.value, val, i);
- size := SHORT(val)
- i := 0;
- END
- i := 1;
- ELSIF attr = "COLOR" THEN
- Color(S.value, textC); col := TRUE
- Color(S.value, textC); col := TRUE
- END
- IF attr = "SIZE" THEN
- END;
- SetFontSize(P, size);
- IF col THEN
- Texts.SetColor(P.W, SHORT(textC))
- Texts.SetColor(P.W, SHORT(textC))
- END
- col := FALSE; size := GetFontSize(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END FONT;
- PROCEDURE GREEN(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetColor(P.W, SHORT(Display3.green))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END GREEN;
- PROCEDURE H(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- style: TextGadgets.Style;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- style := NIL; PushTextAttrs(P);
- IF ~P.left THEN
- WriteLn(P); WriteLn(P)
- WriteLn(P); WriteLn(P)
- ELSE
- P.left := FALSE
- P.left := FALSE
- END;
- CASE ORD(S.value[1])-ORD("0") OF
- 1: Texts.SetFont(P.W, Syntax(20, 0X))
- |2: Texts.SetFont(P.W, Syntax(16, 0X))
- |3: Texts.SetFont(P.W, Syntax(16, "i"))
- |4: Texts.SetFont(P.W, Syntax(14, 0X))
- |5: Texts.SetFont(P.W, Syntax(14, "i"))
- |6: Texts.SetFont(P.W, Syntax(12, 0X))
- 1: Texts.SetFont(P.W, Syntax(20, 0X))
- ELSE
- Texts.SetFont(P.W, Syntax(12, 0X))
- Texts.SetFont(P.W, Syntax(12, 0X))
- END;
- WHILE NextAttr(S, attr) DO
- IF attr = "ALIGN" THEN
- style := TextAlign(S.value)
- style := TextAlign(S.value)
- ELSIF attr = "SRC" THEN
- (* get image *)
- (* get image *)
- ELSIF attr = "DINGBAT" THEN
- (* get icon with name value *)
- (* get icon with name value *)
- END
- IF attr = "ALIGN" THEN
- END;
- IF style # NIL THEN
- P.style := style; WriteObj(P, P.style)
- P.style := style; WriteObj(P, P.style)
- END
- style := NIL; PushTextAttrs(P);
- ELSE
- CloseA(P); PopTextAttrs(P);
- WriteLn(P); WriteLn(P)
- CloseA(P); PopTextAttrs(P);
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END H;
- PROCEDURE HEAD(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END HEAD;
- PROCEDURE HP(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END HP;
- PROCEDURE HR(VAR S: Scanner; on: BOOLEAN);
- VAR
- attr: ARRAY 64 OF CHAR;
- P: Page;
- l: LONGINT;
- w, h, pos: INTEGER;
- attr: ARRAY 64 OF CHAR;
- VAR
- BEGIN
- IF on THEN
- P := S.page; CloseA(P);
- w := dispW; h := 1;
- WHILE NextAttr(S, attr) DO
- IF attr = "SIZE" THEN
- Strings.StrToInt(S.value, l); h := SHORT(l)
- Strings.StrToInt(S.value, l); h := SHORT(l)
- ELSIF attr = "WIDTH" THEN
- pos := 0; Strings.StrToIntPos(S.value, l, pos);
- w := SHORT(l);
- IF S.value[pos] = "%" THEN
- w := SHORT( (LONG((5*dispW) DIV 8) * w) DIV LONG(100) )
- w := SHORT( (LONG((5*dispW) DIV 8) * w) DIV LONG(100) )
- END
- pos := 0; Strings.StrToIntPos(S.value, l, pos);
- END
- IF attr = "SIZE" THEN
- END;
- HorzRule(P, w, h)
- P := S.page; CloseA(P);
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END HR;
- PROCEDURE HTML(VAR S: Scanner; on: BOOLEAN);
(*
- BEGIN
- IF ~on THEN
- Texts.WriteLn(S.page.W);
- (*S.skipWS := TRUE; *)S.state := TextPlain
- Texts.WriteLn(S.page.W);
- END *)
- IF ~on THEN
- END HTML;
- PROCEDURE HTTP(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END HTTP;
- PROCEDURE I(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END I;
- PROCEDURE KBD(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono)
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END KBD;
- PROCEDURE LI(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- i: INTEGER;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- IF P.lists # NIL THEN
- INC(P.lists.itemNr);
- IF P.lists.itemNr > 1 THEN
- WriteLn(P)
- WriteLn(P)
- END;
- FOR i := 1 TO P.lists.nesting DO
- Texts.Write(P.W, Strings.Tab)
- Texts.Write(P.W, Strings.Tab)
- END
- INC(P.lists.itemNr);
- ELSE
- WriteLn(P)
- WriteLn(P)
- END;
- IF (P.lists # NIL) & (P.lists.kind = OrderedList) THEN
- Texts.WriteInt(P.W, P.lists.itemNr, 0)
- Texts.WriteInt(P.W, P.lists.itemNr, 0)
- ELSE
- IF P.lists # NIL THEN
- i := P.lists.nesting MOD LEN(bullets)
- i := P.lists.nesting MOD LEN(bullets)
- ELSE
- i := 0
- i := 0
- END;
- PushTextAttrs(P);
- Texts.SetFont(P.W, bullets[i].f);
- Texts.Write(P.W, bullets[i].c);
- PopTextAttrs(P)
- IF P.lists # NIL THEN
- END;
- Texts.Write(P.W, Strings.Tab)
- IF P.lists # NIL THEN
- END;
- P.blank := FALSE
- (*S.skipWS := TRUE*)
- P := S.page;
- END LI;
- PROCEDURE LINK(VAR S: Scanner; on: BOOLEAN);
(* VAR
- P: Page;
- attr, cmd, caption: ARRAY 64 OF CHAR;
- key: 长整型;
- obj: Objects.Object;
- P: Page;
- BEGIN
- IF on THEN
- P := S.page; caption := ""; cmd := "";
- WHILE NextAttr(S, attr) DO
- IF attr = "HREF" THEN
- HREF(P, S.value, cmd, key);
- IF key # HyperDocs.UndefKey THEN
- cmd := "HyperDocs.FollowLink #Key"
- cmd := "HyperDocs.FollowLink #Key"
- END
- HREF(P, S.value, cmd, key);
- ELSIF attr = "REV" THEN
- IF caption = "" THEN
- COPY(S.value, caption)
- COPY(S.value, caption)
- END
- IF caption = "" THEN
- ELSIF attr = "REL" THEN
- IF caption = "" THEN
- COPY(S.value, caption)
- COPY(S.value, caption)
- END
- IF caption = "" THEN
- ELSIF attr = "TITLE" THEN
- COPY(S.value, caption)
- COPY(S.value, caption)
- END
- IF attr = "HREF" THEN
- END;
- IF cmd # "" THEN
- obj := Gadgets.CreateObject("BasicGadgets.NewButton");
- Attributes.SetString(obj, "Caption", caption);
- Attributes.SetString(obj, "Cmd", cmd);
- obj := Gadgets.CreateObject("BasicGadgets.NewButton");
- P := S.page; caption := ""; cmd := "";
- IF on THEN
(* ?! fixup on reload *)
- Attributes.SetInt(obj, "Key", key);
- 写入对象(P, obj)
- Attributes.SetInt(obj, "Key", key);
- END
- END *)
- END LINK;
- PROCEDURE LISTING(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono);
- S.pre := TRUE
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P);
- S.pre := FALSE
- PopTextAttrs(P);
- END
- P := S.page;
- END LISTING;
- PROCEDURE ISINDEX(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- objt, objb: Objects.Object;
- form: 表单;
- attr: ARRAY 64 OF CHAR;
- prompt: ARRAY 512 OF CHAR;
- key: 长整型;
- P: Page;
- VAR
- BEGIN
- IF on THEN
- P := S.page;
- key := P.base.key; NewForm(); form := Objects.NewObj(Form);
- prompt := "This is a searchable index. Enter search keywords: ";
- WHILE NextAttr(S, attr) DO
- IF attr = "PROMPT" THEN
- COPY(S.value, prompt)
- COPY(S.value, prompt)
- ELSIF attr = "HREF" THEN
- key := HyperDocs.BuildKey(P.base, S.value)
- key := HyperDocs.BuildKey(P.base, S.value)
- END
- IF attr = "PROMPT" THEN
- END;
- WriteObj(P, form); HorzRule(P, dispW, 1);
- Texts.WriteString(P.W, prompt);
- objt := Gadgets.CreateObject("BasicGadgets.NewInteger");
- Attributes.SetInt(objt, "Value", key);
- AddFormObj(P, form, objt, "@ACTION", FALSE, FALSE);
- objt := Gadgets.CreateObject("TextFields.NewTextField");
- AddFormObj(P, form, objt, "QUERY", FALSE, TRUE);
- objb := Gadgets.CreateObject("BasicGadgets.NewButton");
- objb(Display.Frame).H := objt(Display.Frame).H;
- Attributes.SetString(objb, "Query", "ISINDEX");
- Attributes.SetString(objb, "Method", "GET");
- Attributes.SetString(objb, "Caption", "搜索");
- Attributes.SetString(objb, "Cmd", "HTMLDocs.SubmitQuery");
- AddFormObj(P, form, objb, "", FALSE, TRUE);
- HorzRule(P, dispW, 1)
- P := S.page;
- END
- IF on THEN
- END ISINDEX;
- PROCEDURE MENU(VAR S: Scanner; on: BOOLEAN);
- BEGIN
- IF on THEN
- OpenList(S.page, DefList)
- OpenList(S.page, DefList)
- ELSE
- CloseList(S.page)
- CloseList(S.page)
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END MENU;
- PROCEDURE META(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END META;
- PROCEDURE NEXTID(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END NEXTID;
- PROCEDURE NOFRAMES(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- HorzRule(P, dispW, 1)
- P := S.page;
- END NOFRAMES;
- PROCEDURE OL(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- OpenList(P, OrderedList)
- OpenList(P, OrderedList)
- ELSE
- CloseList(P)
- CloseList(P)
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END OL;
- PROCEDURE P(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- style: TextGadgets.Style;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- style := NIL; CloseA(P);
- WriteLn(P); WriteLn(P); (*P.lines := 0;*)
- WHILE NextAttr(S, attr) DO
- IF attr = "ALIGN" THEN
- style := TextAlign(S.value)
- style := TextAlign(S.value)
- END
- IF attr = "ALIGN" THEN
- END;
- IF style # NIL THEN
- PushTextAttrs(P);
- P.style := style; WriteObj(P, P.style)
- PushTextAttrs(P);
- END
- style := NIL; CloseA(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END;
- (*S.skipWS := TRUE*)
- P := S.page;
- END P;
- PROCEDURE PLAINTEXT(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono);
- S.state := TextPlain; S.pre := TRUE
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P);
- S.state := TextHtml; S.pre := FALSE
- PopTextAttrs(P);
- END
- P := S.page;
- END PLAINTEXT;
- PROCEDURE PRE(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono);
- S.pre := TRUE
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P);
- S.pre := FALSE
- PopTextAttrs(P);
- END
- P := S.page;
- END PRE;
- PROCEDURE Q(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- Texts.WriteString(P.W, "<<")
- Texts.WriteString(P.W, "<<")
- ELSE
- Texts.WriteString(P.W, ">>")
- Texts.WriteString(P.W, ">>")
- END
- P := S.page;
- END Q;
- PROCEDURE Range(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END Range;
- PROCEDURE SAMP(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono)
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END SAMP;
- PROCEDURE SMALL(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- SetFontSize(P, GetFontSize(P)-2)
- SetFontSize(P, GetFontSize(P)-2)
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END SMALL;
- PROCEDURE STRIKE(VAR S: Scanner; on: BOOLEAN);
- (* 删除线文本,如何 ? *)
- (* ignore *)
- (* 删除线文本,如何 ? *)
- END STRIKE;
- PROCEDURE STRONG(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "b"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END STRONG;
- PROCEDURE STYLE(VAR S: Scanner; on: BOOLEAN);
- (* ignore *)
- (* ignore *)
- END STYLE;
- PROCEDURE SUB(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- SetFontSize(P, GetFontSize(P)-2);
- Texts.SetOffset(P.W, P.W.voff-4)
- SetFontSize(P, GetFontSize(P)-2);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END SUB;
- PROCEDURE SUP(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- SetFontSize(P, GetFontSize(P)-2);
- Texts.SetOffset(P.W, P.W.voff+4)
- SetFontSize(P, GetFontSize(P)-2);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END SUP;
- PROCEDURE TINY(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- SetFontSize(P, GetFontSize(P)-2)
- SetFontSize(P, GetFontSize(P)-2)
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END TINY;
- PROCEDURE TITLE(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF P.head THEN
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, Syntax(12, 0X));
- Texts.WriteString(P.W, "标题: ")
- PushTextAttrs(P);
- ELSE
- WriteLn(P); PopTextAttrs(P);
- HorzRule(P, dispW, 2);
- Texts.Append(P.T, P.W.buf);
- P.headerLen := P.T.len
- WriteLn(P); PopTextAttrs(P);
- END
- IF on THEN
- ELSIF ~on THEN
- PushTextAttrs(P);
- Texts.OpenWriter(P.W);
- PopTextAttrs(P)
- PushTextAttrs(P);
- END
- (*S.skipWS := TRUE*)
- P := S.page;
- END TITLE;
- PROCEDURE TT(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono)
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END TT;
- PROCEDURE TAB(VAR S: Scanner; on: BOOLEAN);
- VAR
- P: Page;
- attr: ARRAY 64 OF CHAR;
- style: TextGadgets.Style;
- P: Page;
- VAR
- BEGIN
- P := S.page;
- IF on THEN
- Texts.Write(P.W, Strings.Tab);
- style := NIL;
- WHILE NextAttr(S, attr) DO
- IF attr = "ALIGN" THEN
- style := TextAlign(S.value)
- style := TextAlign(S.value)
- END
- IF attr = "ALIGN" THEN
- END;
- IF style # NIL THEN
- PushTextAttrs(P);
- P.style := style; WriteObj(P, P.style)
- PushTextAttrs(P);
- END
- Texts.Write(P.W, Strings.Tab);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END;
- P.blank := FALSE
- (*S.skipWS := TRUE*)
- P := S.page;
- END TAB;
- PROCEDURE U(VAR S: Scanner; on: BOOLEAN);
- (* 下划线文本,如何 ? *)
- (* ignore *)
- (* 下划线文本,如何 ? *)
- END U;
- PROCEDURE UL(VAR S: Scanner; on: BOOLEAN);
- BEGIN
- IF on THEN
- OpenList(S.page, DefList)
- OpenList(S.page, DefList)
- ELSE
- CloseList(S.page)
- CloseList(S.page)
- END;
- (*S.skipWS := TRUE*)
- IF on THEN
- END UL;
- PROCEDURE VARN(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, ChangeFontAttr(P.W.lib(Fonts.Font), "i"))
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P)
- PopTextAttrs(P)
- END
- P := S.page;
- END VARN;
- PROCEDURE XMP(VAR S: Scanner; on: BOOLEAN);
- VAR P: Page;
- VAR P: Page;
- BEGIN
- P := S.page;
- IF on THEN
- PushTextAttrs(P);
- Texts.SetFont(P.W, mono);
- S.pre := TRUE
- PushTextAttrs(P);
- ELSE
- PopTextAttrs(P); S.pre := FALSE
- PopTextAttrs(P); S.pre := FALSE
- END
- P := S.page;
- END XMP;
- PROCEDURE HandleTag(VAR S: Scanner);
- VAR
- Ss: Texts.Scanner;
- gen: ARRAY 64 OF CHAR;
- e: ExtTag;
- i: INTEGER;
- found, on: BOOLEAN;
- prev: CHAR;
- Ss: Texts.Scanner;
- VAR
- BEGIN
- WHILE ~S.end & (S.ch <= " ") DO
- Read(S)
- Read(S)
- END;
- IF S.ch = "!" THEN
- prev := S.ch; Read(S);
- IF S.ch = "-" THEN
- prev := S.ch; Read(S);
- IF S.ch = "-" THEN
- WHILE ~S.end & ((S.ch # ">") OR ((prev # "-") & (prev # "!"))) DO
- IF S.ch > " " THEN
- prev := S.ch
- prev := S.ch
- END;
- Read(S)
- IF S.ch > " " THEN
- END
- WHILE ~S.end & ((S.ch # ">") OR ((prev # "-") & (prev # "!"))) DO
- ELSE
- WHILE ~S.end & (S.ch # ">") DO
- Read(S)
- Read(S)
- END
- WHILE ~S.end & (S.ch # ">") DO
- END
- prev := S.ch; Read(S);
- ELSE
- WHILE ~S.end & (S.ch # ">") DO
- Read(S)
- Read(S)
- END
- WHILE ~S.end & (S.ch # ">") DO
- END;
- Read(S)
- prev := S.ch; Read(S);
- ELSIF ~Strings.IsAlpha(S.ch) & (S.ch # "/") THEN
- Texts.Write(S.page.W, "<")
- Texts.Write(S.page.W, "<")
- ELSE
- S.state := InTag; Next(S);
- IF S.class = OpenEndTag THEN
- on := FALSE; Next(S)
- on := FALSE; Next(S)
- ELSE
- on := TRUE
- on := TRUE
- END;
- IF S.class = Value THEN
- Strings.Upper(S.value, S.value); found := TRUE;
- CASE S.value[0] OF
- "A": IF S.value[1] = 0X THEN
- A(S, on)
- A(S, on)
- ELSIF (S.value = "ADDR") OR (S.value = "Address") THEN
- Address(S, on)
- Address(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"B": IF S.value[1] = 0X THEN
- B(S, on)
- B(S, on)
- ELSIF S.value = "BASE" THEN
- BASE(S, on)
- BASE(S, on)
- ELSIF S.value = "BASEFONT" THEN
- BASEFONT(S, on)
- BASEFONT(S, on)
- ELSIF S.value = "BIG" THEN
- BIG(S, on)
- BIG(S, on)
- ELSIF S.value = "BLINK" THEN
- BLINK(S, on)
- BLINK(S, on)
- ELSIF (S.value = "BQ") OR (S.value = "BLOCKQUOTE") THEN
- BLOCKQUOTE(S, on)
- BLOCKQUOTE(S, on)
- ELSIF S.value = "BODY" THEN
- BODY(S, on)
- BODY(S, on)
- ELSIF S.value = "BR" THEN
- BR(S, on)
- BR(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"C": IF S.value = "CALL" THEN
- CALL(S, on)
- CALL(S, on)
- ELSIF S.value = "CENTER" THEN
- CENTER(S, on)
- CENTER(S, on)
- ELSIF S.value = "CITE" THEN
- CITE(S, on)
- CITE(S, on)
- ELSIF S.value = "CODE" THEN
- CODEx(S, on)
- CODEx(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"D": IF S.value = "DD" THEN
- DD(S, on)
- DD(S, on)
- ELSIF S.value = "DFN" THEN
- DFN(S, on)
- DFN(S, on)
- ELSIF S.value = "DIR" THEN
- DIR(S, on)
- DIR(S, on)
- ELSIF S.value = "DIV" THEN
- DIVI(S, on)
- DIVI(S, on)
- ELSIF S.value = "DL" THEN
- DL(S, on)
- DL(S, on)
- ELSIF S.value = "DT" THEN
- DT(S, on)
- DT(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"E": IF S.value = "EM" THEN
- EM(S, on)
- EM(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"F": IF S.value = "FRAME" THEN
- FRAME(S, on)
- FRAME(S, on)
- ELSIF S.value = "FONT" THEN
- FONT(S, on)
- FONT(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"G": IF S.value = "GREEN" THEN
- GREEN(S, on)
- GREEN(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"H": IF (S.value = "HEAD") OR (S.value = "HEADER") THEN
- HEAD(S, on)
- HEAD(S, on)
- ELSIF S.value = "HP" THEN
- HP(S, on)
- HP(S, on)
- ELSIF S.value = "HR" THEN
- HR(S, on)
- HR(S, on)
- ELSIF S.value = "HTML" THEN
- HTML(S, on)
- HTML(S, on)
- ELSIF S.value = "HTTP" THEN
- HTTP(S, on)
- HTTP(S, on)
- ELSIF Strings.IsDigit(S.value[1]) THEN
- H(S, on)
- H(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"I": IF S.value[1] = 0X THEN
- I(S, on)
- I(S, on)
- ELSIF S.value = "ISINDEX" THEN
- ISINDEX(S, on)
- ISINDEX(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"K": IF S.value = "KBD" THEN
- KBD(S, on)
- KBD(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"L": IF S.value = "LI" THEN
- LI(S, on)
- LI(S, on)
- ELSIF S.value = "LINK" THEN
- LINK(S, on)
- LINK(S, on)
- ELSIF S.value = "LISTING" THEN
- LISTING(S, on)
- LISTING(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"M": IF S.value = "MENU" THEN
- MENU(S, on)
- MENU(S, on)
- ELSIF S.value = "META" THEN
- META(S, on)
- META(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"N": IF S.value = "NEXTID" THEN
- NEXTID(S, on)
- NEXTID(S, on)
- ELSIF S.value = "NOFRAMES" THEN
- NOFRAMES(S, on)
- NOFRAMES(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"O": IF S.value = "OL" THEN
- OL(S, on)
- OL(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"P": IF S.value[1] = 0X THEN
- P(S, on)
- P(S, on)
- ELSIF S.value = "PLAINTEXT" THEN
- PLAINTEXT(S, on)
- PLAINTEXT(S, on)
- ELSIF S.value = "PRE" THEN
- PRE(S, on)
- PRE(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"Q": IF S.value[1] = 0X THEN
- Q(S, on)
- Q(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"R": IF S.value = "RANGE" THEN
- Range(S, on)
- Range(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"S": IF S.value[1] = 0X THEN
- STRIKE(S, on)
- STRIKE(S, on)
- ELSIF S.value = "SAMP" THEN
- SAMP(S, on)
- SAMP(S, on)
- ELSIF S.value = "STRIKE" THEN
- STRIKE(S, on)
- STRIKE(S, on)
- ELSIF S.value = "STRONG" THEN
- STRONG(S, on)
- STRONG(S, on)
- ELSIF S.value = "STYLE" THEN
- STYLE(S, on)
- STYLE(S, on)
- ELSIF S.value = "SMALL" THEN
- SMALL(S, on)
- SMALL(S, on)
- ELSIF S.value = "SUB" THEN
- SUB(S, on)
- SUB(S, on)
- ELSIF S.value = "SUP" THEN
- SUP(S, on)
- SUP(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"T": IF S.value = "TITLE" THEN
- TITLE(S, on)
- TITLE(S, on)
- ELSIF S.value = "TT" THEN
- TT(S, on)
- TT(S, on)
- ELSIF S.value = "TAB" THEN
- TAB(S, on)
- TAB(S, on)
- ELSIF S.value = "TINY" THEN
- TINY(S, on)
- TINY(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"U": IF S.value[1] = 0X THEN
- U(S, on)
- U(S, on)
- ELSIF S.value = "UL" THEN
- UL(S, on)
- UL(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"V": IF S.value = "VAR" THEN
- VARN(S, on)
- VARN(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- |"X": IF S.value = "XMP" THEN
- XMP(S, on)
- XMP(S, on)
- ELSE
- found := FALSE
- found := FALSE
- END
- "A": IF S.value[1] = 0X THEN
- ELSE
- found := FALSE
- found := FALSE
- END;
- IF ~found THEN
- e := extTags;
- WHILE (e # NIL) & (e.tag # S.value) DO
- e := e.next
- e := e.next
- END;
- IF e = NIL THEN
- gen := "HTMLTags."; Strings.Append(gen, S.value);
- Oberon.OpenScanner(Ss, gen);
- IF Ss.class IN {Texts.Name, Texts.String} THEN
- COPY(Ss.s, gen);
- newTag := NIL; Oberon.Call(gen, Oberon.Par, FALSE, i);
- IF i # 0 THEN
- Texts.WriteString(Wr, gen);
- Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf)
- Texts.WriteString(Wr, gen);
- END;
- IF newTag # NIL THEN
- e := newTag; COPY(S.value, e.tag);
- e.next := extTags; extTags := e;
- e.start(S.page)
- e := newTag; COPY(S.value, e.tag);
- END
- COPY(Ss.s, gen);
- END
- gen := "HTMLTags."; Strings.Append(gen, S.value);
- END;
- IF e # NIL THEN
- e.handle(S, on); found := TRUE
- e.handle(S, on); found := TRUE
- END
- e := extTags;
- END;
- WHILE ~S.end & (S.class # CloseTag) DO
- Next(S)
- Next(S)
- END;
- IF ~found THEN
- Strings.Upper(S.value, S.value); found := TRUE;
- S.state := InTag; Next(S);
- WHILE ~S.end & (S.ch <= " ") DO
- ELSE
- ELSE
- END
- END
- END
- END;
- S.state := TextHtml
- END HandleTag;
- PROCEDURE DocHandler(D: Objects.Object; VAR M: Objects.ObjMsg);
- BEGIN
- WITH D: Documents.Document DO
- IF M IS 对象.属性消息 THEN
- WITH M: 对象.属性消息 DO
- IF (M.id = 对象.获取) & (M.name = "Gen") THEN
- M.class := Objects.String; M.s := "HTMLDocs.NewDoc"; M.res := 0
- M.class := Objects.String; M.s := "HTMLDocs.NewDoc"; M.res := 0
- ELSE
- TextDocs.DocHandler(D, M)
- TextDocs.DocHandler(D, M)
- END
- IF (M.id = 对象.获取) & (M.name = "Gen") THEN
- END
- WITH M: 对象.属性消息 DO
- ELSIF M IS Objects.LinkMsg THEN
- WITH M: Objects.LinkMsg DO
- IF M.id = Objects.get THEN
- IF M.name = "DeskMenu" THEN
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLDeskMenu", TRUE);
- IF M.obj = NIL THEN M.obj := Desktops.NewMenu(Menu) END;
- M.res := 0
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLDeskMenu", TRUE);
- ELSIF M.name = "SystemMenu" THEN
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLSystemMenu", TRUE);
- IF M.obj = NIL THEN M.obj := Desktops.NewMenu(Menu) END;
- M.res := 0
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLSystemMenu", TRUE);
- ELSIF M.name = "UserMenu" THEN
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLUserMenu", TRUE);
- IF M.obj = NIL THEN M.obj := Desktops.NewMenu(Menu) END;
- M.res := 0
- M.obj := Gadgets.CopyPublicObject("NetDocs.HTMLUserMenu", TRUE);
- ELSE
- TextDocs.DocHandler(D, M)
- TextDocs.DocHandler(D, M)
- END
- IF M.name = "DeskMenu" THEN
- ELSE
- TextDocs.DocHandler(D, M)
- TextDocs.DocHandler(D, M)
- END
- IF M.id = Objects.get THEN
- END
- WITH M: Objects.LinkMsg DO
- ELSE
- TextDocs.DocHandler(D, M)
- TextDocs.DocHandler(D, M)
- END
- IF M IS 对象.属性消息 THEN
- END
- WITH D: Documents.Document DO
- END DocHandler;
- PROCEDURE TextColor(col: INTEGER): SHORTINT;
- VAR r, g, b: INTEGER;
- VAR r, g, b: INTEGER;
- BEGIN
- Display.GetColor(col, r, g, b);
- IF (0.3*r+0.59*g+0.11*b) > 0.35 THEN
- RETURN SHORT(Display3.black)
- RETURN SHORT(Display3.black)
- ELSE
- RETURN SHORT(Display3.white)
- RETURN SHORT(Display3.white)
- END
- Display.GetColor(col, r, g, b);
- END TextColor;
- PROCEDURE EndPage(P: Page);
- VAR
- me: Oberon.Task;
- e: ExtTag;
- p: Page;
- me: Oberon.Task;
- VAR
- BEGIN
- me := P.task; CloseA(P);
- e := extTags;
- WHILE e # NIL DO
- e.stop(P); e := e.next
- e.stop(P); e := e.next
- END;
- Texts.Append(P.T, P.W.buf);
- WITH me: Task DO
- IF me.S.S # NIL THEN
- me.S.S.Close(me.S.S); me.S.S := NIL
- me.S.S.Close(me.S.S); me.S.S := NIL
- END
- IF me.S.S # NIL THEN
- END;
- P.D.handle := DocHandler;
- Attributes.SetString(P.D, "Type", "HTML");
- Attributes.SetInt(P.D.dsc, "Color", P.textbackC);
- IF P.textbackC # Display3.textbackC THEN
- Texts.ChangeLooks(P.T, 0, P.headerLen, {1}, NIL, TextColor(P.textbackC), 0)
- Texts.ChangeLooks(P.T, 0, P.headerLen, {1}, NIL, TextColor(P.textbackC), 0)
- END;
- IF (P.orgPos > 0) & (P.D.dsc(TextGadgets.Frame).org = 0) THEN
- HyperDocs.ScrollTo(P.D.dsc(TextGadgets.Frame), P.orgPos);
- IF HTTPDocs0.curNode # NIL THEN
- HyperDocs.RememberOrg(P.orgPos, HTTPDocs0.curNode, HTTPDocs0.curNode)
- HyperDocs.RememberOrg(P.orgPos, HTTPDocs0.curNode, HTTPDocs0.curNode)
- END
- HyperDocs.ScrollTo(P.D.dsc(TextGadgets.Frame), P.orgPos);
- END;
- Texts.Append(P.source, P.Ws.buf);
- IF P.cacheSource THEN
- HyperDocs.CacheText(HTTPDocs0.StripLoc(P.docKey), P.source)
- HyperDocs.CacheText(HTTPDocs0.StripLoc(P.docKey), P.source)
- END;
- Oberon.Remove(me); p := pages;
- WHILE (p # NIL) & (p.next # P) DO
- p := p.next
- p := p.next
- END;
- IF p # NIL THEN
- p.next := P.next
- p.next := P.next
- ELSE
- pages := P.next
- pages := P.next
- END;
- P.task := NIL; Oberon.Collect()
- me := P.task; CloseA(P);
- END EndPage;
- PROCEDURE ParseNext(me: Oberon.Task);
- VAR
- P: Page;
- St: Streams.Stream;
- i, minSize, timeOut: LONGINT;
- app: BOOLEAN;
- P: Page;
- VAR
- BEGIN
- WITH me: Task DO
- P := me.S.page;
- IF me.S.state # End THEN
- i := Input.Time(); timeOut := i + Input.TimeUnit; me.time := i;
- St := me.S.S; app := FALSE;
- me.S.avail := St.Available(St); minSize := (*64*)1; (* NetSystem.State 变化后解决挂起问题的解决方法 *)
- IF (me.S.avail < minSize) & (me.S.avail > 0) THEN
- IF St.State(St) = Streams.closed THEN
- minSize := me.S.avail
- minSize := me.S.avail
- ELSIF ~St.buffer THEN
- minSize := 1
- minSize := 1
- END
- IF St.State(St) = Streams.closed THEN
- END;
- WHILE (me.S.avail >= minSize) & (me.time < timeOut) DO
- app := TRUE;
- CASE me.S.class OF
- WhiteSpace: WriteSpace(P)
- |OpenTag: HandleTag(me.S)
- |CharRef: WriteCharRef(P, me.S); P.lines := 0; P.blank := TRUE
- |Character: Texts.Write(P.W, me.S.char); P.lines := 0; P.blank := TRUE
- WhiteSpace: WriteSpace(P)
- ELSE
- (* ??? *)
- END;
- Next(me.S);
- IF me.S.avail <= minSize THEN
- me.S.avail := St.Available(St); me.time := Input.Time()
- me.S.avail := St.Available(St); me.time := Input.Time()
- END;
- IF (me.S.avail < minSize) & (me.S.avail > 0) THEN
- IF St.State(St) = Streams.closed THEN
- minSize := me.S.avail
- minSize := me.S.avail
- ELSIF ~St.buffer THEN
- minSize := 1
- minSize := 1
- END
- IF St.State(St) = Streams.closed THEN
- END
- app := TRUE;
- END;
- me.time := Input.Time(); i := 0;
- WHILE St.eos & (me.S.state # End) & (i < 5) DO (* :-) *)
- app := TRUE;
- CASE me.S.class OF
- WhiteSpace: WriteSpace(P)
- |OpenTag: HandleTag(me.S)
- |CharRef: WriteCharRef(P, me.S); P.lines := 0; P.blank := TRUE
- |Character: Texts.Write(P.W, me.S.char); P.lines := 0; P.blank := TRUE
- WhiteSpace: WriteSpace(P)
- ELSE
- (* ??? *)
- END;
- Next(me.S); INC(i)
- app := TRUE;
- END;
- me.S.avail := 0;
- IF app THEN
- Texts.Append(P.T, P.W.buf); INC(me.time, Input.TimeUnit DIV 5)
- Texts.Append(P.T, P.W.buf); INC(me.time, Input.TimeUnit DIV 5)
- ELSE
- INC(me.time, Input.TimeUnit)
- INC(me.time, Input.TimeUnit)
- END
- i := Input.Time(); timeOut := i + Input.TimeUnit; me.time := i;
- END;
- IF me.S.state = End THEN
- EndPage(P)
- EndPage(P)
- END
- P := me.S.page;
- END
- WITH me: Task DO
- END ParseNext;
(* 查询注册表中 NetSystem 部分的字符串设置。 *)
- PROCEDURE QueryString(CONST key: ARRAY OF CHAR; VAR s: ARRAY OF CHAR): BOOLEAN;
- VAR lKey: ARRAY 32 OF CHAR; S: Texts.Scanner;
- BEGIN
- lKey := "NetSystem."; Strings.Append(lKey, key);
- Oberon.OpenScanner(S, lKey);
- IF S.class IN {Texts.Name, Texts.String} THEN
- COPY(S.s, s)
- COPY(S.s, s)
- ELSE
- COPY("", s)
- COPY("", s)
- END;
- RETURN s # ""
- lKey := "NetSystem."; Strings.Append(lKey, key);
- END QueryString;
- PROCEDURE QueryBool(CONST key: ARRAY OF CHAR): BOOLEAN;
- VAR
- str: ARRAY 16 OF CHAR;
- b: BOOLEAN;
- str: ARRAY 16 OF CHAR;
- VAR
- BEGIN
- IF QueryString(key, str) THEN
- Strings.StrToBool(str, b);
- RETURN b
- Strings.StrToBool(str, b);
- ELSE
- RETURN FALSE
- RETURN FALSE
- END
- IF QueryString(key, str) THEN
- END QueryBool;
- PROCEDURE Parse*(D: Documents.Document; basekey: LONGINT; S: Streams.Stream; head, cache, blocking: BOOLEAN);
- VAR
- me: Task;
- s: HyperDocs.LinkScheme;
- e: ExtTag;
- i, j: LONGINT;
- me: Task;
- VAR
- BEGIN
- imgs := QueryBool("HTMLImages");
- NEW(me);
- IF (D.handle = NIL) OR (D.Store = NIL) THEN
- TextDocs.InitDoc(D); D.W := HyperDocs.docW; D.H := HyperDocs.docH
- TextDocs.InitDoc(D); D.W := HyperDocs.docW; D.H := HyperDocs.docH
- END;
- D.dsc(TextGadgets.Frame).do := HyperDocs.linkMethods;
- NEW(me.P); me.P.D := D; NEW(me.P.T); Texts.Open(me.P.T, ""); me.P.alink := NIL; me.P.clink := NIL;
- me.P.cacheSource := cache; NEW(me.P.source); Texts.Open(me.P.source, ""); Texts.OpenWriter(me.P.Ws);
- me.P.next := pages; pages := me.P; me.P.task := me; me.P.docKey := basekey;
- me.P.handle := Gadgets.objecthandle; me.P.blank := FALSE;
- Links.SetLink(D.dsc, "Model", me.P.T); me.P.lines := 0; me.P.linkkey := HyperDocs.UndefKey;
- me.P.textAttrs := NIL; Texts.OpenWriter(me.P.W); me.P.left := FALSE;
- me.P.linkC := HyperDocs.linkC; me.P.oldLinkC := HyperDocs.oldLinkC;
- me.P.textC := Display3.textC; me.P.textbackC := Display3.textbackC;
- Attributes.SetInt(me.P.D.dsc, "LinkColor", me.P.linkC);
- Attributes.SetInt(me.P.D.dsc, "OldLinkColor", me.P.oldLinkC);
- me.S.page := me.P; me.P.lists := NIL;
- NEW(me.P.base); me.P.base.key := basekey; me.P.base.dockey := me.P.base.key;
- me.P.style := NewStyle();
- WriteObj(me.P, me.P.style); PopTextAttrs(me.P); me.P.orgPos := 0; me.P.head := head;
- OpenScanner(me.S, S);
- IF head THEN
- Texts.WriteString(me.P.W, "URL: "); Texts.Write(me.P.W, 22X)
- Texts.WriteString(me.P.W, "URL: "); Texts.Write(me.P.W, 22X)
- END;
- s := HyperDocs.LinkSchemeByKey(me.P.base.key);
- IF s = NIL THEN
- s := HyperDocs.LinkSchemeByPrefix("file")
- s := HyperDocs.LinkSchemeByPrefix("file")
- END;
- COPY(s.prefix, me.P.base.prefix);
- HyperDocs.RetrieveLink(me.P.base.key, me.S.value);
- IF me.P.base.prefix = "http" THEN
- me.P.base.key := HTTPDocs0.SplitHTTPAdr(me.S.value, me.P.base.host, me.P.base.path, me.P.orgLabel, me.P.base.port);
- i := 0;
- WHILE me.S.value[i] # 0X DO
- INC(i)
- INC(i)
- END;
- WHILE (i > 0) & (me.S.value[i] # "/") DO
- DEC(i)
- DEC(i)
- END;
- IF me.S.value[i] = "/" THEN
- me.S.value[i+1] := 0X
- me.S.value[i+1] := 0X
- END
- me.P.base.key := HTTPDocs0.SplitHTTPAdr(me.S.value, me.P.base.host, me.P.base.path, me.P.orgLabel, me.P.base.port);
- ELSIF me.P.base.prefix = "file" THEN
- HyperDocs.RetrieveLink(HyperDocs.loadingKey, me.S.value);
- i := HyperDocs.SplitFileAdr(me.S.value, me.P.base.path, me.P.orgLabel);
- HyperDocs.RetrieveLink(me.P.base.key, me.S.value);
- me.P.base.key := HyperDocs.SplitFileAdr(me.S.value, me.P.base.path, searchAttr);
- me.P.base.host := ""; me.P.base.port := 0;
- i := 0; j := 0;
- WHILE me.P.base.path[i] # 0X DO
- IF me.P.base.path[i] = "/" THEN j := i+1 END;
- INC(i)
- IF me.P.base.path[i] = "/" THEN j := i+1 END;
- END;
- me.P.base.path[j] := 0X
- HyperDocs.RetrieveLink(HyperDocs.loadingKey, me.S.value);
- ELSE (* proxy *)
- me.P.orgLabel := "";
- SplitHostPort(me.S.value, me.P.base.host, me.P.base.port);
- IF me.P.base.prefix = "ftp" THEN
- i := 6;
- WHILE (me.S.value[i] # 0X) & (me.S.value[i] # "/") DO
- INC(i)
- INC(i)
- END;
- j := 0;
- WHILE me.S.value[i] # 0X DO
- me.P.base.path[j] := me.S.value[i]; INC(j); INC(i)
- me.P.base.path[j] := me.S.value[i]; INC(j); INC(i)
- END;
- IF j > 0 THEN
- me.P.base.path[j] := 0X
- me.P.base.path[j] := 0X
- ELSE
- me.P.base.path := "/"
- me.P.base.path := "/"
- END
- i := 6;
- ELSE
- me.P.base.path := ""
- me.P.base.path := ""
- END
- me.P.orgLabel := "";
- END;
- HyperDocs.RetrieveLink(me.P.base.key, me.S.value);
- IF head THEN
- Texts.WriteString(me.P.W, me.S.value);
- Texts.Write(me.P.W, 22X); WriteLn(me.P)
- Texts.WriteString(me.P.W, me.S.value);
- END;
- e := extTags;
- WHILE e # NIL DO
- e.start(me.P); e := e.next
- e.start(me.P); e := e.next
- END;
- me.P.D.handle := DocHandler;
- Attributes.SetString(me.P.D, "Type", "HTML");
- Attributes.SetInt(me.P.D.dsc, "Color", me.P.textbackC);
- Texts.Append(me.P.T, me.P.W.buf); Read(me.S); Next(me.S);
- me.P.headerLen := me.P.T.len;
- me.time := Oberon.Time(); me.safe := FALSE; me.handle := ParseNext; Oberon.Install(me);
- IF blocking THEN
- WHILE me.P.task = me DO
- me.handle(me)
- me.handle(me)
- END
- WHILE me.P.task = me DO
- END
- imgs := QueryBool("HTMLImages");
- END Parse;
- PROCEDURE Show*;
- VAR
- T: Texts.Text;
- D: Objects.Object;
- T: Texts.Text;
- VAR
- BEGIN
- T := Oberon.MarkedText();
- IF T # NIL THEN
- HTTPDocs0.curNode := NIL;
- D := Gadgets.CreateObject("TextDocs.NewDoc");
- WITH D: Documents.Document DO
- D.W := HyperDocs.docW; D.H := HyperDocs.docH;
- D.handle := DocHandler;
- Parse(D, HyperDocs.UndefKey, TextStreams.OpenReader(T, 0), TRUE, FALSE, TRUE);
- Desktops.ShowDoc(D)
- D.W := HyperDocs.docW; D.H := HyperDocs.docH;
- END
- HTTPDocs0.curNode := NIL;
- END
- T := Oberon.MarkedText();
- END Show;
(** HTMLDocs.Stop *
- 停止标记的 html 文档的所有后台任务。 *)
- PROCEDURE Stop*;
- VAR
- S: 属性.扫描器;
- doc: 文档.文档;
- P, nextP: Page;
- S: 属性.扫描器;
- VAR
- BEGIN
- 属性.打开扫描器(S, 奥伯龙.Par.text, 奥伯龙.Par.pos);
- 属性.扫描(S);
- IF (S.class = Attributes.Char) & (S.c = "*") THEN
- doc := Desktops.CurDoc(Gadgets.context)
- doc := Desktops.CurDoc(Gadgets.context)
- ELSE
- doc := NIL; P := NIL
- doc := NIL; P := NIL
- END;
- IF doc # NIL THEN
- HTTPDocs0.StopDoc(doc);
- P := pages;
- WHILE (P # NIL) & (P.D # doc) DO
- P := P.next
- P := P.next
- END;
- IF P # NIL THEN
- HTTPDocs0.StopDoc(P.D); EndPage(P)
- HTTPDocs0.StopDoc(P.D); EndPage(P)
- END
- HTTPDocs0.StopDoc(doc);
- ELSE
- P := pages;
- WHILE P # NIL DO
- nextP := P.next;
- HTTPDocs0.StopDoc(P.D); EndPage(P);
- P := nextP
- nextP := P.next;
- END
- P := pages;
- END
- 属性.打开扫描器(S, 奥伯龙.Par.text, 奥伯龙.Par.pos);
- END Stop;
- PROCEDURE LoadDoc(D: Documents.Document);
- VAR
- key: 长整型;
- s, so: HyperDocs.LinkScheme;
- T: Texts.Text;
- path, label: ARRAY 64 OF CHAR;
- key: 长整型;
- VAR
- BEGIN
- key := HyperDocs.BuildKey(NIL, D.name);
- IF key # HyperDocs.UndefKey THEN
- s := HyperDocs.LinkSchemeByKey(key);
- IF s.prefix = "file" THEN
- IF HyperDocs.context # NIL THEN
- HTTPDocs0.curNode := HyperDocs.context.new
- HTTPDocs0.curNode := HyperDocs.context.new
- ELSE
- HyperDocs.Remember(key, NIL, HTTPDocs0.curNode)
- HyperDocs.Remember(key, NIL, HTTPDocs0.curNode)
- END;
- key := HyperDocs.SplitFileAdr(D.name, path, label);
- NEW(T); Texts.Open(T, path);
- TextDocs.InitDoc(D); D.W := HyperDocs.docW; D.H := HyperDocs.docH;
- Parse(D, key, TextStreams.OpenReader(T, 0), TRUE, FALSE, FALSE);
- IF (D # NIL) & (D.dsc # NIL) THEN
- IF HyperDocs.context = NIL THEN
- HyperDocs.LinkNodeToDoc(D, HTTPDocs0.curNode)
- HyperDocs.LinkNodeToDoc(D, HTTPDocs0.curNode)
- ELSE
- HyperDocs.context.history := TRUE
- HyperDocs.context.history := TRUE
- END;
- IF D.name = "" THEN
- HyperDocs.RetrieveLink(key, D.name)
- HyperDocs.RetrieveLink(key, D.name)
- END
- IF HyperDocs.context = NIL THEN
- END
- IF HyperDocs.context # NIL THEN
- ELSE
- s := HyperDocs.LinkSchemeByKey(key);
- key := HyperDocs.BuildKey(NIL, D.name);
HALT(99)
- END;
- IF (HyperDocs.context # NIL) & (HyperDocs.context.old # NIL) THEN
- so := HyperDocs.LinkSchemeByKey(HyperDocs.context.old.key);
- IF (so.prefix = "file") OR (so.prefix = "http") THEN
- HyperDocs.context.replace := TRUE
- HyperDocs.context.replace := TRUE
- END
- so := HyperDocs.LinkSchemeByKey(HyperDocs.context.old.key);
- END
- END;
- END
- END LoadDoc;
- PROCEDURE NewDoc*;
- VAR doc: Objects.Object;
- VAR doc: Objects.Object;
- BEGIN
- doc := Gadgets.CreateObject("TextDocs.NewDoc");
- WITH doc: Documents.Document DO
- doc.W := HyperDocs.docW; doc.H := HyperDocs.docH;
- doc.Load := LoadDoc
- doc.W := HyperDocs.docW; doc.H := HyperDocs.docH;
- END;
- doc.handle := DocHandler;
- Objects.NewObj := doc
- doc := Gadgets.CreateObject("TextDocs.NewDoc");
- END NewDoc;
- PROCEDURE InitEntities;
- VAR i: Integer;
- VAR i: Integer;
- BEGIN
- (* entities 确定从索引 {i} 到实体名称的映射。
- entityEncoding 确定从 {i} 到字体的映射。
- 实体显示需要字体中可用性和对字体的正确编码。 *)
- i := 0;
- entityEncoding 确定从 {i} 到字体的映射。
- (* 控制代码
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes" *)
- entityEncoding[i] := Strings.Tab; entities[i] := "tab"; INC(i); (* U+09, 水平制表符 *)
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes" *)
- (* 基本拉丁语
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin" *)
- entityEncoding[i] := 22X; entities[i] := "quot"; INC(i);
- entityEncoding[i] := 22X; entities[i] := "quote"; INC(i);
- entityEncoding[i] := 26X; entities[i] := "amp"; INC(i);
- entityEncoding[i] := 3CX; entities[i] := "lt"; INC(i);
- entityEncoding[i] := 3EX; entities[i] := "gt"; INC(i);
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin" *)
- (* 拉丁语-1 补充。
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Latin-1_Supplement" *)
- entityEncoding[i] := " "; entities[i] := "nbsp"; INC(i); (* U+00 *)
- entityEncoding[i] := 0C0X; entities[i] := "Agrave"; INC(i);
- entityEncoding[i] := 0C1X; entities[i] := "Aacute"; INC(i);
- entityEncoding[i] := 0C2X; entities[i] := "Acirc"; INC(i);
- entityEncoding[i] := 0C3X; entities[i] := "Atilde"; INC(i);
- entityEncoding[i] := 0C4X; entities[i] := "Auml"; INC(i);
- entityEncoding[i] := 0C5X; entities[i] := "Aring"; INC(i);
- entityEncoding[i] := 0C6X; entities[i] := "AElig"; INC(i);
- entityEncoding[i] := 0C7X; entities[i] := "Ccedil"; INC(i);
- entityEncoding[i] := 0C8X; entities[i] := "Egrave"; INC(i);
- entityEncoding[i] := 0C9X; entities[i] := "Eacute"; INC(i);
- entityEncoding[i] := 0CAX; entities[i] := "Ecirc"; INC(i);
- entityEncoding[i] := 0CCX; entities[i] := "Euml"; INC(i);
- entityEncoding[i] := 0CDX; entities[i] := "Igrave"; INC(i);
- entityEncoding[i] := 0CEX; entities[i] := "Iacute"; INC(i);
- entityEncoding[i] := 0CFX; entities[i] := "Icirc"; INC(i);
- entityEncoding[i] := 0CBX; entities[i] := "Iuml"; INC(i);
- entityEncoding[i] := 0D0X; entities[i] := "ETH"; INC(i);
- entityEncoding[i] := 0D1X; entities[i] := "Ntilde"; INC(i);
- entityEncoding[i] := 0D2X; entities[i] := "Ograve"; INC(i);
- entityEncoding[i] := 0D3X; entities[i] := "Oacute"; INC(i);
- entityEncoding[i] := 0D4X; entities[i] := "Ocirc"; INC(i);
- entityEncoding[i] := 0D5X; entities[i] := "Otilde"; INC(i);
- entityEncoding[i] := 0D6X; entities[i] := "Ouml"; INC(i);
- entityEncoding[i] := 0D7X; entities[i] := "Oslash"; INC(i);
- entityEncoding[i] := 0D9X; entities[i] := "Ugrave"; INC(i);
- entityEncoding[i] := 0DAX; entities[i] := "Uacute"; INC(i);
- entityEncoding[i] := 0DBX; entities[i] := "Ucirc"; INC(i);
- entityEncoding[i] := 0DCX; entities[i] := "Uuml"; INC(i);
- entityEncoding[i] := 0DDX; entities[i] := "Yacute"; INC(i);
- entityEncoding[i] := 0DEX; entities[i] := "THORN"; INC(i);
- entityEncoding[i] := 0DFX; entities[i] := "szlig"; INC(i);
- entityEncoding[i] := 0E0X; entities[i] := "agrave"; INC(i);
- entityEncoding[i] := 0E1X; entities[i] := "aacute"; INC(i);
- entityEncoding[i] := 0E2X; entities[i] := "acirc"; INC(i);
- entityEncoding[i] := 0E3X; entities[i] := "atilde"; INC(i);
- entityEncoding[i] := 0E4X; entities[i] := "auml"; INC(i);
- entityEncoding[i] := 0E5X; entities[i] := "aring"; INC(i);
- entityEncoding[i] := 0E6X; entities[i] := "aelig"; INC(i);
- entityEncoding[i] := 0E7X; entities[i] := "ccedil"; INC(i);
- entityEncoding[i] := 0E8X; entities[i] := "egrave"; INC(i);
- entityEncoding[i] := 0E9X; entities[i] := "eacute"; INC(i);
- entityEncoding[i] := 0EAX; entities[i] := "ecirc"; INC(i);
- entityEncoding[i] := 0EBX; entities[i] := "euml"; INC(i);
- entityEncoding[i] := 0ECX; entities[i] := "igrave"; INC(i);
- entityEncoding[i] := 0EDX; entities[i] := "iacute"; INC(i);
- entityEncoding[i] := 0EEX; entities[i] := "icirc"; INC(i);
- entityEncoding[i] := 0EFX; entities[i] := "iuml"; INC(i);
- entityEncoding[i] := 0F0X; entities[i] := "eth"; INC(i);
- entityEncoding[i] := 0F1X; entities[i] := "ntilde"; INC(i);
- entityEncoding[i] := 0F2X; entities[i] := "ograve"; INC(i);
- entityEncoding[i] := 0F3X; entities[i] := "oacute"; INC(i);
- entityEncoding[i] := 0F4X; entities[i] := "ocirc"; INC(i);
- entityEncoding[i] := 0F5X; entities[i] := "otilde"; INC(i);
- entityEncoding[i] := 0F6X; entities[i] := "ouml"; INC(i);
- entityEncoding[i] := 0F7X; entities[i] := "oslash"; INC(i);
- entityEncoding[i] := 0F9X; entities[i] := "ugrave"; INC(i);
- entityEncoding[i] := 0FAX; entities[i] := "uacute"; INC(i);
- entityEncoding[i] := 0FBX; entities[i] := "ucirc"; INC(i);
- entityEncoding[i] := 0FCX; entities[i] := "uuml"; INC(i);
- entityEncoding[i] := 0FDX; entities[i] := "yacute"; INC(i);
- entityEncoding[i] := 0FEX; entities[i] := "thorn"; INC(i);
- entityEncoding[i] := 0FFX; entities[i] := "yuml"; INC(i);
- Texts.WriteInt(Wr, i, 0); Texts.WriteString(Wr, " 字符实体已初始化。"); Texts.WriteLn(Wr);
- Texts.Append(Oberon.Log, Wr.buf)
- Desktops.OpenDoc "https://en.wikipedia.org/wiki/List_of_Unicode_characters#Latin-1_Supplement" *)
- END InitEntities;
(** HTMLDocs.ShowHTML
- 显示标记页面的 HTML 源代码。 *)
- 显示标记页面的 HTML 源代码。 *)
PROCEDURE ShowHTML*;
- VAR
- D: Documents.Document;
- node: 超文档.节点;
- P: Page;
- key, pos: LONGINT;
- T: Texts.Text;
- R: 文本.读取器;
- ch: 字符;
- D: Documents.Document;
BEGIN
- D := Documents.MarkedDoc();
- node := HyperDocs.NodeByDoc(D);
- IF node # NIL THEN
- Attributes.GetInt(D, "DocURL", key);
- P := pages;
- WHILE (P # NIL) & (P.docKey # key) DO
- P := P.next
- P := P.next
- END;
- IF P # NIL THEN
- Texts.Append(P.source, P.Ws.buf); T := P.source
- Texts.Append(P.source, P.Ws.buf); T := P.source
- ELSE
- key := HTTPDocs0.StripLoc(key);
- T := HyperDocs.GetCachedText(key)
- key := HTTPDocs0.StripLoc(key);
- END;
- IF T # NIL THEN
- Texts.OpenReader(R, T, 0);
- Texts.Read(R, ch); pos := 0;
- WHILE ~R.eot DO
- IF ch = Strings.LF THEN
- Texts.WriteLn(Wr);
- Texts.Delete(T, pos, pos+1);
- Texts.Insert(T, pos, Wr.buf);
- Texts.OpenReader(R, T, pos)
- Texts.WriteLn(Wr);
- ELSE
- INC(pos)
- INC(pos)
- END;
- 文本.读取(R, ch)
- IF ch = Strings.LF THEN
- END;
- TextDocs.ShowText("HTML", T, HyperDocs.docW, HyperDocs.docH)
- Texts.OpenReader(R, T, 0);
- END
- Attributes.GetInt(D, "DocURL", key);
- END
END ShowHTML;
(** HTMLDocs.SetImages
- 切换图像加载的开启或关闭。 *)
PROCEDURE SetImages*;
- VAR
- S: 属性.扫描器;
- S: 属性.扫描器;
BEGIN
- 属性.打开扫描器(S, 奥伯龙.Par.text, 奥伯龙.Par.pos);
- 属性.扫描(S);
- IF (S.class = Attributes.Name) OR (S.class = Attributes.String) THEN
- Strings.StrToBool(S.s, imgs)
- Strings.StrToBool(S.s, imgs)
- END;
END SetImages;
PROCEDURE Check;
VAR S: Texts.Scanner;
BEGIN
- Oberon.OpenScanner(S, "HTMLTags");
- IF S.class = Texts.Inval THEN
- Texts.WriteString(Wr, "Oberon.Text - HTMLTags 未找到");
- Texts.WriteLn(Wr); Texts.Append(Oberon.Log, Wr.buf)
- Texts.WriteString(Wr, "Oberon.Text - HTMLTags 未找到");
- END
END Check;
BEGIN
- Texts.OpenWriter(Wr); Texts.OpenWriter(Wq);
- imgs := TRUE; extTags := NIL; newTag := NIL;
- pages := NIL; dispW := Display.Width;
- COPY(GreekCap, GreekTab);
- Strings.Append(GreekTab, GreekMin);
- InitEntities(); mono := Fonts.This("Courier10.Scn.Fnt");
- IF ASCIIBullets THEN
- bullets[0].f := Fonts.This("Default12.Scn.Fnt"); bullets[0].c := "*";
- bullets[1].f := bullets[0].f; bullets[1].c := "o"
- bullets[0].f := Fonts.This("Default12.Scn.Fnt"); bullets[0].c := "*";
- ELSE
- bullets[0].f := Fonts.This("Default10.Scn.Fnt"); bullets[0].c := CHR(29);
- bullets[1].f := bullets[0].f; bullets[1].c := CHR(28)
- bullets[0].f := Fonts.This("Default10.Scn.Fnt"); bullets[0].c := CHR(29);
- END;
- Check()
END HTMLDocs.