import re import os import tempfile import sys import klammer_base import urllib import kutil # :section (argtype section_link, Andy 2026-10-12) is absent ("false"), # written alone ("true": the section is in the current file) or written # with a basename (the file that has the section). A section link is # resolved by @document when it assembles its files (sks/document/ # section_link.h), from this marker: the heading's text and the file, "" # meaning the current one, separated by KTSL because either may contain an # underscore. def section_file(section): """The file a :section value names: "" for the current file, None when the link is not a section link at all.""" s = str(section) if s in ("", "false", "False"): return None return "" if s in ("true", "True") else s def section_marker(title, file): return f"__seclink__{title}__KTSL__{file}__" def html_link(target, link_text, is_section, no_quotation_marks, file=""): if not link_text: if is_section: link_text = target if no_quotation_marks else f"“{target}”" else: # Allow long URLs to break at a slash: link_text = re.sub('/', '/', target) link_text = re.sub('//', '//', link_text) link_text = f'{link_text}' if is_section: url = section_marker(target, file) elif target.startswith("http") or ".html" in target: url = target else: url = f"^#{target}" result = f'{link_text}' return result def add_latex_footnote_if_necessary(url, link_text): result = "" if (('http://' in url or 'https://' in url) and ('http://' not in link_text and 'https://' not in link_text)): escaped_url = re.sub('#', '\\#', url) escaped_url = re.sub('%', '\\%', escaped_url) result += f'\\footnote{{\\\rule{{0pt}}{{12pt}}\\texttt{{{escaped_url}}}}}' return result def latex_link(target, link_text, is_section, no_quotation_marks, add_footnote, file=""): if target.startswith("http"): if link_text and link_text != "URL": result = f"#/ \\href{{{target}}}{{{link_text}}} #/" else: #result = f"\\\url{{{target}}}" result = f"#/ \\href{{{target}}}{{{target}}} #/" elif is_section: if not link_text: link_text = target if no_quotation_marks else f"``{target}''" result = f"\\hyperlink{{{section_marker(target, file)}}}{{{link_text}}}" else: result = f"\\hyperlink{{{target}}}{{{link_text}}}" # if add_footnote: # if self.footnote: # result += add_latex_footnote_if_necessary(target, link_text) # print(result) return result class Link(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) # self.show("Link") def html(self): file = section_file(self.section) return html_link(self.target, self.text, file is not None, self.nq, file or "") def tex(self): file = section_file(self.section) return latex_link(self.target, self.text, file is not None, self.nq, self.footnote, file or "") def txt(self): text = f'{self.text} ' if self.text else '' return f'{text}[{self.target}]' class Target(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) id = K.id.strip() id = re.compile(r'\s+', re.S).sub('-', id) self.id = re.sub('_', '-', id) def html(self): id = self.id.split(':')[-1] return f'{self.text}' def tex(self): result = f'\\hypertarget{{{self.id}}}{{{self.text}}}' #result += '\\label{{{}-label}}'.format(id) return result # Better to fail than return nothing; not possible to have a target in a text file. # def txt(self): # return "" class Email(klammer_base.Klammer_base): def __init__(self, K): super().__init__(K) def html(self): def val(attr, s): return "{}={}&".format(attr, re.sub(" ", "%20", s)) domain = "&^#46;".join(self.domain.split(".")) address = "{}&^#64;{}".format(self.name, domain) href = "mailto&^#58;{}?".format(address) if self.subject: href += val("subject", self.subject) if self.body: href += val("body", self.body) href = href[:-1] result = '{}'.format(href, address) return result def tex(self): return r'\texttt{{{}^@{}}}'.format(self.name, self.domain)