4

The solution is simple when I use packages like tikz. But I am not supposed to use packages. I need to use post script in latex. I am trying to draw this oval using two lines and two curves in a macro and I need to pass currentpoint to the macro. I do not know how to pass currentpoint to the macro. Is there a way to pass currentpoint(which has x, y) to the macro so that these x and y points are used to draw the lines and curves? I mentioned that I am not supposed to use packages in my program as this is my project and my professor asked me to write this program using postscript in LATEX.

Below is the sample of what I need to do with my program: enter image description here

From what I understand, after I type the word LaTEX, when I say \special{pS: currentpoint}, it points to the x and y coordinates of the point after the word LaTEX. If I pass those coordinates to my macro and calculate the points: enter image description here

Below is my code:

\documentclass{article}                                             
\usepackage{calc} 
\begin{document}

\newcommand{\drawoval}[4] {

\newcommand\x{#1}
\newcommand\y{#2} 
\newcommand\length{#3}
\newcommand\height{#4}

\newcommand\x1{\the\numexpr\x-\length}
\newcommand\y1{\the\y} 
\newcommand\x2{\the\x}
\newcommand\y2{\the\y}
\newcommand\x3{\the\numexpr\x+5}
\newcommand\y3{\the\numexpr\y+\height/2}
\newcommand\x4{\the\x}
\newcommand\y4{\the\numexpr\y+\height}
\newcommand\x5{\the\numexpr\x-\length}
\newcommand\y5{\the\numexpr\y+\height}
\newcommand\x6{\the\numexpr\x-\length+5}
\newcommand\y6{\the\numexpr\y+\height/2}

\special{pS: x1 y1 x6 y6 x5 y5 curveto 1 0 0 setrgbcolor stroke}
\special{pS: x2 y2 x3 y3 x4 y4 curveto 1 0 0 setrgbcolor stroke}
\special{pS: x1 y1} \special{pS: x2 y2 moveto lineto 1 0 0 setrgbcolor stroke}
\special{pS: x5 y5} \special{pS: x4 y4 moveto lineto 1 0 0 setrgbcolor stroke}

}

\newlength{\wordlength} 
\newlength{\wordheight}

\settowidth{\wordlength}{Postscript}
\settoheight{\wordheight}{Postscript}
% This is the part where I am struck
This is an example of what I need to do in my program using Postscript in LaTEX \drawoval{x coordinate of currentpoint}{y coordinate of currentpoint}{\the\wordlength}{\the\wordheight} program
%\drawoval{\special{pS: currentpoint}}
\end{document}

Below program works but it gives me error when I try to call the macro \drawoval more than once. Please suggest me how to avoid this.

\documentclass{article}%%
\usepackage{calc}%%
\begin{document}%%
\makeatletter%%
    \def\strippt{\strip@pt}%%
\makeatother%%
\newsavebox\wordbox%%
\newcommand{\drawoval}[1] {%%
\sbox\wordbox{#1}%%
    \def\mywidth{\wd\wordbox}%%
    \def\myheight{\ht\wordbox}%%
    \newcommand\newwidth{\strippt\dimexpr\mywidth+4pt \relax}%%
    \newcommand\newwordwidth{\strippt\dimexpr\mywidth+0pt \relax}%%
    \newcommand\newheight{\strippt\dimexpr\myheight+6pt \relax}%%
    \newcommand\rightpoint{\strippt\dimexpr\mywidth+9pt \relax}%%
    \special{" 4 -8 moveto
                -2 2 -2 4 4 \newheight\space curveto
                \newwordwidth\space 0 rlineto
                \newwidth\space -8 moveto
                \rightpoint\space 2 \rightpoint\space 4 \newwidth\space \newheight\space curveto
                4 -8 moveto
                \newwordwidth\space 0 rlineto
                1 0 0 setrgbcolor
                stroke}
    #1
}%%
This is the \drawoval{demo program} of my project%%
\end{document}%%
  • 1
    Welcome to TeX SE! What do you mean when you say that you are 'not supposed to use packages'? Says who? In any case, please post the code you have/what you've tried and maybe explain a bit more what you are trying to do. What is the relationship of the lines and curves to the oval? What is the current point meant to do? – cfr May 6 '15 at 1:23
  • 1
    I'm afraid that if this is a project for school then it needs to be your own work and you ought not to be asking us to do it for you. – cfr May 6 '15 at 2:51
  • 1
    I'm voting to close this question as off-topic because it is a homework question. – cfr May 6 '15 at 2:52
  • 1
    This is for my school but my professor advised me to get help from tex. stackexchange.com if I get struck somewhere and I am not requesting for the program. I am just asking if it is possible to just pass the currentpoint to the macro in a latex program. I hope it is fine to ask questions. – Monica May 6 '15 at 2:59
  • 1
    Sounds fair! And yes all the students can get help from this website. I updated the question with my code. Thank You for your patience. – Monica May 6 '15 at 3:41
5

Seeing as this is homework, I will not provide a complete answer here (maybe after a couple weeks have safely passed). But, I will provide a couple of pointers regarding your code.

Point 1: Excess whitespce

You've got a lot of excess whitespace creeping into your solution. Blank lines, in particular, will be treated as new paragraphs---probably not want you intended to do. All your lines ending in anything other than a control sequence are also creating spurious whitespace. Put a comment at the end of each of those lines to keep the whitespace out. Whitespace at the beginning of the line isn't a problem, though.

Point 2: Legal control sequence names

Control sequence names cannot be defined using non-alphabetic characters. So, you'll not be able to define a control sequence \x1 directly using \newcommand (there are ways to do this, but you don't need them here). Instead, you could define \newcommand\tmpxi, \newcommand\tmpxii, and so forth.

Point 3: \numexpr vs \dimexpr

\numexpr is only going to work with integer values. If you feed it something that is not an integer, then it will truncate the number. If you want to manipulate lengths use \dimexpr. However, PostScripts will not be expecting you to feed it units. So you need a method for pealing the units off of your lengths before you feed them to the PostScript code. You can do that with \strip@pt

For example, you might want to define

\makeatletter
\newcommand\tmpxi{\strip@pt\dimexpr\x-\length}
\makeatother

The \makeat... are necessary to get @ to behave as an alphabetic character (see point 2 above).

Point 4: Getting the desired coordinate matrix for PostScripts

You'll probably want to use \special{" instead of \special{ps: so that PostScripts obeys the lengths that you want. See my own question about this for an explanation

Point 5: whitespace following control sequences

After a control sequence, white space will be gobbled up. This can potential have unintended affects with your PostScript code. For example, with

\def\tmpxi{10}
\special{"
   0 0 moveto
   \tmpxi 0 lineto
   stroke
}

you'll get an error because after LaTeX reads this it will ship it off to the dvi driver as

0 0 moveto
100 lineto
stroke

to get around this you can write

\def\tmpxi{10}
\special{"
   0 0 moveto
   \tmpxi\space 0 lineto
   stroke 
 }

Point 6: Absolute vs. Relative commands

You'll probably have an easier time of it if you use the relative commands rmoveto and rlineto. That way you don't need to worry too much about where currentpoint is.

Suggestion 1: saveboxes

If you want to wrap a particular word, you could create a command to save the word to a box, measure the dimensions of the box, and then use those dimensions to more easily calculate where to draw the lines.

For example

\newsavebox\mycontentbox
\newcommand\myoval[1]{%%
    \sbox\mycontentbox{#1}%%
    \def\mywidth{\wd\mycontentbox}%%
    ... 
    }

Other commands to access dimensions are

\dp=depth
\ht=height (above the baseline)

Final Result

Sticking with these general principles, this is what I can easily produce (box, not oval though)

enter image description here

One final point, at no point in my work did I have to refer to currentpoint. Additionally you should note that I made no corrections for how the box itself rudely intrudes upon the space surrounding it.

Solution

Here's a solution. There are a couple of things to note. First of all, I avoid creating LaTeX macros as much as possible. They're not necessary; postscript can do all the arithmetic calculations necessary. Secondly, now that I see some more of what you've put together, I would define the macros and everything else you need in the preamble to your document, not the body. Thirdly, I'm very sloppy about how I create the stripes for the background: in particular, I don't pay much heed to where they should begin or end with respect to the box itself. To make things terminate where I want them to terminate, I create the path and then invoke postscript's clip. Finally, I define several functions in postscript code to make the code for the paths and the code for the stripes easier to read.

\documentclass{article}
\usepackage[margin=1in]{geometry}

\makeatletter
\newsavebox\myovalbox
\newcommand\myoval[1]{%%
  \sbox\myovalbox{#1}%%
  \special{"
    /mytxtht             \strip@pt\ht\myovalbox\space                      def
    /mytxtdp             \strip@pt\dp\myovalbox\space                      def
    /mytxtwd             \strip@pt\wd\myovalbox\space                      def
    %%
    /mytxtboxsep         3                                                 def
    /myboxwd             { mytxtboxsep dup add mytxtwd add }               def
    /myboxdp             { mytxtboxsep         mytxtdp add }               def    
    /myboxht             { mytxtboxsep dup add mytxtht mytxtdp add add }   def
    %%
    /myboxhstart         { mytxtboxsep neg }                               def    
    /myboxvstart         { myboxdp     neg }                               def
    %%
    /myinterstripesep    4                                                 def
    /mystripeprotrusion  6                                                 def
    /mystriperise        { mystripeprotrusion dup add myboxht add }        def
    /mystriperun         8                                                 def
    /mystripebot         { mystripeprotrusion         myboxdp add neg }    def
    /mystripestart       { mytxtboxsep dup add myinterstripesep add neg }  def
    /mystripeend         { mytxtboxsep myboxwd add}                        def
    %% draw the box
    newpath
    1 0 0 setrgbcolor
    myboxhstart   myboxvstart   moveto
    myboxwd       0             rlineto
    0             myboxht       rlineto
    myboxwd neg   0             rlineto
    closepath
    clip
    %% for loop:  start-value increment end-value { iteration action } for  
    %% the for loop takes the current value of the loop and                 
    %% places it at the beginning of iteration action, hence                
    %% the "moveto" below appears to only have one argument                 
    mystripestart myinterstripesep mystripeend 
      {             mystripebot   moveto 
        mystriperun mystriperise  rlineto 
      } 
    for
    stroke
    %%
  }%%
  \usebox{\myovalbox}}
\makeatother

\begin{document}

This is an example of what I need to do in my program using \myoval{Postscript in LaTeX} program.

\end{document}

enter image description here

There are quite a few resources available on-line for postscript coding. There are some nice resources suggested at posted at this site. Namely,

A final note about \def vs \newcommand

It might be worth your time to peruse the question and answers to What is the difference between \def and \newcommand. It is very easy to misuse \def and bludgeon essential commands out of existence with disastrous effects on your code. My own approach with \def and \newcommand is to use \newcommand for commands I intend to use at the document (user interface) level. I use \def for the underlying commands that make the user level interface do what I want. And, a fair number of people on this site seem to take this approach. If you're not sure what macro names are already taken, then you can take the following approach

\newcommand\mymacroname{}
\def\mymacroname{<my real definition>}

The advantage to this approach is that if \mymacroname is already defined, you'll be issued a warning by \newcommand and you won't accidentally bludgeon something you may rely upon (and there is a lot of macros you rely upon without knowing it). You might wonder, if I do this why bother with \def? Well, with \def you can pass arguments in manners not conventional to \newcommand. There is a package xparse which actually allows you to create such non-conventional approaches in a much less dangerous way than \def does: it could be worth a read through.

The second thing I do when I use \def is to provide it a complex name the makes clear three things: (1) that I'm its author, (2) what I'm using it for, (3) what it's meant to do. So, for the macro \myoval above, I might have had various macros named:

\def\ae@boxtext@determine@dimensions#1{....}

where ae signals who I am, boxtext signals what I'm using this command for, and determine@dimensions says something about what the macro is supposed to do.

  • As as retired professor who used to give assignments like this with those kinds of allowed resources, I want to complement you on a great interaction with a student. – R. Schumacher May 7 '15 at 1:42
  • You suggestions are so helpful. Thanks a lot for giving such detailed information. I really appreciate your time and patience. – Monica May 7 '15 at 3:22
  • @ Ellet, Could you please let me know which IDE you have used to run this program. I am currently using Visual Tex and I have issues with it. Below I listed all the issues I have. I am new to Latex. So please don't mind if some of my questions are kind of silly. – Monica May 12 '15 at 7:21
  • 1. I am unable to use either dimexpr or numexpr when I use VTex. It simple does a string concatenation of two numbers and it further gives me an error saying "Undefined Control Sequence". However, I was able to use both dimexpr and numexpr in sharelatex.com website using the same code( But I am unable to see my PostSciprt curves and lines in sharelatex). – Monica May 12 '15 at 7:32
  • 2. I am unable to see anything in my PDF file when I use \special{" instead of special{pS:. Should I be looking the output in PS mode instead of PDF mode. I actually tried that by installing GhostView(I think which is used to view PS files). But it still does not show me whatever is written after \special{". – Monica May 12 '15 at 7:32
0

I can put here a solution of "rounded box problem" using \pdfliteral. Just for comparison with PostScript solution. This can help you with your homework because you can see an idea how to avoid the usage of curveto operator. This solution is only a slight modification of my another answer here

\def\mybox#1{\leavevmode \setbox0=\hbox{#1}%
   \edef\posxA{\expandafter\ignorept\the\wd0 \space}%
   \hbox{\kern3pt\pdfliteral{q 1 0 0 rg 1 0 0 RG .9963 0 0 .9963 0 0 cm
            1 j 6 w 0 0 \posxA 5.5 re B 5 w 1 g 1 G 0 0 \posxA 5.5 re B Q}%
         \box0 \kern3pt}%
}
{\lccode`\?=`\p \lccode`\!=`\t  \lowercase{\gdef\ignorept#1?!{#1}}}

This is a \mybox{test} of my \mybox{rounded box}.

The result:round

The main idea is to measure the width of the rounded box and to set the result into \posxA (without pt unit). The operator .9963 0 0 .9963 0 0 cm is equal to the PostScript .9963 .9963 scale, this transforms the default PDF/PostScript unit in coordinate system (bp) to TeX unit (pt). Then two rectangles are drawn. First with 6 pt diameter for outline (with rounded corner) in red color. Second the same rectangle with 5 pt diameter for outline in white color. The visible result is only border of the first red rectangle 0.5pt thick.

0

For further comparison, here is a solution using the gmp package to embed a Metapost graphic. Here, the use of PostScript is entirely hidden behind the MP language of course, so it might not meet the OP homework requirements.

\documentclass{article}
\usepackage[shellescape]{gmp}
\newsavebox{\ringbox}
\newcommand{\ringer}[1]{\sbox\ringbox{#1}%
    \lower4pt\hbox to \wd\ringbox
    {\hss\smash{\MPring{\mpdim{\wd\ringbox}}{\mpdim{\ht\ringbox}}{red}}\hss}%
    \kern -\wd\ringbox \box\ringbox
}
\def\MPring#1#2#3{\begin{mpost}
        w := #1; h := #2; 
        path c; c = quartercircle scaled 4 shifted (w,1.2h)
                 -- quartercircle scaled 4 rotated  90 shifted (0,1.2h) 
                 -- quartercircle scaled 4 rotated 180 shifted (0,0)
                 -- quartercircle scaled 4 rotated 270 shifted (w,0)
                 -- cycle;
        for i=-100 upto 100: draw (left--right) scaled w rotated 42 shifted (6i,0)
        withcolor #3; endfor; clip currentpicture to c;
        draw c withcolor #3;
\end{mpost}}
\begin{document}

In theory, the interrelation of system and/or subsystem technologies must utilize
and be functionally interwoven with the preliminary qualification limit.  In
particular, any \ringer{associated supporting element} necessitates that
urgent consideration be applied to possible bidirectional logical
relationship approaches.  

\end{document}

For explanations, you can read about the gmp package on CTAN. Please note that since I've used the shellescape package option you need to compile this with pdflatex -shell-escape.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.