summaryrefslogtreecommitdiff
path: root/appl/ebook/reader.m
blob: cf0824aef2b5fb8ade255127818702375c4ba59f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

# the public interface to this looks like:
#	Reader: module {
#		PATH: con "/dis/ebook/reader.dis";
#		init: fn(displ: ref Draw->Display);
#		Datasource: adt {
#			new:		fn(f: string, win: ref Tk->Toplevel, width: int, evch: string): (ref Datasource, string);
#			copy:	fn(d: self ref Datasource): ref Datasource;
#			mark:	fn(d: self ref Datasource): ref Mark;
#			goto:	fn(d: self ref Datasource, m: ref Mark);
#			atmark:	fn(d: self ref Datasource, m: ref Mark): int;
#			next:		fn(d: self ref Datasource, linkch: chan of (string, string, string)): string;
#	
#			linestart:	fn(d: self ref Datasource, w: string, y: int): int;
#			linkoffset:	fn(d: self ref Datasource, w: string, s: string): int;
#		};
#	};


Reader: module {
	PATH: con "/dis/ebook/reader.dis";
	init: fn(displ: ref Draw->Display);
	Datasource: adt {
		x:		ref Xml->Parser;
		t:		ref Text;
		title:		string;
		win:		ref Tk->Toplevel;
		evch:	string;			# tk channel on which to send events
		tags:		list of ref Xml->Item.Tag;
		width:	int;
		filename:	string;
		error:	string;
		item:		ref Xml->Item;
		imark:	ref Xml->Mark;		# mark at start of item
		fontinfo:	list of ref Fontinfo;
		styles:	list of ref Stylesheet->Style;
		stylesheet:	ref Stylesheet->Sheet;
		linkch:	chan of (string, string, string);		# (linkname, widgetname, internal reference)
		warningch: chan of (Xml->Locator, string);
		startmark:	ref Reader->Mark;	# mark start of body for copy()
		fallbacks:	list of (string, string);

		# public interface consists solely of the following few methods, along with the Mark adt.
		new:		fn(f: string, fallbacks: list of (string, string), win: ref Tk->Toplevel, width: int, evch: string, warningch: chan of (Xml->Locator, string)): (ref Datasource, string);
		copy:	fn(d: self ref Datasource): ref Datasource;
		mark:	fn(d: self ref Datasource): ref Mark;
		str2mark:	fn(d: self ref Datasource, s: string): ref Mark;
		mark2str:	fn(d: self ref Datasource, m: ref Mark): string;
		goto:	fn(d: self ref Datasource, m: ref Mark);
		atmark:	fn(d: self ref Datasource, m: ref Mark): int;
		next:		fn(d: self ref Datasource, linkch: chan of (string, string, string)): (Block, string);
		fileoffset:	fn(d: self ref Datasource): int;

		rectforfileoffset:	fn(t: self ref Datasource, w: string, fileoffset: int): (int, Draw->Rect);
		fileoffsetnearyoffset:	fn(t: self ref Datasource, w: string, yoffset: int): int;
		linestart:	fn(d: self ref Datasource, w: string, y: int): int;
		linkoffset:	fn(d: self ref Datasource, w: string, s: string): int;
		event:	fn(d: self ref Datasource, e: string): ref Event;
	};

	Block: adt {
		w: string;
		tmargin, bmargin: int;
	};

	Event: adt {
		pick {
		Link =>
			url:	string;
		Texthit =>
			fileoffset:	int;
		}
	};
		
	Mark: adt {
		xmark:	ref Xml->Mark;
		eq:	fn(m1: self ref Mark, m2: ref Mark): int;
		fileoffset:	fn(m: self ref Mark): int;
	};

	Text: adt {
		win:		ref Tk->Toplevel;
		w:		string;
		tags:		array of list of (string, int);	# hash of (attrs, tagnum); holds all currently used tags in widget
		max:		int;			# max tagnum
		href:		string;
		margins:		list of Margin;		# margins of enclosing blocks
		margin:		Margin;			# current margin values
		outertmargin:	int;
		outerbmargin:	int;
		needspace:	int;			# vspace waiting
		lastwhite:		int;			# did the last text hold trailing whitespace?
		startofline:	int;
		style:	ref Stylesheet->Style;
		fontinfo:	ref Fontinfo;
		evch:	string;

		new:		fn(win: ref Tk->Toplevel, w: string, width: int, evch: string): ref Text;
		addtext:	fn(t: self ref Text, text: string, ws1, ws2: int, fileoffset: int);
		gettag:	fn(t: self ref Text,  s: string): string;
		linebreak:	fn(t: self ref Text);
		addmark:	fn(t: self ref Text): string;
		widgetname:	fn(t: self ref Text, t: int): string;
		addwidget:	fn(t: self ref Text, w: string, fileoffset: int, invisible: int);
		startblock:	fn(t: self ref Text);
		endblock:		fn(t: self ref Text);
		finalise:	fn(t: self ref Text, addvspace: int);
		vspace:	fn(t: self ref Text, h: int);
	};

	Margin: adt {
		l, r, b, textindent: int;
	};

	Fontinfo: adt {
		path:		string;
		em:		int;
		ex:		int;
	};
};