def _build_html_head(self): '''Add title, metadata, and styles''' self.elements.head.append(E.meta(charset='UTF-8')) self._build_html_title() for key, value in self._default_meta_values: self.meta[key] = value self._build_html_head_meta() self._build_html_head_links() self._build_html_stylesheets()
def gen_body_redirect(code, location): from lxml.html.builder import E from lxml.html import tostring return tostring(E.HTML( E.HEAD( E.meta(**{ "http-equiv": "content-type", "content": "text/html;charset=utf-8", }), E.TITLE(code), ), E.BODY( E.H1(code), E.P("The document has moved"), E.A("here", HREF=location), ".", ) ))
def gen_body_redirect(code, location): from lxml.html.builder import E from lxml.html import tostring return tostring( E.HTML( E.HEAD( E.meta( **{ "http-equiv": "content-type", "content": "text/html;charset=utf-8", }), E.TITLE(code), ), E.BODY( E.H1(code), E.P("The document has moved"), E.A("here", HREF=location), ".", )))
def _build_html_head_meta(self): '''Builds the meta elements.''' head = self.elements.head for key, value in self.meta.items(): head.append(E.meta(name=key, content=value))
def main(): # TODO: combine command-line and option file. # TODO: option to generate a default configuration file parser = argparse.ArgumentParser() # TODO: doc parser.add_argument("-s", "--standalone", action="store_true") # TODO: doc args = parser.parse_args() standalone = args.standalone conf = json.load((DATA / "artdoc.js").open()) if Path("artdoc.js").exists(): user_conf = json.load(Path("artdoc.js").open()) conf.update(user_conf) info("Document:") doc_patterns = conf["doc"] if isinstance(doc_patterns, basestring): doc_patterns = [doc_patterns] docs = [] for pattern in doc_patterns: matches = list(WORKDIR.glob(pattern)) #subinfo("matching {!r}:".format(pattern)) for match in matches: subinfo(str(match)) docs.extend(matches) if not docs: sys.exit("error: no document found") # info("HTML template:") # template_file = HTML / "index.html" # subinfo(str(template_file)) # template = template_file.open().read().encode("utf-8") info("Bibliography:") bib_patterns = conf["bib"] if isinstance(bib_patterns, basestring): bib_patterns = [bib_patterns] bibs = [] for pattern in bib_patterns: matches = list(WORKDIR.glob(pattern)) #subinfo("matching {!r}:".format(pattern)) for match in matches: subinfo(str(match)) bibs.extend(matches) if not bibs: print() info("JS:") cmd = coffee["-c", str(JS / "main.coffee")] subinfo(cmd) cmd() info("CSS:") cmd = stylus[str(CSS / "style.styl")] subinfo(str(cmd)) cmd() # TODO: copy only what is required. shutil.copytree(str(DATA), str(ARTDOC)) for doc in docs: pass info("PANDOC: generate JSON file") args = ["-t", "json", "--smart"] for bib in bibs: args.extend(["--bibliography", str(bib)]) args.append(str(doc)) cmd = pandoc[args] subinfo(cmd, "> json") json_str = cmd() info("Convert raw TeX to raw HTML") cmd = local[str(BIN / "rawHTML.hs")] subinfo(cmd, "< json > json") json_str = (cmd << json_str)() # info("Flag/Box Proofs") # cmd = local[str(BIN / "proof.hs")] # subinfo(cmd, "< json > json") # try: # json_str = (cmd << json_str)() # except Exception as error: # print(repr(error)) # info("Wrap Section-Like Sequence of Blocks") # cmd = local[str(BIN / "div.hs")] # subinfo(cmd, "< json > json") # try: # json_str = (cmd << json_str)() # except Exception as error: # print(repr(error)) info("Wrap Section-Like Sequence of Blocks") cmd = local[str(BIN / "section.hs")] subinfo(cmd, "< json > json") try: json_str = (cmd << json_str)() except Exception as error: print(repr(error)) info("Flag Tombstones (end of proofs)") cmd = local[str(BIN / "tombstone.hs")] subinfo(cmd, "< json > json") try: json_str = (cmd << json_str)() except Exception as error: print(repr(error)) info("Convert Images to SVG Images") cmd = local[str(BIN / "svg.hs")] subinfo(cmd, "< json > json") json_str = (cmd << json_str)() info("Generate HTML body from markdown") args = ["--email-obfuscation", "none", "-f", "json", "--mathjax", "-t", "html5", "--section-divs"] cmd = pandoc[args] subinfo(cmd, "< json > body") pandoc_body_str = (cmd << json_str)() pandoc_html = lxml.html.document_fromstring(pandoc_body_str) pandoc_body = pandoc_html.cssselect("body")[0] info("Generate standalone HTML doc") html = HTML.html(HTML.head, HTML.body) body = html.cssselect("body")[0] head = html.cssselect("head")[0] head.append(HTML.meta(charset="utf-8")) body.attrib.update(pandoc_body.attrib) body.extend(pandoc_body[:]) # ---------------------------------------------------------------------- info("Add JQuery") head.extend(jquery(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Velocity") head.extend(velocity(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Clipboard.js") head.extend(clipboard(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Highlight.js") head.extend(highlight(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Google Fonts support") head.extend(google_fonts(["Alegreya", "Alegreya SC"], standalone=standalone)) # ---------------------------------------------------------------------- info("Add Mathjax support") head.extend(mathjax(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Font Awesome support") head.extend(font_awesome(standalone=standalone)) # ---------------------------------------------------------------------- info("Add artdoc css & js files") head.extend(artdoc()) # ---------------------------------------------------------------------- info("Setting language to english (required for hyphens)") html.set("lang", "en") # ---------------------------------------------------------------------- info("Ensure ids uniqueness") id_count = {} for elt in html.iter(): _id = elt.get("id") if _id is not None: count = id_count.get(_id, 0) if count > 0: elt.set("id", _id + "-" + str(count)) id_count[_id] = count + 1 # ---------------------------------------------------------------------- info("Turning headers into self-links") sections = html.cssselect("section") for section in sections: id_ = section.get("id") heading = None if len(section): first = section[0] if first.tag in "h1 h2 h3 h4 h5 h6".split(): heading = first if id_ and heading is not None: contents = [heading.text or ""] + heading[:] heading.text, heading[:] = None, [] href = {"href": "#" + id_} link = HTML.a(href, *contents) heading.insert(0, link) # ---------------------------------------------------------------------- # TODO: deal with metadata & insert a document header with: # - title, # - date (format: Month Day, Year), autoformat, autogen ? # - author(s) (with mail & affiliation when available ?). # Assume custom metadata or parse the author field ? # Representation of multiple authors ? MMm eLIFEsciences use # popup for author info. Ex: http://elifesciences.org/content/4/e06356 ! # here, use hints from http://dtd.nlm.nih.gov/book/tag-library/: # # - name (don't be more precise) # - affiliation (concatenate) # - address ??? # - email --> Font Awesome Icon # - url / uri ? # - form of ID ? (like HAL ? or ZBlatt ?) # TODO: look at the rendering of # http://kieranhealy.org/blog/archives/2014/01/23/plain-text/: # - small grey date on top, bold title, bold author name, # italics affiliation, repeat. metadata = get_metadata(str(doc)) items = [] date = parse_html(metadata.get("date")) if date is not None: items.append(HTML.p({"class": "date"}, *date)) # def textify(item): # if isinstance(item, basestring): # return item # elif hasattr(item, "text"): # return item.text # else: # return "".join([textify(it) or "" for it in item]) title = parse_html(metadata.get("title")) title_id = None if title is not None: #title_id = textify(title).lower().replace(" ", "-") items.append( HTML.h1( {"class": "title"}, HTML.a( {"href": "#"}, *title ) ) ) head.insert(0, HTML.title(*title)) authors = metadata.get("author") or [] for author in authors: if isinstance(author, basestring): name = parse_html(author) email = None affiliation = None else: name = parse_html(author.get("name")) email = parse_html(author.get("email")) affiliation = parse_html(author.get("affiliation")) if name is not None: if email is not None: name = [HTML.a({"href": "mailto:" + email[0]}, *name)] name = HTML.p({"class": "author"}, *name) items.append(name) if affiliation is not None: affiliation = HTML.p({"class": "affiliation"}, *affiliation) items.append(affiliation) header_attr = {"class": "main"} # if title_id is not None: # header_attr["id"] = title_id header = HTML.header(header_attr, *items) # print("HEADER", lxml.html.tostring(header)) body.insert(0, header) # print("BODY", lxml.html.tostring(body)) # print("HTML", lxml.html.tostring(html)) # ---------------------------------------------------------------------- info("Generate the standalone HTML file") html_str = lxml.html.tostring(html, encoding="utf-8", doctype="<!DOCTYPE html>") doc.with_suffix(".html").open("wb").write(html_str) sys.exit(0)
def main(): # TODO: combine command-line and option file. # TODO: option to generate a default configuration file parser = argparse.ArgumentParser() # TODO: doc parser.add_argument("-s", "--standalone", action="store_true") # TODO: doc args = parser.parse_args() standalone = args.standalone conf = json.load((DATA / "artdoc.js").open()) if Path("artdoc.js").exists(): user_conf = json.load(Path("artdoc.js").open()) conf.update(user_conf) info("Document:") doc_patterns = conf["doc"] if isinstance(doc_patterns, basestring): doc_patterns = [doc_patterns] docs = [] for pattern in doc_patterns: matches = list(WORKDIR.glob(pattern)) #subinfo("matching {!r}:".format(pattern)) for match in matches: subinfo(str(match)) docs.extend(matches) if not docs: sys.exit("error: no document found") # info("HTML template:") # template_file = HTML / "index.html" # subinfo(str(template_file)) # template = template_file.open().read().encode("utf-8") info("Bibliography:") bib_patterns = conf["bib"] if isinstance(bib_patterns, basestring): bib_patterns = [bib_patterns] bibs = [] for pattern in bib_patterns: matches = list(WORKDIR.glob(pattern)) #subinfo("matching {!r}:".format(pattern)) for match in matches: subinfo(str(match)) bibs.extend(matches) if not bibs: print() info("JS:") cmd = coffee["-c", str(JS / "main.coffee")] subinfo(cmd) cmd() info("CSS:") cmd = stylus[str(CSS / "style.styl")] subinfo(str(cmd)) cmd() # TODO: copy only what is required. shutil.copytree(str(DATA), str(ARTDOC)) for doc in docs: pass info("PANDOC: generate JSON file") args = ["-t", "json", "--smart"] for bib in bibs: args.extend(["--bibliography", str(bib)]) args.append(str(doc)) cmd = pandoc[args] subinfo(cmd, "> json") json_str = cmd() info("Convert raw TeX to raw HTML") cmd = local[str(BIN / "rawHTML.hs")] subinfo(cmd, "< json > json") json_str = (cmd << json_str)() # info("Flag/Box Proofs") # cmd = local[str(BIN / "proof.hs")] # subinfo(cmd, "< json > json") # try: # json_str = (cmd << json_str)() # except Exception as error: # print(repr(error)) # info("Wrap Section-Like Sequence of Blocks") # cmd = local[str(BIN / "div.hs")] # subinfo(cmd, "< json > json") # try: # json_str = (cmd << json_str)() # except Exception as error: # print(repr(error)) info("Wrap Section-Like Sequence of Blocks") cmd = local[str(BIN / "section.hs")] subinfo(cmd, "< json > json") try: json_str = (cmd << json_str)() except Exception as error: print(repr(error)) info("Flag Tombstones (end of proofs)") cmd = local[str(BIN / "tombstone.hs")] subinfo(cmd, "< json > json") try: json_str = (cmd << json_str)() except Exception as error: print(repr(error)) info("Convert Images to SVG Images") cmd = local[str(BIN / "svg.hs")] subinfo(cmd, "< json > json") json_str = (cmd << json_str)() info("Generate HTML body from markdown") args = [ "--email-obfuscation", "none", "-f", "json", "--mathjax", "-t", "html5", "--section-divs" ] cmd = pandoc[args] subinfo(cmd, "< json > body") pandoc_body_str = (cmd << json_str)() pandoc_html = lxml.html.document_fromstring(pandoc_body_str) pandoc_body = pandoc_html.cssselect("body")[0] info("Generate standalone HTML doc") html = HTML.html(HTML.head, HTML.body) body = html.cssselect("body")[0] head = html.cssselect("head")[0] head.append(HTML.meta(charset="utf-8")) body.attrib.update(pandoc_body.attrib) body.extend(pandoc_body[:]) # ---------------------------------------------------------------------- info("Add JQuery") head.extend(jquery(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Velocity") head.extend(velocity(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Clipboard.js") head.extend(clipboard(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Highlight.js") head.extend(highlight(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Google Fonts support") head.extend( google_fonts(["Alegreya", "Alegreya SC"], standalone=standalone)) # ---------------------------------------------------------------------- info("Add Mathjax support") head.extend(mathjax(standalone=standalone)) # ---------------------------------------------------------------------- info("Add Font Awesome support") head.extend(font_awesome(standalone=standalone)) # ---------------------------------------------------------------------- info("Add artdoc css & js files") head.extend(artdoc()) # ---------------------------------------------------------------------- info("Setting language to english (required for hyphens)") html.set("lang", "en") # ---------------------------------------------------------------------- info("Ensure ids uniqueness") id_count = {} for elt in html.iter(): _id = elt.get("id") if _id is not None: count = id_count.get(_id, 0) if count > 0: elt.set("id", _id + "-" + str(count)) id_count[_id] = count + 1 # ---------------------------------------------------------------------- info("Turning headers into self-links") sections = html.cssselect("section") for section in sections: id_ = section.get("id") heading = None if len(section): first = section[0] if first.tag in "h1 h2 h3 h4 h5 h6".split(): heading = first if id_ and heading is not None: contents = [heading.text or ""] + heading[:] heading.text, heading[:] = None, [] href = {"href": "#" + id_} link = HTML.a(href, *contents) heading.insert(0, link) # ---------------------------------------------------------------------- # TODO: deal with metadata & insert a document header with: # - title, # - date (format: Month Day, Year), autoformat, autogen ? # - author(s) (with mail & affiliation when available ?). # Assume custom metadata or parse the author field ? # Representation of multiple authors ? MMm eLIFEsciences use # popup for author info. Ex: http://elifesciences.org/content/4/e06356 ! # here, use hints from http://dtd.nlm.nih.gov/book/tag-library/: # # - name (don't be more precise) # - affiliation (concatenate) # - address ??? # - email --> Font Awesome Icon # - url / uri ? # - form of ID ? (like HAL ? or ZBlatt ?) # TODO: look at the rendering of # http://kieranhealy.org/blog/archives/2014/01/23/plain-text/: # - small grey date on top, bold title, bold author name, # italics affiliation, repeat. metadata = get_metadata(str(doc)) items = [] date = parse_html(metadata.get("date")) if date is not None: items.append(HTML.p({"class": "date"}, *date)) # def textify(item): # if isinstance(item, basestring): # return item # elif hasattr(item, "text"): # return item.text # else: # return "".join([textify(it) or "" for it in item]) title = parse_html(metadata.get("title")) title_id = None if title is not None: #title_id = textify(title).lower().replace(" ", "-") items.append( HTML.h1({"class": "title"}, HTML.a({"href": "#"}, *title))) head.insert(0, HTML.title(*title)) authors = metadata.get("author") or [] for author in authors: if isinstance(author, basestring): name = parse_html(author) email = None affiliation = None else: name = parse_html(author.get("name")) email = parse_html(author.get("email")) affiliation = parse_html(author.get("affiliation")) if name is not None: if email is not None: name = [HTML.a({"href": "mailto:" + email[0]}, *name)] name = HTML.p({"class": "author"}, *name) items.append(name) if affiliation is not None: affiliation = HTML.p({"class": "affiliation"}, *affiliation) items.append(affiliation) header_attr = {"class": "main"} # if title_id is not None: # header_attr["id"] = title_id header = HTML.header(header_attr, *items) # print("HEADER", lxml.html.tostring(header)) body.insert(0, header) # print("BODY", lxml.html.tostring(body)) # print("HTML", lxml.html.tostring(html)) # ---------------------------------------------------------------------- info("Generate the standalone HTML file") html_str = lxml.html.tostring(html, encoding="utf-8", doctype="<!DOCTYPE html>") doc.with_suffix(".html").open("wb").write(html_str) sys.exit(0)