# Is there a portable robust self-contained way to obfuscate email addresses in TeX?

It is a well-known fact that spammers crawl web pages and automatically extract email addresses not only from HTML files, but also from other formats, e.g., PDF.

It is therefore desirable to have an obfuscation method for email addresses in TeX that works with commonly used formats (e.g., PDF, PostScript, DVI), produces results that look identical to what one would get without obfuscation, and does not allow any commonly used software (e.g., pdftotext) to extract the unobfuscated email address. (A use case I have a mind is uploading a paper on arXiv with an email address in it.)

Thus the desired properties of obfuscation can be summarized as follows.

1. Portability: the end result must look exactly like the unobfuscated version when compiled with any commonly used software: tex, tex+dvips, tex+dvipdfm(x), pdftex, tex+dvips+ghostscript (directly or via a script such as ps2pdf). In particular, when compiled by arXiv, all three resulting files (DVI, PostScript, and PDF) must have an email address in them that looks exactly like an unobfuscated email address, i.e., the reader of the paper should not be able to guess that obfuscation was used by merely looking at the paper (though copy-paste might fail).

2. Robustness: none of the commonly used software, such as

• catdvi, dvi2tty, crudetype for DVI,
• ghostscript (directly or via a script such as ps2ascii), ps2txt, ps2a, pstotext for PostScript,
• pdftotext, pdfbox, pdf2txt.py, or ghostscript for PDF,

should be able to extract (after a possible removal of whitespace) the unobfuscated email from any of the files produced in 1.

3. Self-containedness: the method must not require any external files and must only use the current font. (Otherwise one could just use a font with randomly remapped characters, which would be a very reliable obfuscation method, but not a very practical one if one wants to publish a paper in journal. For the same reason using other fonts (even in the same family) is also not acceptable because it easily breaks if the fonts are changed.)

Methods that are known not to work:

1. Typesetting the email address in a nontrivial order, e.g., randomly permuting letters. Fails with catdvi, dvipdfm+pdftotext, pdftex+pdftotext.

2. Inserting in the middle of the email address some additional text typeset in a microscopic font (cmr10 at 1sp, for example). Fails with tex+dvipdfm+pdftotext. It also exposes bugs in catdvi and pdftex 1.40.15, i.e., the latter is a noncompliant implementation of TeX. Even though one can work around these bugs by using 8sp instead of 1sp, the method also fails with pdftex+pdftotext.

3. Inserting horizontal microspaces such as 1sp or -1sp in the middle of the email address. Same as 2.

4. Raising or lowering individual letters by a microscopic amount (e.g., 1sp). Works with catdvi, but fails with pdftotext.

5. Replacing some period with the dot accent lowered by its height minus the height of the period. Although this method does satisfy all of the above criteria, and, in a certain sense, is a solution (which I currently use in my papers together with typesetting in a different order), for pdftotext it merely replaces periods with spaces, which is still vulnerable to automatic collection (spam software is known to deobfuscate even more sophisticated variants such as “user at example dot com” and periods replaced by spaces certainly do not present a problem), so it violates condition 2, if not in letter, then in spirit. It also relies on rather subtle properties of Computer Modern fonts, which means it might break condition 1 if the publisher uses a more poorly designed font.

6. Inserting some additional white-colored text that is typeset before the email address and overlaps with it. Unlike the previous methods this one is somewhat nonportable, but it works fine with most software using color specials, and some special hacks for pdftex (it does break some less commonly used software such as dvilj). Unfortunately, this method totally fails when one prints the document on a nonwhite paper or simply displays it on a nonwhite background (which is not that uncommon, some people prefer light gray or similar colors as background). Ostensibly, the problem could be solved by using background-colored text, but I don't know any reasonably portable way to do it, though some programs might allow such hacks.

