2121
2222newPackage (
2323 " DocConverter" ,
24- Version => " 0.1" ,
25- Date => " " ,
26- Authors => {{Name => " Mike Stillman, Franziska Hinkelmann" ,
27- 28- HomePage => " " }},
29- Headline => " Convert simpleDOC to HTML for TryM2 tutorials" ,
30- DebuggingMode => true
24+ Version => " 0.5" ,
25+ Date => " Jan 2014" ,
26+ Authors => {
27+ {
28+ Name => " Mike Stillman" ,
29+ 30+ HomePage =>" http://www.math.cornell.edu/~mike"
31+ },
32+ {
33+ Name => " Franziska Hinkelmann" ,
34+ 35+ },
36+ {
37+ Name => " Lars Kastner" ,
38+ Email => " " ,
39+ HomePage =>" "
40+ }
41+ },
42+ Headline => " Convert tutorial and simpleDOC formats to HTML for TryM2 tutorials" ,
43+ DebuggingMode => true ,
44+ PackageExports => {" Text" }
3145 )
3246
33- needsPackage " Text"
34-
35- export {convert, keywordRE, descriptionRE, tutorialToSimpleDoc}
47+ export {
48+ convert,
49+ convertSimpledocToHtml,
50+ convertContents,
51+ tutorialToSimpleDoc,
52+ simpledocExample,
53+ tutorialExample
54+ }
3655
3756keywordRE = ///^\s* Key |^\s* Headline |^\s* Description ///
3857descriptionRE = ///^\s* Text |^\s* Code |^\s* Example ///
@@ -81,7 +100,7 @@ toHtml String := (s) -> (
81100 s = replaceWithValueOf s;
82101 -- print s;
83102 s = html TEX s;
84- s | " <BR >\n"
103+ s | " <br/ >\n"
85104 )
86105
87106toHtmlPara = method ()
@@ -96,17 +115,78 @@ printHead = method()
96115printHead String := title -> (
97116 s := " <html>\n" ;
98117 s = s | " <head>\n" ;
99- s = s | " \n <title>\n" ;
100- s = s | title;
101- s = s | " \n" ;
118+ s = s | " <title>\n" ;
119+ s = s | title | " \n" ;
102120 s = s | " </title>\n" ;
103121 s = s | " </head>\n" ;
104122 s = s | " <body>\n"
105123 )
106124
107- convert = method ()
108- convert String := (filename) -> (
109- contents := lines get filename;
125+ processTextSection = (lines ) -> (
126+ -- Each line should be either completely blank, or
127+ -- have some text. Each contiguous group of non-empty lines
128+ -- will be wrapped in a <p></p>.
129+ -- A string is returned.
130+ -- --return toHtmlPara concatenate between("\n", lines); -- all lines in a text section
131+ -- this next part is new. Is it valid? 8 Jan 2014 MES
132+ stripSpace := apply (lines , line -> replace (" ^\\s*" , " " , line));
133+ groups := sublists (stripSpace,
134+ line -> #line > 0 ,
135+ toList ,
136+ identity );
137+ concatenate apply (groups, g -> if not instance (g, List )
138+ then " "
139+ else ( " <p>\n"
140+ | concatenate apply (g, g1 -> " " | html TEX g1 | " \n" )
141+ | " </p>\n" )
142+ ))
143+
144+ initialSpaceSize = (line) -> (
145+ -- Returns the number of spaces at the beginning of the line.
146+ -- NO tabs are allowed in line!!
147+ initialSpace := regex (" ^ *" , line);
148+ initialSpace#0#1
149+ )
150+ processExampleSection = (lines ) -> (
151+ -- Each line should be either completely blank, or
152+ -- have some text. Each line with more indentation than the
153+ -- previous is appended to a <code> block
154+ -- A string is returned.
155+ sizes := lines / initialSpaceSize;
156+ minsize := min sizes;
157+ if minsize != sizes#0 then error " The first line of an Example section should have the
158+ smallest indentation of all lines in the section." ;
159+ lines = apply (lines , line -> substring (line, minsize));
160+ pos := positions (sizes, i -> i == minsize);
161+ pos = append (pos, #lines );
162+ concatenate for i from 0 to #pos - 2 list (
163+ -- we make a single <code>m2code</code> from each of these
164+ -- where m2code might be several lines, in which case it is:
165+ -- <code>line1<br/>
166+ -- line2<br/>
167+ -- line3</code><br/>
168+ first := pos#i;
169+ last := pos#(i+ 1)-1;
170+ if first == last then (
171+ " <code>" | lines #first | " </code><br/>\n"
172+ ) else (
173+ " <code>" |
174+ concatenate (for j from first to last -1 list (lines #j | " <br/>\n" ))
175+ | lines #last | " </code><br/>\n"
176+ )
177+ )
178+ )
179+
180+ processSUBSECTION = (lines ) -> (
181+ -- lines should be of length 1 here.
182+ concatenate for line in lines list (
183+ " <h4>" | replace (" ^ *" , " " , line) | " </h4>\n"
184+ )
185+ )
186+
187+ convertContents = method ()
188+ convertContents String := (docstring) -> (
189+ contents := lines docstring;
110190 contents = select (contents, s -> not match (///^\s* -- ///, s));
111191 M := groupLines(contents, keywordRE);
112192 -- MKey := first select(M, x -> match(///^\s*Key///, first x));
@@ -124,11 +204,9 @@ convert String := (filename) -> (
124204 -- Keyword is: Text, Code, Example (that is it at the moment)
125205 k := first m;
126206 if k === " Text" then
127- toHtmlPara concatenate between (" \n" , m#1) -- all lines in a text section
128- else if k === " Example" then (
129- m1 := select (last m, x -> not match (///^\s* $///, x));
130- concatenate apply (m1, x -> " <code>" | replace (///^\s* ///, " " , x) |" </code><br>\n" )
131- )
207+ processTextSection m#1
208+ else if k === " Example" then
209+ processExampleSection m#1
132210 else if k === " Code" then (
133211 if match ( ///^\s* SUBSECTION ///, first last m) then (
134212 s := " " ;
@@ -147,6 +225,12 @@ convert String := (filename) -> (
147225 s | cc | " </div>\n </body>\n</html>\n"
148226 )
149227
228+ convert = method ()
229+ convert String := (filename) -> convertContents get filename
230+
231+
232+ convertSimpledocToHtml = method ()
233+ convertSimpledocToHtml String := (docstring) -> convertContents docstring
150234
151235mat := (pat,line) -> class line === String and match (pat,line)
152236
@@ -204,13 +288,171 @@ tutorialToSimpleDoc String := (x) -> (
204288 )
205289 )
206290
291+ simpledocExample = ///Keyword
292+ " unused"
293+ Headline
294+ My wonderful tutorial (by F. Bar)
295+ Description
296+ Code
297+ SUBSECTION " Name of the first lesson in the tutorial"
298+ Text
299+ Some text, allowing TeX, and things like {\tt ring }.
300+
301+ A blank line in a Text section places the parts in separate paragraphs.
302+ Here is a second line for this paragraph.
303+ Example
304+ R = ZZ/32003
305+ f = i -> i^3
306+ g = (x) -> (
307+ x^2-x-1
308+ ) -- these 3 lines will be placed in one clickable button.
309+ Code
310+ SUBSECTION " Name of the second lesson in the tutorial"
311+ Text
312+ Some more text, and perhaps some math like $x^2-x-1$.
313+ Or whatever.
314+ Example
315+ S = QQ [a..d]
316+ ///
317+
318+ doc ///
319+ Key
320+ DocConverter
321+ Headline
322+ Conversion from simpledoc format to the html format of web.macaulay2.com
323+ Description
324+ Text
325+ Tutorials for use with the web based Macaulay2, at
326+ web.macaulay2.com, are required to be in a special html format .
327+ This package is able to translate simpledoc and then Macaulay2
328+ tutorial format , to the required html format , suitable for
329+ uploading to web.macaulay2.com/submit.
330+
331+ For example, here is an example/template simpledoc file that you
332+ may base your own examples from :
333+
334+ Example
335+ print simpledocExample;
336+ Text
337+ The command @TO " convert" @ will create an html file named:
338+ filename.html , which may be uploaded to web.macaulay2.com.
339+ Example
340+ -- convert "filename.simpledoc"
341+ Text
342+ The workhorse for the convert routine is @TO " convertContents" @,
343+ which takes a string which is in simpledoc and returns a string,
344+ which is html .
345+ Example
346+ convertContents simpledocExample
347+ Text
348+ You may then write this to a file " eg.html" in the usual way.
349+ Pre
350+ " eg.html" << convertContents simpledocExample << close
351+ Text
352+ There are a number of tutorials written for Macaulay2 in an older,
353+ not well documented format . For example:
354+ Example
355+ print tutorialExample;
356+ Text
357+ Use @TO " tutorialToSimpleDoc" @ to translate to simpledoc, and then
358+ @TO " convertContents" @ to convert it to the html format required
359+ at web.macaulay2.com
360+ Caveat
361+ Not all features of the simpledoc format are available, see
362+ @TO " convertContents" @.
363+ SeeAlso
364+ SimpleDoc
365+ ///
366+
367+ doc ///
368+ Key
369+ convertSimpledocToHtml
370+ Headline
371+ Convert simpledoc format to html for tutorials
372+ Usage
373+ convertSimpledocToHtml filename
374+ Inputs
375+ filename:String
376+ Outputs
377+ :String
378+ The html of the tutorial , suitable for use as a tutorial at web.macaulay2.com
379+ Description
380+ Text
381+ The input file is expected to be in @TO " SimpleDoc" @ format .
382+ However, not all such files are accepted. Here is a template of
383+ what is allowed and expected:
384+ Pre
385+ Keyword
386+ " unused"
387+ Headline
388+ Name of the tutorial (by F. Bar)
389+ Description
390+ Code
391+ SUBSECTION " Name of the first lesson in the tutorial"
392+ Text
393+ Some text, allowing TeX, and things like {\tt ring }.
394+
395+ A blank line in a Text section places the parts in separate paragraphs.
396+ Example
397+ R = ZZ/32003
398+ f = i -> i^3
399+ g = (x) -> (
400+ x^2-x-1
401+ ) -- these 3 lines will be placed in one clickable button.
402+ Code
403+ SUBSECTION " Name of the second lesson in the tutorial"
404+ Text
405+ ...
406+ Example
407+ ...
408+ ...
409+ Text
410+ Here is an example input string, useful as an example or template.
411+
412+ Example
413+ print simpledocExample;
414+ Text
415+
416+ The output format is html , which may be used as a tutorial at web.macaulay2.com.
417+ Here is an example output.
418+
419+ Example
420+ print convertSimpledocToHtml simpledocExample;
421+ Text
422+
423+ The following keywords, allowed in simpledoc documentation, are ignored:
424+ {\bf Key ,Usage , Inputs , Outputs , Consequences , SeeAlso , Subnodes , Caveat }
425+ are all ignored.
426+
427+ SeeAlso
428+ " SimpleDoc"
429+ ///
430+
207431end
208432
433+ // test of processTextSection
434+ restart
435+ debug loadPackage " DocConverter"
436+ contents = lines simpledocExample
437+ contents = select (contents, s -> not match (///^\s* -- ///, s));
438+ M = groupLines(contents, keywordRE);
439+ groups = groupLines(M#2#1, descriptionRE)
440+ group = groups#1#1
441+ processTextSection group
442+ group = groups#2#1
443+ processExampleSection group
444+
445+ s = ///
446+ Your first input prompt will be {\tt " i1 : " }. In response to the prompt,
447+ type {\tt 2 + 2} and press return . The expression you entered will be
448+ evaluated - no punctuation is required at the end of the line.
449+ ///
209450restart
210451loadPackage " DocConverter"
211- -- L = convert "beginningM2.simpledoc";
212- L = convert " tutorials/gettingStarted.simpledoc" ;
452+ L = convert " gettingStarted.simpledoc" ;
213453" public/tutorials/getting-started.html" << L << close ;
454+
455+
214456fn = " Beginning.html"
215457fn << L << close
216458get (" !open " | fn)
0 commit comments