• Publicidad

Opciones usando Getopt::Long

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Opciones usando Getopt::Long

Notapor pablgonz » 2015-11-26 13:36 @608

Hola a todos en el foro.

Estoy escribiendo un pequeño script para extraer/copiar bloques de texto de un archivo latex, y deseo agregarle opciones mediante Getopt::Long.

Mi idea es poder usar el script al estilo Linux script [opciones] archivo pero me he topado con un pequeño dilema. Me explico: Al correr el script sobre un archivo deseo que acepte solo las extensiones .tex y .ltx; si el archivo no tiene extensión o es otra, dar un mensaje y salir.
Si el archivo de entrada es test.tex y se usa la opción --output que no esté seguida de una cadena, el valor por defecto sería test-out.tex, algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. script --output test.tex 

produciría test-out.tex como salida, y
Sintáxis: [ Descargar ] [ Ocultar ]
  1. script --output otro test.tex 

produciría otro.tex como salida.

En esto es donde me pierdo: deseo validar el archivo de entrada y salida, para que el archivo de entrada tenga solo la extensión válida y el nombre del archivo de salida no contenga la extensión ni sea el mismo nombre que el archivo de entrada.

No sé si es posible lo de asignarle un valor por defecto si se pasa la opción --output. De no ser así, mostrar un mensaje de error y salir.

El tema es que añadiré más opciones dentro del mismo script.