• I'm flabbergasted by your scope of operation for spam mails. But maybe you can explain what fail means in this context? I can stick anything in the email address. And from the look of it the best thing you can do is to put your website address and let people find you there. However you do realize I hope that if somebody who has your mail in her/his addressbook gets compromised to spam indexing all your efforts goes down the drain right? Apr 5, 2015 at 20:49
• @percusse: Failing means that the indicated software recovers the unobfuscated email address. As for your suggestion to put the website address, some of my coauthors simply don't have one. Apr 5, 2015 at 20:52
• If you want to avoid this for DVI files, you're out of luck: an @ will correspond to @ in the DVI file, so dvi2tty will most certainly display the address. You could use a remapped font, but this would violate several of your constraints. Apr 5, 2015 at 21:00
• many journals wouldn't accept any of the suggested obfuscation techniques so i don't think that's much of an objection:-) Apr 5, 2015 at 22:21
• @DmitriPavlov Any journal that publishes an HTML version of articles is going to simply retype your address. Apr 6, 2015 at 13:17

If you really want to hide the text you could extract the paths and draw them, the following's pretty poor, mostly as I ignored the distinction between move and line segments but it could be improved to render essentially the same as the original text.

First use a bit of postscript to convert the text to a path;

/Times-Roman findfont 10 scalefont setfont

newpath
100 100 moveto
(someone@example.org)
true
charpath
flattenpath
{== == (move) ==}
{== == (line) ==}
{== == == ==(curve) ==}
{(close) ==}
pathforall
showpage


that produces

a path of the form

104.429482
103.061745
(line)
104.429482
102.952805
(line)
104.320549
102.795456
(line)


then a bit of editing you can render that path with tikz:

with a bit more care the individual path segments could be closed and filled to produce essentially the original font rendering, but here I just stroke the entire path.

\documentclass{article}
\usepackage{tikz}

\begin{document}

aaa

