Re: Beginners question

[email protected] Tue, 12 Sep 2023 19:12:59 +0200
Newsgroups gmane.comp.tex.metapost
Message-ID <trinity-032cbab8-baa5-48bc-a1df-2165a61c5293-1694538779237@3c-app-gmx-bap48>
--abmob-fe9ad177-9ca6-4d01-ac3d-2782e542533b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

> It is possible to get it by using the writing facilities of TeX and the =
reading facilities of MetaPost.  I can't recall if MetaPost provides a way=
 of opening a shell (on a Unix-like system) and calling arbitrary programs=
.  If so, it's not too difficult.

For what it's worth, I've attached a file with the function that performs =
this particular feat of magic.  You can skip to line 73.  It should be fai=
rly intuitive, even if you don't know C++.  `real' is a `typedef' for `flo=
at' (it's a long story).

> Gesendet: Dienstag, 12. September 2023 um 18:48 Uhr
> Von: [email protected]
> An: "Metapost List" <[email protected]>
> Betreff: Aw: Re: [metapost] Beginners question
>
> > I have my own routine that typesets a text and gets back a hbox with t=
he text.
>
> I don't quite understand this.  What language is your routine in and whe=
re is it used?  MetaPost has no concept of hboxes (or vboxes for that matt=
er).
> Obviously, ultimately you're using TeX. When you call TeX from MP to typ=
eset text, the result is a `picture'.  It's easy to get the dimensions of =
a `picture' using the `box' macros, which must be included separately.  Th=
at is, they are not in `plain.mp' but rather in `boxes.mp', which is in th=
e same directory (in my installation and almost certainly in everybody els=
e's).  They are also documented separately, namely in "Drawing Boxes in Me=
taPost" (`mpboxes.mp').  _However_, what isn't so easy is getting the dime=
nsions of the hbox or vbox, i.e., the height, width and depth.  If it has =
depth and you want to know where the baseline is, you're out of luck (unle=
ss someone else knows a way of doing this).  MetaPost doesn't store this i=
nformation anywhere.
>
> It is possible to get it by using the writing facilities of TeX and the =
reading facilities of MetaPost.  I can't recall if MetaPost provides a way=
 of opening a shell (on a Unix-like system) and calling arbitrary programs=
.  If so, it's not too difficult.  I've implemented exactly this feature i=
n GNU 3DLDF, but that wouldn't help you if you want to use MP directly, un=
less possibly as an example, and would be off-topic for this mailing list,=
 anyway.
>
> "The MFbook" lesen schadet nicht. (Reading "The MFbook" won't do you any=
 harm.)
>
> > Gesendet: Dienstag, 12. September 2023 um 18:18 Uhr
> > Von: "Patrick Gundlach" <[email protected]>
> > An: [email protected]
> > Betreff: Re: [metapost] Beginners question
> >
> >
> >
> > > Am 12.09.2023 um 17:18 schrieb [email protected]:
> > >
> > > However, I don't think it does anything than `label' would.  What do=
 you mean by "font implementation"?
> >
> > I have my own routine that typesets a text and gets back a hbox with t=
he text. I need some kind of macro for the user to be able to specify the =
text, the font family (this is system dependent) and a style. Both the fon=
t family and the style should be optional.
> >
> > I will check out Aditya's and Tacos solution and read the MetaFont man=
ual.
> >
> > Thanks
> >   Patrick
> >
> >
> >
> > --
> > http://tug.org/metapost/
> >

--abmob-fe9ad177-9ca6-4d01-ac3d-2782e542533b
Content-Type: text/plain
Content-Disposition: attachment; filename=ttemp.txt
Content-Transfer-Encoding: quoted-printable

