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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
|
-- Copyright 1993-2003 by Daniel R. Grayson
-- Revamped by P. Zinn-Justin and Mahrud Sayrafi 2020
needs "regex.m2" -- for toLower
needs "lists.m2" -- for all
needs "methods.m2"
-----------------------------------------------------------------------------
-- Hypertext type declarations and basic constructors
-----------------------------------------------------------------------------
-- Hypertext, HypertextParagraph, and HypertextContainer
Hypertext = new Type of BasicList
Hypertext.synonym = "markup list"
-- A paragraph starts on a new line and ends with a line break.
HypertextParagraph = new Type of Hypertext
HypertextParagraph.synonym = "markup list paragraph"
-- A container's contents are indented
HypertextContainer = new Type of Hypertext
HypertextContainer.synonym = "markup list container"
toString Hypertext := s -> concatenate(toString class s, toString toList s)
toExternalString Hypertext := s -> concatenate(toString class s, toExternalString toList s)
new Hypertext from VisibleList := (M,x) -> x
new Hypertext from Thing := (M,x) -> {x}
new Hypertext from Net := (M,x) -> {toString x}
-----------------------------------------------------------------------------
-- URL type declaration and constructor
-----------------------------------------------------------------------------
URL = new SelfInitializingType of BasicList
new URL from String := (URL, str) -> { str }
-- relative URLs and filenames
isAbsoluteURL = url -> match( "^(#|mailto:|[a-z]+://)", url )
-- TODO: phase this one out eventually
toURL = method()
toURL String := pth -> (
if isAbsolutePath pth then concatenate(rootURI,
if fileExists pth then realpath pth
else (
stderr << "-- *** warning: file needed for URL not found: " << pth << endl;
pth))
else if isAbsoluteURL pth then pth
else (
r := if htmlDirectory === null then pth else relativizeFilename(htmlDirectory, pth);
if debugLevel == 121 then (
stderr << "--toURL String: htmlDirectory = " << htmlDirectory << endl;
stderr << "-- pth = " << pth << endl;
stderr << "-- relative result = " << r << endl;
);
r))
toURL(String, String) := (prefix,tail) -> ( -- this is the good one
-- we assume we are installing an html file in the directory installPrefix|htmlDirectory
r := if prefix === installPrefix -- note: installPrefix might be null, if we aren't installing a package
and htmlDirectory =!= null
then relativizeFilename(htmlDirectory,tail)
else prefix|tail;
if debugLevel == 121 then (
stderr << "--toURL(String,String): htmlDirectory = " << htmlDirectory << endl;
stderr << "-- prefix = " << prefix << endl;
stderr << "-- result = " << r << endl;
);
r)
-----------------------------------------------------------------------------
-- MarkUpType type declarations
-----------------------------------------------------------------------------
-- MarkUpType
MarkUpType = new Type of SelfInitializingType
MarkUpType.synonym = "markup type"
options MarkUpType := X -> if X.?Options then X.Options else new OptionTable from {}
-- e.g. a MENU, which does not correspond to an html entity.
-- It does not have a qname, nor a default method for producing html,
-- so one should be provided.
IntermediateMarkUpType = new Type of MarkUpType
IntermediateMarkUpType.synonym = "intermediate markup type"
-----------------------------------------------------------------------------
-- Setting GlobalAssignHooks
-----------------------------------------------------------------------------
MarkUpType.GlobalAssignHook = (X, x) -> (
if not x.?qname then x.qname = toLower toString X;
if not hasAttribute(x, ReverseDictionary) then setAttribute(x, ReverseDictionary, X))
IntermediateMarkUpType.GlobalAssignHook = globalAssignFunction
-----------------------------------------------------------------------------
-- MarkUptypes
-----------------------------------------------------------------------------
-- The qname (qualified name) is the lowercase name of the type by default.
-- See the end for exceptions (e.g. PARA.qname = p)
-- Standard html
HTML = new MarkUpType of HypertextContainer
HEAD = new MarkUpType of HypertextContainer
META = new MarkUpType of HypertextParagraph
LINK = new MarkUpType of HypertextParagraph
TITLE = new MarkUpType of HypertextParagraph
BODY = new MarkUpType of HypertextContainer
STYLE = new MarkUpType of Hypertext
SPAN = new MarkUpType of Hypertext
PARA = new MarkUpType of HypertextParagraph -- double spacing inside
DIV = new MarkUpType of HypertextContainer
BR = new MarkUpType of Hypertext
HR = new MarkUpType of HypertextParagraph
SCRIPT = new MarkUpType of HypertextParagraph
-- Headers
HEADER1 = new MarkUpType of HypertextParagraph
HEADER2 = new MarkUpType of HypertextParagraph
HEADER3 = new MarkUpType of HypertextParagraph
HEADER4 = new MarkUpType of HypertextParagraph
HEADER5 = new MarkUpType of HypertextParagraph
HEADER6 = new MarkUpType of HypertextParagraph
SUBSECTION = HEADER2
-- Emphasis (TODO: strikethrough)
EM = new MarkUpType of Hypertext
ITALIC = new MarkUpType of Hypertext
SMALL = new MarkUpType of Hypertext
BOLD = new MarkUpType of Hypertext
STRONG = new MarkUpType of Hypertext
SUB = new MarkUpType of Hypertext
SUP = new MarkUpType of Hypertext
TT = new MarkUpType of Hypertext
-- Lists (TODO: OL)
OL = new MarkUpType of HypertextContainer
UL = new MarkUpType of HypertextContainer
LI = new MarkUpType of HypertextContainer
DL = new MarkUpType of HypertextContainer
DT = new MarkUpType of HypertextParagraph
DD = new MarkUpType of HypertextParagraph
-- Links and references
IMG = new MarkUpType of Hypertext
ANCHOR = new MarkUpType of Hypertext
LABEL = new MarkUpType of Hypertext
-- Blockquotes
BLOCKQUOTE = new MarkUpType of HypertextParagraph
-- Code
CODE = new MarkUpType of Hypertext
PRE = new MarkUpType of HypertextParagraph
-- Tables
TABLE = new MarkUpType of HypertextContainer
TR = new MarkUpType of HypertextContainer
TD = new MarkUpType of Hypertext
TH = new MarkUpType of TD
CDATA = new MarkUpType of Hypertext
COMMENT = new MarkUpType of Hypertext
TEX = new IntermediateMarkUpType of Hypertext
ExampleItem = new IntermediateMarkUpType of Hypertext
HREF = new IntermediateMarkUpType of Hypertext
LATER = new IntermediateMarkUpType of Hypertext
LITERAL = new IntermediateMarkUpType of Hypertext -- fake!!!!! check later
MENU = new IntermediateMarkUpType of HypertextContainer -- e.g. help sum
TO = new IntermediateMarkUpType of Hypertext
TO2 = new IntermediateMarkUpType of Hypertext
TOH = new IntermediateMarkUpType of Hypertext
-----------------------------------------------------------------------------
-- LATER
-----------------------------------------------------------------------------
toExternalString LATER := x -> toExternalString x#0()
-----------------------------------------------------------------------------
-- MarkUpType constructors
-----------------------------------------------------------------------------
new HR from List :=
new BR from List := (X,x) -> if all(x, e -> instance(e, Option)) then x else error "expected empty list"
br = BR{}
hr = HR{}
-- used in the TEX constructor below
convertTexTable := new HashTable from {
"url" => "HREF",
"bf" => "BOLD",
"em" => "EM",
"it" => "ITALIC",
"tt" => "TT",
}
-- the regex should match the tag and content
-- inside braces as subexpressions #2 and #3
convertTex := (tags, re, str) -> (
off := 0;
while (m := regex(re, off, str)) =!= null do (
off = m#3#0;
tag := substring(m#2, str);
if match(tags, tag) then (
tag = convertTexTable#tag;
if debugLevel > 1 then printerr("parsing ", tag, " in TEX");
str = replace(regexQuote substring(m#1, str), "\"," | tag | "{" | format substring(m#3, str) | "},\"", str)));
str)
new TEX from String := (T, t) -> T {t}
new TEX from BasicList := (T, t) -> (
-- TODO: https://www.overleaf.com/learn/latex/Font_sizes,_families,_and_styles#Reference_guide
-- we do this so {"{\tt", TO sum, "}"} can be rendered correctly
s := demark_"," \\ toExternalString \ t;
-- parsing nested braces contained in \url{...}
s = convertTex("url", ///((?:\\\\(url))?\{((?:[^}{]+|(?1))*+)\})///, s);
-- parsing nested braces contained in {\xx ...}
s = convertTex("bf|tt|em|it", ///(\{(?:\\\\(bf|tt|em|it))? *((?:[^}{]+|(?1))*+)\})///, s);
-- miscellaneous replacements
s = replace("---", "—", s);
s = replace("\\b--\\b", "–", s);
-- evaluate Hypertext types
s = evaluateWithPackage(getpkg "Text", s, value);
if instance(s, BasicList) then s else {s})
isLink = x -> instance(x, TO) or instance(x, TO2) or instance(x, TOH)
new TO from Thing :=
new TOH from Thing := (TO, x) -> new TO from {x}
-- document tags can be sequences or arrays, so keep them intact
new TO from List := (TO, x) -> if x#?1 then { makeDocumentTag x#0, concatenate drop(toSequence x,1) } else { makeDocumentTag x#0 }
new TO2 from List :=
new TO2 from Sequence := (TO2, x) -> { makeDocumentTag x#0, concatenate drop(toSequence x,1) }
new TOH from List := (TOH, x) -> { makeDocumentTag x#0 }
new HREF from List := (HREF, x) -> (
url := if x#?0 and (instance(x#0, String) or instance(x#0, Sequence) and #x#0 === 2 and all(x#0, y -> instance(y, String)))
then x#0 else error "HREF expected URL to be a string or a sequence of 2 strings";
if x#?1 then prepend(url, drop(x, 1)) else {url})
new OL from VisibleList :=
new UL from VisibleList := (T, x) -> (
apply(nonnull x, e -> (
if class e === TO then LI{TOH{e#0}}
else if instance(e, LI) or instance(e,Option) then e
else LI e)))
-- TODO: deprecate this
ul = x -> ( x = nonnull x; if 0 < #x then UL x )
-- Written by P. Zinn-Justin
new TABLE from VisibleList := (T,x) -> (
apply(nonnull x, e -> (
if instance(e, TR) or instance(e, Option) then e else TR e)))
new TR from VisibleList := (T,x) -> (
apply(nonnull x, e -> (
if instance(e, TD) or instance(e, Option) then e else TD e)))
-- the main idea of these comparisons is so sorting will sort by the way things will print:
TO ? TO :=
TO ? TOH :=
TOH ? TO :=
TOH ? TOH := (x,y) -> x#0 ? y#0
TO ? TO2 :=
TOH ? TO2 := (x,y) -> x#0 ? y#1
TO2 ? TO :=
TO2 ? TOH := (x,y) -> x#1 ? y#0
TO2 ? TO2 := (x,y) -> x#1 ? y#1
-----------------------------------------------------------------------------
-- Fixing the qname for non-standard type names
-----------------------------------------------------------------------------
ANCHOR.qname = "a"
BOLD.qname = "b"
ExampleItem.qname = "code"
HEADER1.qname = "h1"
HEADER2.qname = "h2"
HEADER3.qname = "h3"
HEADER4.qname = "h4"
HEADER5.qname = "h5"
HEADER6.qname = "h6"
HREF.qname = "a"
ITALIC.qname = "i"
LITERAL.qname = "div"
MENU.qname = "div"
PARA.qname = "p"
TEX.qname = "#PCDATA"
TO.qname = "a"
TO2.qname = "a"
TOH.qname = "span"
-----------------------------------------------------------------------------
-- Add acceptable html attributes to the type of an html tag
-----------------------------------------------------------------------------
addAttribute = (T, opts) -> (
T.Options = new OptionTable from apply(opts, opt ->
if class opt === Option then opt else opt => null))
-- html global attributes
htmlGlobalAttr = {
"accesskey",
"class",
"contenteditable",
-- "data-*", -- at the moment can't handle this
"dir",
"draggable",
"dropzone",
"hidden",
"id",
"lang",
"spellcheck",
"style",
"tabindex",
"title",
"translate",
"xmlns"
}
scan({HTML, HEAD, TITLE, BODY}, T -> addAttribute(T, htmlGlobalAttr))
addAttribute(META, htmlGlobalAttr | {"name", "content", "http-equiv"})
addAttribute(LINK, htmlGlobalAttr | {"href", "rel", "title", "type"})
addAttribute(STYLE, htmlGlobalAttr | {"type"})
addAttribute(SCRIPT, htmlGlobalAttr | {"src", "type"})
-- html global and event attributes
htmlAttr = htmlGlobalAttr | {
"onafterprint","onbeforeprint","onbeforeunload","onerror","onhashchange",
"onload","onmessage","onoffline","ononline","onpagehide","onpageshow",
"onpopstate","onresize","onstorage","onunload","onblur","onchange",
"oncontextmenu","onfocusscript","oninputscript","oninvalid","onresetscript",
"onsearch","onselect","onsubmit","onkeydown","onkeypress","onkeyup",
"onclick","ondblclick","onmousedown","onmousemove","onmouseout",
"onmouseover","onmouseup","onmousewheel","onwheel","ondrag","ondragend",
"ondragenter","ondragleave","ondragover","ondragstart","ondrop","onscroll",
"ontoggle"
}
scan({BR, HR, PARA, PRE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6,
BLOCKQUOTE, EM, ITALIC, SMALL, BOLD, STRONG, SUB, SUP, SPAN, TT, LI, CODE,
DL, DT, DD, OL, UL, DIV, TABLE, TR}, T -> addAttribute(T, htmlAttr))
addAttribute(LABEL, htmlAttr | {"for", "from"})
addAttribute(ANCHOR, htmlAttr | {"href", "rel", "target", "type"})
addAttribute(TD, htmlAttr | {"colspan", "headers", "rowspan"})
addAttribute(TH, htmlAttr | {"colspan", "headers", "rowspan"})
addAttribute(IMG, htmlAttr | {"alt", "src", "srcset", "width", "height",
"sizes", "crossorigin", "longdesc", "referrerpolicy", "ismap", "usemap"})
M2CODE = method()
M2CODE Thing := x -> prepend("class" => "language-macaulay2", CODE x)
-- Written by P. Zinn-Justin
style = method(Options => true)
style Hypertext := true >> o -> x -> (
str := concatenate apply(keys o, key -> if class key === String then key|":"|toString o#key|";");
if str === "" then return x;
i := position(toList x, y -> class y === Option and y#0 === "style");
if i=!=null then (
str = concatenate(x#i#1, if #x#i#1>0 and last x#i#1 =!= ";" then ";",str);
x = drop(x,{i,i});
);
append(x,"style"=>str)
)
-- Local Variables:
-- compile-command: "make -C $M2BUILDDIR/Macaulay2/m2 "
-- End:
|