\fbox{%
\begin{tikzpicture}[xscale=-.03,yscale=.03,rotate=90]
\draw

(103.085953,103.098053)
--
(104.429482,103.061745)
--
(104.429482,102.952805)
--
(104.320549,102.795456)
--
(104.393173,102.529175)
--
(104.526314,101.839249)
--
(104.178329,100.876991)
--
(103.303818,100.495712)
--
(102.565483,100.762)
--
(101.887665,101.657692)
--
(101.56086,102.22657)
--
(100.822517,102.73494)
--
(100.308105,102.514038)
--
(100.120491,101.923973)
--
(100.432167,101.122093)
--
(101.488235,100.665169)
--
(101.488235,100.50782)
--
(99.9631424,100.50782)
--
(99.9631424,100.640961)
--
(100.072075,100.870934)
--
(99.9994583,101.318779)
--
(99.902626,102.032913)
--
(100.274818,103.019379)
--
(101.16143,103.424858)
--
(101.793861,103.234222)
--
(102.33551,102.601791)
--
(102.964912,101.536652)
--
(103.63063,101.113014)
--
(104.114784,101.321808)
--
(104.296341,101.875557)
--
(104.024,102.535225)
--
(103.085953,102.952805)
--
(103.085953,103.098053)
--
(104.526314,106.344925)
--
(103.884811,104.780495)
--
(102.22657,104.178329)
--
(100.562286,104.786552)
--
(99.902626,106.332825)
--
(100.589523,107.885147)
--
(102.299194,108.511528)
--
(103.89994,107.900284)
--
(104.526314,106.344925)
--
(104.247925,106.223892)
--
(103.609444,107.234566)
--
(101.960289,107.627945)
--
(100.65004,107.310211)
--
(100.181015,106.441757)
--
(100.810417,105.497658)
--
(102.698624,105.061913)
--
(103.827316,105.373589)
--
(104.247925,106.223892)
--
(99.9994583,109.044098)
--
(99.9994583,111.234909)
--
(100.144699,111.234909)
--
(100.268768,110.696281)
--
(100.653069,110.557091)
--
(103.424858,110.557091)
--
(103.594315,110.690231)
--
(104.005852,111.719063)
--
(103.754692,112.209274)
--
(102.977013,112.372673)
--
(100.846725,112.372673)
--
(100.302055,112.248611)
--
(100.144699,111.706963)
--
(99.9994583,111.706963)
--
(99.9994583,113.909866)
--
(100.144699,113.909866)
--
(100.317184,113.337959)
--
(100.931458,113.19574)
--
(103.412758,113.19574)
--
(104.005852,114.272987)
--
(103.77285,114.850952)
--
(102.928604,115.011322)
--
(100.858833,115.011322)
--
(100.317184,114.896339)
--
(100.144699,114.357712)
--
(99.9994583,114.357712)
--
(99.9994583,116.512207)
--
(100.144699,116.512207)
--
(100.168907,116.258026)
--
(100.749901,115.834389)
--
(102.771248,115.834389)
--
(104.084526,115.546921)
--
(104.526314,114.696625)
--
(103.691147,113.086807)
--
(104.526314,112.045868)
--
(104.381065,111.422516)
--
(103.763771,110.520775)
--
(104.502106,110.520775)
--
(104.526314,110.448151)
--
(104.078468,109.068306)
--
(103.909019,109.068306)
--
(103.957436,109.383011)
--
(103.328026,109.734024)
--
(100.834625,109.734024)
--
(100.296,109.597855)
--
(100.144699,109.044098)
--
(99.9994583,109.044098)
--
(101.609276,120.685036)
--
(100.813446,119.97998)
--
(100.580444,119.159943)
--
(101.367195,117.913239)
--
(102.722832,117.622742)
--
(102.722832,120.64872)
--
(103.464195,120.503471)
--
(103.957436,120.225082)
--
(104.526314,118.966278)
--
(103.851524,117.477493)
--
(102.105537,116.908615)
--
(100.495712,117.404877)
--
(99.902626,118.748405)
--
(100.326263,119.99511)
--
(101.548752,120.842384)
--
(101.609276,120.685036)
--
(103.037537,117.64695)
--
(103.890862,117.976784)
--
(104.1632,118.687889)
--
(103.924149,119.341499)
--
(103.037537,119.644096)
--
(103.037537,117.64695)
--
(104.526314,123.562737)
--
(103.884811,121.998306)
--
(102.22657,121.396133)
--
(100.562286,122.004356)
--
(99.902626,123.550629)
--
(100.589523,125.102959)
--
(102.299194,125.729332)
--
(103.89994,125.118088)
--
(104.526314,123.562737)
--
(104.247925,123.441696)
--
(103.609444,124.45237)
--
(101.960289,124.845749)
--
(100.65004,124.528023)
--
(100.181015,123.659569)
--
(100.810417,122.715462)
--
(102.698624,122.279724)
--
(103.827316,122.5914)
--
(104.247925,123.441696)
--
(99.9994583,126.286118)
--
(99.9994583,128.367981)
--
(100.144699,128.367981)
--
(100.280869,127.853569)
--
(100.653069,127.714378)
--
(103.424858,127.714378)
--
(103.866653,128.277206)
--
(103.981644,128.73111)
--
(103.748642,129.278809)
--
(103.025429,129.457336)
--
(100.967766,129.457336)
--
(100.338364,129.327225)
--
(100.144699,128.827942)
--
(99.9994583,128.827942)
--
(99.9994583,130.873489)
--
(100.144699,130.873489)
--
(100.308105,130.398422)
--
(100.798309,130.280411)
--
(103.049637,130.280411)
--
(104.132942,129.971756)
--
(104.526314,129.118423)
--
(104.362915,128.486008)
--
(103.727455,127.69017)
--
(104.502106,127.69017)
--
(104.526314,127.617546)
--
(104.078468,126.261909)
--
(103.909019,126.261909)
--
(103.957436,126.528191)
--
(103.824287,126.818687)
--
(103.328026,126.891312)
--
(100.883041,126.891312)
--
(100.320206,126.7733)
--
(100.144699,126.286118)
--
(99.9994583,126.286118)
--
(101.609276,135.121964)
--
(100.813446,134.416916)
--
(100.580444,133.596878)
--
(101.367195,132.350174)
--
(102.722832,132.059677)
--
(102.722832,135.085663)
--
(103.464195,134.940414)
--
(103.957436,134.662018)
--
(104.526314,133.403214)
--
(103.851524,131.914429)
--
(102.105537,131.345551)
--
(100.495712,131.841812)
--
(99.902626,133.185349)
--
(100.326263,134.432037)
--
(101.548752,135.279312)
--
(101.609276,135.121964)
--
(103.037537,132.083893)
--
(103.890862,132.413712)
--
(104.1632,133.124817)
--
(103.924149,133.778427)
--
(103.037537,134.081024)
--
(103.037537,132.083893)
--
(100.713585,142.32077)
--
(100.241531,140.38414)
--
(100.459404,139.225189)
--
(101.061569,138.317398)
--
(101.990547,137.724304)
--
(103.170677,137.515518)
--
(104.514214,137.754562)
--
(105.591461,138.423309)
--
(106.341904,140.287308)
--
(106.130081,141.379684)
--
(105.555145,142.278397)
--
(104.704849,142.883591)
--
(103.666939,143.107513)
--
(102.326431,142.717163)
--
(101.730316,141.848709)
--
(102.178162,141.461395)
--
(102.359718,141.473495)
--
(104.853119,142.115)
--
(104.853119,141.43718)
--
(104.477898,141.340347)
--
(104.998367,140.626221)
--
(104.550522,139.573181)
--
(103.63063,138.937729)
--
(102.517067,138.701691)
--
(101.736366,138.949829)
--
(101.415611,139.573181)
--
(102.117638,140.79567)
--
(101.603226,141.089188)
--
(101.403511,141.69136)
--
(102.108559,142.965302)
--
(103.763771,143.506943)
--
(104.898514,143.25882)
--
(105.812355,142.574951)
--
(106.423607,141.549149)
--
(106.644501,140.275208)
--
(106.378212,138.868134)
--
(105.642899,137.727341)
--
(104.553551,136.95874)
--
(103.206993,136.680344)
--
(101.890694,136.955704)
--
(100.828575,137.724304)
--
(100.12352,138.874176)
--
(99.8663101,140.311523)
--
(99.9813,141.270752)
--
(100.423088,142.429703)
--
(100.713585,142.32077)
--
(104.56263,140.771469)
--
(103.933228,141.170898)
--
(102.408134,140.735153)
--
(101.839249,139.996811)
--
(102.063171,139.564102)
--
(102.674416,139.403717)
--
(104.017952,139.875778)
--
(104.56263,140.771469)
--
(101.609276,148.769119)
--
(100.813446,148.064072)
--
(100.580444,147.244034)
--
(101.367195,145.99733)
--
(102.722832,145.706833)
--
(102.722832,148.732803)
--
(103.464195,148.58757)
--
(103.957436,148.309174)
--
(104.526314,147.050369)
--
(103.851524,145.561584)
--
(102.105537,144.992706)
--
(100.495712,145.488968)
--
(99.902626,146.832504)
--
(100.326263,148.079193)
--
(101.548752,148.926468)
--
(101.609276,148.769119)
--
(103.037537,145.731049)
--
(103.890862,146.060867)
--
(104.1632,146.771973)
--
(103.924149,147.425583)
--
(103.037537,147.72818)
--
(103.037537,145.731049)
--
(99.9994583,151.925217)
--
(99.9994583,153.910263)
--
(100.144699,153.910263)
--
(100.737793,153.099289)
--
(102.662315,151.840485)
--
(103.848495,152.651443)
--
(104.272133,153.450302)
--
(104.429482,153.450302)
--
(104.429482,151.901)
--
(104.272133,151.901)
--
(104.05426,152.28833)
--
(103.424858,151.925217)
--
(102.98912,151.63472)
--
(103.182785,151.489471)
--
(104.05426,151.041626)
--
(104.272133,151.465271)
--
(104.429482,151.465271)
--
(104.429482,149.431808)
--
(104.272133,149.431808)
--
(104.272133,149.516541)
--
(103.691147,150.266983)
--
(102.274986,151.198975)
--
(100.653069,150.073318)
--
(100.259689,149.728363)
--
(100.144699,149.359192)
--
(99.9994583,149.359192)
--
(99.9994583,150.787445)
--
(100.144699,150.787445)
--
(100.326263,150.388016)
--
(100.725693,150.58168)
--
(101.936081,151.368439)
--
(100.556236,152.26413)
--
(100.38678,152.324646)
--
(100.144699,151.925217)
--
(99.9994583,151.925217)
--
(100.653069,158.533951)
--
(100.459404,158.110306)
--
(101.02829,157.807709)
--
(102.952805,157.807709)
--
(103.957436,157.62616)
--
(104.526314,156.391556)
--
(104.1632,155.144852)
--
(103.424858,154.745422)
--
(103.001221,155.169067)
--
(103.412758,155.604797)
--
(103.570107,155.580597)
--
(103.800079,155.556381)
--
(104.142014,155.762161)
--
(104.284241,156.270523)
--
(104.078468,156.815201)
--
(103.473274,157.00885)
--
(102.86808,157.00885)
--
(102.253807,155.547318)
--
(101.80294,154.902771)
--
(100.955666,154.551758)
--
(100.199173,154.839233)
--
(99.902626,155.580597)
--
(100.616753,157.020966)
--
(100.066025,157.202515)
--
(99.902626,157.65036)
--
(100.38678,158.533951)
--
(100.653069,158.533951)
--
(101.209846,157.00885)
--
(100.689377,156.754669)
--
(100.471504,156.040543)
--
(100.695427,155.598755)
--
(101.234055,155.423248)
--
(101.270363,155.423248)
--
(102.008705,155.774261)
--
(102.638107,157.00885)
--
(101.209846,157.00885)
--
(99.9994583,158.78511)
--
(99.9994583,160.975906)
--
(100.144699,160.975906)
--
(100.268768,160.437286)
--
(100.653069,160.298096)
--
(103.424858,160.298096)
--
(103.594315,160.431244)
--
(104.005852,161.460068)
--
(103.754692,161.950272)
--
(102.977013,162.113678)
--
(100.846725,162.113678)
--
(100.302055,161.989609)
--
(100.144699,161.447968)
--
(99.9994583,161.447968)
--
(99.9994583,163.650879)
--
(100.144699,163.650879)
--
(100.317184,163.078964)
--
(100.931458,162.936752)
--
(103.412758,162.936752)
--
(104.005852,164.013992)
--
(103.77285,164.591949)
--
(102.928604,164.752335)
--
(100.858833,164.752335)
--
(100.317184,164.637344)
--
(100.144699,164.098724)
--
(99.9994583,164.098724)
--
(99.9994583,166.25322)
--
(100.144699,166.25322)
--
(100.168907,165.999039)
--
(100.749901,165.575394)
--
(102.771248,165.575394)
--
(104.084526,165.287933)
--
(104.526314,164.437637)
--
(103.691147,162.827805)
--
(104.526314,161.78688)
--
(104.381065,161.163528)
--
(103.763771,160.26178)
--
(104.502106,160.26178)
--
(104.526314,160.189163)
--
(104.078468,158.809311)
--
(103.909019,158.809311)
--
(103.957436,159.124008)
--
(103.328026,159.475021)
--
(100.834625,159.475021)
--
(100.296,159.338852)
--
(100.144699,158.78511)
--
(99.9994583,158.78511)
--
(97.8691635,166.455963)
--
(97.8691635,168.840424)
--
(98.03862,168.840424)
--
(98.1808395,168.126297)
--
(98.7769623,167.968948)
--
(100.326263,167.968948)
--
(99.902626,168.961472)
--
(100.631882,170.43512)
--
(102.432343,171.031235)
--
(103.933228,170.565231)
--
(104.526314,169.385101)
--
(103.739563,167.968948)
--
(104.502106,167.968948)
--
(104.526314,167.908432)
--
(104.017952,166.492264)
--
(103.860603,166.492264)
--
(103.872704,166.746445)
--
(103.766792,167.0672)
--
(103.315926,167.145874)
--
(98.7164383,167.145874)
--
(98.2020264,167.018784)
--
(98.03862,166.455963)
--
(97.8691635,166.455963)
--
(103.279617,167.968948)
--
(103.721405,168.298782)
--
(103.933228,168.973572)
--
(103.415779,169.854126)
--
(102.032913,170.18396)
--
(100.716614,169.854126)
--
(100.217323,168.997772)
--
(100.429146,168.310883)
--
(100.858833,167.968948)
--
(103.279617,167.968948)
--
(99.9994583,171.612228)
--
(99.9994583,173.936172)
--
(100.144699,173.936172)
--
(100.299026,173.330978)
--
(100.822517,173.19783)
--
(106.692917,173.19783)
--
(106.717125,173.161514)
--
(106.28138,171.588013)
--
(106.124031,171.588013)
--
(106.124031,171.648529)
--
(106.148239,171.963242)
--
(106.01812,172.287018)
--
(105.543045,172.374771)
--
(100.858833,172.374771)
--
(100.320206,172.223465)
--
(100.144699,171.612228)
--
(99.9994583,171.612228)
--
(101.609276,178.202805)
--
(100.813446,177.497742)
--
(100.580444,176.677704)
--
(101.367195,175.431)
--
(102.722832,175.140503)
--
(102.722832,178.166489)
--
(103.464195,178.02124)
--
(103.957436,177.742844)
--
(104.526314,176.484039)
--
(103.851524,174.99527)
--
(102.105537,174.426376)
--
(100.495712,174.922638)
--
(99.902626,176.266174)
--
(100.326263,177.512878)
--
(101.548752,178.360153)
--
(101.609276,178.202805)
--
(103.037537,175.164719)
--
(103.890862,175.494553)
--
(104.1632,176.205658)
--
(103.924149,176.859268)
--
(103.037537,177.161865)
--
(103.037537,175.164719)
--
(100.979874,179.858)
--
(100.423088,179.313339)
--
(99.8905182,179.845901)
--
(100.423088,180.402679)
--
(100.979874,179.858)
--
(104.526314,183.579956)
--
(103.884811,182.015533)
--
(102.22657,181.413361)
--
(100.562286,182.021576)
--
(99.902626,183.567856)
--
(100.589523,185.120178)
--
(102.299194,185.746552)
--
(103.89994,185.135315)
--
(104.526314,183.579956)
--
(104.247925,183.458923)
--
(103.609444,184.469589)
--
(101.960289,184.862976)
--
(100.65004,184.545242)
--
(100.181015,183.676788)
--
(100.810417,182.732681)
--
(102.698624,182.296951)
--
(103.827316,182.608627)
--
(104.247925,183.458923)
--
(99.9994583,186.170197)
--
(99.9994583,188.530457)
--
(100.144699,188.530457)
--
(100.320206,187.86171)
--
(100.883041,187.695282)
--
(103.098053,187.695282)
--
(103.615494,187.934341)
--
(103.896912,188.385208)
--
(103.751663,188.639389)
--
(103.558006,189.038818)
--
(104.005852,189.414047)
--
(104.526314,188.88147)
--
(104.329628,188.318634)
--
(103.594315,187.695282)
--
(104.502106,187.695282)
--
(104.526314,187.646866)
--
(103.993744,186.194397)
--
(103.836395,186.194397)
--
(103.872704,186.53331)
--
(103.279617,186.872223)
--
(100.822517,186.872223)
--
(100.347443,186.757233)
--
(100.144699,186.170197)
--
(99.9994583,186.170197)
--
(103.812187,194.074051)
--
(104.199509,194.074051)
--
(104.199509,193.323608)
--
(104.296341,192.778931)
--
(104.368965,192.561066)
--
(104.526314,191.774307)
--
(104.063339,190.60022)
--
(102.916496,190.128174)
--
(102.147896,190.33696)
--
(101.597168,191.048065)
--
(101.209846,190.624435)
--
(100.532028,190.16449)
--
(100.011559,190.684952)
--
(99.3579483,189.943588)
--
(98.8132706,189.728745)
--
(98.1354523,190.221985)
--
(97.8570633,191.423294)
--
(98.4864655,193.396225)
--
(99.5153,193.989319)
--
(100.259689,193.668564)
--
(100.568336,192.803131)
--
(100.62886,191.532227)
--
(100.895142,190.757584)
--
(101.249184,190.954269)
--
(101.512444,191.350662)
--
(101.488235,191.532227)
--
(101.464027,191.90744)
--
(101.851349,192.936279)
--
(102.98912,193.444641)
--
(103.812187,193.263092)
--
(103.812187,194.074051)
--
(99.9752502,190.902817)
--
(99.8542099,192.488434)
--
(99.7452698,193.435562)
--
(99.3700485,193.710922)
--
(98.68013,193.196518)
--
(98.4138412,191.846924)
--
(98.6105347,190.805984)
--
(99.1400757,190.418671)
--
(99.4547806,190.500366)
--
(99.9752502,190.902817)
--
(103.328026,190.951233)
--
(104.002823,191.141876)
--
(104.247925,191.677475)
--
(103.787979,192.391602)
--
(102.601791,192.694199)
--
(101.95121,192.497513)
--
(101.706108,191.955856)
--
(102.144875,191.226608)
--
(103.291718,190.951233)
--
(103.328026,190.951233)
;

\end{tikzpicture}}

