├── CHANGELOG ├── Makefile ├── README.md ├── addfont4ht.sty ├── alt-packages ├── fontspec-alt4ht.4ht ├── fontspec-alt4ht.lua ├── fontspec-alt4ht.sty ├── mathtools-alt4ht.sty ├── pdfpages-alt4ht.sty ├── polyglossia-alt4ht.4ht ├── polyglossia-alt4ht.sty ├── titlesec-alt4ht.sty └── xeCJK-alt4ht.sty ├── alternative4ht.sty ├── cssframework.sty ├── helpers4ht-doc.tex ├── helpers4ht.tex ├── include4ht.sty ├── indexing4ht.4ht ├── indexing4ht.sty ├── mathjax-latex-4ht.sty ├── rfclang.sty └── textstyle4ht.sty /CHANGELOG: -------------------------------------------------------------------------------- 1 | # 2015/09/25 2 | 3 | - Initial version 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | tex_content = helpers4ht $(wildcard *.sty) $(wildcard *.4ht) $(wildcard *.tex) $(wildcard *.lua) 2 | doc_file = helpers4ht-doc.pdf 3 | TEXMFHOME = $(shell kpsewhich -var-value=TEXMFHOME) 4 | INSTALL_DIR = $(TEXMFHOME)/tex/latex/helpers4ht 5 | MANUAL_DIR = $(TEXMFHOME)/doc/latex/helpers4ht 6 | SYSTEM_DIR = /usr/local/bin 7 | BUILD_DIR = build 8 | ALT_DIR = /alt-packages 9 | BUILD_HELPERS = $(BUILD_DIR)/helpers4ht/ 10 | BUILD_ALT = $(BUILD_HELPERS)/alt-packages 11 | alt = $(wildcard alt-packages/*.sty) 12 | 13 | all: doc 14 | 15 | doc: $(doc_file) readme.tex 16 | 17 | helpers4ht-doc.pdf: helpers4ht-doc.tex readme.tex changelog.tex 18 | latexmk -lualatex helpers4ht-doc.tex 19 | 20 | readme.tex: README.md 21 | pandoc -f markdown+definition_lists+inline_notes -t LaTeX README.md > readme.tex 22 | 23 | changelog.tex: CHANGELOG.md 24 | pandoc -f markdown+definition_lists -t LaTeX CHANGELOG.md > changelog.tex 25 | 26 | build: doc $(tex_content) 27 | @rm -rf build 28 | @mkdir -p $(BUILD_ALT) 29 | @cp $(tex_content) helpers4ht-doc.pdf $(BUILD_HELPERS) 30 | @cp README.md $(BUILD_HELPERS)README 31 | @cp $(alt) $(BUILD_ALT) 32 | cd $(BUILD_DIR) && zip -r helpers4ht.zip helpers4ht 33 | 34 | install: doc $(tex_content) 35 | mkdir -p $(INSTALL_DIR) 36 | mkdir -p $(MANUAL_DIR) 37 | cp $(tex_content) $(INSTALL_DIR) 38 | cp $(alt) $(INSTALL_DIR)$(ALT_DIR) 39 | cp $(doc_file) $(MANUAL_DIR) 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The `helpers4ht` package. 2 | 3 | This is a bundle of packages providing support for tex4ht configuration. With exception of `alternative4ht`, you shouldn't use them in your documents, but in the `.cfg` files instead. Provided packages are: 4 | 5 | addfont4ht 6 | 7 | : support for web fonts. [Example](https://tex.stackexchange.com/a/289562/2891). 8 | 9 | alternative4ht 10 | 11 | : provides support for patching unsupported packages with tex4ht. See [Using fontspec package with tex4ht](http://michal-h21.github.io/samples/helpers4ht/fontspec.html) for example. 12 | 13 | cssframework 14 | 15 | : simple CSS framework and preprocessor. It doesn't have any documentation or sample usage yet 16 | 17 | include4ht 18 | 19 | : declare additional files to be included, like CSS or Javascript. [Example](http://tex.stackexchange.com/a/210849/2891). This file is deprecated, tex4ht now provides `\Configure{AddJs}{filename.js}` and `\Configure{AddCss}{filename.css}` commands for the HTML output. 20 | 21 | indexing4ht 22 | 23 | : support for indexing with Xindy see an [example](http://tex.stackexchange.com/a/210849/2891) 24 | 25 | rfclang 26 | 27 | : get RFC language codes from babel language name. This functionality is built in TeX4ht itself, so this package is obsolete. 28 | 29 | textstyle4ht 30 | 31 | : support for conversion of LaTeX text styling (color, size, etc.) to CSS. new commands tor tag insertion are introduced. See a [tutorial](http://michal-h21.github.io/samples/helpers4ht/textstyle.html) 32 | 33 | mathjax-latex-4ht 34 | 35 | : save LaTeX math verbatim in the output document and use `Mathjax` for the displaying. See 36 | [this answer](http://tex.stackexchange.com/a/185802/2891) for some background and [another one](http://tex.stackexchange.com/a/265916/2891) for sample use. 37 | 38 | # Installation 39 | 40 | 41 | cd `kpsewhich -var-value TEXMFHOME` 42 | mkdir -p tex/latex 43 | cd tex/latex 44 | git clone git@github.com:michal-h21/helpers4ht.git 45 | 46 | #Usage 47 | 48 | To use package in the `.cfg` file, you must include it before the `\Preamble` command: 49 | 50 | \RequirePackage{cssframework} 51 | \Preamble{xhtml} 52 | \begin{document} 53 | \EndPreamble 54 | 55 | See [wiki](https://github.com/michal-h21/helpers4ht/wiki) for more information. 56 | -------------------------------------------------------------------------------- /addfont4ht.sty: -------------------------------------------------------------------------------- 1 | % This package declares new font family in the CSS file 2 | % Usage: 3 | % 4 | % \NormalFont{FontFamilyName}{normal-font-file.otf} 5 | % \BoldFont{FontFamilyName}{bold-font-file.otf} 6 | % \BoldItalicFont{FontFamilyName}{bold-italic-font-file.otf} 7 | % \ItalicFont{FontFamilyName}{italic-font-file.otf} 8 | % \Css{body{font-family: rmfamily, "FontFamilyName", serif;}} 9 | % 10 | % The default font family name for a declared font is rmfamily 11 | % It can be changed using \SetFontFamily command. 12 | 13 | % It is necessary to provide three names 14 | % #1 font family name that will be used later in the user CSS 15 | % #2 font family from the user file system, which will be used if available (so downloading of the fonts is not necessary) 16 | % #3 filename of the font which should be used if the local version is not available 17 | \RequirePackage{include4ht} 18 | \newcommand\AddFontFace[4]{% 19 | \Css{@font-face { 20 | font-family: #1; 21 | src: local("#2"), 22 | url('#3'); 23 | #4 24 | }} 25 | \AddFile{#3} 26 | } 27 | 28 | % The default font family declared by font definition commands 29 | \edef\CurrentFontFamily{rmfamily} 30 | 31 | % If more font families are used, they need to have different names 32 | \newcommand\SetFontFamily[1]{ 33 | \edef\CurrentFontFamily{#1} 34 | } 35 | 36 | 37 | % Declarations for common font styles, just local family name and font file name are needed to be provided 38 | \newcommand\NormalFont[2]{\AddFontFace{\CurrentFontFamily}{#1}{#2}{font-weight: normal;font-style: normal;}} 39 | \newcommand\BoldFont[2]{\AddFontFace{\CurrentFontFamily}{#1}{#2}{font-weight: bold;font-style: normal;}} 40 | \newcommand\ItalicFont[2]{\AddFontFace{\CurrentFontFamily}{#1}{#2}{font-weight: normal;font-style: italic;}} 41 | \newcommand\BoldItalicFont[2]{\AddFontFace{\CurrentFontFamily}{#1}{#2}{font-weight: bold;font-style: italic;}} 42 | 43 | -------------------------------------------------------------------------------- /alt-packages/fontspec-alt4ht.4ht: -------------------------------------------------------------------------------- 1 | % we must individually allow fonts for processing by Lua callbacks, in order to support tfm fonts 2 | % as cmr is used for text by default, it shouldn't be necessary to add more fonts, as they are likely 3 | % tfm math fonts 4 | \NewConfigure{AllowFont}[1]{% 5 | \directlua{add_allowed_font("#1")} 6 | } 7 | 8 | -------------------------------------------------------------------------------- /alt-packages/fontspec-alt4ht.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local glyph_id = node.id "glyph" 4 | local whatsit_id = node.id "whatsit" 5 | local special_subtype = node.subtype "special" 6 | local dir_id = node.id "dir" 7 | local glue_id = node.id "glue" 8 | 9 | local escape = function(char) 10 | -- prepare tex4ht special for entity with unicode value 11 | return string.format("t4ht@+&{35}x%x{59}", char) 12 | end 13 | 14 | local make_node = function(data) 15 | -- make special whathsit 16 | local n = node.new(whatsit_id,special_subtype) 17 | n.data = data 18 | return n 19 | end 20 | 21 | -- this should be table with patterns for allowed fonts 22 | local allowed_names = {"^cmr", "^cmb","^cmt", "^cmb", "^cmcs", "^rm%-l", "^cmi", "^none"} 23 | 24 | local testfont = function(name) 25 | -- test font name for all allowed names, when it is found, return true 26 | for _, x in ipairs(allowed_names) do 27 | local r = name:match(x) 28 | if r then 29 | return true 30 | end 31 | end 32 | return false 33 | end 34 | 35 | local fonttypes = {} 36 | local get_font_type = function(id) 37 | if fonttypes[id]~=nil then return fonttypes[id] end 38 | local f = font.getfont(id) or {name = "none"} 39 | local name = f.name 40 | local type = testfont(string.lower(name)) 41 | if not type then 42 | print("Unsupported font", name) 43 | end 44 | fonttypes[id] = type 45 | return type 46 | end 47 | 48 | local xchar = string.byte("x") 49 | 50 | local utfchar = unicode.utf8.char 51 | function M.char_to_entity(head) 52 | -- traverse characters 53 | for n in node.traverse(head) do 54 | if n.id == glyph_id then 55 | -- we need to process only default text font, ie cmr, because user may request special mathematical fonts, 56 | -- which should be processed via htf files as usual 57 | local t = get_font_type(n.font) 58 | if t == true then 59 | local char = n.char 60 | if char > 127 then 61 | local new = escape(char) 62 | local x = make_node(new) 63 | -- insert tex4ht special before char, it will replace the char 64 | node.insert_before(head, n, x) 65 | -- in standard tex4ht accented characters are replaced with "x" char. they are later removed anyway 66 | -- maybe we don't need to do that, but we can, so why not? 67 | n.char = xchar 68 | end 69 | end 70 | elseif n.id == dir_id then 71 | -- when text direction is TRT, the spaces in the DVI file have negative width and they are not recognized by tex4ht 72 | -- so we just change the direction to normal TLT 73 | n.dir = "TLT" 74 | end 75 | end 76 | return head 77 | end 78 | 79 | M.allowed = allowed_names 80 | 81 | return M 82 | 83 | -------------------------------------------------------------------------------- /alt-packages/fontspec-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \RequirePackage{ifluatex} 2 | \RequirePackage{xparse} 3 | 4 | % we will just define font commands to do nothing. we are only interested in exporting unicode values 5 | 6 | % main commands 7 | 8 | \DeclareDocumentCommand{\newfontfamily}{m o m o}{\gdef#1{\relax}} 9 | \DeclareDocumentCommand{\newfontface}{m o m o}{\gdef#1{\relax}} 10 | \DeclareDocumentCommand{\setmainfont}{m o}{} 11 | \DeclareDocumentCommand{\setsansfont}{m o}{} 12 | \DeclareDocumentCommand{\setmonofont}{m o}{} 13 | \DeclareDocumentCommand{\fontspec}{m o}{} 14 | 15 | % math commands 16 | 17 | \DeclareDocumentCommand{\setmathrm}{m o}{} 18 | \DeclareDocumentCommand{\setmathsf}{m o}{} 19 | \DeclareDocumentCommand{\setmathtt}{m o}{} 20 | \DeclareDocumentCommand{\setboldmathrm}{m o}{} 21 | 22 | % features 23 | 24 | \DeclareDocumentCommand{\defaultfontfeatures}{t+ o m}{} 25 | \DeclareDocumentCommand{\addfontfeatures}{m}{} 26 | \DeclareDocumentCommand{\addfontfeature}{m}{} 27 | 28 | 29 | % we can use callback to escape unicode characters with LuaLaTeX, we need other method for XeLaTeX 30 | \ifluatex 31 | \RequirePackage{luatexbase} 32 | \directlua{% 33 | local fontspec = require "fontspec-alt4ht" 34 | luatexbase.add_to_callback("pre_linebreak_filter", fontspec.char_to_entity, "Char to entity") 35 | luatexbase.add_to_callback("hpack_filter", fontspec.char_to_entity, "hpack-char-to-entity") 36 | function add_allowed_font(pattern) 37 | print("Fontspec-4ht: Adding pattern to allowed fonts", pattern) 38 | table.insert(fontspec.allowed, pattern) 39 | end 40 | } 41 | \else 42 | 43 | \fi 44 | -------------------------------------------------------------------------------- /alt-packages/mathtools-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{mathtools-alt4ht} 2 | \RequirePackage{mathtools} 3 | 4 | \MHInternalSyntaxOn 5 | 6 | \renewcommand\MT_delim_default_inner_wrappers:n [1]{ 7 | \@namedef{MT_delim_\MH_cs_to_str:N #1 _star_wrapper:nnn}##1##2##3{ 8 | %\mathopen{}\mathclose\bgroup ##1 ##2 \aftergroup\egroup ##3 9 | ##1##2##3 10 | } 11 | \@namedef{MT_delim_\MH_cs_to_str:N #1 _nostar_wrapper:nnn}##1##2##3{ 12 | \mathopen{##1}##2\mathclose{##3} 13 | } 14 | } 15 | \MHInternalSyntaxOff 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /alt-packages/pdfpages-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{pdfpages-alt4ht} 2 | \RequirePackage{graphicx} 3 | \RequirePackage{xkeyval} 4 | \define@key{includepdf}{pages}{\edef\current@pdf@page{\the\numexpr #1-1\relax}} 5 | 6 | \newcommand\includepdf[2][]{% 7 | \def\current@pdf@page{0} 8 | \setkeys*{includepdf}{#1} 9 | \filename@parse{#2} 10 | \def\current@png@name{\filename@area\filename@base-\current@pdf@page.png} 11 | \IfFileExists{\current@png@name}{}{% 12 | \Needs{"convert #2[\current@pdf@page] 13 | \current@png@name"} 14 | } 15 | \includegraphics{\current@png@name} 16 | } 17 | 18 | \endinput 19 | -------------------------------------------------------------------------------- /alt-packages/polyglossia-alt4ht.4ht: -------------------------------------------------------------------------------- 1 | % package for language codes 2 | \RequirePackage{rfclang} 3 | 4 | % this is used in \text commands 5 | \NewConfigure{PrintLang}{2} 6 | 7 | \renewcommand\printlang[1]{\a:PrintLang#1\b:PrintLang} 8 | 9 | \Configure{PrintLang}{\HCode{}}{\HCode{}} 10 | 11 | % this is used in \begin{} environment 12 | \NewConfigure{LangEnv}{2} 13 | 14 | \pend:def\Startlang{\a:LangEnv} 15 | \pend:def\Endlang{\b:LangEnv} 16 | 17 | \Configure{LangEnv}{\ifvmode\IgnorePar\fi\EndP\HCode{
}\par}{\ifvmode\IgnorePar\fi\EndP\HCode{
}} 18 | 19 | 20 | -------------------------------------------------------------------------------- /alt-packages/polyglossia-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{polyglossia-alt4ht} 2 | \RequirePackage{etoolbox,xkeyval,ifluatex} 3 | \RequirePackage{fontspec-alt4ht} 4 | 5 | \ifluatex 6 | % fixes for gloss-french.ldf 7 | \directlua{ 8 | polyglossia = {} 9 | local emptyfn = function() return nil end 10 | polyglossia.load_frpt = emptyfn 11 | polyglossia.activate_frpt = emptyfn 12 | } 13 | 14 | \fi 15 | 16 | 17 | 18 | % we need helper macros which can be configured from tex4ht, because we don't know all possible 19 | % names for \text and \begin{} 20 | \newcommand\printlang[1]{#1} 21 | \newcommand\Startlang{} 22 | \newcommand\Endlang{} 23 | 24 | % emulate basic commands 25 | \newcommand\polyselect@language[1]{% 26 | \gdef\languagename{#1}% 27 | \ifcsdef{date#1}{\csuse{date#1}}{} 28 | \ifcsdef{captions#1}{\csuse{captions#1}}{} 29 | } 30 | 31 | % load language file 32 | 33 | \newcommand\poly@load@lang@file[1]{% 34 | \typeout{Ujj #1} 35 | \IfFileExists{gloss-#1.ldf}{% 36 | \ifcsundef{#1@loaded}{% 37 | \makeatletter 38 | \typeout{l@#1} 39 | % we don\t use real language numbers from language.dat, because it isn't used at all 40 | \csgdef{l@#1}{1} 41 | \input{gloss-#1.ldf} 42 | \makeatother 43 | \csgdef{#1@loaded}{\relax} 44 | }{} 45 | }{\typeout{}} 46 | } 47 | 48 | % make language selectiong command and environment 49 | \newcommand\poly@setuplanguage[1]{% 50 | \long\csgdef{text#1}##1{\bgroup\polyselect@language{#1}\printlang{##1}\egroup} 51 | \newenvironment{#1}[1][]{\polyselect@language{#1}\Startlang}{\Endlang} 52 | \poly@load@lang@file{#1} 53 | } 54 | % save main language so we can work with it later 55 | % this is basically copied from babel 56 | \newcommand\setdefaultlanguage[2][]{% 57 | \gdef\bbl@main@language{#2}% 58 | \poly@setuplanguage{#2} 59 | \polyselect@language{#2} 60 | } 61 | 62 | % this is just alias 63 | \newcommand\setmainlanguage[1]{\setdefaultlanguage{#1}} 64 | 65 | % we 66 | \newcommand\setotherlanguage[1]{\poly@setuplanguage{#1}} 67 | \newcommand\setotherlanguages[1]{} 68 | 69 | % Add commands used in language files 70 | 71 | \newcommand\PolyglossiaSetup[2]{} 72 | \newcommand\xpg@warning[1]{\typeout{[Polyglossia]: #1}} 73 | \newcommand\xpg@ifdefined[3]{} 74 | \newif\ifsystem@babelshorthands 75 | \system@babelshorthandsfalse 76 | 77 | % we can also try to pretend that fontspec is loaded 78 | % but we will need to provide more macros and Lua functions in order to do that! 79 | % \@namedef{ver@fontspec.sty}{} 80 | % \RequirePackage{polyglossia} 81 | -------------------------------------------------------------------------------- /alt-packages/titlesec-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{titlesec-altht} 2 | % Use titlesec as normally, just redefine some macros which can be used in 3 | % the preamble 4 | \RequirePackage{titlesec} 5 | \renewcommand\titleformat[5]{\PackageWarning{titlesec-4ht}{Title format is unsupported, use CSS to style headings instead}} 6 | \endinput 7 | -------------------------------------------------------------------------------- /alt-packages/xeCJK-alt4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{xeCJK-alt4ht} 2 | \RequirePackage{xparse} 3 | 4 | % support xeCJK document commands 5 | \NewDocumentCommand\xeCJKShipoutHook{}{} 6 | \NewDocumentCommand \makexeCJKactive { } { \XeTeXinterchartokenstate = 1 } 7 | \NewDocumentCommand \makexeCJKinactive { } { \XeTeXinterchartokenstate = 0 } 8 | \NewDocumentCommand \xeCJKDeclareCharClass { s > { \TrimSpaces } m m } 9 | {} 10 | \NewDocumentCommand \xeCJKnobreak { }{} 11 | 12 | % basic font commands 13 | \NewDocumentCommand \setCJKfallbackfamilyfont { m O { } m }{} 14 | \NewDocumentCommand \CJKfamily { t+ t- m }{} 15 | \NewDocumentCommand \setCJKmainfont { O { } m }{} 16 | \NewDocumentCommand \setCJKsansfont { O { } m }{} 17 | \NewDocumentCommand \setCJKmonofont { O { } m }{} 18 | 19 | % families 20 | \NewDocumentCommand \setCJKfamilyfont { m O { } m }{\gdef#1{\relax}} 21 | \NewDocumentCommand \newCJKfontfamily { o m O { } m }{\gdef#2{\relax}} 22 | \NewDocumentCommand \CJKfontspec { O { } m }{} 23 | 24 | % font features 25 | \NewDocumentCommand \defaultCJKfontfeatures { m }{} 26 | \NewDocumentCommand \addCJKfontfeatures { s O { } m }{} 27 | 28 | % math fonts 29 | \NewDocumentCommand \setCJKmathfont { O { } m }{} 30 | 31 | % misc? 32 | \NewDocumentCommand \xeCJKVerbAddon { }{} 33 | \NewDocumentCommand \xeCJKOffVerbAddon { }{} 34 | 35 | \NewDocumentCommand \xeCJKsetup { m }{} 36 | 37 | % verbatim copy 38 | \NewDocumentCommand \xeCJKsetemboldenfactor { m } 39 | { \xeCJKsetup { EmboldenFactor = {#1} } } 40 | \NewDocumentCommand \xeCJKsetslantfactor { m } 41 | { \xeCJKsetup { SlantFactor = {#1} } } 42 | \NewDocumentCommand \punctstyle { m } { \xeCJKsetup { PunctStyle = {#1} } } 43 | \NewDocumentCommand \xeCJKplainchr { } { \xeCJKsetup { PunctStyle = plain } } 44 | \NewDocumentCommand \CJKsetecglue { m } { \xeCJKsetup { CJKecglue = {#1} } } 45 | \NewDocumentCommand \CJKspace { } { \xeCJKsetup { CJKspace = true } } 46 | \NewDocumentCommand \CJKnospace { } { \xeCJKsetup { CJKspace = false } } 47 | \NewDocumentCommand \xeCJKallowbreakbetweenpuncts { } 48 | { \xeCJKsetup { AllowBreakBetweenPuncts = true } } 49 | \NewDocumentCommand \xeCJKnobreakbetweenpuncts { } 50 | { \xeCJKsetup { AllowBreakBetweenPuncts = false } } 51 | \NewDocumentCommand \xeCJKenablefallback { } 52 | { \xeCJKsetup { AutoFallBack = true } } 53 | \NewDocumentCommand \xeCJKdisablefallback { } 54 | { \xeCJKsetup { AutoFallBack = false } } 55 | 56 | % ToDo: add support for xuninode-addon.sty - it loads EU2 or EU1 encodings, 57 | % how to prevent that? 58 | 59 | 60 | -------------------------------------------------------------------------------- /alternative4ht.sty: -------------------------------------------------------------------------------- 1 | % Enable tex4ht to patch packages before \begin{document} 2 | % configurations provided by .4ht files are used after \begin{document} 3 | % so if some command which causes tex4ht to fail is used in the preamble, 4 | % we have no chance to catch it 5 | % with \altusepackage, we may choose to not include package at all, when tex4ht 6 | % is running, or use special patch file in the form of packagename-alt4ht.sty 7 | % normal \usepackage is used when tex4ht is not running 8 | \ProvidesPackage{alternative4ht} 9 | 10 | 11 | \newcommand{\altusepackage}[2][]{% 12 | \ifdefined\HCode% 13 | \IfFileExists{#2-alt4ht.sty}{% 14 | \usepackage[#1]{#2-alt4ht}% 15 | }{\typeout{alternative4ht: no patch file for #2}} 16 | \else% 17 | \usepackage[#1]{#2}% 18 | \fi% 19 | } 20 | \endinput 21 | -------------------------------------------------------------------------------- /cssframework.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{cssframework} 2 | \RequirePackage{include4ht} 3 | \edef\css@curroutpufile{} 4 | 5 | % open css file 6 | \newcommand\cssstartoutput[1]{% 7 | \xdef\css@curroutpufile{#1}% 8 | \special{t4ht>\css@curroutpufile}% 9 | } 10 | 11 | % close css file 12 | \newcommand\cssstopoutput{% 13 | \special{t4ht<\css@curroutpufile}% 14 | } 15 | 16 | \newcommand\CssLink[1]{% 17 | \Configure{@HEAD}% 18 | {\HCode{}}% 19 | } 20 | % #1 template name 21 | % #2 css output file 22 | \newcommand\processcss[2]{% 23 | \CssLink{#2} 24 | \AtBeginDocument{% 25 | \cssstartoutput{#2}% 26 | \NoFonts% 27 | \input{#1}% 28 | \EndNoFonts% 29 | \cssstopoutput% 30 | } 31 | } 32 | 33 | \newcommand\includecss[1]{% 34 | \AddCss{#1}% 35 | } 36 | 37 | \edef\css@selectrpath{} 38 | \def\hnl{\HCode{\Hnewline}} 39 | %\def\finselectr{} 40 | \newcommand\Selector[2]{% 41 | \bgroup% 42 | \edef\css@selectrpath{\css@selectrpath{} #1} 43 | \hnl\unskip\css@selectrpath\{\hnl 44 | #2 45 | \hnl\}\hnl 46 | \egroup% 47 | } 48 | 49 | % support for media queries 50 | % default medium is all, #2 is rule, #3 is 51 | \newcommand\MediaQuery[3][all]{% 52 | @media #1 and (#2)\{\hnl 53 | #3\hnl% 54 | \}\hnl% 55 | } 56 | 57 | % Various helper functions 58 | % default font size 59 | \newcommand\emwidth{16} 60 | % convert pt to rem 61 | \newcommand\CalcRem[1]{\strip@pt\dimexpr(#1)/\emwidth} 62 | % support for browsers without rem 63 | \newcommand\RemProperty[2]{% 64 | #1:\the\dimexpr #2\relax;#1:\CalcRem{#2}rem; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /helpers4ht-doc.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | 4 | \usepackage[english]{babel} 5 | \usepackage{hyperref} 6 | \ifdefined\HCode 7 | \usepackage[T1]{fontenc} 8 | \usepackage[utf8]{inputenc} 9 | \else 10 | \usepackage{fontspec} 11 | \setmainfont{TeX Gyre Schola} 12 | \fi 13 | \usepackage{microtype} 14 | 15 | \title{The \texttt{helpers4ht} bundle} 16 | \author{Michal Hoftich\footnote{\url{michal.h21@gmail.com}}} 17 | \date{Version 0.1\\12/11/2015} 18 | \begin{document} 19 | \maketitle 20 | \tableofcontents 21 | This is a bundle of packages providing support for tex4ht configuration. With 22 | the exception of \texttt{alternative4ht}, you shouldn't use them in your 23 | documents, but put them in a \texttt{.cfg} file instead. 24 | 25 | A \texttt{cfg} file is \TeX\ file with special structure, which provides 26 | configurations for \texttt{tex4ht} conversion. The basic structure is following: 27 | 28 | \begin{verbatim} 29 | ...early definitions... 30 | \Preamble{options} 31 | ...definitions... 32 | \begin{document} 33 | ...insertions into the header of the html file... 34 | \EndPreamble 35 | \end{verbatim} 36 | 37 | Options for \verb|\Preamble| commands are the same as for second parameter of 38 | \texttt{htlatex} command, for example: 39 | 40 | \begin{verbatim} 41 | \Preamble{xhtml,2} 42 | \end{verbatim} 43 | 44 | 45 | \input{readme} 46 | 47 | \input{changelog} 48 | \end{document} 49 | -------------------------------------------------------------------------------- /helpers4ht.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \input ProTex.sty 3 | \AlProTex{4ht,<<<>>>,title,list,`} 4 | \usepackage[utf8]{inputenc} 5 | \usepackage[T1]{fontenc} 6 | \begin{document} 7 | \title{helpers4ht -- helper packages for tex4ht configuration} 8 | \author{Michal Hoftich} 9 | \def\texforht{\texttt{tex4ht}} 10 | \maketitle 11 | 12 | \tableofcontents 13 | \section{Introduction} 14 | 15 | Purpose of this package is to provide various packages for easier 16 | \texforht\ configuring. 17 | 18 | \section{Package loading} 19 | \section{HTML tags} 20 | \section{Visual styling} 21 | \section{Pictures} 22 | \section{Math} 23 | \section{Indexing} 24 | 25 | Package \texttt{indexing4ht} is provided for helping with index creation. 26 | 27 | \end{document} 28 | 29 | -------------------------------------------------------------------------------- /include4ht.sty: -------------------------------------------------------------------------------- 1 | % This file is deprecated, tex4ht now provides \Configure{AddJs}{filename.js} and \Configure{AddCss}{filename.css} commands 2 | \newcommand\AddFile[1]{\special{t4ht+@File: #1}}% 3 | 4 | \newcommand\AddCss[1]{% 5 | \AddFile{#1}% 6 | \Configure{@HEAD}{\HCode{}} 7 | } 8 | 9 | \newcommand\AddJs[1]{% 10 | \AddFile{#1}% 11 | \Configure{@HEAD}{\HCode{\Hnewline}} 12 | } 13 | -------------------------------------------------------------------------------- /indexing4ht.4ht: -------------------------------------------------------------------------------- 1 | \@ifpackageloaded{imakeidx}{% 2 | \makeatletter 3 | \newcommand\:wrindex[3]{% 4 | \edef\th@idx@entry{\detokenize{#2}} 5 | \imki@wrindexentry{#1}{\th@idx@entry}{#3} 6 | } 7 | \makeatother 8 | }{%ToDo: Provide configuration for index writing without imakeidx 9 | \newcommand\:wrindex[3]{} 10 | } 11 | 12 | % because imakeidx has support for multiple indices, we need to select a 13 | % right one 14 | \NewConfigure{indexname}{1} 15 | % default index name is \jobname 16 | 17 | % configure variable which is saved on every index call 18 | % section mark is used by default, other possible values may be paragraphs, or 19 | % links to individual index entries 20 | \NewConfigure{indexvalue}{1} 21 | \Configure{indexvalue}{\getCurrentSectionNumber} 22 | \NewConfigure{indexidentifier}{1} 23 | \Configure{indexidentifier}{\CurSecHaddr} 24 | 25 | % we need to suppress adding of multiple identical identifiers 26 | \edef\curseccnt{} 27 | \renewcommand\index[2][]{% 28 | \ifx|#1|% 29 | \Configure{indexname}{\jobname}% 30 | \else\Configure{indexname}{#1}% 31 | \fi% 32 | \:wrindex{\a:indexname}{#2}{\a:indexvalue} 33 | % save identifier only if it haven't been used yet 34 | \expandafter\ifcsname usedsec\a:indexvalue\endcsname 35 | \else% 36 | \Tag{sec\a:indexvalue}{\a:indexidentifier} 37 | \fi% 38 | \expandafter\gdef\csname usedsec\a:indexvalue\endcsname{yes} 39 | \let\curseccnt\newseccnt 40 | } 41 | 42 | % print index locators. make links to destinations in document 43 | \newcommand\idxlocator[1]{% 44 | \ifTag{sec#1}{\a:locatorlink{\Ref{sec#1}}{}#1\b:locatorlink}{#1} % 45 | %\ifTag{sec#1}{\Link{\Ref{sec#1}}{}#1\EndLink}{#1}% 46 | \typeout{\LikeRef{sec#1}} 47 | } 48 | 49 | \NewConfigure{locatorlink}{2} 50 | \Configure{locatorlink}{\Link}{\EndLink} 51 | 52 | % to support crossreferencess, we save index keyword with unique identifier 53 | 54 | \GetTitleStringSetup{expand} 55 | \GetTitleStringDisableCommands{% 56 | \renewcommand\LaTeX{LaTeX} 57 | } 58 | 59 | \newcount\idxkwdcnt 60 | \LinkCommand\IdxKWLink{span,href,id} 61 | \newcommand\idxkeyword[1]{% 62 | \global\advance\idxkwdcnt by 1\relax% 63 | % use tags only one time 64 | \GetTitleString{#1} 65 | \ifcsdef{idxkw\GetTitleStringResult}{}% 66 | %{\Tag{idxkw#1}{idxkw\the\idxkwdcnt}}% 67 | {\expandafter\Tag\expandafter{idxkw\GetTitleStringResult}{idxkw\the\idxkwdcnt}}% 68 | \csgdef{idxkw\GetTitleStringResult}{x} 69 | \a:IdxKW{}{idxkw\the\idxkwdcnt}#1\b:IdxKW 70 | } 71 | 72 | 73 | \NewConfigure{IdxKW}{2} 74 | \Configure{IdxKW}{\IdxKWLink}{\EndIdxKWLink} 75 | 76 | 77 | \renewcommand\see[1]{% 78 | \GetTitleString{#1}% 79 | \a:see\ \ifTag{idxkw#1}{\a:seeLink{\Ref{idxkw\GetTitleStringResult}}{}#1\b:seeLink}{#1} 80 | } 81 | 82 | % make link configurable, in order to enable user to add custom parameters 83 | \NewConfigure{seeLink}{2} 84 | \Configure{seeLink}{\Link}{\EndLink} 85 | 86 | \NewConfigure{see}{1} 87 | \Configure{see}{\textit{see}} 88 | 89 | \renewcommand\seealso[1]{% 90 | \GetTitleString{#1}% 91 | \a:seealso\ \ifTag{idxkw#1}{\a:seeAlsoLink{\Ref{idxkw\GetTitleStringResult}}{}#1\b:seeAlsoLink}{#1} 92 | } 93 | 94 | \NewConfigure{seeAlsoLink}{2} 95 | \Configure{seeAlsoLink}{\Link}{\EndLink} 96 | 97 | \NewConfigure{seealso}{1} 98 | \Configure{seealso}{\textit{see also}} 99 | 100 | -------------------------------------------------------------------------------- /indexing4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{indexing4ht} 2 | 3 | \RequirePackage{etoolbox} 4 | \RequirePackage{gettitlestring} 5 | % Command for retrieving full section number for current sectioning command 6 | \newcommand\getCurrentSectionNumber{% 7 | \ifnum\c@section=0 % 8 | \thechapter 9 | \else 10 | \ifnum\c@subsection=0 % 11 | \thesection 12 | \else 13 | \ifnum\c@subsubsection=0 % 14 | \thesubsection 15 | \else 16 | \thesubsubsection 17 | \fi 18 | \fi 19 | \fi 20 | } 21 | 22 | \begin{filecontents*}{\jobname.xdy} 23 | (define-attributes (("default" "definition" "textbf"))) 24 | ( define-location-class "sec-num" :var 25 | ("arabic-numbers" 26 | :sep "." "arabic-numbers" 27 | :sep "." "arabic-numbers" 28 | :sep "." "arabic-numbers" 29 | :sep "." "arabic-numbers" 30 | )) 31 | (require "texindy.xdy") 32 | (markup-keyword :open "\idxkeyword{" :close "}" ) 33 | (markup-locref :open "\idxlocator{" :close "}") 34 | (markup-locref :open "\textbf{\idxlocator{" :close "}}" :attr "textbf") 35 | (markup-locref :open "\textbf{\idxlocator{" :close "}}" :attr "definition") 36 | \end{filecontents*} 37 | \endinput 38 | -------------------------------------------------------------------------------- /mathjax-latex-4ht.sty: -------------------------------------------------------------------------------- 1 | \RequirePackage{etoolbox,expl3,environ} 2 | \ExplSyntaxOn 3 | \cs_new_protected:Npn \alteqtoks #1 4 | { 5 | \tl_set:Nx \l_tmpa_tl {\detokenize{#1}} 6 | % delete spaces before left brackets 7 | \regex_replace_all:nnN { \x{20} \x{7B} } { \x{7B} } \l_tmpa_tl 8 | % replace < > and & with xml entities 9 | \regex_replace_all:nnN { \x{26} } { & } \l_tmpa_tl 10 | \regex_replace_all:nnN { \x{3C} } { < } \l_tmpa_tl 11 | \regex_replace_all:nnN { \x{3E} } { > } \l_tmpa_tl 12 | \tl_set:Nx \l_tmpb_tl{ \l_tmpa_tl } 13 | \HCode{\l_tmpb_tl} 14 | } 15 | 16 | \ExplSyntaxOff 17 | \AtBeginDocument{% 18 | \Configure{HTML}{\HCode{\Hnewline}}{\HCode{\Hnewline}} 19 | %\Configure{@HEAD}{\HCode{\Hnewline}} 20 | \Configure{@HEAD}{\HCode{ 21 | \Hnewline 38 | }} 39 | \Configure{@HEAD}{\HCode{ \Hnewline}} 40 | \long\def\AltMathOne#1${\alteqtoks{\(#1\)}$} 41 | \Configure{$}{}{}{\expandafter\AltMathOne} 42 | \long\def\AltlMath#1\){\expandafter\alteqtoks{\(#1\)}\)} 43 | \Configure{()}{\AltlMath}{} 44 | \long\def\AltlDisplay#1\]{\alteqtoks{\[#1\]}\]} 45 | \Configure{[]}{\AltlDisplay}{} 46 | 47 | \newcommand\VerbMathToks[2]{% 48 | \alteqtoks{\begin{#2} 49 | #1 50 | \end{#2}}% 51 | } 52 | \newcommand\VerbMath[1]{% 53 | \ifcsdef{#1}{% 54 | \RenewEnviron{#1}{% 55 | \NoFonts\expandafter\VerbMathToks\expandafter{\BODY}{#1}\EndNoFonts% 56 | } 57 | }{}% 58 | } 59 | 60 | \VerbMath{subarray} 61 | \VerbMath{smallmatrix} 62 | \VerbMath{matrix} 63 | \VerbMath{pmatrix} 64 | \VerbMath{bmatrix} 65 | \VerbMath{Bmatrix} 66 | \VerbMath{vmatrix} 67 | \VerbMath{Vmatrix} 68 | \VerbMath{cases} 69 | \VerbMath{subequations} 70 | \VerbMath{aligned} 71 | \VerbMath{alignedat} 72 | \VerbMath{gathered} 73 | \VerbMath{gather} 74 | \VerbMath{gather*} 75 | \VerbMath{alignat} 76 | \VerbMath{alignat*} 77 | \VerbMath{xalignat} 78 | \VerbMath{xalignat*} 79 | \VerbMath{xxalignat} 80 | \VerbMath{align} 81 | \VerbMath{align*} 82 | \VerbMath{flalign} 83 | \VerbMath{flalign*} 84 | \VerbMath{split} 85 | \VerbMath{multline} 86 | \VerbMath{multline*} 87 | \VerbMath{equation} 88 | \VerbMath{equation*} 89 | \VerbMath{math} 90 | \VerbMath{displaymath} 91 | 92 | % it is necessary to reset env configurations for multline 93 | \ConfigureEnv{multline}{}{}{}{} 94 | \ConfigureEnv{multline*}{}{}{}{} 95 | 96 | 97 | % fixes for tables of contents 98 | 99 | \def\fixmathjaxtoc#1{\def#1{\detokenize{#1}}} 100 | \fixmathjaxtoc\left 101 | \fixmathjaxtoc\right 102 | \fixmathjaxtoc\int 103 | \fixmathjaxtoc\, 104 | \fixmathjaxtoc\sin 105 | \fixmathjaxtoc\cos 106 | \fixmathjaxtoc\tan 107 | \fixmathjaxtoc\arcsin 108 | \fixmathjaxtoc\arccos 109 | \fixmathjaxtoc\arctan 110 | \fixmathjaxtoc\csc 111 | \fixmathjaxtoc\sec 112 | \fixmathjaxtoc\cot 113 | \fixmathjaxtoc\sinh 114 | \fixmathjaxtoc\cosh 115 | \fixmathjaxtoc\tanh 116 | \fixmathjaxtoc\coth 117 | \fixmathjaxtoc\log 118 | 119 | 120 | } 121 | -------------------------------------------------------------------------------- /rfclang.sty: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Update 2021/05/29: TeX4ht now provides similar code by default, 3 | % so this package is obsolete. 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5 | 6 | % this code is copied from tex4ebook.sty 7 | \RequirePackage{etoolbox} 8 | 9 | %Declare RFC3066 language code for babel language name 10 | \def\DeclareLanguage#1#2{% 11 | \csgdef{rfclang#1}{#2}% 12 | } 13 | 14 | \def\GetMainLanguage{% 15 | \ifx\bbl@main@language\@undefined en-US% 16 | \else% 17 | \ifcsdef{rfclang\bbl@main@language}{\csuse{rfclang\bbl@main@language}}{}% 18 | \fi% 19 | } 20 | 21 | \def\GetLanguage{% 22 | \ifx\languagename\@undefined en-US% 23 | \else% 24 | \ifcsdef{rfclang\languagename}{\csuse{rfclang\languagename}}{}% 25 | \fi% 26 | } 27 | 28 | \DeclareLanguage{english}{en-US} 29 | \DeclareLanguage{czech}{cs-CZ} 30 | \DeclareLanguage{french}{fr} 31 | \DeclareLanguage{polish}{pl-PL} 32 | \DeclareLanguage{german}{de} 33 | \DeclareLanguage{bulgarian}{bg} 34 | \DeclareLanguage{catalan}{ca} 35 | \DeclareLanguage{croatian}{hr} 36 | \DeclareLanguage{danish}{da} 37 | \DeclareLanguage{dutch}{nl} 38 | \DeclareLanguage{USenglish}{en-US} 39 | \DeclareLanguage{american}{en-US} 40 | \DeclareLanguage{UKenglish}{en-GB} 41 | \DeclareLanguage{british}{en-GB} 42 | \DeclareLanguage{canadian}{en-US} 43 | \DeclareLanguage{australian}{en-US} 44 | \DeclareLanguage{newzealand}{en-US} 45 | \DeclareLanguage{esperanto}{eo} 46 | \DeclareLanguage{estonian}{et} 47 | \DeclareLanguage{finnish}{f\/i} 48 | \DeclareLanguage{francais}{fr} 49 | \DeclareLanguage{canadien}{fr} 50 | \DeclareLanguage{acadian}{fr} 51 | \DeclareLanguage{galician}{gl} 52 | \DeclareLanguage{austrian}{de} 53 | \DeclareLanguage{german}{de} 54 | \DeclareLanguage{germanb}{de} 55 | \DeclareLanguage{ngerman}{de} 56 | \DeclareLanguage{naustrian}{de} 57 | \DeclareLanguage{greek}{el} 58 | \DeclareLanguage{polutonikogreek}{el} 59 | \DeclareLanguage{hebrew}{he} 60 | \DeclareLanguage{magyar}{hu} 61 | \DeclareLanguage{hungarian}{hu} 62 | \DeclareLanguage{icelandic}{is} 63 | \DeclareLanguage{interlingua}{ie} 64 | \DeclareLanguage{irish}{ga} 65 | \DeclareLanguage{italian}{it} 66 | \DeclareLanguage{latin}{la} 67 | %\DeclareLanguage{lowersorbian}{no code?} 68 | %\DeclareLanguage{samin}{no code?} 69 | \DeclareLanguage{norsk}{no} 70 | \DeclareLanguage{nynorsk}{no} 71 | \DeclareLanguage{portuges}{pt} 72 | \DeclareLanguage{portuguese}{pt} 73 | \DeclareLanguage{brazilian}{pt} 74 | \DeclareLanguage{brazil}{pt} 75 | \DeclareLanguage{romanian}{ro} 76 | \DeclareLanguage{russian}{ru} 77 | %\DeclareLanguage{scottish}{no code?} 78 | \DeclareLanguage{spanish}{es} 79 | \DeclareLanguage{slovak}{sk} 80 | \DeclareLanguage{slovene}{sl} 81 | \DeclareLanguage{swedish}{sv} 82 | \DeclareLanguage{serbian}{sr} 83 | \DeclareLanguage{turkish}{tr} 84 | \DeclareLanguage{ukrainian}{uk} 85 | %\DeclareLanguage{uppersorbian}{no code?} 86 | \DeclareLanguage{welsh}{cy} 87 | 88 | -------------------------------------------------------------------------------- /textstyle4ht.sty: -------------------------------------------------------------------------------- 1 | \ProvidesPackage{textstyle4ht} 2 | \RequirePackage{xcolor} 3 | \RequirePackage{cssframework} 4 | \RequirePackage{xparse} 5 | \ExplSyntaxOn 6 | 7 | % some helper macros using LaTeX3 8 | % I know this style mixing is ugly, but I am too used to old school :) 9 | \NewDocumentCommand {\RoundingUpFunction} { m } 10 | { 11 | \fp_eval:n { ceil(#1) } 12 | } 13 | 14 | \seq_new:N \ts_tag_stack 15 | \tl_new:N \ts_current_tag 16 | \tl_new:N \ts_current_params 17 | \tl_new:N \ts_default_inline 18 | \tl_new:N \ts_default_block 19 | 20 | \NewDocumentCommand {\PushTag}{ m } 21 | { 22 | \seq_gpush:Nx \ts_tag_stack {#1} 23 | } 24 | 25 | \NewDocumentCommand {\PopTag}{ } 26 | { 27 | \seq_gpop:NN \ts_tag_stack \ts_current_params 28 | } 29 | 30 | \NewDocumentCommand{\DefaultInlineTag}{ m } 31 | { 32 | \tl_set:Nn \ts_default_inline {#1} 33 | } 34 | 35 | \NewDocumentCommand{\DefaultBlockTag}{ m } 36 | { 37 | \tl_set:Nn \ts_default_block {#1} 38 | } 39 | 40 | \DefaultInlineTag{span} 41 | \DefaultBlockTag{div} 42 | 43 | % print an element 44 | \cs_new:Npn\ts_print_tag#1#2#3{ 45 | \tl_gset:Nn\ts_current_params{{\ts_current_tag}{#1}{#3}} 46 | \PushTag{\ts_current_params} 47 | #3\HCode{<\ts_current_tag}\HCode{~ class="#1" #2>} 48 | } 49 | \cs_new:Npn\ts_set_tag#1#2{ 50 | \IfNoValueTF{#1}{ 51 | \tl_gset:Nn \ts_current_tag {#2} 52 | }{ 53 | \tl_gset:Nn \ts_current_tag {#1} 54 | } 55 | } 56 | 57 | \NewDocumentCommand\TSFontSeries{m m}{ 58 | \cs_new:cpn{ts-font-series#1}{#2} 59 | } 60 | 61 | \NewDocumentCommand\TSFontShape{m m}{ 62 | \cs_new:cpn{ts-font-shape#1}{#2} 63 | } 64 | 65 | \cs_new:Npn\tsf@getseries{ 66 | \cs_if_exist_use:c{ts-font-series\f@series} 67 | } 68 | 69 | \cs_new:Npn\tsf@getshape{ 70 | \cs_if_exist_use:c{ts-font-shape\f@shape} 71 | } 72 | 73 | 74 | \cs_new:Npn\ts_get_tag#1#2#3{#1} 75 | \cs_new:Npn\ts_get_class#1#2#3{#2} 76 | \cs_new:Npn\ts_get_end#1#2#3{#3} 77 | \cs_new:Npn\ts_save_style#1#2#3{ 78 | \cs_if_exist_use:cTF{ts_tag_#1_#2}{} 79 | { 80 | \cs_new:cpn{ts_tag_#1_#2}{\relax} 81 | \FontAttr{#1.#2} 82 | } 83 | } 84 | 85 | \NewDocumentCommand{\SaveStyle}{}{ 86 | \expandafter\ts_save_style\ts_current_params 87 | } 88 | 89 | % trick to grab the style inside command which can't be modified 90 | % #1 \InlineTag or \BlockTag with all parameters 91 | % #2 command which we want to grab 92 | \NewDocumentCommand{\GrabStyle}{ m m }{ 93 | \setbox0=\hbox{#1#2{\SaveStyle}\EndTag} 94 | \expandafter\Css\expandafter{\css@body} 95 | \typeout{\css@body} 96 | } 97 | 98 | % optional element name, class, attributes 99 | \NewDocumentCommand{\InlineTag}{ o m m } 100 | { 101 | \ts_set_tag{#1}{\ts_default_inline} 102 | \ts_print_tag{#2}{#3}{} 103 | } 104 | 105 | \NewDocumentCommand{\BlockTag}{ o m m } 106 | { 107 | \ts_set_tag{#1}{\ts_default_block} 108 | \ts_print_tag{#2}{#3}{\ifvmode\IgnorePar\fi\EndP} 109 | \par 110 | } 111 | 112 | 113 | 114 | \NewDocumentCommand{\EndTag}{ } 115 | { 116 | \seq_gpop:NNTF \ts_tag_stack \ts_current_params { 117 | %\PopTag 118 | \SaveStyle 119 | \expandafter\ts_get_end\ts_current_params 120 | \HCode{} 121 | }{\typeout{textstyle4ht warning: tag stack is empty}} 122 | } 123 | \ExplSyntaxOff 124 | 125 | % extract current color as hexadecimal value 126 | \newcommand\tsf@getColor[1][.]{ 127 | % colorname `.` holds current color 128 | \extractcolorspec{#1}{\tsf@color} 129 | \expandafter\convertcolorspec\tsf@color{HTML}\tsf@color 130 | %\tmpcolor 131 | } 132 | 133 | % write css color for given css selector 134 | \newcommand\CssColor[1]{% 135 | % save current color 136 | \tsf@getColor% 137 | \Css{#1{color:\#\tsf@color;}}% 138 | } 139 | 140 | \TSFontShape{n}{font-style:normal;} 141 | \TSFontShape{it}{font-style:italic;} 142 | \TSFontShape{sl}{font-style:oblique;} 143 | \TSFontShape{sc}{font-variant:small-caps;} 144 | 145 | \TSFontSeries{m}{font-weight:normal;} 146 | \TSFontSeries{b}{font-weight:bold;} 147 | \TSFontSeries{bx}{font-weight:600;} 148 | \TSFontSeries{sb}{font-weight:900;} 149 | \TSFontSeries{c}{font-stretch: condensed;} 150 | 151 | % write css font information of current font face 152 | \newcommand\FontAttr[1]{% 153 | \bgroup\normalsize 154 | \xdef\tsf@normalsize{\RoundingUpFunction{\f@size}} 155 | \egroup 156 | \edef\tsf@fontsize{\strip@pt\dimexpr\f@size pt/\tsf@normalsize\relax rem} 157 | \tsf@getColor 158 | \xdef\css@body{#1{ 159 | font-size:\tsf@fontsize; 160 | color: \#\tsf@color; 161 | \tsf@getseries 162 | \tsf@getshape 163 | }} 164 | \expandafter\Css\expandafter{\css@body} 165 | } 166 | 167 | \newcommand\DeclareHColor[1]{% 168 | \tsf@getColor[#1]% 169 | \Configure{HColor}{#1}{\#\tsf@color}% 170 | } 171 | --------------------------------------------------------------------------------