int
Scan_Parse::measure_text_func(Scanner_Node scanner_node,
                              void* v,
                              Pointer_Vector<real>* pv)
{

@q **** (4) Preliminaries.@>

#if DEBUG_COMPILE
   bool DEBUG =3D false; /* |true| */ @;
#endif /* |DEBUG_COMPILE|  */@;

   stringstream cerr_strm;

   bool error_stop_value   =3D true;
   bool warning_stop_value =3D true;
   string thread_name      =3D "";

   if (scanner_node)
      scanner_node->get_thread_name_and_stop_values(&thread_name,
                                                    &error_stop_value,
                                                    &warning_stop_value);
   int status =3D 0;

   ofstream out_strm;
   ifstream in_strm;

@q **** (4) @>

#if DEBUG_COMPILE
  if (DEBUG)
    {
        cerr_strm << thread_name
                  << "Entering 'Scan_Parse::measure_text_func'.";

        log_message(cerr_strm);
        cerr_message(cerr_strm);
        cerr_strm.str("");
    }

#endif /* |DEBUG_COMPILE|  */@;

@q **** (4) @>
@
@<Define |Scan_Parse| functions@>=3D

   string* s =3D static_cast<string*>(v);

#if DEBUG_COMPILE
   if (DEBUG)
     {
         cerr_strm << thread_name << "In `Scan_Parse::measure_text_func':"
                   << "`s' =3D=3D " << *s << endl;

         log_message(cerr_strm);
         cerr_message(cerr_strm);
         cerr_strm.str("");
     }
#endif /* |DEBUG_COMPILE|  */@;

@q **** (4) @>

   Id_Map_Entry_Node header_entry =3D scanner_node->lookup("measure_text_h=
eader");

   string header_string =3D "";

   if (header_entry && header_entry->object)
   {
       header_string =3D *static_cast<string*>(header_entry->object);
   }


   int fd;
   char out_file_name[] =3D "aXXXXXX";
   fd =3D mkstemp(out_file_name);
   close(fd);

   out_strm.open(out_file_name);

   char in_file_name[] =3D "bXXXXXX";
   fd =3D mkstemp(in_file_name);
   close(fd);

@q **** (4) @>

   stringstream command_string;

   out_strm << "\\scrollmode" << header_string << "\\setbox0=3D\\hbox{" <<=
 *s << "}"
            << "\\message{\\the\\wd0;\\the\\ht0;\\the\\dp0}\\bye" << endl;

   out_strm.close();

   command_string.str("");

   command_string << "tex " << out_file_name << " | grep -E ^[0-9] > " << =
in_file_name;

#if 0
   cerr << "command_string.str() =3D=3D " << command_string.str() << endl;
#endif

   /* !!START HERE:  LDF 2021.09.04.  Add error handling.  */

   status =3D system(command_string.str().c_str());

#if 0
   cerr << "status =3D=3D " << status << endl;
#endif

   in_strm.open(in_file_name);

   string temp_str;

   in_strm >> temp_str;

#if 0
   cerr << "temp_str =3D=3D " << temp_str << endl;
#endif

   in_strm.close();

   /* !!START HERE:  LDF 2021.09.04.  Add error handling.  */

   stringstream temp_strm;

   temp_strm << out_file_name << ".log";

   unlink(in_file_name);
   unlink(out_file_name);
   unlink(temp_strm.str().c_str());

   temp_strm.str("");

   real wd =3D 0;
   real ht =3D 0;
   real dp =3D 0;

#if 0
  cerr << "temp_str =3D=3D " << temp_str << endl;
#endif

  int j =3D 0;

  for (int i =3D 0; i < temp_str.length(); ++i)
  {
#if 0
      cerr << "temp_str[i] =3D=3D " <<  temp_str[i] << endl;
#endif

      if (isdigit(temp_str[i]) || temp_str[i] =3D=3D '.')
        temp_strm << temp_str[i];
      else if (temp_str[i] =3D=3D 'p')
      {
         if (j =3D=3D 0)
         {
#if 0
            cerr << "j =3D=3D " << j << endl;
            cerr << "temp_strm.str() =3D=3D " <<  temp_strm.str() << endl;
#endif
            temp_strm >> wd;
            temp_strm.clear();
         }
         else if (j =3D=3D 1)
         {
#if 0
            cerr << "j =3D=3D " << j << endl;
            cerr << "temp_strm.str() =3D=3D " <<  temp_strm.str() << endl;
#endif
            temp_strm >> ht;
            temp_strm.clear();
         }
         else
         {
#if 0
            cerr << "j =3D=3D " << j << endl;
            cerr << "temp_strm.str() =3D=3D " <<  temp_strm.str() << endl;
#endif
            temp_strm >> dp;
            temp_strm.clear();
            break;
         }
         j++;
         temp_strm.str("");
      }
      else
         continue;

  }

#if 0
  cerr << "Before conversion from pt to cm:" << endl
       << "wd =3D=3D " << wd << endl
       << "ht =3D=3D " << ht << endl
       << "dp =3D=3D " << dp << endl;
#endif

  wd *=3D 2.54 / 72.27;
  ht *=3D 2.54 / 72.27;
  dp *=3D 2.54 / 72.27;

#if 0
  cerr << "After conversion from pt to cm:" << endl
       << "wd =3D=3D " << wd << endl
       << "ht =3D=3D " << ht << endl
       << "dp =3D=3D " << dp << endl;
#endif

  real *wwd =3D new real;
  real *hht =3D new real;
  real *ddp =3D new real;

  *wwd =3D wd;
  *hht =3D ht;
  *ddp =3D dp;

  *pv +=3D wwd;
  *pv +=3D hht;
  *pv +=3D ddp;

@q **** (4) @>

#if DEBUG_COMPILE
  if (DEBUG)
    {
        cerr_strm << thread_name
                  << "Exiting 'Scan_Parse::measure_text_func' "
                  << "successfully with return value 0.";

        log_message(cerr_strm);
        cerr_message(cerr_strm);
        cerr_strm.str("");
    }

#endif /* |DEBUG_COMPILE|  */@;

@q **** (4) @>

   delete s;
   s =3D 0;
   v =3D 0;

   return 0;

}  /* End of |Scan_Parse::measure_text_func| definition.  */

--abmob-fe9ad177-9ca6-4d01-ac3d-2782e542533b
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

--
http://tug.org/metapost/

--abmob-fe9ad177-9ca6-4d01-ac3d-2782e542533b--