Dejo el código que llevo a la fecha:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' if 0;
  2. use v5.18;
  3. use File::Basename;           #
  4. use Getopt::Long qw(:config bundling_override require_order); #
  5. use autodie;                  #
  6.  
  7. #------------------------ Constantes -----------------------------------
  8. my $imageDir    = "images";             #
  9. my $other       = "other";              #
  10. my $BPL         = '\begin{postscript}';
  11. my $EPL         = '\end{postscript}';
  12. my $sipgf       = 'pgfpicture';
  13. my $nopgf       = 'pgfinterruptpicture';
  14.  
  15. #---------------- Creamos el directorio para las imágenes -------------#
  16. -e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
  17.  
  18. my $usage = <<"END_OF_USAGE";
  19. Uso: programa [opt] archivo.tex
  20. END_OF_USAGE
  21.  
  22. my $output; # archivo de salida
  23.  
  24. my $result=GetOptions (
  25.                 'output|o=s'    => \$output,            # nombre archivo de salida
  26.                 'help|h'        => \$::opt_help,        # muestra ayuda
  27.         ) or die $usage;
  28.  
  29. # help
  30. if ($::opt_help) {
  31.     print $usage;
  32.     exit(0);
  33. }
  34.  
  35. #--------------------- Arreglo de la extensión -------------------------
  36. my @SuffixList = ('.tex', '', '.ltx');    # posibles
  37. my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
  38. $ext = '.tex' if not $ext;
  39.  
  40. # nombre del archivo de salida
  41. if ($output eq '') {
  42.         $output = "$name-out";
  43.     print "El nombre de es $output";
  44. }
  45.  
  46. #------------------- Abrimos el archivo -------------------------------
  47. open my $ENTRADA, '<', "$name$ext";
  48. my $archivo;
  49. {
  50.     local $/;
  51.     $archivo = <$ENTRADA>;
  52. }
  53. close   $ENTRADA;
  54.  
  55. #--------------------- Dividimos el archivo de entrada -----------------
  56. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
  57.  
  58. # \pspicture to \begin{pspicture}
  59. $cuerpo =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
  60.  
  61. # Verbatim environments
  62. my $VERBATIM  = qr/(?: (v|V)erbatim\*?| PSTexample | aling)/xi;
  63.  
  64. # postscript environment
  65. my $POSTSCRIPT = qr/(?: postscript)/xi;
  66.  
  67. # tikzpicture environment
  68. my $ENVIRONMENT    = qr/(?: tikzpicture | pspicture\*?)/xi;
  69.  
  70. # falla izquierda (*SKIP)(*F)| acepta la derecha <img src="http://perlenespanol.com/foro/images/smilies/icon_smile.gif" alt=":)" title="Smile" />
  71. # tikz/pst to Postscript
  72. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  73.         (
  74.         (?:\\(psset|tikzset)(\{(?:\{.*?\}|[^\{])*\}).*?)?  # si está lo guardo
  75.         (\\begin\{($ENVIRONMENT)\} (.*?)  \\end\{\g{-2}\})
  76.     )
  77.     /$BPL\n$1\n$EPL/gmsx;
  78.  
  79. # pgfpicture to Postscript
  80. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  81.     (
  82.         \\begin\{$sipgf\}
  83.             .*?
  84.             (
  85.                 \\begin\{$nopgf\}
  86.                 .+?
  87.                 \\end\{$nopgf\}
  88.                 .*?
  89.             )*?
  90.         \\end\{$sipgf\}
  91.     )
  92.     /$BPL\n$1\n$EPL/gmsx;
  93.  
  94. # other to PostScript
  95. my $EXPORT  = qr/(forest|ganttchart|tikzcd|circuitikz|dependency|$other\*?)/x;
  96.  
  97. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  98.         (\\begin\{($EXPORT)\} (.*?)  \\end\{\g{-2}\})
  99.         /$BPL\n$1\n$EPL/gmsx;
  100.  
  101. # escribir la salida
  102. open my $SALIDA, '>', "$output$ext";
  103.     print $SALIDA <<"EOC";
  104. $cabeza$cuerpo$final
  105. EOC
  106. close $SALIDA;
  107.  
  108. __END__
  109.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Y el archivo test:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{lmodern}
  3. \usepackage{pstricks-add}
  4. \begin{document}
  5.  
  6. texto\begin{pspicture}(-0.5,-0.5)(5,3.5)
  7. Deberia quedar dentro de postricpt
  8. \end{pspicture}texto
  9.  
  10. \section{NO Anidados}
  11. PSPICTURE
  12.  
  13. \psset{
  14. unit=1.0cm,
  15. }
  16. \begin{pspicture}(-0.5,-0.5)(5,3.5)
  17. Deberia quedar dentro de postricpt
  18. \end{pspicture}
  19. PGF
  20.  
  21. \begin{pgfpicture}
  22. Deberia quedar dentro de postcript
  23. \end{pgfpicture}
  24.  
  25. TIKZ
  26. \tikzset{
  27. algo
  28. }
  29. \begin{tikzpicture}
  30. \shadedraw [shading=ball] (0,0) circle (2cm);
  31. \end{tikzpicture}
  32.  
  33. \section{Otros}
  34.  
  35. \begin{forest}
  36. FOREST
  37. \end{forest}
  38.  
  39. \begin{ganttchart}
  40. ganttchart
  41. \end{ganttchart}
  42.  
  43. \begin{tikzcd}
  44. tikzcd
  45. \end{tikzcd}
  46.  
  47. \begin{circuitikz}
  48. circuitikz
  49. \end{circuitikz}
  50.  
  51. \begin{dependency}
  52. dependency
  53. \end{dependency}
  54.  
  55. \section{Otros anidados en postscript}
  56.  
  57. \begin{postscript}
  58. \begin{forest}
  59. FOREST
  60. \end{forest}
  61. \end{postscript}
  62.  
  63. \begin{postscript}
  64. \begin{ganttchart}
  65. ganttchart
  66. \end{ganttchart}
  67. \end{postscript}
  68.  
  69. \begin{postscript}
  70. \begin{tikzcd}
  71. tikzcd
  72. \end{tikzcd}
  73. \end{postscript}
  74.  
  75. \begin{postscript}
  76. \begin{circuitikz}
  77. circuitikz
  78. \end{circuitikz}
  79. \end{postscript}
  80.  
  81. \begin{postscript}
  82. \begin{dependency}
  83. dependency
  84. \end{dependency}
  85. \end{postscript}
  86.  
  87. \section{Otros anidados en tikzpicture}
  88.  
  89. \begin{tikzpicture}
  90. \begin{forest}
  91. FOREST
  92. \end{forest}
  93. \end{tikzpicture}
  94.  
  95. \begin{tikzpicture}
  96. \begin{ganttchart}
  97. ganttchart
  98. \end{ganttchart}
  99. \end{tikzpicture}
  100.  
  101. \begin{tikzpicture}
  102. \begin{tikzcd}
  103. tikzcd
  104. \end{tikzcd}
  105. \end{tikzpicture}
  106.  
  107. \begin{tikzpicture}
  108. \begin{circuitikz}
  109. circuitikz
  110. \end{circuitikz}
  111. \end{tikzpicture}
  112.  
  113. \begin{tikzpicture}
  114. \begin{dependency}
  115. dependency
  116. \end{dependency}
  117. \end{tikzpicture}
  118.  
  119. \section{Anidados}
  120. PGF
  121. \begin{postscript}
  122. \begin{pgfpicture}
  123. PGF anidado queda de la misma manera
  124. \end{pgfpicture}
  125. \end{postscript}
  126.  
  127. PSPICTURE
  128. \begin{postscript}
  129. \begin{pspicture}(-0.5,-0.5)(5,3.5)
  130. pspicture anidaddo queda de la misma manera
  131. \end{pspicture}
  132. \end{postscript}
  133.  
  134. TIKZpicture
  135. \begin{postscript}
  136. \begin{tikzpicture}
  137. \shadedraw [shading=ball] (0,0) circle (2cm);
  138. \end{tikzpicture}
  139. \end{postscript}
  140.  
  141. \end{document}
  142.  
  143.  
  144. \begin{pspicture}(-0.5,-0.5)(5,3.5)
  145. IGNORAR
  146. \end{pspicture}
  147.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Agradecido de antemano.
Saludos
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Publicidad

Re: Opciones usando Getopt::Long

Notapor explorer » 2015-11-28 09:55 @454

No entiendo muy bien cuál es el problema.

Si se trata de comprobar las entradas recibidas, consistirá en hacer expresiones regulares para comprobar si los archivos tienen o no las extensiones solicitadas. Y reaccionar según sea el caso.

En la documentación sí que se ve que se puede asignar una referencia a una subrutina o incluso una subrutina anónima de forma directa, a cada opción de GetOptions(), para que se ejecuten cuando se encuentre la opción correspondiente. Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $verbose = '';   # option variable with default value (false)
  2. GetOptions ('verbose' => \$verbose,
  3.             'quiet'   => sub { $verbose = 0 });
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Ahí vemos dos cosas: en la primera línea declaramos la variable $verbose y la definimos con un valor inicial, que puede ser el valor por defecto que quieres tener en tu programa.

Y dentro de GetOptions() ves la subrutina anónima que se ajusta al valor 'quiet', que se ejecutará cuando se encuentre esa opción en la línea de comandos.

Las subrutinas reciben dos o tres argumentos: el nombre de la opción y luego siguen los posibles valores recibidos pasados en la línea de comandos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Opciones usando Getopt::Long

Notapor pablgonz » 2015-11-28 12:32 @564

Gracias por la respuesta
explorer escribiste:No entiendo muy bien cuál es el problema.

Si se trata de comprobar las entradas recibidas, consistirá en hacer expresiones regulares para comprobar si los archivos tienen o no las extensiones solicitadas. Y reaccionar según sea el caso.

En efecto es eso lo que deseo hacer, es decir siendo test.tex el archivo de entrada quiero que el comportamiento del script sea algo así:

1. Si ingreso script -o salida test.tex debería chequear si "salida" es un nombre valido para el archivo de salida, no comenzar por "-" o "." y ser distinto del nombre de entrada (test), si cumple con estos requisitos ejecutar $outfile para escribir el archivo de salida.
2. Si ingreso script -o test.tex debería crear el nombre de salida por defecto (test-out) y ejecutar $outfile para escribir el archivo de salida, de no ser posible hacer esto, mostrar un mensaje de que el nombre de salida es obligatorio (y sin extensión) y luego salir.
3. Si ingreso script test.tex no debería crear salida.

Actualice a la versión 5.22 y modifique el código dejándolo de la siguiente manera:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' if 0;
  2. use v5.22;
  3. use File::Basename;           #
  4. use Getopt::Long qw(:config bundling_override require_order); #
  5. use autodie;                  #
  6.  
  7. #------------------------ Constantes -----------------------------------
  8. my $imageDir    = "images";             #
  9. my $other       = "other";              #
  10. my $BPL         = '\begin{postscript}';
  11. my $EPL         = '\end{postscript}';
  12. my $sipgf       = 'pgfpicture';
  13. my $nopgf       = 'pgfinterruptpicture';
  14.  
  15. #---------------- Creamos el directorio para las imágenes -------------#
  16. -e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
  17.  
  18. my $usage = <<"END_OF_USAGE";
  19. Uso: programa [opt] archivo.tex
  20. END_OF_USAGE
  21.  
  22. my $outfile   = 0; # creamos el archivo de salida
  23.  
  24. my $output=""; # nombre del archivo de salida
  25.  
  26. my $result=GetOptions (
  27.     "outfile"    => \$outfile, # ejecuta la escritura de salida
  28.     'help|h'     => \$::opt_help, # muestra ayuda
  29.     'output|o=s' => sub { $outfile = 1}, # Si se ingresa -o ejecuta $outfile
  30.     ) or die $usage;
  31.  
  32. # help
  33. if ($::opt_help) {
  34.     print $usage;
  35.     exit(0);
  36. }
  37.  
  38. # help functions
  39. sub errorUsage { die "@_ (use script --help)\n"; }
  40.  
  41. @ARGV > 0 or errorUsage "Falta ingresar el nombre del archivo de entrada";
  42. @ARGV < 2 or errorUsage "Opción desconocida o varios archivos de entrada";
  43.  
  44. #--------------------- Arreglo de la extensión -------------------------
  45. my @SuffixList = ('.tex', '', '.ltx');    # posibles
  46. my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
  47. $ext = '.tex' if not $ext;
  48.  
  49. # revisamos el nombre del archivo de salida
  50. if ($output eq "$name") {
  51.     die "El nombre del archivo de salida no puede ser igual al del archivo de entrada\n";
  52. }
  53. if ($output =~ /(^\-|^\.).*?/){
  54.     die "$output no es un nombre valido para el archivo de salida\n";
  55. }
  56.  
  57. print "El nombre de salida es $output\n";
  58.  
  59. #------------------- Abrimos el archivo -------------------------------
  60. open my $ENTRADA, '<', "$name$ext";
  61. my $archivo;
  62. {
  63.     local $/;
  64.     $archivo = <$ENTRADA>;
  65. }
  66. close   $ENTRADA;
  67.  
  68. #--------------------- Dividimos el archivo de entrada -----------------
  69. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
  70.  
  71. # \pspicture to \begin{pspicture}
  72. $cuerpo =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
  73.  
  74. # Verbatim environments
  75. my $VERBATIM  = qr/(?: (v|V)erbatim\*?| PSTexample | aling)/xi;
  76.  
  77. # postscript environment
  78. my $POSTSCRIPT = qr/(?: postscript)/xi;
  79.  
  80. # tikzpicture environment
  81. my $ENVIRONMENT    = qr/(?: tikzpicture | pspicture\*?)/xi;
  82.  
  83. # falla izquierda (*SKIP)(*F)| acepta la derecha <img src="http://perlenespanol.com/foro/images/smilies/icon_smile.gif" alt=":)" title="Smile" />
  84. # tikz/pst to Postscript
  85. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  86.         (
  87.         (?:\\(psset|tikzset)(\{(?:\{.*?\}|[^\{])*\}).*?)?  # si está lo guardo
  88.         (\\begin\{($ENVIRONMENT)\} (.*?)  \\end\{\g{-2}\})
  89.     )
  90.     /$BPL\n$1\n$EPL/gmsx;
  91.  
  92. # pgfpicture to Postscript
  93. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  94.     (
  95.         \\begin\{$sipgf\}
  96.             .*?
  97.             (
  98.                 \\begin\{$nopgf\}
  99.                 .+?
  100.                 \\end\{$nopgf\}
  101.                 .*?
  102.             )*?
  103.         \\end\{$sipgf\}
  104.     )
  105.     /$BPL\n$1\n$EPL/gmsx;
  106.  
  107. # other to PostScript
  108. my $EXPORT  = qr/(forest|ganttchart|tikzcd|circuitikz|dependency|$other\*?)/x;
  109.  
  110. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  111.         (\\begin\{($EXPORT)\} (.*?)  \\end\{\g{-2}\})
  112.         /$BPL\n$1\n$EPL/gmsx;
  113.  
  114. # escribir la salida
  115. if ($outfile) {
  116. print "Creamos $output$ext\n";
  117.  
  118. open my $SALIDA, '>', "$output$ext";
  119.     print $SALIDA <<"EOC";
  120. $cabeza$cuerpo$final
  121. EOC
  122. close $SALIDA;
  123.  
  124. }# cerramos
  125. __END__
  126.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
pero, no logro dar con lo que deseo, $output queda con el nombre por defecto. He revisado varios ejemplos en el foro y en la red y no logro dar con el código correcto.
Agradecido por todo.
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Opciones usando Getopt::Long

Notapor explorer » 2015-11-30 01:13 @092

Hay un problema:

El primer punto y el segundo son, esencialmente, la misma entrada.

Quiero decir que '-o' está precediendo a un nombre de archivo, por lo que Getopt::Long los meterá en la misma variable $output.

Desde luego que se puede resolver, pero hay que poner varias líneas para resolver las distintas excepciones. Es mucho mejor simplificar el problema añadiendo opciones o simplificando las reglas de entrada.

Por ejemplo, podemos decir:

1- si al programa se le dan dos nombres de archivo, el primero siempre será el de entrada y el segundo, el de salida.

2- si se le pasan argumentos, se hace que sea obligatorio que sean acompañados de un parámetro. Así, un '-i' antecede al nombre de un archivo de entrada. Y '-o' al de salida.

Estos dos puntos te lo resuelve Getoptions(). Luego puedes hacer las siguientes comprobaciones:

1- si solo se pasa un parámetro, es el archivo de entrada. Entonces al de salida se le da un nombre por defecto.

2- comprobamos el nombre de los archivos de entrada y de salida. Si no son válidos, terminamos con error.

3- procesar.

4- ¡beneficios!
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Opciones usando Getopt::Long

Notapor pablgonz » 2015-11-30 11:00 @500

Gracias por la respuesta.

Tienes razón básicamente el punto 1 y 2 son idénticos.

De la forma en la cual tengo escrito el código ahora, no guarda en $output el valor ingresado en la línea de comandos para luego ejecutar $outfile y escribir el archivo de salida.

Obviando las comprobaciones para al archivo de salida, que se resumen esencialmente a que no tenga el mismo nombre del archivo de entrada (lo de la extensión lo puedo saltear dejando salida.tex.tex), ¿qué debo modificar para que $outfile se ejecute solo si está presente -o salida?

Seguiré intentando.
Agradecido,
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Opciones usando Getopt::Long

Notapor pablgonz » 2015-12-08 20:27 @894

Tomando las ideas que me diste, logré mi cometido.

Al final lo dejé así:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. script [opciones] entrada [salida] 
usando defined veo si está presente ARGV[1] y si está, hago las comprobaciones y ejecuto lo que deseo. El código quedo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' && eval 'exec perl -S $0 $argv:q' if 0;
  2. use v5.22;
  3. use File::Basename;           #
  4. use Getopt::Long qw(:config bundling_override require_order); #
  5. use autodie;                  #
  6.  
  7. #------------------------ Constantes -----------------------------------
  8. my $imageDir    = "images";             #
  9. my $other       = "other";              #
  10. my $BPL         = '\begin{postscript}';
  11. my $EPL         = '\end{postscript}';
  12. my $sipgf       = 'pgfpicture';
  13. my $nopgf       = 'pgfinterruptpicture';
  14.  
  15. #------------------------ Opciones y ayuda -----------------------------
  16.  
  17. my $usage = <<"END_OF_USAGE";
  18. Uso: script [opciones] entrada.tex [salida]
  19. END_OF_USAGE
  20.  
  21. # help functions
  22. sub errorUsage { die "@_ (use script --help)\n"; }
  23.  
  24. my $result=GetOptions (
  25.     'help|h'     => \$::opt_help, # muestra ayuda
  26.     ) or die "use script --help para ver las opciones\n";
  27.  
  28. # help
  29. if ($::opt_help) {
  30.     print $usage;
  31.     exit(0);
  32. }
  33.  
  34. @ARGV > 0 or errorUsage "Falta ingresar el nombre del archivo de entrada";
  35. @ARGV < 3 or errorUsage "Opción desconocida o varios archivos de entrada";
  36.  
  37. #--------------------- Arreglo de la extensión -------------------------
  38. my @SuffixList = ('.tex', '', '.ltx');    # posibles
  39. my ($name, $path, $ext) = fileparse($ARGV[0], @SuffixList);
  40. $ext = '.tex' if not $ext;
  41.  
  42. #------------------- Abrimos el archivo -------------------------------
  43. open my $ENTRADA, '<', "$name$ext";
  44. my $archivo;
  45. {
  46.     local $/;
  47.     $archivo = <$ENTRADA>;
  48. }
  49. close   $ENTRADA;
  50.  
  51. #---------------- Creamos el directorio para las imágenes -------------#
  52. -e $imageDir or mkdir($imageDir,0744) or die "No puedo crear $imageDir: $!\n";
  53.  
  54. #--------------------- Dividimos el archivo de entrada -----------------
  55. my($cabeza,$cuerpo,$final) = $archivo =~ m/\A (.+?) (\\begin\{document\} .+?)(\\end\{document\}.*)\z/msx;
  56.  
  57. # \pspicture to \begin{pspicture}
  58. $cuerpo =~ s/\\pspicture(\*)?(.+?)\\endpspicture/\\begin{pspicture$1}$2\\end{pspicture$1}/gmsx;
  59.  
  60. # Verbatim environments
  61. my $VERBATIM  = qr/(?: (v|V)erbatim\*?| PSTexample | aling)/xi;
  62.  
  63. # postscript environment
  64. my $POSTSCRIPT = qr/(?: postscript)/xi;
  65.  
  66. # tikzpicture environment
  67. my $ENVIRONMENT    = qr/(?: tikzpicture | pspicture\*?)/xi;
  68.  
  69. # tikz/pst to Postscript
  70. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  71.         (
  72.         (?:\\(psset|tikzset)(\{(?:\{.*?\}|[^\{])*\}).*?)?  # si está lo guardo
  73.         (\\begin\{($ENVIRONMENT)\} (.*?)  \\end\{\g{-2}\})
  74.     )
  75.     /$BPL\n$1\n$EPL/gmsx;
  76.  
  77. # pgfpicture to Postscript
  78. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  79.     (
  80.         \\begin\{$sipgf\}
  81.             .*?
  82.             (
  83.                 \\begin\{$nopgf\}
  84.                 .+?
  85.                 \\end\{$nopgf\}
  86.                 .*?
  87.             )*?
  88.         \\end\{$sipgf\}
  89.     )
  90.     /$BPL\n$1\n$EPL/gmsx;
  91.  
  92. # other to PostScript
  93. my $EXPORT  = qr/(forest|ganttchart|tikzcd|circuitikz|dependency|$other\*?)/x;
  94.  
  95. $cuerpo =~ s/\\begin\{$POSTSCRIPT\}.+?\\end\{$POSTSCRIPT\}(*SKIP)(*F)|
  96.         (\\begin\{($EXPORT)\} (.*?)  \\end\{\g{-2}\})
  97.         /$BPL\n$1\n$EPL/gmsx;
  98.  
  99. # El nombre del archivo de salida se guarda en $ARGV[1]
  100. my $output = $ARGV[1];
  101.  
  102. # Si $output está presente, validamos
  103. if (defined $output) {
  104. # No comienze por -, -- o .
  105. if ($output =~ /(^\-|^\.).*?/){
  106.     die "$output no es un nombre valido para el archivo de salida\n";
  107.     } #
  108. # Si $output es igual al nombre de entrada agregamos -out
  109. if ($output eq "$ARGV[0]" or $output eq "$name") {
  110.     $output = "$name-out$ext";  
  111.     } #
  112. # Si la última extensión es .ltx o .tex la quitamos
  113. if ($output =~ /.*?$ext/){
  114.     $output =~ s/(.+?)$ext/$1/gms;
  115.     } #
  116. # Escribir la salida
  117.  
  118. print "Creamos $output$ext\n";
  119. open my $SALIDA, '>', "$output$ext";
  120.     print $SALIDA <<"EOC";
  121. $cabeza$cuerpo$final
  122. EOC
  123. close $SALIDA;
  124. } # cerramos defined
  125.  
  126. __END__
  127.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Quizás se pueda hacer más corto, pero es lo que buscaba.
Agradecido,
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Opciones usando Getopt::Long

Notapor explorer » 2015-12-09 01:22 @098

O sea, que solo usas GetOptions para saber si el usuario pide ayuda o no... un poco más, y no lo necesitas en absoluto.

Es una lástima que no lo uses para lo que quieres. Bastaría con añadir las líneas que tienes de comprobación del nombre de salida, dentro de GetOptions. Otra cosa es que puedas (a lo peor no tienes toda la información en ese momento), en cuyo caso estás obligado a hacerlo más tarde, como lo tienes ahora.

Otra cosa: no entiendo para qué quieres usar la primera línea.

Esa configuración que muestra la primera línea es para cuando ocurre el extraño caso de que un intérprete, distinto de perl -normalmente el shell-, intente ejecutarlo, y en ese caso, obligarle a ejecutar perl.

Pero eso se hacía hace diez años o más. Hoy en día no es necesario: en sistemas Unix/Linux, el propio sistema sabe qué intérprete debe lanzar basado en la línea shebang (#!/usr/bin/perl...). Y en sistemas Windows, basta con configurar bien el sistema para que asocie la extensión '.pl' al intérprete perl.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Opciones usando Getopt::Long

Notapor pablgonz » 2015-12-09 06:50 @326

explorer escribiste:O sea, que solo usas GetOptions para saber si el usuario pide ayuda o no... un poco más, y no lo necesitas en absoluto.
En realidad uso GetOptions para añadir todo el resto de las opciones dentro del script, ésta es solo una parte (no coloqué todo el código, para que quedara más corto el mensaje), puse algo así como un MWE.

explorer escribiste:...Bastaría con añadir las líneas que tienes de comprobación del nombre de salida, dentro de GetOptions. Otra cosa es que puedas (a lo peor no tienes toda la información en ese momento), en cuyo caso estás obligado a hacerlo más tarde, como lo tienes ahora.
Traté de hacerlo así y no hubo caso... :( , de todas maneras, me gusta cómo quedó.

explorer escribiste:Otra cosa: no entiendo para qué quieres usar la primera línea.

Esa configuración que muestra la primera línea es para cuando ocurre el extraño caso de que un intérprete, distinto de perl -normalmente el shell-, intente ejecutarlo, y en ese caso, obligarle a ejecutar perl.
Pero eso se hacía hace diez años o más...
Tienes razón, el primer script que con el que empecé a interesarme en Perl tenía esa primera línea y tiene más de diez años, la actualizaré.

Saludos
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 11 invitados

cron