bbb

\end{document}

• Sorry, this is not at all related to my question. I asked for a method to produce output that looks exactly like a normal email address, not some sort of TeX CAPTCHA. Apr 6, 2015 at 12:17
• Since this point seems to be unclear, I added a clarification (in bold) to the original post. Apr 6, 2015 at 13:06
• @DmitriPavlov yes that point was clear as I said in the answer, you can use the same technique but using the same font, I just used Times Roman for simplicity. Apr 6, 2015 at 19:26

Here's an even more "self-contained" way to do what David Carlisle suggested, made by following links from Can we extract the points making the character from the font file? and playing with the code found there. This compiled with pdflatex.

\immediate\write18{tex pgflibraryshapes.letters.dtx}
%\documentclass[border=10]{standalone}
\documentclass[landscape]{article}
\pagestyle{empty}
\thispagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{
shapes.letters,
decorations.pathmorphing,
decorations.pathreplacing,
decorations.text,
decorations.footprints,
}

\pgfmathsetmacro{\emcm}{1em/1cm}
\pgfkeys{
/pgf/letter/.cd,
size=1,
every letter/.append style={
fill,
},
sentence width=.9\textwidth,
}

\begin{document}
\node[letter=h] (1) {};
\node[letter=o,right of previous letter,at=(1.east)] (2) {};
\node[letter=l,right of previous letter,at=(2.east)] (3) {};
\node[letter=t,right of previous letter,at=(3.east)] (4) {};
\node[letter=z,right of previous letter,at=(4.east)] (5) {};
\node[letter=e,right of previous letter,at=(5.east)] (6) {};
\node[letter=r,right of previous letter,at=(6.east)] (7) {};
\node[letter=m,right of previous letter,at=(7.east)] (8) {};
\node[letter=a,right of previous letter,at=(8.east)] (9) {};
\node[letter=n,right of previous letter,at=(9.east)] (10) {};
\node[letter=n,right of previous letter,at=(10.east)] (11) {};
\node[letter=1,right of previous letter,at=(11.east)] (12) {};
\node[letter=7,right of previous letter,at=(12.east)] (13) {};
\node[letter=@,right of previous letter,at=(13.east)] (14) {};
\node[letter=g,right of previous letter,at=(14.east)] (15) {};
\node[letter=m,right of previous letter,at=(15.east)] (16) {};
\node[letter=a,right of previous letter,at=(16.east)] (17) {};
\node[letter=i,right of previous letter,at=(17.east)] (18) {};
\node[letter=l,right of previous letter,at=(18.east)] (19) {};
\node[letter=.,right of previous letter,at=(19.east)] (20) {};
\node[letter=c,right of previous letter,at=(20.east)] (21) {};
\node[letter=o,right of previous letter,at=(21.east)] (22) {};
\node[letter=m,right of previous letter,at=(22.east)] (23) {};
\node[above=23] (joe) {Hi, I'm Joe};
\node[below=23] (joe) {Corneli, Phd};
\end{tikzpicture}

\end{document}

• \write18 is disabled by default on most distributions. This is as far from being portable (criterion 1 in my list, by the way) as possible. Also this totally fails with DVI, and arXiv produces DVI, so it is out of the question. Apr 6, 2015 at 12:20
• What's worse, this solution requires an external file pgflibraryshapes.letters.dtx that is not even present in my distribution of TeX Live. The original post specifically requests that no external files can be used. Apr 6, 2015 at 12:50