Projects
Multimedia
tovid
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 9
View file
tovid.changes
Changed
@@ -1,4 +1,17 @@ ------------------------------------------------------------------- +Fri May 24 13:24:31 UTC 2019 - Luigi Baldoni <aloisio@gmx.com> + +- Update to version 0.35.2 + * Fixed set_chapters not having exec bit set + * Fixed grep for libav filters + * Some python3 fixes + * Fixed scope problem that only showed up on freebsd for some + reason. + * Fixed imagemagick spumux buttons for IM-6.9.1-x. + * Make ffmpeg the default encoder when both ffmpeg and avconv + are present. + +------------------------------------------------------------------- Mon Apr 6 19:29:20 UTC 2015 - aloisio@gmx.com - Version 0.35.0
View file
tovid.spec
Changed
@@ -1,6 +1,7 @@ -# vim: set ts=4 sw=4 et: # -# Copyright (c) 2015 Luigi Baldoni <aloisio@gmx.com> +# spec file for package tovid +# +# Copyright (c) 2015-2019 Luigi Baldoni <aloisio@gmx.com> # Copyright (c) 2005-2010 oc2pus # # All modifications and additions to the file contributed by third parties @@ -12,24 +13,24 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments to packman@links2linux.de +# Please submit bugfixes or comments via https://bugs.links2linux.org/ +# -%{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} -%{!?python_sitearch: %global python_sitearch %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} Name: tovid -Version: 0.35.0 +Version: 0.35.2 Release: 0 Summary: Video conversion and DVD authoring tools -License: GPL-2.0+ +License: GPL-2.0-or-later Group: Productivity/Multimedia/Video/Editors and Convertors -Url: http://tovid.wikia.com/wiki/Tovid_Wiki -Source: https://github.com/tovid-suite/tovid/releases/download/v0.35.0/tovid-%{version}.tar.gz +URL: http://tovid.wikia.com/wiki/Tovid_Wiki +Source: https://github.com/tovid-suite/tovid/releases/download/%{version}/tovid-%{version}.tar.gz BuildRequires: hicolor-icon-theme BuildRequires: python-devel BuildRequires: python-setuptools BuildRequires: txt2tags BuildRequires: update-desktop-files +Requires: /usr/bin/mkisofs Requires: ImageMagick >= 6.0 Requires: MPlayer Requires: bc @@ -39,7 +40,6 @@ Requires: ffmpeg Requires: lsdvd Requires: mjpegtools -Requires: /usr/bin/mkisofs Requires: normalize Requires: python-base >= %{py_ver} Requires: python-tk @@ -48,11 +48,7 @@ Requires: tk Recommends: libdvdcss2 Recommends: transcode -BuildRoot: %{_tmppath}/%{name}-%{version}-build -%py_requires -%if 0%{?suse_version} > 1110 BuildArch: noarch -%endif %description tovid is a suite of utilities designed to make DVD @@ -64,6 +60,14 @@ %prep %setup -q +# fix shebang +sed -i 's|^#!.*|#!%{_bindir}/bash|' \ + src/idvid src/makedvd src/makempg \ + src/todisc src/todisc-fade-routine \ + src/tovid-init.in +sed -i 's|^#!.*|#!%{_bindir}/python|' \ + src/set_chapters src/titleset-wizard \ + src/todiscgui src/tovid-stats %build python setup.py build @@ -82,8 +86,8 @@ done %files -%defattr(-,root,root) -%doc AUTHORS ChangeLog COPYING README +%license COPYING +%doc AUTHORS ChangeLog README %{_bindir}/tovid %{python_sitelib}/libtovid %{python_sitelib}/tovid-%{version}* @@ -93,6 +97,6 @@ %{_datadir}/icons/*/*/apps/tovid.png %{_datadir}/icons/*/*/apps/titleset-wizard.png %{_datadir}/icons/*/scalable/apps/*.svg -%doc %{_mandir}/man1/tovid.1%{ext_man} +%{_mandir}/man1/tovid.1%{?ext_man} %changelog
View file
tovid-0.35.0.tar.gz/docs/src/en/tovid.html
Deleted
@@ -1,1918 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML> -<HEAD> -<META NAME="generator" CONTENT="http://txt2tags.org"> -<TITLE>tovid manual</TITLE> -</HEAD><BODY BGCOLOR="white" TEXT="black"> -<CENTER> -<H1>tovid manual</H1> -</CENTER> - -<P></P> -<HR NOSHADE SIZE=1> -<P></P> - - <UL> - <LI><A HREF="#toc1">Name</A> - <LI><A HREF="#toc2">Description</A> - <LI><A HREF="#toc3">Usage</A> - <LI><A HREF="#toc4">Configuration</A> - <LI><A HREF="#toc5">Command:gui</A> - <LI><A HREF="#toc6">Usage</A> - <LI><A HREF="#toc7">Command:titlesets</A> - <LI><A HREF="#toc8">Command:disc</A> - <UL> - <LI><A HREF="#toc9">Usage</A> - <LI><A HREF="#toc10">General Options</A> - <LI><A HREF="#toc11">Menu style</A> - <LI><A HREF="#toc12">Thumbnail style</A> - <LI><A HREF="#toc13">Slideshows</A> - <LI><A HREF="#toc14">Burning the disc</A> - <LI><A HREF="#toc15">Advanced usage</A> - <LI><A HREF="#toc16">Menu Style</A> - <LI><A HREF="#toc17">Thumbnail Style</A> - <LI><A HREF="#toc18">Dvdauthor options</A> - <LI><A HREF="#toc19">Usage notes</A> - </UL> - <LI><A HREF="#toc20">Command:mpg</A> - <UL> - <LI><A HREF="#toc21">Usage</A> - <LI><A HREF="#toc22">Basic options</A> - <LI><A HREF="#toc23">Advanced options</A> - </UL> - <LI><A HREF="#toc24">Command:id</A> - <UL> - <LI><A HREF="#toc25">Usage</A> - <LI><A HREF="#toc26">Options</A> - <LI><A HREF="#toc27">Examples</A> - </UL> - <LI><A HREF="#toc28">Command:dvd</A> - <UL> - <LI><A HREF="#toc29">Usage</A> - <LI><A HREF="#toc30">Options</A> - </UL> - <LI><A HREF="#toc31">Command:chapters</A> - <UL> - <LI><A HREF="#toc32">Examples</A> - </UL> - <LI><A HREF="#toc33">CONTACT</A> - </UL> - -<P></P> -<HR NOSHADE SIZE=1> -<P></P> - -<A NAME="toc1"></A> -<H1>Name</H1> - -<P> -tovid: Make DVDs from video files -</P> - -<A NAME="toc2"></A> -<H1>Description</H1> - -<P> -<B>tovid</B> is a command-line tool for creating DVDs. It can encode your video -files to DVD-compliant MPEG format, generate simple or complex DVD menus, -author and burn a ready-to-watch DVD, with just a few shell commands. A -graphical interface is also provided to make the process even easier. -</P> -<P> -<B>NOTE</B>: As of tovid 0.35, the legacy scripts <B>makemenu</B> and <B>makexml</B> -have been removed and no longer appear in this manpage. -All of their functions and more can be done with the 'tovid disc' command, -(todisc script). See <B>Command:disc</B> and the <A HREF="http://tovid.wikia.com">wiki</A> -for more info. -</P> -<P> -Also note that as of tovid 0.32, this is the only manual page provided by tovid. -There is now a single executable frontend to all functionality in the suite, so -if you were expecting to find manpages for <B>todisc</B>, <B>idvid</B>, <B>makempg</B> -and their kin, they can all be found in the <B>tovid</B> manpage you are reading now. -And yes, this makes for a pretty large manual page. If you are viewing this -manpage from the command-line <B>man</B> utility, which normally pages through the -<B>less</B> utility, you can skip to a section by searching with the <B>/</B> key, -followed by a <B>^</B> to match the given section name. For example, to skip to -the <B>mpg</B> command, type <B>/^Command:mpg</B>. See <B>man less</B> for more on how -to navigate. -</P> - -<A NAME="toc3"></A> -<H1>Usage</H1> - -<P> -<B>tovid</B> <I>COMMAND</I> [<I>OPTIONS</I>] -</P> -<P> -Where <I>COMMAND</I> is one of the following: -</P> -<P> - Main Commands -</P> - -<DL> -<DT><B>disc</B></DT><DD> - Encode, make menus, author, burn. (was <B>todisc</B>. See <B>Command:disc</B>) -<DT><B>gui</B></DT><DD> - Start the tovid GUI (was <B>todiscgui</B>. See <B>Command:gui</B>) -<DT><B>titlesets</B></DT><DD> - A GUI wizard for multiple titlesets. (new: See <B>Command:titlesets</B>) -</DL> - -<P> - Helper Commands -</P> - -<DL> -<DT><B>mpg</B></DT><DD> - Encode videos to MPEG format (was <B>tovid</B>. See <B>Command:mpg</B>) -<DT><B>dvd</B></DT><DD> - Author and/or burn a DVD (was <B>makedvd</B>. See <B>Command:dvd</B>) -<DT><B>id</B></DT><DD> - Identify one or more video files (was <B>idvid</B>. See <B>Command:id</B>) -<DT><B>chapters</B></DT><DD> - A GUI using mplayer for setting chapter points. It will return a string of - chapter points to the terminal, in a format recognized by 'tovid disc' - (todisc) or by 'tovid gui', for the <B>-chapters</B> option. -</DL> - -<P> -The <I>OPTIONS</I> differ for each command; run <B>tovid <command></B> with no -further arguments to get help on a command, and what options it expects. -</P> - -<A NAME="toc4"></A> -<H1>Configuration</H1> - -<P> -Two configuration files are created the first time you run tovid: -</P> - -<DL> -<DT><B>~/.tovid/preferences</B></DT><DD> - Defines working directory for all scripts. - You can define the output directory for makempg here. - The 'ffmpeg' executable can be set here: ffmpeg or avconv (TOVID_FFMPEG) -<DT><B>~/.tovid/tovid.ini</B></DT><DD> - Includes command-line options that should be passed to the various - <B>tovid</B> sub-commands. Note: each sub-command has its own section, - starting with the line [sub-command], for example: - -<PRE> - [disc] - ; -no-warn - -static - -no-ask -</PRE> - -</DL> - -<P> -Edit these files if you wish to change your configuration. -</P> -<P> -The following environment variables are also honoured: -</P> - -<PRE> - TOVID_HOME (directory containing preferences: ~/.tovid) - TOVID_WORKING_DIR (working directory for all scripts). - TOVID_OUTPUT_DIR (output directory for the makempg script). - TOVID_FFMPEG_CMD (the 'ffmpeg' executable to use: ffmpeg or avconv) -</PRE> - -<P> -These will override 'TOVID_HOME', 'WORKING_DIR', 'OUTPUT_DIR', -and 'TOVID_FFMPEG' if set in ~/.tovid/preferences. -</P> - -<A NAME="toc5"></A> -<H1>Command:gui</H1> - -<A NAME="toc6"></A> -<H1>Usage</H1> - -<P> -<B>tovid gui</B> [<I>OPTIONS</I>] -</P> -<P> -<B>tovid gui</B> starts the graphical user interface (GUI) for tovid. This is -the easiest way to start creating DVDs with tovid. The optional arguments -<I>OPTIONS</I> are any option used by todisc ('tovid disc') which will save -entering it manually, OR the full path to a saved script from the GUI. -You can also combine these, but the script must be the FIRST option -directly after <B>tovid gui</B> . (This option to save the contents of your -project allows you to use it as a bash script later, or to reload the -project to continue working with it at another time.) -</P> -<P> -<B>tovid gui</B> will also take the option <B>--position</B>, which denotes the -screen position that the GUI will start at, in the form '+X+Y', similar to -this part of the Xorg -geometry string. -</P> -<P> -All help is integrated in the form of tooltips. You can also see -**Command:disc ** for more detail about the options. Note: if you wish to use -a GUI to make multiple titlesets on the same DVD use <B>*tovid titlesets*</B>, -which is a wizard that uses the the 'tovid gui. See <B>*Command:titlesets*</B>. -</P> -<P> -Please note that although the interface may seem complex with so many options, -you can create a fully functional DVD with only a few options on the opening -tab of the GUI (select video files and an output name). -</P> - -<A NAME="toc7"></A> -<H1>Command:titlesets</H1> - -<P> -<B>tovid titlesets</B> will assist in making a DVD with multiple titlesets. It can -be started without any options, or you can feed it the path to a saved titleset -script as an option. The option to save a script is also useful as the resulting -script can be run later from a terminal. -</P> - -<A NAME="toc8"></A> -<H1>Command:disc</H1> - -<P> -<B>tovid disc</B> creates a DVD file-system with optional menus, from a list of -multimedia video files and their titles. As todisc can function as a master -script, calling other scripts as it needs them, it is the easiest command line -program for creating a DVD from start to finish, including automatically -converting non-compliant videos and prompting to burn at completion. It can do -animated menus, static thumbnail menus, text-only menus, or author with no menu. -In addition, it can do slideshows, using images as input, and even combine -slideshows with videos. It supports sub-menus for chapter breaks, -configurable menu style, animated backgrounds and transparency effects. -From simple (no menu) to complex (switched menus and titlesets), you should -be able to do what you want with 'tovid disc'. -</P> - -<A NAME="toc9"></A> -<H2>Usage</H2> - -<PRE> - tovid disc [OPTIONS] \ - -files <file list> -titles <title list> - -out mydvd -</PRE> - -<P> -For example: -</P> - -<PRE> - $ tovid disc -files File1.mpg File2.mpg File3.mpg \ - -titles "Episode 1" "Episode 2" "Episode 3" \ - -out Season_one -</PRE> - -<P> -The number of <B>-files</B> and <B>-titles</B> must be equal, though if you do not -include any titles <B>tovid disc</B> will use the basename of the included files -as titles. If you are doing a slideshow or multiple slideshows, use -<B>-slides</B> rather than <B>-files</B> for passing in the images. You may use --files and -slides more than once to create an ordering in a mixed -slideshows/videos menu. See Slideshows part of Usage section, below. -</P> -<P> -If the input files are not mpeg, you will have the option to auto-encode them. -</P> -<P> -General Options -</P> -<P> -<B>At present there are 2 display arrangements or "templates":</B> -</P> - -<DL> -<DT>A. (Default)</DT><DD> - Thumbs will be centred, and as large as space restraints allow. -<P></P> -<DT>B. <B>-showcase</B> IMAGE|VIDEO</DT><DD> - Produces an arrangement with small buttons on - the side and the showcase image/video in the centre. If no IMAGE or VIDEO - argument is supplied, the central thumb will be omitted. -<P></P> - Note: <B>-textmenu</B>, <B>-quick-menu</B> and <B>-switched-menus</B> are all types - of showcase style menus. See descriptions under <B>Menu style</B> section. -</DL> - -<P> -The <B>-titles</B> arguments should be double or single quoted, or have the spaces -backslash-escaped. Special characters (like ", !, *, &, ?) may need to be -backslash-escaped. To include a quoted string within a title, backslash-escape -the quotes. These titles are used for labelling thumbnails on the main menu, -and for the submenu title for that video. ( see also <B>-submenu-titles</B> ) -</P> -<P> -The <B>-showcase</B> styles can use longer titles than the default arrangement. -With a showcase style, use: <B>-showcase-titles-align west</B> to give more space -for the title, or use <B>-showcase-titles-align east</B> to allow titles of more -than one line. -</P> -<P> -The default style can only show about 16 characters (depending on the number -of thumbs, and what <B>-titles-font</B> and <B>-titles-fontsize</B> is being used). -If your titles are too long to fit in the label area, you may try using -sub-menus, which can display longer titles, for example: -</P> - -<PRE> - $ tovid disc -submenus \ - -files file1.mpg file2.mpg ... \ - -titles "Short 1" "Short 2" \ - -submenus \ - -submenu-titles "Long Title One" "Long Title Two" \ - -out foo - -</PRE> - -<P> -The <B>-align</B> argument will position both titles and thumbs either south, -north east, west, southwest, northwest, southeast, northeast, subject to -certain constraints of each arrangement. For example a showcase style with -a showcase thumb can only do north|south|center. -</P> -<P> -More Examples: -</P> -<P> -A text-only menu: -</P> - -<PRE> - $ tovid disc -textmenu ... -</PRE> - -<P> -No menu: -</P> - -<PRE> - $ tovid -nomenu -files file1.mpg file2.mp4 "file 3.avi" -out mydvd -</PRE> - -<P> -<B>Titlesets</B> -</P> -<P> -A word should be mentioned here about titlesets, which is really just a -hierarchy of menus. You need to use titlesets, for example, if you have videos -of different resolutions, or otherwise want to arrange videos on separate menus. -If you want to have titlesets you need to put all the options for each titleset -menu you would like to have between <B>-titleset</B> and <B>-end-titleset</B> options. -</P> -<P> -Additionally, for the main menu (the opening menu that will let you jump to -each titleset), you need to put options between <B>-vmgm</B> and <B>-end-vmgm</B>. -You do not use <B>-files</B> for the opening menu options (<B>-vmgm</B>), but you -will need as many TITLES after <B>-titles</B> as you have menus. -</P> -<P> -Any options outside the <B>-titleset</B> <B>-end-titleset</B> and <B>-vmgm</B> -<B>-end-vmgm</B> areas will be global options applying to every titleset. -If a global option is duplicated inside a <B>-titleset</B> or <B>-vmgm</B> area, the -global option will be overridden. -</P> -<P> -Note: you do not need titlesets for a single menu with chapter break menus, for -that just use <B>-submenus</B> or <B>-ani-submenus</B> -</P> -<P> -Example of using <B>tovid disc</B> with titlesets: -</P> - -<PRE> - $ tovid disc -static -out MY_DVD \ - \ - -titleset \ - -files 1.mpg 2.mpg 3.mpg \ - -titles "Title One" "Title Two" "Title Three" \ - -end-titleset \ - \ - -titleset \ - -files 4.mpg 5.mpg \ - -titles "Title Four" "Title Five" \ - -background foo.jpg \ - -showcase bar.png \ - -end-titleset \ - \ - -vmgm \ - -titles "Season One" "Season Two" \ - -background bg.jpg \ - -bgaudio foo.mp3 \ - -titles-fontsize 20 \ - -end-vmgm -</PRE> - -<P> -See also <B>-titleset</B> and <B>-vmgm</B> -</P> -<P> -<B>Slideshows</B> -</P> -<P> -You can also use <B>tovid disc</B> to make slideshows. This can either be a single -slideshow, or multiple slideshows on the same menu. -Remember to use <B>-slides</B> rather than <B>-files</B> for passing in the -images. Images can be any filetype that imagemagick supports: for example -JPEG, PNG, GIF, TGA BMP etc. For a single slideshow do not use <B>-titles</B>: -use -menu-title to set the slideshow title. -</P> -<P> -For a single slideshow the default is an animated menu that transitions from -slide to slide. The default transition type is 'crossfade', which fades each -slide into the next and loops back to the first slide at the end. If instead -you use <B>-static</B>, then a static 'polaroid stack' menu of all the slides is -created, with a single spumux'ed button for navigating with the enter key. You -may have to experiment to find out which DVD remote button advances the slides. -Try the 'next chapter'(skip ?) button and the play or enter buttons. -If you want to limit the number of slides in the menu to a subset of all files -entered with <B>-slides</B>, then use <B>-menu-slide-total</B> INT. Be sure to use -a long enough audio file for <B>-bgaudio</B> or set <B>-menu-length</B> so the menu -is long enough to support the slides plus transitions. -</P> -<P> -You can also put multiple slideshows on one menu. To do this, use -<B>-slides IMAGES</B> for each slideshow desired. You can even mix videos -with slideshows by using <B>-files</B> <B>-slides</B> <B>-titles</B> multiple times. -</P> -<P> -Example of a single slideshow with an animated menu with transitions: -</P> - -<PRE> - $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \ - -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \ - -out myslideshow -</PRE> - -<P> -Example of multiple slideshows on one menu: -</P> - -<PRE> - $ tovid disc -menu-title "Autumn in Toronto" \ - -slides photos/september/*.jpg \ - -slides photos/october/*.jpg \ - -slides photos/november/*.jpg \ - -tile3x1 -rotate -5 5 -5 -align center \ - -bgaudio background.wav \ - -out myslideshow -</PRE> - -<P> -Example of mixed videos and slideshows: -</P> - -<PRE> - $ tovid disc -menu-title "Autumn in Toronto" \ - -files fall_fair.mov \ - -slides photos/september/*.jpg \ - -files harvest.mpg \ - -slides photos/october/*.jpg \ - -titles "Fall Fair" "September" "Harvest" "October" \ - -background autumn.png \ - -bgaudio bg.mp3 \ - -out myslideshow -</PRE> - -<P> -See the other slideshow options in the Slideshows options section. -</P> -<P> -<B>Encoding Options</B> -</P> -<P> -These are options for reencoding your non-compliant videos. They are passed -directly to the <B>tovid mpg</B> command which is invoked by <B>tovid disc</B> when -non-compliant files are found. For details, see the <B>Command:mpg</B> section. -Here is a list of possible options you can pass: - <B>-config</B>, <B>-ntscfilm</B>, <B>-dvd-vcd</B>, <B>-half-dvd</B>, <B>-kvcd</B>, - <B>-kvcdx3</B>, <B>-kvcdx3a</B>, <B>-kdvd</B>, <B>-bdvd</B>, <B>-704</B>, <B>-normalize</B>, - <B>-amplitude</B>, <B>-overwrite</B>, <B>-panavision</B>, <B>-force</B>, <B>-fps</B>, - <B>-vbitrate</B>, <B>-quality</B>, <B>-safe</B>, <B>-crop</B>, <B>-filters</B>, - <B>-abitrate</B>, <B>-priority</B>, <B>-deinterlace</B>, <B>-progressive</B>, - <B>-interlaced</B>, <B>-interlaced_bf</B>, <B>-type</B>, <B>-fit</B>, <B>-discsize</B>, - <B>-parallel</B>, <B>-mkvsub</B>, <B>-autosubs</B>, <B>-subtitles</B>, <B>-update</B>, - <B>-mplayeropts</B>, <B>-audiotrack</B>, <B>-downmix</B>, <B>-ffmpeg</B>, <B>-nofifo</B>, - <B>-from-gui</B>, <B>-slice</B>, <B>-quiet</B>, - <B>-fake</B>, <B>-keepfiles</B> -</P> - -<A NAME="toc10"></A> -<H2>General Options</H2> - -<DL> -<DT><B>-keep-files</B>, <B>-keepfiles</B></DT><DD> - Keep all intermediate/temporary files (helps with debugging) -<DT><B>-no-ask</B> | <B>-noask</B></DT><DD> - Skip all interactive questions. No preview, automatic re-encoding with - tovid if needed, no interactive option to use background video for bgaudio. -<DT><B>-no-warn</B>, <B>-nowarn</B></DT><DD> - Don't pause after outputting warning or info messages -<DT><B>-jobs</B></DT><DD> - By default, <B>tovid disc</B> starts a parallel job for each processor - detected. With this option you can manually set the number of jobs. For - example if you have a computer with 2 CPUs you can set "-jobs 1" to keep - one processor free for other things. At present this applies to the time - consuming imagemagick loops: you will notice a substantial speedup now if - you have a multi-cpu system. -<DT><B>-grid</B></DT><DD> - Show a second preview image with a grid and numbers that will help in finding - coordinates for options that might use them, like <B>-text-start</B> -<DT><B>-no-confirm-backup</B></DT><DD> - This option is for when your DVD contains images for a slideshow. - Slideshows are an experimental (but well tested) feature. Todisc is - unlikely to overwrite your personal files, but you should take precautions - and backup your images, as you would with any beta software. Todisc - will prompt you to backup your files normally. If you have already backed - up your images, use this option to disable the prompt. -<P></P> -==Options== -<P></P> -<DT><B>-ntsc</B></DT><DD> - 720x480 output, compatible with NTSC standard (default) -<DT><B>-pal</B></DT><DD> - 720x576 output, compatible with PAL standard -<DT><B>-submenus</B></DT><DD> - Create a sub-menu with chapters for each video (default: no sub-menus) -<DT><B>-ani-submenus</B></DT><DD> - Create an animated sub-menu with chapters for each video (default: not - animated) -<DT><B>-no-menu | -nomenu</B></DT><DD> - With this option todisc will just create a DVD file system, ready for - burning, with NO MENU, just the supplied video files. These do not need - to be compliant, as non-compliant files will be encoded as usual. The - <B>-out</B> option is not required. Each video will be a chapter unless - <B>-chapters</B> OPTION is passed. The <B>-chapters</B> option is a number - indicating the chapter interval in minutes, or a HH:MM:SS string - indicating chapter points. See <B>-chapters</B> -<DT><B>-encode-only</B></DT><DD> - This option was originally meant for the GUI, to allow it to be used for - just encoding rather than making a DVD structure. But it works well from - the command line as well as it has the added advantage that you can input - a list of files. Remember any makempg ('tovid mpg') options you use will - be passed on to the makempg script when encoding. -</DL> - -<A NAME="toc11"></A> -<H2>Menu style</H2> - -<DL> -<DT><B>-showcase</B> IMAGE|VIDEO</DT><DD> - If used without an argument, use showcase style without a central thumb. - This is a different arrangement of images for the menu: small thumbnails - go at left (and right) side of screen, with a larger image in the centre. - Maximum of 10 videos. If the provided argument is a video file, the - central thumb will be animated (regardless of whether <B>-static</B> is part - of the command line). Only 4:3 or 16:9 videos and images are accepted for - for the showcase file: if not one of these todisc will assume it is the - aspect ratio as the videos in the titleset. -<DT><B>-textmenu</B>, <B>-text-menu</B> NUM</DT><DD> - If used without an argument, create a textmenu out of the supplied titles - The optional argument specifies how many titles are in the 1st column, - i.e. giving 4 titles and using "-textmenu 2" would make 2 columns of 2 - titles. The default is to put all titles up to 13 in the first column - before starting a second column. Maximum: 2 columns and 26 titles. - Note that column 2 titles are justified to the left unless you add - <B>-edge-justify</B> to the command line. The menu will be static if no video - files are supplied with either <B>-background</B> or <B>-showcase</B> options. -<DT><B>-quick-menu</B></DT><DD> - If you are using ffmpeg 0.8 or newer you can use this option. This will - make a very quick menu by using ffmpeg instead of imagemagick. - There are two choices: you can either use '-showcase IMAGE|VIDEO' or - '-background VIDEO'. There are no fancy effects like <B>-wave</B> - or <B>-rotate</B> available for it, but it is extremely fast. It will be a - text-menu style of menu, with no video thumbs, and a central showcase - IMAGE(static) | VIDEO(animated). - (i) see <B>-bg-color</B> if you are not using a <B>-background</B> and want to - change the default. (default is dark blue for -quick-menu arrangements). ) - (ii) Note: todisc will still work with 'vhooks' if you have an old ffmpeg - with vhooks compiled in. -<P></P> - Specifying the IMAGE|VIDEO argument to <B>-showcase</B> is mandatory for this - style of menu, unless used in conjunction with <B>-switched-menus</B> - in which case the videos passed with <B>-files</B> automatically become the - showcase videos. If <B>-quick-menu</B> is used in combination with - <B>-switched-menus</B> it really speeds up an otherwise time consuming process. -<P></P> - Example: -<PRE> - -quick-menu -showcase /home/grepper/showcase.mpg -</PRE> - - See <B>-switched-menus</B> for example of making switched menus with - <B>-quick-menu</B> -<P></P> -<DT><B>-bg-color</B>, <B>-bg-colour</B></DT><DD> - The color to use for the menu background. (default: ntsc-safe black) - Note: use a color a great deal darker than you want, as it appears quite - a bit lighter in the video version. You can use hexadecimal ('#ffac5f') - notation or named colors ('Lime'). convert -list color will show them. - See <A HREF="http://www.imagemagick.org/script/color.php">colors</A> for more details. -<DT><B>-submenu-bg-color</B>, <B>-submenu-bg-colour</B></DT><DD> - The color to use as background for the submenu(s). - (default: ntsc-safe black) See <B>-bg-color</B> -<DT><B>-static</B></DT><DD> - Main menu will consist of static thumbnail links. (default: animated) - If you use a video for -showcase or -background then it will still be - a 'moving' menu, in spite of the static buttons. This option also does - double duty for the <B>-switched-menus</B> option, and will create static - "switched" images. - See also <B>-switched-menus</B> -<DT><B>-background</B> IMAGE|VIDEO</DT><DD> - Menu background. This can be a image file or an video file. If it is a - video file the background will be animated. Pick a file of correct aspect - ratio: i.e. it should still look good when resized to 4:3 aspect ratio. - It will be resized to fill the entire background. -<DT><B>-submenu-background</B> IMAGE</DT><DD> - Submenu background. This can be only be an image file. Pick a file of - correct aspect ratio: i.e. it should still look good when resized to - 4:3 aspect ratio. It will be resized to fill the entire background. -<DT><B>-menu-title</B></DT><DD> - Title for the root menu - may be longer than thumbnail labels - Also if you use \n in the title, you can use multi line titles, but you - would need to adjust <B>-title-fontsize</B> to something smaller than default - for example: -<P></P> -<PRE> - $ tovid disc ... -menu-title "A\nMultilined\nTitle" -title-fontsize 24 -</PRE> - -<DT><B>-title-font</B>, <B>-menu-font</B> FONT</DT><DD> - Font to use for titles, either by ImageMagick font name (ex., "Arial") or - explicit pathname (ex., "/full/path/to/arial.ttf"). To see a complete - list of acceptable ImageMagick font names, run <B>convert -list type</B>, and - refer to the leftmost column -<DT><B>-title-fontsize</B>, <B>-menu-fontsize</B></DT><DD> - Font size for main menu - best to -preview if you use this -<DT><B>-submenu-font</B></DT><DD> - Font to use for the sub-menu main titles. See <B>-title-font</B> -<DT><B>-submenu-fontsize</B></DT><DD> - Font size for the sub-menu main titles -<DT><B>-menu-fade</B> ['BACKGROUND DURATION']</DT><DD> - Fade the menu in and out The background will fade in first, then title (and - mist if called for), then the menu thumbs. The fadeout is in reverse - order. 'BACKGROUND DURATION' is an integer denoting the amount of time - the background will play before the menu begins to fade in. This can allow - you to do a 'transition' to the menu: if you supply a -background VIDEO it - will play for the indicated time before the menu fades in. Leave the - optional argument empty (just <B>-menu-fade</B>) to get the default behavior - of showing the background for 1 second before fading the menu in. To - disable the fadeout portion, use '<B>-loop</B> inf'. See also: - <B>-transition-to-menu</B> and <B>-loop</B> -<DT><B>-transition-to-menu</B></DT><DD> - This option goes with the <B>-menu-fade</B> option above, which must be - enabled for it to have effect. It is a convenience option for animated - backgrounds: the background will become static at the exact point the - thumbs finish fading in. This menu does not loop unless you pass - <B>-loop</B> VALUE. See also: <B>-loop</B> -<DT><B>-bgaudio</B>, <B>-bg-audio*</B> FILE</DT><DD> - An file containing audio for the main menu background. For static menus - the default is to use 20 seconds of audio. You can change this using the - <B>-menu-length</B> option. -<DT><B>-submenu-audio</B> FILE(S)</DT><DD> - List of files for sub-menu audio backgrounds. If one file is given, then - it will be used for all sub-menus. Otherwise the number given must equal - the number of submenus, though the keyword "none" in this list may be used for - silence. See also <B>-submenu-length</B> -<DT><B>-titleset</B> . . . <B>-end-titleset</B></DT><DD> - If you have more than one titleset, put options for each titleset between - <B>-titleset</B> and <B>-end-titleset</B>. A separate menu will be created that - can be accessed from the main menu (VMGM). You can create this main menu - using the <B>-vmgm</B> <B>-end-vmgm</B> options. See <B>-vmgm</B> below and - TITLESET paragraph opening <B>Usage</B> section. -<DT><B>-vmgm</B> . . . <B>-end-vmgm</B></DT><DD> - The VMGM menu is the root menu when you use titlesets. - Put your VMGM menu options between <B>-vmgm</B> and <B>-end-vmgm</B>. - You only need <B>-titles</B> "Titleset One title" "Titleset Two title" - . . . , and not <B>-files</B>. - Any other options can be used, but the menu will be a textmenu style by - default. <B>Hint</B>: use <B>-showcase</B> IMAGE/VIDEO to create a fancier - VMGM menu. -<DT><B>-no-vmgm-menu</B>, <B>-no-vmgm</B></DT><DD> - This will skip the creation of a VMGM ( root menu ) for titlesets. The DVD - will start with the first titleset. You can not use this option unless also - using <B>-quick-nav</B> as you would not have a way to get to other titlesets. -<DT><B>-skip-vmgm</B></DT><DD> - Start DVD from the first titleset instead of the VMGM ( root ) menu. -<DT><B>-switched-menus</B>, <B>-switched-menu</B></DT><DD> - This will make a "switched menu": there will be a central image where the - showcase image would go, and text menu titles along the menu edge where - textmenu titles go. As you select a video title with the down or up arrow - on your DVD remote, the image in the centre will change to the image or - video made from that selected video. Do not use <B>-showcase</B> IMAGE/VIDEO - with this option. -<P></P> - This can be a time consuming process for making animated menus as you need - to make a separate menu for each video provided with <B>-files</B>. The - process can be greatly sped up by using <B>-quick-menu</B> in conjunction with - this, though you will lose fancy options like <B>-rotate</B> and <B>-wave</B>. -<P></P> - Note that if you want to just have a static rather than an 'animated' - image, add <B>-static</B> to the command line. -<P></P> - Example for using with <B>-quick-menu</B>: -<PRE> - -switched-menus -quick-menu -</PRE> - -</DL> - -<A NAME="toc12"></A> -<H2>Thumbnail style</H2> - -<DL> -<DT><B>-titles-font</B> FONT</DT><DD> - Display thumbnail or textmenu titles in the given font -<DT><B>-titles-fontsize</B> POINTS</DT><DD> - Font size to use for thumbnail or textmenu titles -<DT><B>-thumb-shape</B></DT><DD> - normal|oval|vignette|plectrum|arch|spiral|blob|star|flare - Apply a shaped transparency mask to thumbnail videos. - These "feathered" shapes look best against a plain background (or used - in conjunction with <B>-thumb-mist</B> [COLOR]). For this rectangular - semi-transparent misted background for each thumb: see <B>-thumb-mist</B>. - Note: if you wish to make your own mask PNGS you can put them in - $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the - command line using the filename minus the path and extension. - (i.e ~/.tovid/masks/tux.png becomes -thumb-shape tux) - No frame is used for shaped thumbs. -<DT><B>-thumb-frame-size</B> INT</DT><DD> - The size (thickness) of the thumb frames in pixels. This will also set the - thickness of the raised "frame" of thumbs when you use <B>-3d-thumbs</B>. - See also <B>-showcase-frame-size</B> and <B>-thumb-frame-color</B> -<DT><B>-thumb-frame-color</B>, <B>-thumb-frame-colour</B> COLOR</DT><DD> - The color of frames for video thumbnails. Use hexadecimal or named colors - notation. Remember to quote if using hexadecimal! ( '#ffac5f' ). -<DT><B>-3d-thumbs</B>, <B>-3dthumbs</B></DT><DD> - This will give an illusion of 3D to the thumbnails: dynamic lighting on - rounded thumbs, and a raised effect on rectangular thumbs. Try it ! -</DL> - -<A NAME="toc13"></A> -<H2>Slideshows</H2> - -<DL> -<DT><B>-slides</B> IMAGES</DT><DD> - Use <B>-slides</B> IMAGES to pass in images for a slideshow. The default is - to make an animated menu of the slides, moving from one slide to the - next. If you use <B>-static</B>, a 'polaroid stack' montage is created. This - composites the slides onto the background in 'random' locations with random - rotations. <B>-slides</B> IMAGES can be used multiple times if you wish to - make a menu with multiple slideshows. You can also make a menu - of mixed videos and slideshows by using <B>-slides</B> IMAGES, and <B>-files</B> - VIDEOS multiple times. For such a menu, the number of <B>-titles</B> - needs to match the number of <B>-files</B> passed in plus the number of - slideshows. (Each time you use <B>-slides</B> counts as one title.) To use - a transition between the slides, use <B>-slide-transition</B> - crossfade|fade. See <B>-slide-transition</B> <B>-menu-slide-total</B> -<P></P> -<DT><B>-menu-slide-total</B> INT</DT><DD> - Use INT number of the slides that were passed in with <B>-slides</B> - to make the animated or static slide menu. The length of the menu is - determined by 1) <B>-menu-length</B> NUM if given, and by 2) the length - of the audio from <B>-bgaudio</B>. For submenu slideshows, it is determined - by 1) <B>-submenu-length</B> NUM if given, and by 2) the length of the - audio from <B>-submenu-audio</B> FILE(S). -<P></P> -<DT><B>-submenu-slide-total</B> INT</DT><DD> - This option is the same as <B>-menu-slide-total</B> except that it is - for submenu slideshows. -<P></P> -<DT><B>-slide-transition</B> crossfade|fade [crossfade]</DT><DD> - The type of fade transition between slides in a animated slide menu. Be - sure the menu length is long enough to support the 1 second transitions - between the slides. The length is determined by 1) the length of the - -bgaudio AUDIO 2) the length given with -menu-length NUM. For submenu - slideshows, it is determined by 1) <B>-submenu-length</B> NUM if given, and - by 2) the length of the audio from <B>-submenu-audio</B> FILE(S). -<P></P> - See <B>-menu-slide-total</B> , <B>-bgaudio</B> , <B>-menu-length</B> , - <B>-submenu-length</B>, and <B>-submenu-audio</B>. -<P></P> - The 'crossfade' transition fades from one slide to another. The 'fade' - transition fades in and out from and to black. If you don't use this - option, the default is to use a 'crossfade' transition. -<P></P> -<DT><B>-slideshow-menu-thumbs</B> FILES</DT><DD> - Use the FILES instead of the 1st image in each slideshow as the - thumb that shows on the menu. This option is for multiple slideshows - or mixed slideshow/video menus only. -<P></P> -<DT><B>-slides-to-bin</B> FILES</DT><DD> - FILES will be resized to 640x480 using a 'box' filter - this - is called 'binning'. It will reduce the 'signal to noise' ratio for the - image in the animated slide menu. Use this if you get some unwanted - effects for certain images, such as pixels shifting in what should be a - static image. See also <B>-slides-to-blur</B> and <B>-slide-border</B> -<P></P> -<DT><B>-slides-to-blur</B> FILES</DT><DD> - FILES will be blurred a small amount - which will help on - slides that still have noise even after 'binning' with -slides-to-bin. - The default blur is 0x0.2 - you can increase this with - -slide-blur ARG. See also <B>-slides-to-bin</B> and <B>-slide-border</B> -<P></P> -<DT><B>-slide-blur</B> VALUE or LIST of VALUES [0x0.2]</DT><DD> - The argument to use for blurring files. It will be passed to - imagemagick: convert -blur ARG. The format of the arg is {radius}x{sigma} - and the default is 0x0.2. Using values between 0x0.1 and 0x0.9 is probably - the best range. Use a single value for all, or a list to have a different - blur for each file passed with <B>-slides-to-blur</B>. You must pass in - <B>-files-to-blur</B> FILES to use this option. Blurring can help 'noise' - problems in the video. See also <B>-slides-to-bin</B> and <B>-slide-border</B> -<P></P> -<DT><B>-slide-border</B> WIDTH [100]</DT><DD> - Pad the slides with a border for the animated slide menu. The default - without using an argument is 100. Using this option can also solve some - noise/ringing effects if used alone or in conjunction with 'binning' - (<B>-slides-to-bin</B>) or blurring (<B>-slides-to-blur</B>). -<P></P> -<DT><B>-slide-frame</B> WIDTH [12]</DT><DD> - Frame the slides for the animated slideshow menu. The default width - without using an argument is 12. See also <B>-slide-frame-color</B> -<P></P> -<DT><B>-slide-frame-color</B>, <B>-slide-frame-colour</B></DT><DD> - The color of the slide frame if passing <B>-slide-frame</B>. The default if - you don't use this option is a color-safe white: rgb(235,235,235). -<P></P> -<DT><B>-showcase-slideshow</B></DT><DD> - If doing multiple slideshows or mixed videos and slideshow(s), then use - the animated slideshow as a showcase video. It will be composed of slides - from each slideshow in the menu. The thumb for each slideshow button will - be static. If you used with a mixed menu of videos and slideshows, then - the video thumbs WILL be animated, so you may wish to use -static or - -textmenu with the option in that case. If you want to use the - **-switched-menus option with a mixed menu leave this option out. -<P></P> -<DT><B>-background-slideshow</B>, <B>-bg-slideshow</B></DT><DD> - If doing multiple slideshows or mixed videos and slideshow(s), then use - the animated slideshow as a background video. See <B>-showcase-slideshow</B> - for additional details. -<P></P> -<DT><B>-no-confirm-backup</B></DT><DD> - Slideshows are an experimental (but well tested) feature. Todisc is - unlikely to overwrite your personal files, but you should take precautions - and backup your images, as you would with any beta software. Todisc - will prompt you to backup your files normally. If you have already backed - up your images, use this option to disable the prompt. - See <B>General Options</B> -<P></P> -<DT><B>-use-dvd-slideshow</B> <A HREF="FILE">CONFIG</A></DT><DD> - If you pass this option without an argument, tovid will use the - dvd-slideshow program to create the animated slide menu, assuming you have - this program installed. The optional argument is the dvd-slideshow - configuration file - if you don't use this argument tovid will create it - for you. If you want to use the 'Ken Burns effect' - then the - configuration file argument is required. Note: the configuration file will - override many of the above options for slideshows. -</DL> - -<A NAME="toc14"></A> -<H2>Burning the disc</H2> - -<DL> -<DT><B>-burn</B></DT><DD> - Prompt to burn the DVD directory on completion. -<P></P> -<DT><B>-device</B></DT><DD> - Device to use for the burning program [ /dev/dvdrw ] -<P></P> -<DT><B>-speed</B></DT><DD> - The speed to use for burning the disc. -</DL> - -<A NAME="toc15"></A> -<H2>Advanced usage</H2> - -<H3>Options</H3> - -<DL> -<DT><B>-menu-length</B></DT><DD> - The desired animated main menu length in seconds -<DT><B>-submenu-length</B></DT><DD> - The desired submenu length. This will also affect the length of submenu - audio for static submenus. (Assuming that -submenu-audio was passed in). - The default is to use 10 seconds of audio for static menus. -<DT><B>-submenu-stroke</B> COLOR</DT><DD> - The color for the sub-menu font shadow -<DT><B>-submenu-title-color</B>, <B>-submenu-title-colour</B></DT><DD> - The fill color used for sub-menu title fonts -<DT><B>-submenu-titles</B></DT><DD> - You can supply a list of titles here for sub-menus without the length - restrictions found in thumb titles. Must equal number of videos -<DT><B>-chapters</B> [ NUM | CHAPTER POINTS in HH:MM:SS ]</DT><DD> - The number of chapters for each video (default: 6) OR - the actual chapter points in HH:MM:SS format. - Chapter points will be used for generating the submenu thumbs, and for - seeking with your DVD player. You can pass in just one value that will - be used for all videos, or supply a list of values (number of chapters) - or time code strings. -<P></P> - If you just pass an integer for 'number of chapters', then tovid will - make the chapter points for you by dividing the video length by the number - you supply. If using the <B>-no-menu</B> option, the INT passed in will be - the chapter interval in minutes, rather than the above formula. -<P></P> - If passing HH:MM:SS format you need to pass the string of chapter points for - each video and each string should have comma separated values. - Additionally, the first chapter should always start at 00:00:00 as - dvdauthor will add that if it is not there already. -<P></P> - To get your time codes, you can play your videos in mplayer and press 'o' - to see them on-screen. I have found these to be very accurate in my short - tests. For greater frame accuracy you could try loading the file in - avidemux and find the time codes for the frames you want. -<P></P> - If passing grouped chapters you need to join the chapters from all the - videos in a group with a '+' separator. If you want to skip creating - chapters for a video in the group use '0' for its chapters. -<P></P> - Note: chapters for grouped videos should probably be passed in using the - above HH:MM:SS format. (Arbitrary chapters using just an INT for the # of - chapters is not guaranteed to work reliably in all cases for grouped videos - at the moment.) -<P></P> - Example for passing just number of chapters ( 4 videos ): -<PRE> - -chapters 5 2 4 8 -</PRE> - -<P></P> - Example of passing chapter points ( 4 videos ): -<PRE> - -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \ - 00:00:00,00:04:25.623,00:09:12,00:15:51 \ - 00:00:00,00:05:10,00:13:41,00:18:13.033 \ - 00:00:00,00:15:23.342,00:26:42.523 -</PRE> - -<P></P> - Example of passing grouped chapters using the '+' separator: -<PRE> - -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \ - 00:00:00... etc. -</PRE> - -<P></P> -<DT><B>-chapter-titles</B> LIST</DT><DD> - If you are using submenus, you can pass a list of titles for the - chapters. Each title must be quoted, and the number of titles given - must equal the total number of chapters for all videos. In other words - if you use -chapters 4 6 8 , you must give 18 chapter titles, in the same - order that the videos were passed in. Note: if you are passing in options - on the command line to the 'tovid disc' GUI, you must repeat the option - <B>-chapter-titles</B> for each video, accompanied by its respective chapter - titles. (you can also choose to use this syntax for the todisc script.) -<P></P> -<DT><B>-chapter-font</B> FONT</DT><DD> - Use FONT as the font for submenu chapters. -<P></P> -<DT><B>-chapter-fontsize</B> SIZE</DT><DD> - Use SIZE as the pointsize for the chapters font. -<DT><B>-chapter-color</B> COLOR</DT><DD> - The color for the chapters font. -<DT><B>-chapter-stroke</B> COLOR</DT><DD> - The color for the chapters font shadow -<P></P> -<DT><B>-seek</B> NUM | "NUM1 NUM2 NUM3 . . ."</DT><DD> - Seek to NUM seconds before generating thumbnails (default: 2.0 seconds) - If a quoted string of values matching the number of videos is used, then - each video can use a different seek value - If using switched menus, the <B>-seek</B> value(s) will be used to generate - the showcase image that displays on switching to another video choice with - the up/down arrow keys. -<DT><B>-fast-seek</B></DT><DD> - Use faster seek method for ffmpeg. This is not as accurate as the default - method, and may produce grey frames. -<DT><B>-frame-safe</B> Instead of seeking and then outputting one frame for</DT><DD> - previews and static menus, output 9 frames and choose the largest. Not - frame accurate (may be as much as 9 frames off), but safer. Choose this - if you are getting grey frames/thumbnails with some videos. You can also - use it to try to get the 'best' frame. This option - has no effect on submenus at present. -<DT><B>-showcase-seek</B> NUM</DT><DD> - Seek to NUM seconds before generating thumbnails for showcase video - (default: 2.0 seconds) -<DT><B>-bgvideo-seek</B>, <B>-bg-video-seek</B> NUM</DT><DD> - Seek to NUM seconds before generating images for background video - (default: 2.0 seconds) -<DT><B>-bgaudio-seek</B>, **-bg-audio-seek NUM</DT><DD> - Seek to NUM seconds before generating audio for bgaudio - (default: 2.0 seconds) -<DT><B>-group</B> N VIDEO1 VIDEO2 . . .</DT><DD> - Allow grouping videos in dvdauthor.xml, so they will play sequentially as - a group. The videos passed in after the 'N' will be grouped with the 'Nth' - video. Example: -<P></P> -<PRE> - -group 2 2.mpg 3.mpg 4.mpg -</PRE> - -<P></P> - will group these 3 videos with the 2nd video given with <B>-files</B>, so that - they will play sequentially as one title. Only one thumbnail and/or title - will appear on the menu for the group: it will be made from the 1st video - in the group. In the above example if you passed: -<PRE> - -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg -</PRE> - - then the group will consist of bar.mpg 2.mpg, 3.mpg and 4.mpg, and only the - title and/or thumbnail for bar.mpg will appear in the menu. You can use - <B>-group</B> more than once for multiple groups. Be sure to quote video - filenames if they contain spaces. -</DL> - -<A NAME="toc16"></A> -<H2>Menu Style</H2> - -<DL> -<DT><B>-menu-title-geo</B> north|south|east|west|center [south]</DT><DD> - The position of the menu title. You may need to use -align as well if - you don't want your title covering other parts of your menu. See - <B>-align</B> -<DT><B>-menu-title-offset</B> OFFSET (+X+Y)</DT><DD> - Move menu title by this offset from its N|S|E|W|Center position. You - may need to use -align as well if you don't want your title covering other - parts of your menu. See <B>-align</B> -<DT><B>-button-style</B> line|rect|text|text-rect [line]</DT><DD> - The style of button that you will see when you play the DVD. - "line" style underlines the title, "rect" draws a rectangle around the - thumb when you select it in the DVD player, "text" highlights the video - title text, and "text-rect" draws a rectangle around the title - text. -<DT><B>-title-color</B>, <B>-title-colour</B> COLOR</DT><DD> - Color to use for the main menu title. For list of supported colors do: - <B>convert -list</B> color. HTML notation may be used: "#ff0000". See: - <A HREF="http://www.imagemagick.org/script/color.php">http://www.imagemagick.org/script/color.php</A> -<DT><B>-title-stroke</B> COLOR</DT><DD> - Shadow color for the main menu's title font. Use "none" for transparent - outline (see title-color). Note: this is not a -stroke in the sense that - imagemagick uses the term, but a shadow (the font is drawn twice). To get - a true imagemagick stroke see <B>-title-font-deco</B> -<DT><B>-title-font-deco</B>, <B>-title-fontdeco</B> "IMAGEMAGICK STRING"</DT><DD> - Sets the font decoration method to FONTDECORATION. It is used by the 'convert' - ImageMagick command to draw the menu text. You can add colored text - outlines, gradient fills, and many others. See <B>Usage notes</B> -<DT><B>-titles-stroke</B> COLOR</DT><DD> - Shadow color for the thumb or textmenu video titles font. Use "none" for - transparent outline (see <B>-titles-color</B>). Note: this is not a -stroke - in the sense that imagemagick uses the term, but a shadow - (the font is drawn twice). To get a true imagemagick stroke, - see <B>-titles-font-deco</B> -<DT><B>-titles-font-deco</B>, <B>-titles-fontdeco</B> "IMAGEMAGICK STRING"</DT><DD> - Sets the font decoration method to FONTDECORATION. It is used by the 'convert' - ImageMagick command to draw the menu text. You can add colored text - outlines, gradient fills, and others. See <B>Usage notes</B> for more info. -<DT><B>-highlight-color</B>, <B>-highlight-colour</B></DT><DD> - Color to use for the menu buttons that your DVD remote uses to navigate. -<DT><B>-select-color</B>, <B>-select-colour</B></DT><DD> - Color to use for the menu buttons that your DVD remote uses to select. -<DT><B>-text-mist</B></DT><DD> - Put a semi-transparent misted background behind the text for the menu's - title, just slightly larger than the text area. -<DT><B>-text-mist-color</B>, <B>-text-mist-colour</B> COLOR</DT><DD> - Color of the mist behind the menu's title (see title-color). -<DT><B>-text-mist-opacity</B></DT><DD> - Opacity of the mist behind the menu's title - see <B>-opacity</B> -<DT><B>-title-opacity</B></DT><DD> - Opacity of the menu title text -<DT><B>-titles-opacity</B></DT><DD> - Opacity of the text for video titles -<DT><B>-submenu-title-opacity</B></DT><DD> - Opacity of the text for submenu menu titles -<DT><B>-chapter-title-opacity</B></DT><DD> - Opacity of the text for submenu chapter titles -<DT><B>-menu-audio-fade</B></DT><DD> - Number of sec to fade given menu audio in and out (default: 1.0 seconds) - If you use <B>-menu-audio-fade</B> 0 then the audio will not be faded. -<DT><B>-submenu-audio-fade</B></DT><DD> - Number of secs to fade sub-menu audio in and out (default: 1.0 seconds). - See <B>-menu-audio-fade</B> -<DT><B>-intro</B> VIDEO</DT><DD> - Use a introductory video that will play before the main menu. - At present it must be a DVD compatible video at the correct resolution etc. - Only 4:3 aspect is supported: 16:9 will give unexpected results. -</DL> - -<H3>Style options specific to showcase/textmenu arrangements</H3> - -<DL> -<DT><B>-text-start</B> N</DT><DD> - This option is for <B>-textmenu</B> menus. The titles will start at the Nth - pixel from the top of the menu ( Y axis ). -<DT><B>-title-gap</B> N</DT><DD> - This option is for <B>-textmenu</B> menus. The gap is the space between - titles vertically ( Y axis ). -<DT><B>-rotate</B> DEGREES</DT><DD> - Rotate the showcase image|video clockwise by DEGREES. - (default: if used without options, the rotate will be 5 degrees). Note: - this will not turn a portait image into a landscape image! -<DT><B>-showcase-geo</B> GEOMETRY</DT><DD> - The position of the showcase image. ( +X+Y position ) - For example: <B>-showcase-geo</B> +300+200 -<DT><B>-wave</B> default|GEOMETRY</DT><DD> - Wave effect for showcase image|video. Alters thumbs along a sine wave using - GEOMETRY. (default: no wave) - "default" will produce a wave arg of -20x556, which - produces a gentle wave with a small amount of distortion. - See: <A HREF="http://www.imagemagick.org/Usage/distorts/#wave">http://www.imagemagick.org/Usage/distorts/#wave</A> if you want - to try other values. -<DT><B>-showcase-shape</B> egg|oval|plectrum|arch|spiral|galaxy|flat-tube|normal</DT><DD> - Apply a shaped transparency mask to showcase videos or images. - Note: if you wish to make your own mask PNGS you can put them in - $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the - command line using the filename minus the path and extension. - No frame is used for shaped thumbs. -<DT><B>-showcase-framestyle</B> none|glass</DT><DD> - For -showcase-* style template only - "none" will use the default frame method, using "convert -frame . . ." - "glass" will use mplayer to make frames, which gives an interesting - animated effect to the frames, and can be much faster ( especially if you - don't use <B>-rotate</B> or <B>-wave</B> as thumbs will not need to be processed - again after mplayer spits them out. Note: you need to be using either - <B>-showcase</B> IMAGE or <B>-showcase</B> VIDEO for this "frame style" to work. -<DT><B>-showcase-frame-size</B> PIXELS</DT><DD> - The size of the showcase frame. This value will be used for both width and - height for the 'thickness' of the frame. This will also set the thickness - of the raised "frame" of the showcase thumb when you use <B>-3d-showcase</B>. - See also <B>-thumb-frame-size</B> and <B>-showcase-frame-color</B> -<DT><B>-showcase-frame-color</B>, <B>-showcase-frame-colour</B> PIXELS</DT><DD> - The color of the showcase frame. Use hexadecimal or named colors notation. - Remember to quote! ( '#ffac5f' ). -<DT><B>-3d-showcase</B>, <B>-3dshowcase</B></DT><DD> - This will give an illusion of 3D to the showcase thumb: dynamic lighting on - rounded thumbs, and a raised effect on rectangular thumbs. Try it ! -</DL> - -<A NAME="toc17"></A> -<H2>Thumbnail Style</H2> - -<DL> -<DT><B>-user-thumbs</B> IMAGE(S)</DT><DD> - Supply your own images for menu buttons, rather than relying on todisc to - generate them from the video. They must be the same aspect ratio as the - videos in the titleset (4:3 or 16:9), as todisc will resize them without - checking and cropping. There must be on image for each thumb that will be - displayed on the menu (ie. one thumb for each video in a titleset). -<DT><B>-opacity</B> [0-100] (default 100)</DT><DD> - Opacity of thumbnail videos as a percentage (no percent sign). - Anything less than 100(%) is semi-transparent. Not recommended with dark - backgrounds. -<DT><B>-thumb-blur</B>, <B>-blur</B> NUM</DT><DD> - The amount of feather blur to apply to the thumb-shape. The default is 1.0 - which will more or less keep the shape and produces transparency at the - edges. Choose float or integer values between 0.1 and 2.0. 3D thumbs are - set to a tiny blur, so this option doesn't affect the <B>-3dthumbs</B> option. -<DT><B>-showcase-blur</B> NUM</DT><DD> - The amount of 'feather' blur to apply to the showcase image/video. Choose - values between 0.1 and 2.0. This option has no effect on <B>-3d-showcase</B>. - See <B>-thumb-blur</B> for more info. -<DT><B>-align</B> DIRECTION</DT><DD> - This will align thumbs/titles in DIRECTION, which is a compass direction - as used by imagemagick: ie. north|south|east|west|northeast|northwest etc. - If <B>-align</B> south then menu title will align north, unless you manually - set one or both of <B>-menu-title-geo</B> or <B>-menu-title-offset</B>. - Only <B>-align</B> north|south|center has any effect on showcase with thumb, - or with the default montage arrangement of central thumbs. The most - apparent changes with be with textmenu, though with 2 column arrangements - only the north* and south* changes will show an effect. -<P></P> - Diagram: -<DT> . northwest north northeast .</DT><DD> -<DT> . .</DT><DD> -<DT> . west center east .</DT><DD> -<DT> . .</DT><DD> -<DT> . southwest south souteast .</DT><DD> -<DT><B>-thumb-mist</B> [COLOR]</DT><DD> - Use a mist behind thumbnails. The optional argument is the color of the - mist. This option helps with contrast. Be sure to set the font color - to an appropriate color if using a colored mist, and/or use a bold font. -<DT><B>-titles-color</B>, <B>-titles-colour</B> COLOR</DT><DD> - Color to use for the thumb or textmenu titles. If your titles are not - clear enough or look washed out, try using a <B>-titles-stroke</B> that - is the same color as used with <B>-titles-color</B> (see <B>-title-color</B>) -<DT><B>-showcase-titles-align</B> west|east (default: center [centre])</DT><DD> - The default is to center the text above the thumbnails. This option will - align the titles either to the left (west) or right (east). Aligning west - gives more space to the titles. Aligning east also does so, and as well - will facilitate using \n in your titles to achieve multi line titles. -<DT><B>-tile-3x1</B>, <B>-tile3x1</B></DT><DD> - Use a montage tile of 3x1 instead of the usual 2x2 for 3 videos - ie. -<P></P> - [movie1] [movie2] [movie3] instead of: -<P></P> - [movie1] [movie2] -<P></P> - [movie3] -<P></P> - This option only comes into play if the number of videos supplied equals 3 - Otherwise it will be silently ignored. Not used for -showcase-* style. -<DT><B>-tile-4x1</B>, <B>-tile4x1</B></DT><DD> - Same as <B>-tile-3x1</B> above, except use tile of 4x1. (one row of 4 videos) -<DT>**-thumb-columns 3|4</DT><DD> - Same as <B>-tile-3x1</B> and tile-4x1** above, except it accepts either '3' - (1 row of 3 thumbs), or '4' (one row of 4 thumbs) as an argument. This - alternative was added to help compact the gui layout. -<DT><B>-rotate-thumbs</B> DEGREE LIST ( list of degrees, one for each thumb )</DT><DD> - Rotate thumbs the given amount in degrees - can be positive or negative. - There must be one value for each file given with <B>-files</B>. - If the values are not the same distance from zero, the thumbs will be of - different sizes as images are necessarily resized *after* rotating. With - the default montage template - this will also resize the titles; with the - showcase template the titles will remain the same size. Example: -<P></P> -<PRE> - -rotate-thumbs -10 10 -10 10 -10 (for 5 files) -</PRE> - - **Note: this option will not turn a portrait image into a landscape image! -</DL> - -<A NAME="toc18"></A> -<H2>Dvdauthor options</H2> - -<DL> -<DT><B>-loop</B> PAUSE</DT><DD> - Pause in seconds at end of menu. Use "inf" if you wish indefinite pause. - Note: using "inf" with <B>-menu-fade</B> will disable the fadeout portion of - the fade. (default: "inf" for static menu, 10.0 seconds for animated.) -<DT><B>-playall</B></DT><DD> - This option will create a button on the main menu that will allow going - right to the 1st title and playing all videos in succession before - returning to the main menu. If doing titlesets you can use this within - the <B>-vmgm</B> ... <B>-end-vmgm</B> options to allow playing ALL titlesets. - (If you want also to have a playall button in each titleset you could use - this option between each <B>-titleset</B> ... <B>-end-titleset</B> option or put - it outside of the vmgm and titlset options as a global option. -<DT><B>-videos-are-chapters</B></DT><DD> - A button will be made on the main menu for each video, which you can use as - a chapter button. Selecting any video will play them all in order - starting with the selected one. -<DT><B>-chain-videos</B> NUM | N1-NN</DT><DD> - Without options this will chain all videos together so they play - sequentially without returning to the main menu, except for the last, which - will return. You can also specify which videos you want to behave this way - by number or by a range. ( ie. <B>-chain-videos</B> 1 2 4-6 ). -<DT><B>-subtitle-lang</B> "lang1 lang2 . . ."</DT><DD> - This allows selectable subtitles in the DVD, assuming you have optional - subtitles muxed into your videos. Use 2 character language codes. -<DT><B>-audio-channel</B> "Video1_track Video2_track Video3_track . . ."</DT><DD> - "VideoN_track" is the track number to use in a multi-track (multi-language) - mpeg: usually something like <B>-audio-channel</B> "1 0 1". The 1st track is - 0, 2nd is 1 . . . etc. If the tracks are 0. English 1.French, then the - above would make French the audio language on Video1 and Video3, and - English the audio language on Video2. You can check the mpeg with - "mplayer -v . . .". -<DT><B>-audio-lang</B> LANGUAGE CODES</DT><DD> - Identify the audio tracks on the DVD. These language codes are used for - each video in the titleset. When you use the audio button on your DVD - remote the language name is displayed. Example: <B>-audio-lang</B> en fr -<DT><B>-aspect</B> 4:3|16:9</DT><DD> - This will output a <video aspect WIDTH:HEIGHT /> tag for the dvdauthor - xml file. It will affect all videos in the titleset. Example: -<P></P> -<PRE> - -aspect 16:9 -</PRE> - -<DT><B>-widescreen</B> nopanscan|noletterbox [nopanscan]</DT><DD> - This will output a <video widescreen=nopanscan /> tag (for example) - for the dvdauthor xml file. It will affect all videos in the titleset. Use - in conjunction with <B>-aspect</B> if your dvd player is cropping your videos. - Example: -<P></P> -<PRE> - -aspect 16:9 -widescreen -</PRE> - -<DT><B>-quick-nav</B></DT><DD> - This option will allow navigation of a menu with more than one titleset by - using the left and right arrow keys of your DVD remote. When you press - this key the highlight will go the next or previous title. If you are at - the end of a titleset the right key will go to the next titleset. If you - are at the beginning of a titleset, the left key will go to the previous - titleset. If no next or previous titleset it will cycle to the end or - beginning of the titlesets. -<DT><B>-outlinewidth</B>, <B>-outline-width</B> WIDTH</DT><DD> - For spumux outlinewidth variable. If there is a large gap between words in - a text button, this option may help. -<DT><B>-video-pause</B> PAUSE (single value or list)</DT><DD> - The pause in seconds after playing a video title. This is useful for - slideshows: the 'slide' will remain on the screen for this length of time. - If you have grouped videos you should probably not pause the videos that - have a grouped title after it, but instead see <B>-grouped-video-pause</B>. - Note: if you provide a list of values they must be one for each video. -<DT><B>-group-video-pause</B> PAUSE (single value or list)</DT><DD> - The pause in seconds after a grouped video plays. If you wish to pause - after the whole group finishes, then only use a value greater than zero - for the last video in the group. If providing a list of values they must - equal the number of grouped videos. -</DL> - -<A NAME="toc19"></A> -<H2>Usage notes</H2> - -<P> -The argument given to various *-font options that set the font to use must be -one of the fonts listed by the command 'convert -list type'. Please note that -many of your installed fonts may not be available; if you want to maximize the -number of fonts available to todisc, download and run -<A HREF="http://www.cit.gu.edu.au/~anthony/anthony.html">Anthony Thyssen's</A> -<A HREF="http://www.imagemagick.org/Usage/scripts/imagick_type_gen">imagick_type_gen</A> -script and run it like this: -imagick_type_gen > ~/.magick/type.xml. -If that doesn't work, try imagick_type_gen > ~/.magick/type.mgk. -</P> -<P> -Or you can specify a ttf font file directly to the *-font options if you don't -want to install fonts to ImageMagick. -</P> -<P> -The *-stroke options in todisc are not a stroke in the sense that ImageMagick -uses the term, but rather a font shadow (the text is drawn twice) To get a -truer Imagemagick -stroke try something like: --title-font-deco "-stroke black" (or -titles-font-deco "-stroke black"). The -<B>-fontdeco</B> option is quite flexible and takes a lot of ImageMagick's -<I>convert</I> options. Please refer to the tovid -<A HREF="http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus">wiki</A> and Anthony -Thyssen's guide [<A HREF="http://www.imagemagick.org/Usage">http://www.imagemagick.org/Usage</A>] for further explanation and examples. -</P> - -<A NAME="toc20"></A> -<H1>Command:mpg</H1> - -<P> -<B>tovid mpg</B> converts arbitrary video files into (S)VCD/DVD-compliant -MPEG format, suitable for burning to CD/DVD-R for playback on a -standalone DVD player. -</P> - -<A NAME="toc21"></A> -<H2>Usage</H2> - -<P> -<B>tovid mpg</B> [<I>OPTIONS</I>] <B>-in</B> <I>INFILE</I> <B>-out</B> <I>OUTPREFIX</I> -</P> -<P> -Where <I>INFILE</I> is any multimedia video file, and <I>OUTPREFIX</I> is what -you want to call the output file, minus the file extension. <I>OPTIONS</I> -are additional customizations, described below. -</P> -<P> -By default, you will (hopefully) end up with an NTSC DVD-compliant -MPEG-2 video file; if you burn this file to a DVD-R, it should be -playable on most DVD players. -</P> -<P> -For example: -</P> - -<DL> -<DT><CODE>tovid mpg -in foo.avi -out foo_encoded</CODE></DT><DD> - Convert 'foo.avi' to NTSC DVD format, saving to 'foo_encoded.mpg'. -<P></P> -<DT><CODE>tovid mpg -pal -vcd foo.avi -out foo_encoded</CODE></DT><DD> - Convert 'foo.avi' to PAL VCD format, saving to 'foo_encoded.mpg'. -</DL> - -<A NAME="toc22"></A> -<H2>Basic options</H2> - -<DL> -<DT><B>-v</B>, <B>-version</B></DT><DD> - Print tovid version number only, then exit. -<DT><B>-quiet</B></DT><DD> - Reduce output to the console. -<DT><B>-fake</B></DT><DD> - Do not actually encode; only print the commands (mplayer, mpeg2enc etc.) - that would be executed. Useful in debugging; have tovid give you the - commands, and run them manually. -<DT><B>-ffmpeg</B></DT><DD> - Use ffmpeg for video encoding, instead of mplayer/mpeg2enc. Try this if - you have any problems with the default encoding method. Using this option, - encoding will be considerably faster. It can do almost everything that - mpeg2enc does such as -filters and -subtitles by using a pipe from mplayer - though using these options will make encoding somewhat slower. The - exceptions are some special options like -kvcd* -bdvd where you will still - need to use the default mpeg2enc option. -</DL> - -<H3>Television standards</H3> - -<DL> -<DT><B>-ntsc</B></DT><DD> - NTSC format video (USA, Americas) (default) -<DT><B>-ntscfilm</B></DT><DD> - NTSC-film format video -<DT><B>-pal</B></DT><DD> - PAL format video (Europe and others) -</DL> - -<H3>Formats</H3> - -<P> -Standard formats, should be playable in most DVD players: -</P> - -<DL> -<DT><B>-dvd</B></DT><DD> - (720x480 NTSC, 720x576 PAL) DVD-compatible output (default) -<DT><B>-half-dvd</B></DT><DD> - (352x480 NTSC, 352x576 PAL) Half-D1-compatible output -<DT><B>-svcd</B></DT><DD> - (480x480 NTSC, 480x576 PAL) Super VideoCD-compatible output -<DT><B>-dvd-vcd</B></DT><DD> - (352x240 NTSC, 352x288 PAL) VCD-on-DVD output -<DT><B>-vcd</B></DT><DD> - (352x240 NTSC, 352x288 PAL) VideoCD-compatible output -</DL> - -<P> -Non-standard formats, playable in some DVD players: -</P> - -<DL> -<DT><B>-kvcd</B></DT><DD> - (352x240 NTSC, 352x288 PAL) KVCD-enhanced long-playing video CD -<DT><B>-kdvd</B></DT><DD> - (720x480 NTSC, 720x576 PAL) KVCD-enhanced long-playing DVD -<DT><B>-kvcdx3</B></DT><DD> - (528x480 NTSC, 520x576 PAL) KVCDx3 specification -<DT><B>-kvcdx3a</B></DT><DD> - (544x480 NTSC, 544x576 PAL) KVCDx3a specification (slightly wider) -<DT><B>-bdvd</B></DT><DD> - (720x480 NTSC, 720x576 PAL) BVCD-enhanced long-playing DVD -</DL> - -<P> -See <A HREF="http://kvcd.net/">kvcd.net</A> for details on the KVCD specification. Please -note that KVCD ("K Video Compression Dynamics") is the name of a compression -scheme that can be applied to any MPEG-1 or MPEG-2 video, and has little to -do with VCD ("Video Compact Disc"), which is the name of a standard video disc -format. -</P> - -<A NAME="toc23"></A> -<H2>Advanced options</H2> - -<H3>Aspect ratios</H3> - -<P> -tovid automatically determines aspect ratio of the input video by playing it in -mplayer. If your video plays with correct aspect in mplayer, you should not -need to override the default tovid behavior. -</P> -<P> -If mplayer does not play your video with correct aspect, you may provide an -explicit aspect ratio in one of several ways: -</P> - -<DL> -<DT><B>-full</B></DT><DD> - Same as <B>-aspect 4:3</B> -<DT><B>-wide</B></DT><DD> - Same as <B>-aspect 16:9</B> -<DT><B>-panavision</B></DT><DD> - Same as <B>-aspect 235:100</B> -<DT><B>-aspect</B> <I>WIDTH</I><B>:</B><I>HEIGHT</I></DT><DD> - Custom aspect, where <I>WIDTH</I> and <I>HEIGHT</I> are integers. -</DL> - -<P> -The above are the intended INPUT aspect ratio. tovid chooses an optimal output -aspect ratio for the selected disc format (VCD, DVD, etc.) and does the -appropriate letterboxing or anamorphic scaling. Use <B>-widetv</B> to encode -for a widescreen monitor or TV. -</P> - -<H3>Video stream options</H3> - -<DL> -<DT><B>-quality</B> <I>NUM</I> (default 6)</DT><DD> - Desired output quality, on a scale of 1 to 10, with 10 giving the best - quality at the expense of a larger output file. Default is 6. Output size - can vary by approximately a factor of 4 (that is, <B>-quality 1</B> output - can be 1/4 the size of <B>-quality 10</B> output). Your results may vary. - WARNING: With <B>-quality 10</B>, the output bitrate may be too high for - your hardware DVD player to handle. Stick with 9 or lower unless you - have phenomenally good eyesight. -<P></P> - At present, this option affects both output bitrate and quantization (but - may, in the future, affect other quality/size-related attributes). Use - <B>-vbitrate</B> if you want to explicitly provide a maximum bitrate. -<P></P> -<DT><B>-vbitrate</B> <I>NUM</I></DT><DD> - Maximum bitrate to use for video (in kbits/sec). Must be within allowable - limits for the given format. Overrides default values. Ignored for VCD, - which must be constant bitrate. -<P></P> -<DT><B>-interlaced</B></DT><DD> - Do interlaced encoding of the input video (top fields first). Use this - option if your video is interlaced, and you want to preserve as much - picture quality as possible. This option is ignored for VCD, which - doesn't support it. -<P></P> - You can tell your source video is interlaced by playing it, and pausing - during a scene with horizontal motion; if you see a "comb" effect at the - edges of objects in the scene, you have interlaced video. Use this option - to encode it properly. -<P></P> - If you would prefer to have output in progressive format, use - <B>-progressive</B>. If you have a DV camera, use <B>-interlaced_bf</B> since - DV footage is generally bottom fields first. -<P></P> -<DT><B>-interlaced_bf</B></DT><DD> - Do interlaced encoding of the input video (bottom fields first). -<P></P> -<DT><B>-deinterlace</B>, <B>-progressive</B></DT><DD> - Convert interlaced source video into progressive output video. Because - deinterlacing works by averaging fields together, some picture quality is - invariably lost. Uses an adaptive kernel deinterlacer (kerndeint), or, - if that's not available, the libavcodec deinterlacer (lavcdeint). -<P></P> -<DT><B>-mkvsub</B> <I>LANG</I> (EXPERIMENTAL)</DT><DD> - Attempt to encode an integrated subtitle stream (such as may be found in - Matroska .mkv files) in the given language code (eng, jpn, etc.) May work - for other formats. -<P></P> -<DT><B>-autosubs</B></DT><DD> - Automatically include subtitle files with the same name as the input video. -<P></P> -<DT><B>-subtitles</B> <I>FILE</I></DT><DD> - Get subtitles from <I>FILE</I> and encode them into the video. WARNING: This - hard-codes the subtitles into the video, and you cannot turn them off while - viewing the video. By default, no subtitles are loaded. If your video is - already compliant with the chosen output format, it will be re-encoded to - include the subtitles. This works with both -ffmpeg and the default, - mpeg2enc. -<P></P> -<DT><B>-dvd-subtitles</B>, <B>-dvdsubs</B> | <I>FILE</I></DT><DD> - Get subtitles from <I>FILE(S)</I> and add them <B>as a subtitle stream</B> into the - video. This allows selectable subtitles on your DVD. You can use more than - one file for multiple languages. Be sure to use the -subtitle-lang option - in 'tovid disc' so the name of the language will show up on the DVD instead - of 'UNKNOWN' or similar -<P></P> -<DT><B>-dvdsubs-only</B></DT><DD> - Use this if you have an already complient MPEG and wish to add a subtitle - stream without re-encoding, using <B>-dvdsubs</B> , -<P></P> -<DT><B>-dvdsubs-fontsize</B> <I>NUM</I> [18]</DT><DD> - The pointsize in pixels for DVD selectable subtitles. To affect this for - hard-coded subtitles ( <B>-subtitles</B> ) you will need to pass options to - the player via <B>-mplayeropts</B> or <B>-mpvopts</B>. -<P></P> -<DT><B>-type</B> {live|animation|bw}</DT><DD> - Optimize video encoding for different kinds of video. Use 'live' (default) - for live-action video, use 'animation' for cartoons or anime, and 'bw' for - black-and-white video. This option currently only has an effect with - KVCD/KSVCD output formats; other formats may support this in the future. -<P></P> -<DT><B>-safe</B> <I>PERCENT</I></DT><DD> - Fit the video within a safe area defined by <I>PERCENT</I>. For example, - <B>-safe 90%</B> will scale the video to 90% of the width/height of the output - resolution, and pad the edges with a black border. Use this if some of the - picture is cut off when played on your TV. The percent sign is optional. -<P></P> -<DT><B>-filters</B> {none,denoise,deblock,contrast,all} (default none)</DT><DD> - Apply post-processing filters to enhance the video. If your input video is - very high quality, use 'none'. If your input video is grainy, use 'denoise'; - if it looks washed out or faded, use 'contrast'. You can use multiple - filters separated by commas. To apply all filters, use 'all'. This works - with both mpeg2enc and -ffmpeg. -<P></P> -<DT><B>-fps</B> <I>RATIO</I></DT><DD> - Force input video to be interpreted as <I>RATIO</I> frames per second. May be - necessary for some ASF, MOV, or other videos. <I>RATIO</I> should be an - integer ratio such as "24000:1001" (23.976fps), "30000:1001" (29.97fps), or - "25:1" (25fps). This option is temporary, and may disappear in future - releases. (Hint: To convert a decimal like 23.976 to an integer ratio, just - multiply by 1000, i.e. 23976:1000) -<P></P> -<DT><B>-crop</B> <I>WIDTH</I>:<I>HEIGHT</I>:<I>X</I>:<I>Y</I></DT><DD> - Crop a portion of the video <I>WIDTH</I> by <I>HEIGHT</I> in size, with the - top-left corner at <I>X</I>, <I>Y</I>. -<P></P> -<DT><B>-widetv</B></DT><DD> - Always encode to 16:9 widescreen (only supported by <B>-dvd</B>, <B>-kdvd</B>, - <B>-bdvd</B>), for optimal viewing on a widescreen monitor or TV. -</DL> - -<H3>Audio stream options</H3> - -<DL> -<DT><B>-normalize</B></DT><DD> - Analyze the audio stream and then normalize the volume of the audio. - This is useful if the audio is too quiet or too loud, or you want to - make volume consistent for a bunch of videos. Similar to running - normalize without any parameters. The default is -12dB average level - with 0dB gain. -<P></P> -<DT><B>-amplitude</B> <I>NUM</I>[dB]</DT><DD> - In addition to analyzing and normalizing, apply the gain to the audio - such that the 'average' (RMS) sound level is <I>NUM</I>. Valid values - range 0.0 - 1.0, with 0.0 being silent and 1.0 being full scale. Use - <I>NUM</I>dB for a decibel gain below full scale (the default without - -amplitude is -12dB). -<P></P> -<DT><B>-abitrate</B> <I>NUM</I></DT><DD> - Encode audio at <I>NUM</I> kilobits per second. Reasonable values include - 128, 224, and 384. The default is 224 kbits/sec, good enough for most - encodings. The value must be within the allowable range for the chosen disc - format; Ignored for VCD, which must be 224. -<P></P> -<DT><B>-audiotrack</B> <I>NUM</I></DT><DD> - Encode the given audio track, if the input video has multiple audio tracks. - <I>NUM</I> is <I>1</I> for the first track, <I>2</I> for the second, etc. You may - also provide a list of tracks, separated by spaces or commas, for example - <B>-audiotrack 3,1,2</B>. Use <B>tovid id</B> on your source video to determine - which audio tracks it contains. -<P></P> -<DT><B>-downmix</B></DT><DD> - Encode all audio tracks as stereo. This can save space on your DVD if - your player only does stereo. The default behavior of tovid is to use - the original number of channels in each track. For aac audio, downmixing - is not possible: tovid runs a quick 1 frame test to try to downmix the - input track with the largest number of channels, and if it fails then it - will revert to the default behavior of using the original channels. -</DL> - -<H3>Other options</H3> - -<DL> -<DT><B>-config</B> <I>FILE</I></DT><DD> - Read configuration from <I>FILE</I>, containing 'tovid' alone on the first - line, and free-formatted (whitespace-separated) tovid command-line options - on remaining lines. -<P></P> -<DT><B>-force</B></DT><DD> - Force encoding of already-compliant video or audio streams. -<P></P> -<DT><B>-overwrite</B></DT><DD> - Overwrite any existing output files (with the same name as the given - <B>-out</B> option). -<P></P> -<DT><B>-priority</B> {low|medium|high}</DT><DD> - Sets the main encoding process to the given priority. With high priority, - it may take other programs longer to load and respond. With lower priority, - other programs will be more responsive, but encoding may take 30-40% - longer. The default is high priority. -<P></P> -<DT><B>-discsize</B> <I>NUM</I></DT><DD> - When encoding, tovid automatically splits the output file into several - pieces if it exceeds the size of the target media. This option sets the - desired target DVD/CD-R size to <I>NUM</I> mebibytes (MiB, 2^20). By default, - splitting occurs at 700 for CD, 4300 for DVD. Use higher values at your - own risk. Use 650 or lower if you plan to burn to smaller-capacity CDs. - Doesn't work with the <B>-ffmpeg</B> option. -<P></P> -<DT><B>-fit</B> <I>NUM</I></DT><DD> - Fit the output file into <I>NUM</I> MiB. Rather than using default (or - specified) video bitrates, tovid will calculate the correct video bitrate - that will limit the final output size to <I>NUM</I> MiB. This is different - than <B>-discsize</B>, which cuts the final file into <I>NUM</I> MiB pieces. - <B>-fit</B> makes sure that the file never exceeds <I>NUM</I> MiB. This works - with <B>-ffmpeg</B>, but not with <B>-vcd</B> since VCDs have a standardized - constant bitrate. -<P></P> -<DT><B>-parallel</B></DT><DD> - Perform ripping, encoding, and multiplexing processes in parallel using - named pipes. Maximizes CPU utilization and minimizes disk usage. Note that - this option simply does more tasks simultaneously, in order to make better - use of available CPU cycles; it's unrelated to multi-CPU processing (which - is done automatically anyway). Has no effect when <B>-ffmpeg</B> is used. -<P></P> -<DT><B>-update</B> <I>SECS</I></DT><DD> - Print status updates at intervals of <I>SECS</I> seconds. This affects how - regularly the progress-meter is updated. The default is once every five - seconds. -<P></P> -<DT><B>-mpv</B></DT><DD> - Use mpv instead of mplayer. This option is experimental. -<P></P> -<DT><B>-mplayeropts</B> <I>OPTIONS</I></DT><DD> - Append <I>OPTIONS</I> to the mplayer command run during video encoding. Use - this if you want to add specific video filters (documented in the mplayer - manual page). Overriding some options will cause encoding to fail, so use - this with caution! -<P></P> -<DT><B>-mpvopts</B> <I>OPTIONS</I></DT><DD> - Append <I>OPTIONS</I> to the mpv command run during video encoding. Use - this if you want to add specific video filters (documented in the mplayer - or mpv manual page). Overriding some options will cause encoding to fail, - so use this with caution! -<P></P> -<DT><B>-nofifo</B> (EXPERIMENTAL)</DT><DD> - Do not use a FIFO pipe for video encoding. If you are getting "Broken pipe" - errors with normal encoding, try this option. WARNING: This uses lots of - disk space (about 2 GB per minute of video). -<P></P> -<DT><B>-keepfiles</B></DT><DD> - Keep the intermediate files after encoding. Usually, this means the audio - and video streams are kept (eg the .ac3 and .m2v files for an NTSC DVD). - This doesn't work with -parallel because the intermediate files are named - pipes, and not real files. -<P></P> -<DT><B>-slice</B> <I>START</I>-<I>END</I></DT><DD> - Encode a segment from <I>START</I> to <I>END</I> (in seconds). Only works with - -ffmpeg. -<P></P> -<DT><B>-from-gui</B></DT><DD> - Put makempg into a fully non-interactive state, suitable for calling from - a gui. -<P></P> -<DT><B>-noask</B></DT><DD> - Don't ask questions when choices need to be made. Assume reasonable - answers. -</DL> - -<A NAME="toc24"></A> -<H1>Command:id</H1> - -<P> -<B>tovid id</B> identifies each multimedia video file in a -list, and reports its compliance with video disc standards such as VCD, -SVCD, and DVD. -</P> - -<A NAME="toc25"></A> -<H2>Usage</H2> - -<P> -<B>tovid id</B> [<I>OPTIONS</I>] <I>VIDEO_FILE(s)</I> -</P> -<P> -For example: -</P> - -<DL> -<DT><CODE>tovid id foo.avi</CODE></DT><DD> -<DT><CODE>tovid id -tabluar videos/*.mpg</CODE></DT><DD> -</DL> - -<A NAME="toc26"></A> -<H2>Options</H2> - -<DL> -<DT><B>-terse</B></DT><DD> - Print raw video characteristics, no formatting. Helpful when - calling from other scripts. -<P></P> -<DT><B>-verbose</B></DT><DD> - Print extra information from mplayer, tcprobe, and ffmpeg. -<P></P> -<DT><B>-accurate</B></DT><DD> - Do lengthy play-time estimation by scanning through the entire video file. - Use this if the default behavior is giving you inaccurate play times. -<P></P> -<DT><B>-fast</B></DT><DD> - Skip lengthy play-time estimation, and go with what mplayer reports - as being the video duration. Unlike pre-0.32 versions of tovid, this - is now the default behavior, and the <B>-fast</B> option doesn't do anything. -<P></P> -<DT><B>-tabular</B></DT><DD> - Display output in a table format for easier comparison. Most useful - when identifying multiple video files. -<P></P> -<DT><B>-keepfiles</B></DT><DD> - Keep temporary directory for debugging. -<P></P> -<DT><B>-isformat</B> [<I>pal-dvd</I>|<I>ntsc-dvd</I>] (same syntax for vcd and svcd)</DT><DD> - Check <I>VIDEO_FILE</I> for compliance with the given disc format. - If <I>VIDEO_FILE</I> matches the given format, then <B>tovid id</B> reports "true" - and exits successfully. Otherwise, <B>tovid id</B> reports "false" and exits - with status 1 (failure). This checks and reports both vcd/svcd/dvd - and pal/ntsc. -<P></P> -<DT><B>-mpv</B></DT><DD> - This option is mainly for testing. If you have only mpv installed instead - of mplayer, it is used automatically. With this option, you can have BOTH - installed and choose which one to use. (default: mplayer) -</DL> - -<A NAME="toc27"></A> -<H2>Examples</H2> - -<DL> -<DT><CODE>tovid id -verbose homevideo.avi</CODE></DT><DD> - Report everything mplayer, ffmpeg, and transcode can determine about - homevideo.avi. -<P></P> -<DT><CODE>tovid id -isformat dvd homevideo.mpg</CODE></DT><DD> - Check to see if homevideo.mpg is compliant with the DVD standard. -</DL> - -<A NAME="toc28"></A> -<H1>Command:dvd</H1> - -<P> -<B>tovid dvd</B> takes a DVD directory as generated by tovid with 'tovid disc' or -one of the GUI frontends like 'tovid gui' or 'tovid titlesets' and burns -it to appropriate media. This will also work if the DVD directory is -generated by the dvdauthor backend that tovid also uses. -</P> -<P> -Running this program may slow down your other applications, due to intense -disk activity. -</P> - -<A NAME="toc29"></A> -<H2>Usage</H2> - -<P> -<B>tovid dvd</B> [<I>OPTIONS</I>] <I>DVD_DIR</I> -</P> -<P> -For example: -</P> - -<DL> -<DT><CODE>tovid dvd /path/to/DVD/directory</CODE></DT><DD> -</DL> - -<A NAME="toc30"></A> -<H2>Options</H2> - -<DL> -<DT><B>-burn</B></DT><DD> - Burn a DVD file-system in <I>DVD_DIR</I> (must contain a VIDEO_TS folder). - This option is currently not necessary as the makedvd script ONLY burns - now that legacy scripts like makexml have been removed. Left for - compatibility only. -<P></P> -<DT><B>-eject</B></DT><DD> - Eject the DVD tray after burning is complete. By default, the DVD is not - ejected. -<P></P> -<DT><B>-device</B> <I>DEVICE</I> (default /dev/dvdrw)</DT><DD> - Burn the disc image to <I>DEVICE</I>, the Linux device file-system - name of your DVD-recorder. Common examples might be /dev/dvdrw, - /dev/scd1, and /dev/hdc. You can also use a bus/id/lun triple - such as ATAPI:0,1,0 -<P></P> -<DT><B>-speed</B> <I>NUM</I> (default 1)</DT><DD> - Burn disc at speed <I>NUM</I>. -<P></P> -<DT><B>-label</B> <I>DISC_LABEL</I></DT><DD> - Uses <I>DISC_LABEL</I> as the volume ID. This appears as the mount - name of the disc on some computer platforms. Must be <=32 - alphanumeric digits without spaces. -<P></P> -<DT><B>-quiet</B></DT><DD> - Limit output to essential messages. -<P></P> -<DT><B>-noask</B></DT><DD> - Don't ask interactive questions and assume answers that will continue - execution. -</DL> - -<P> - After burning, the DVD can be previewed by calling: - <I><B>xine</B> dvd:/path/to/output/directory</I> - or: - <I><B>vlc</B> /path/to/output/directory</I> -</P> - -<A NAME="toc31"></A> -<H1>Command:chapters</H1> - -<P> -<B>tovid chapters</B> will start a GUI using mplayer to set chapter points in a -video. If the video plays through and you want to add more chapters you can -press the play button again, but remember that new chapter points will be -appended (in correct sequential order). It will display the resulting chapter -points, and also output to a terminal (useful for scripts). As well it will -give the option of saving the chapters string to a text file. -</P> -<P> -Note that the 'tovid gui' now features a similar widget when you press the -chapters button on the opening page. -</P> - -<A NAME="toc32"></A> -<H2>Examples</H2> - -<DL> -<DT><CODE>tovid chapters foo.avi</CODE></DT><DD> -<P></P> -<DT><CODE>chapters=$(tovid chapters /home/grepper/videos/foo.avi)</CODE></DT><DD> -</DL> - -<A NAME="toc33"></A> -<H1>CONTACT</H1> - -<P> -For further assistance, contact information, forum and IRC links, -please refer to the <A HREF="http://tovid.wikia.com/">tovid homepage</A>. -</P> - -<!-- html code generated by txt2tags 2.6 (http://txt2tags.org) --> -<!-- cmdline: txt2tags -t html -\-toc -\-toc-level 2 docs/src/en/tovid.t2t --> -</BODY></HTML>
View file
tovid-0.35.0.tar.gz/docs/src/en/tovid.wiki
Deleted
@@ -1,1663 +0,0 @@ -'''tovid manual''' - - - - ----- - -__TOC__ - ----- - - -== Name == - -tovid: Make DVDs from video files - -== Description == - -'''tovid''' is a command-line tool for creating DVDs. It can encode your video -files to DVD-compliant MPEG format, generate simple or complex DVD menus, -author and burn a ready-to-watch DVD, with just a few shell commands. A -graphical interface is also provided to make the process even easier. - -'''NOTE''': As of tovid 0.35, the legacy scripts '''makemenu''' and '''makexml''' -have been removed and no longer appear in this manpage. -All of their functions and more can be done with the 'tovid disc' command, -(todisc script). See '''Command:disc''' and the [http://tovid.wikia.com wiki] -for more info. - -Also note that as of tovid 0.32, this is the only manual page provided by tovid. -There is now a single executable frontend to all functionality in the suite, so -if you were expecting to find manpages for '''todisc''', '''idvid''', '''makempg''' -and their kin, they can all be found in the '''tovid''' manpage you are reading now. -And yes, this makes for a pretty large manual page. If you are viewing this -manpage from the command-line '''man''' utility, which normally pages through the -'''less''' utility, you can skip to a section by searching with the '''/''' key, -followed by a '''^''' to match the given section name. For example, to skip to -the '''mpg''' command, type '''/^Command:mpg'''. See '''man less''' for more on how -to navigate. - -== Usage == - -'''tovid''' ''COMMAND'' [''OPTIONS''] - -Where ''COMMAND'' is one of the following: - - Main Commands - -; '''disc''' -: Encode, make menus, author, burn. (was '''todisc'''. See '''Command:disc''') -; '''gui''' -: Start the tovid GUI (was '''todiscgui'''. See '''Command:gui''') -; '''titlesets''' -: A GUI wizard for multiple titlesets. (new: See '''Command:titlesets''') - - Helper Commands - -; '''mpg''' -: Encode videos to MPEG format (was '''tovid'''. See '''Command:mpg''') -; '''dvd''' -: Author and/or burn a DVD (was '''makedvd'''. See '''Command:dvd''') -; '''id''' -: Identify one or more video files (was '''idvid'''. See '''Command:id''') -; '''chapters''' -: A GUI using mplayer for setting chapter points. It will return a string of -: chapter points to the terminal, in a format recognized by 'tovid disc' -: (todisc) or by 'tovid gui', for the '''-chapters''' option. - -The ''OPTIONS'' differ for each command; run '''tovid <command>''' with no -further arguments to get help on a command, and what options it expects. - -== Configuration == - -Two configuration files are created the first time you run tovid: - -; '''~/.tovid/preferences''' -: Defines working directory for all scripts. -: You can define the output directory for makempg here. -: The 'ffmpeg' executable can be set here: ffmpeg or avconv (TOVID_FFMPEG) -; '''~/.tovid/tovid.ini''' -: Includes command-line options that should be passed to the various -: '''tovid''' sub-commands. Note: each sub-command has its own section, -: starting with the line [sub-command], for example: -<pre> - [disc] - ; -no-warn - -static - -no-ask -</pre> - - -Edit these files if you wish to change your configuration. - -The following environment variables are also honoured: - -<pre> - TOVID_HOME (directory containing preferences: ~/.tovid) - TOVID_WORKING_DIR (working directory for all scripts). - TOVID_OUTPUT_DIR (output directory for the makempg script). - TOVID_FFMPEG_CMD (the 'ffmpeg' executable to use: ffmpeg or avconv) -</pre> - -These will override 'TOVID_HOME', 'WORKING_DIR', 'OUTPUT_DIR', -and 'TOVID_FFMPEG' if set in ~/.tovid/preferences. - -== Command:gui == - -== Usage == - -'''tovid gui''' [''OPTIONS''] - -'''tovid gui''' starts the graphical user interface (GUI) for tovid. This is -the easiest way to start creating DVDs with tovid. The optional arguments -''OPTIONS'' are any option used by todisc ('tovid disc') which will save -entering it manually, OR the full path to a saved script from the GUI. -You can also combine these, but the script must be the FIRST option -directly after '''tovid gui''' . (This option to save the contents of your -project allows you to use it as a bash script later, or to reload the -project to continue working with it at another time.) - -'''tovid gui''' will also take the option '''--position''', which denotes the -screen position that the GUI will start at, in the form '+X+Y', similar to -this part of the Xorg -geometry string. - -All help is integrated in the form of tooltips. You can also see -**Command:disc ** for more detail about the options. Note: if you wish to use -a GUI to make multiple titlesets on the same DVD use '''*tovid titlesets*''', -which is a wizard that uses the the 'tovid gui. See '''*Command:titlesets*'''. - -Please note that although the interface may seem complex with so many options, -you can create a fully functional DVD with only a few options on the opening -tab of the GUI (select video files and an output name). - -== Command:titlesets == - -'''tovid titlesets''' will assist in making a DVD with multiple titlesets. It can -be started without any options, or you can feed it the path to a saved titleset -script as an option. The option to save a script is also useful as the resulting -script can be run later from a terminal. - -== Command:disc == - -'''tovid disc''' creates a DVD file-system with optional menus, from a list of -multimedia video files and their titles. As todisc can function as a master -script, calling other scripts as it needs them, it is the easiest command line -program for creating a DVD from start to finish, including automatically -converting non-compliant videos and prompting to burn at completion. It can do -animated menus, static thumbnail menus, text-only menus, or author with no menu. -In addition, it can do slideshows, using images as input, and even combine -slideshows with videos. It supports sub-menus for chapter breaks, -configurable menu style, animated backgrounds and transparency effects. -From simple (no menu) to complex (switched menus and titlesets), you should -be able to do what you want with 'tovid disc'. - -=== Usage === - -<pre> - tovid disc [OPTIONS] \ - -files <file list> -titles <title list> - -out mydvd -</pre> - -For example: - -<pre> - $ tovid disc -files File1.mpg File2.mpg File3.mpg \ - -titles "Episode 1" "Episode 2" "Episode 3" \ - -out Season_one -</pre> - -The number of '''-files''' and '''-titles''' must be equal, though if you do not -include any titles '''tovid disc''' will use the basename of the included files -as titles. If you are doing a slideshow or multiple slideshows, use -'''-slides''' rather than '''-files''' for passing in the images. You may use --files and -slides more than once to create an ordering in a mixed -slideshows/videos menu. See Slideshows part of Usage section, below. - -If the input files are not mpeg, you will have the option to auto-encode them. - -General Options - -'''At present there are 2 display arrangements or "templates":''' - -; A. (Default) -: Thumbs will be centred, and as large as space restraints allow. -: -; B. '''-showcase''' IMAGE|VIDEO -: Produces an arrangement with small buttons on -: the side and the showcase image/video in the centre. If no IMAGE or VIDEO -: argument is supplied, the central thumb will be omitted. -: -: Note: '''-textmenu''', '''-quick-menu''' and '''-switched-menus''' are all types -: of showcase style menus. See descriptions under '''Menu style''' section. - -The '''-titles''' arguments should be double or single quoted, or have the spaces -backslash-escaped. Special characters (like ", !, *, &, ?) may need to be -backslash-escaped. To include a quoted string within a title, backslash-escape -the quotes. These titles are used for labelling thumbnails on the main menu, -and for the submenu title for that video. ( see also '''-submenu-titles''' ) - -The '''-showcase''' styles can use longer titles than the default arrangement. -With a showcase style, use: '''-showcase-titles-align west''' to give more space -for the title, or use '''-showcase-titles-align east''' to allow titles of more -than one line. - -The default style can only show about 16 characters (depending on the number -of thumbs, and what '''-titles-font''' and '''-titles-fontsize''' is being used). -If your titles are too long to fit in the label area, you may try using -sub-menus, which can display longer titles, for example: - -<pre> - $ tovid disc -submenus \ - -files file1.mpg file2.mpg ... \ - -titles "Short 1" "Short 2" \ - -submenus \ - -submenu-titles "Long Title One" "Long Title Two" \ - -out foo - -</pre> - -The '''-align''' argument will position both titles and thumbs either south, -north east, west, southwest, northwest, southeast, northeast, subject to -certain constraints of each arrangement. For example a showcase style with -a showcase thumb can only do north|south|center. - -More Examples: - -A text-only menu: - -<pre> - $ tovid disc -textmenu ... -</pre> - -No menu: - -<pre> - $ tovid -nomenu -files file1.mpg file2.mp4 "file 3.avi" -out mydvd -</pre> - -'''Titlesets''' - -A word should be mentioned here about titlesets, which is really just a -hierarchy of menus. You need to use titlesets, for example, if you have videos -of different resolutions, or otherwise want to arrange videos on separate menus. -If you want to have titlesets you need to put all the options for each titleset -menu you would like to have between '''-titleset''' and '''-end-titleset''' options. - -Additionally, for the main menu (the opening menu that will let you jump to -each titleset), you need to put options between '''-vmgm''' and '''-end-vmgm'''. -You do not use '''-files''' for the opening menu options ('''-vmgm'''), but you -will need as many TITLES after '''-titles''' as you have menus. - -Any options outside the '''-titleset''' '''-end-titleset''' and '''-vmgm''' -'''-end-vmgm''' areas will be global options applying to every titleset. -If a global option is duplicated inside a '''-titleset''' or '''-vmgm''' area, the -global option will be overridden. - -Note: you do not need titlesets for a single menu with chapter break menus, for -that just use '''-submenus''' or '''-ani-submenus''' - -Example of using '''tovid disc''' with titlesets: - -<pre> - $ tovid disc -static -out MY_DVD \ - \ - -titleset \ - -files 1.mpg 2.mpg 3.mpg \ - -titles "Title One" "Title Two" "Title Three" \ - -end-titleset \ - \ - -titleset \ - -files 4.mpg 5.mpg \ - -titles "Title Four" "Title Five" \ - -background foo.jpg \ - -showcase bar.png \ - -end-titleset \ - \ - -vmgm \ - -titles "Season One" "Season Two" \ - -background bg.jpg \ - -bgaudio foo.mp3 \ - -titles-fontsize 20 \ - -end-vmgm -</pre> - -See also '''-titleset''' and '''-vmgm''' - -'''Slideshows''' - -You can also use '''tovid disc''' to make slideshows. This can either be a single -slideshow, or multiple slideshows on the same menu. -Remember to use '''-slides''' rather than '''-files''' for passing in the -images. Images can be any filetype that imagemagick supports: for example -JPEG, PNG, GIF, TGA BMP etc. For a single slideshow do not use '''-titles''': -use -menu-title to set the slideshow title. - -For a single slideshow the default is an animated menu that transitions from -slide to slide. The default transition type is 'crossfade', which fades each -slide into the next and loops back to the first slide at the end. If instead -you use '''-static''', then a static 'polaroid stack' menu of all the slides is -created, with a single spumux'ed button for navigating with the enter key. You -may have to experiment to find out which DVD remote button advances the slides. -Try the 'next chapter'(skip ?) button and the play or enter buttons. -If you want to limit the number of slides in the menu to a subset of all files -entered with '''-slides''', then use '''-menu-slide-total''' INT. Be sure to use -a long enough audio file for '''-bgaudio''' or set '''-menu-length''' so the menu -is long enough to support the slides plus transitions. - -You can also put multiple slideshows on one menu. To do this, use -'''-slides IMAGES''' for each slideshow desired. You can even mix videos -with slideshows by using '''-files''' '''-slides''' '''-titles''' multiple times. - -Example of a single slideshow with an animated menu with transitions: - -<pre> - $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \ - -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \ - -out myslideshow -</pre> - -Example of multiple slideshows on one menu: - -<pre> - $ tovid disc -menu-title "Autumn in Toronto" \ - -slides photos/september/*.jpg \ - -slides photos/october/*.jpg \ - -slides photos/november/*.jpg \ - -tile3x1 -rotate -5 5 -5 -align center \ - -bgaudio background.wav \ - -out myslideshow -</pre> - -Example of mixed videos and slideshows: - -<pre> - $ tovid disc -menu-title "Autumn in Toronto" \ - -files fall_fair.mov \ - -slides photos/september/*.jpg \ - -files harvest.mpg \ - -slides photos/october/*.jpg \ - -titles "Fall Fair" "September" "Harvest" "October" \ - -background autumn.png \ - -bgaudio bg.mp3 \ - -out myslideshow -</pre> - -See the other slideshow options in the Slideshows options section. - -'''Encoding Options''' - -These are options for reencoding your non-compliant videos. They are passed -directly to the '''tovid mpg''' command which is invoked by '''tovid disc''' when -non-compliant files are found. For details, see the '''Command:mpg''' section. -Here is a list of possible options you can pass: - '''-config''', '''-ntscfilm''', '''-dvd-vcd''', '''-half-dvd''', '''-kvcd''', - '''-kvcdx3''', '''-kvcdx3a''', '''-kdvd''', '''-bdvd''', '''-704''', '''-normalize''', - '''-amplitude''', '''-overwrite''', '''-panavision''', '''-force''', '''-fps''', - '''-vbitrate''', '''-quality''', '''-safe''', '''-crop''', '''-filters''', - '''-abitrate''', '''-priority''', '''-deinterlace''', '''-progressive''', - '''-interlaced''', '''-interlaced_bf''', '''-type''', '''-fit''', '''-discsize''', - '''-parallel''', '''-mkvsub''', '''-autosubs''', '''-subtitles''', '''-update''', - '''-mplayeropts''', '''-audiotrack''', '''-downmix''', '''-ffmpeg''', '''-nofifo''', - '''-from-gui''', '''-slice''', '''-quiet''', - '''-fake''', '''-keepfiles''' - -=== General Options === - -; '''-keep-files''', '''-keepfiles''' -: Keep all intermediate/temporary files (helps with debugging) -; '''-no-ask''' | '''-noask''' -: Skip all interactive questions. No preview, automatic re-encoding with -: tovid if needed, no interactive option to use background video for bgaudio. -; '''-no-warn''', '''-nowarn''' -: Don't pause after outputting warning or info messages -; '''-jobs''' -: By default, '''tovid disc''' starts a parallel job for each processor -: detected. With this option you can manually set the number of jobs. For -: example if you have a computer with 2 CPUs you can set "-jobs 1" to keep -: one processor free for other things. At present this applies to the time -: consuming imagemagick loops: you will notice a substantial speedup now if -: you have a multi-cpu system. -; '''-grid''' -: Show a second preview image with a grid and numbers that will help in finding -: coordinates for options that might use them, like '''-text-start''' -; '''-no-confirm-backup''' -: This option is for when your DVD contains images for a slideshow. -: Slideshows are an experimental (but well tested) feature. Todisc is -: unlikely to overwrite your personal files, but you should take precautions -: and backup your images, as you would with any beta software. Todisc -: will prompt you to backup your files normally. If you have already backed -: up your images, use this option to disable the prompt. -: -: ==Options== -: -; '''-ntsc''' -: 720x480 output, compatible with NTSC standard (default) -; '''-pal''' -: 720x576 output, compatible with PAL standard -; '''-submenus''' -: Create a sub-menu with chapters for each video (default: no sub-menus) -; '''-ani-submenus''' -: Create an animated sub-menu with chapters for each video (default: not -: animated) -; '''-no-menu | -nomenu''' -: With this option todisc will just create a DVD file system, ready for -: burning, with NO MENU, just the supplied video files. These do not need -: to be compliant, as non-compliant files will be encoded as usual. The -: '''-out''' option is not required. Each video will be a chapter unless -: '''-chapters''' OPTION is passed. The '''-chapters''' option is a number -: indicating the chapter interval in minutes, or a HH:MM:SS string -: indicating chapter points. See '''-chapters''' -; '''-encode-only''' -: This option was originally meant for the GUI, to allow it to be used for -: just encoding rather than making a DVD structure. But it works well from -: the command line as well as it has the added advantage that you can input -: a list of files. Remember any makempg ('tovid mpg') options you use will -: be passed on to the makempg script when encoding. - -=== Menu style === - -; '''-showcase''' IMAGE|VIDEO -: If used without an argument, use showcase style without a central thumb. -: This is a different arrangement of images for the menu: small thumbnails -: go at left (and right) side of screen, with a larger image in the centre. -: Maximum of 10 videos. If the provided argument is a video file, the -: central thumb will be animated (regardless of whether '''-static''' is part -: of the command line). Only 4:3 or 16:9 videos and images are accepted for -: for the showcase file: if not one of these todisc will assume it is the -: aspect ratio as the videos in the titleset. -; '''-textmenu''', '''-text-menu''' NUM -: If used without an argument, create a textmenu out of the supplied titles -: The optional argument specifies how many titles are in the 1st column, -: i.e. giving 4 titles and using "-textmenu 2" would make 2 columns of 2 -: titles. The default is to put all titles up to 13 in the first column -: before starting a second column. Maximum: 2 columns and 26 titles. -: Note that column 2 titles are justified to the left unless you add -: '''-edge-justify''' to the command line. The menu will be static if no video -: files are supplied with either '''-background''' or '''-showcase''' options. -; '''-quick-menu''' -: If you are using ffmpeg 0.8 or newer you can use this option. This will -: make a very quick menu by using ffmpeg instead of imagemagick. -: There are two choices: you can either use '-showcase IMAGE|VIDEO' or -: '-background VIDEO'. There are no fancy effects like '''-wave''' -: or '''-rotate''' available for it, but it is extremely fast. It will be a -: text-menu style of menu, with no video thumbs, and a central showcase -: IMAGE(static) | VIDEO(animated). -: (i) see '''-bg-color''' if you are not using a '''-background''' and want to -: change the default. (default is dark blue for -quick-menu arrangements). ) -: (ii) Note: todisc will still work with 'vhooks' if you have an old ffmpeg -: with vhooks compiled in. -: -: Specifying the IMAGE|VIDEO argument to '''-showcase''' is mandatory for this -: style of menu, unless used in conjunction with '''-switched-menus''' -: in which case the videos passed with '''-files''' automatically become the -: showcase videos. If '''-quick-menu''' is used in combination with -: '''-switched-menus''' it really speeds up an otherwise time consuming process. -: -: Example: -<pre> - -quick-menu -showcase /home/grepper/showcase.mpg -</pre> - -: See '''-switched-menus''' for example of making switched menus with -: '''-quick-menu''' -: -; '''-bg-color''', '''-bg-colour''' -: The color to use for the menu background. (default: ntsc-safe black) -: Note: use a color a great deal darker than you want, as it appears quite -: a bit lighter in the video version. You can use hexadecimal ('#ffac5f') -: notation or named colors ('Lime'). convert -list color will show them. -: See [http://www.imagemagick.org/script/color.php colors] for more details. -; '''-submenu-bg-color''', '''-submenu-bg-colour''' -: The color to use as background for the submenu(s). -: (default: ntsc-safe black) See '''-bg-color''' -; '''-static''' -: Main menu will consist of static thumbnail links. (default: animated) -: If you use a video for -showcase or -background then it will still be -: a 'moving' menu, in spite of the static buttons. This option also does -: double duty for the '''-switched-menus''' option, and will create static -: "switched" images. -: See also '''-switched-menus''' -; '''-background''' IMAGE|VIDEO -: Menu background. This can be a image file or an video file. If it is a -: video file the background will be animated. Pick a file of correct aspect -: ratio: i.e. it should still look good when resized to 4:3 aspect ratio. -: It will be resized to fill the entire background. -; '''-submenu-background''' IMAGE -: Submenu background. This can be only be an image file. Pick a file of -: correct aspect ratio: i.e. it should still look good when resized to -: 4:3 aspect ratio. It will be resized to fill the entire background. -; '''-menu-title''' -: Title for the root menu - may be longer than thumbnail labels -: Also if you use \n in the title, you can use multi line titles, but you -: would need to adjust '''-title-fontsize''' to something smaller than default -: for example: -: -<pre> - $ tovid disc ... -menu-title "A\nMultilined\nTitle" -title-fontsize 24 -</pre> - -; '''-title-font''', '''-menu-font''' FONT -: Font to use for titles, either by ImageMagick font name (ex., "Arial") or -: explicit pathname (ex., "/full/path/to/arial.ttf"). To see a complete -: list of acceptable ImageMagick font names, run '''convert -list type''', and -: refer to the leftmost column -; '''-title-fontsize''', '''-menu-fontsize''' -: Font size for main menu - best to -preview if you use this -; '''-submenu-font''' -: Font to use for the sub-menu main titles. See '''-title-font''' -; '''-submenu-fontsize''' -: Font size for the sub-menu main titles -; '''-menu-fade''' ['BACKGROUND DURATION'] -: Fade the menu in and out The background will fade in first, then title (and -: mist if called for), then the menu thumbs. The fadeout is in reverse -: order. 'BACKGROUND DURATION' is an integer denoting the amount of time -: the background will play before the menu begins to fade in. This can allow -: you to do a 'transition' to the menu: if you supply a -background VIDEO it -: will play for the indicated time before the menu fades in. Leave the -: optional argument empty (just '''-menu-fade''') to get the default behavior -: of showing the background for 1 second before fading the menu in. To -: disable the fadeout portion, use ''''-loop''' inf'. See also: -: '''-transition-to-menu''' and '''-loop''' -; '''-transition-to-menu''' -: This option goes with the '''-menu-fade''' option above, which must be -: enabled for it to have effect. It is a convenience option for animated -: backgrounds: the background will become static at the exact point the -: thumbs finish fading in. This menu does not loop unless you pass -: '''-loop''' VALUE. See also: '''-loop''' -; '''-bgaudio''', '''-bg-audio*''' FILE -: An file containing audio for the main menu background. For static menus -: the default is to use 20 seconds of audio. You can change this using the -: '''-menu-length''' option. -; '''-submenu-audio''' FILE(S) -: List of files for sub-menu audio backgrounds. If one file is given, then -: it will be used for all sub-menus. Otherwise the number given must equal -: the number of submenus, though the keyword "none" in this list may be used for -: silence. See also '''-submenu-length''' -; '''-titleset''' . . . '''-end-titleset''' -: If you have more than one titleset, put options for each titleset between -: '''-titleset''' and '''-end-titleset'''. A separate menu will be created that -: can be accessed from the main menu (VMGM). You can create this main menu -: using the '''-vmgm''' '''-end-vmgm''' options. See '''-vmgm''' below and -: TITLESET paragraph opening '''Usage''' section. -; '''-vmgm''' . . . '''-end-vmgm''' -: The VMGM menu is the root menu when you use titlesets. -: Put your VMGM menu options between '''-vmgm''' and '''-end-vmgm'''. -: You only need '''-titles''' "Titleset One title" "Titleset Two title" -: . . . , and not '''-files'''. -: Any other options can be used, but the menu will be a textmenu style by -: default. '''Hint''': use '''-showcase''' IMAGE/VIDEO to create a fancier -: VMGM menu. -; '''-no-vmgm-menu''', '''-no-vmgm''' -: This will skip the creation of a VMGM ( root menu ) for titlesets. The DVD -: will start with the first titleset. You can not use this option unless also -: using '''-quick-nav''' as you would not have a way to get to other titlesets. -; '''-skip-vmgm''' -: Start DVD from the first titleset instead of the VMGM ( root ) menu. -; '''-switched-menus''', '''-switched-menu''' -: This will make a "switched menu": there will be a central image where the -: showcase image would go, and text menu titles along the menu edge where -: textmenu titles go. As you select a video title with the down or up arrow -: on your DVD remote, the image in the centre will change to the image or -: video made from that selected video. Do not use '''-showcase''' IMAGE/VIDEO -: with this option. -: -: This can be a time consuming process for making animated menus as you need -: to make a separate menu for each video provided with '''-files'''. The -: process can be greatly sped up by using '''-quick-menu''' in conjunction with -: this, though you will lose fancy options like '''-rotate''' and '''-wave'''. -: -: Note that if you want to just have a static rather than an 'animated' -: image, add '''-static''' to the command line. -: -: Example for using with '''-quick-menu''': -<pre> - -switched-menus -quick-menu -</pre> - - -=== Thumbnail style === - -; '''-titles-font''' FONT -: Display thumbnail or textmenu titles in the given font -; '''-titles-fontsize''' POINTS -: Font size to use for thumbnail or textmenu titles -; '''-thumb-shape''' -: normal|oval|vignette|plectrum|arch|spiral|blob|star|flare -: Apply a shaped transparency mask to thumbnail videos. -: These "feathered" shapes look best against a plain background (or used -: in conjunction with '''-thumb-mist''' [COLOR]). For this rectangular -: semi-transparent misted background for each thumb: see '''-thumb-mist'''. -: Note: if you wish to make your own mask PNGS you can put them in -: $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the -: command line using the filename minus the path and extension. -: (i.e ~/.tovid/masks/tux.png becomes -thumb-shape tux) -: No frame is used for shaped thumbs. -; '''-thumb-frame-size''' INT -: The size (thickness) of the thumb frames in pixels. This will also set the -: thickness of the raised "frame" of thumbs when you use '''-3d-thumbs'''. -: See also '''-showcase-frame-size''' and '''-thumb-frame-color''' -; '''-thumb-frame-color''', '''-thumb-frame-colour''' COLOR -: The color of frames for video thumbnails. Use hexadecimal or named colors -: notation. Remember to quote if using hexadecimal! ( '#ffac5f' ). -; '''-3d-thumbs''', '''-3dthumbs''' -: This will give an illusion of 3D to the thumbnails: dynamic lighting on -: rounded thumbs, and a raised effect on rectangular thumbs. Try it ! - -=== Slideshows === - -; '''-slides''' IMAGES -: Use '''-slides''' IMAGES to pass in images for a slideshow. The default is -: to make an animated menu of the slides, moving from one slide to the -: next. If you use '''-static''', a 'polaroid stack' montage is created. This -: composites the slides onto the background in 'random' locations with random -: rotations. '''-slides''' IMAGES can be used multiple times if you wish to -: make a menu with multiple slideshows. You can also make a menu -: of mixed videos and slideshows by using '''-slides''' IMAGES, and '''-files''' -: VIDEOS multiple times. For such a menu, the number of '''-titles''' -: needs to match the number of '''-files''' passed in plus the number of -: slideshows. (Each time you use '''-slides''' counts as one title.) To use -: a transition between the slides, use '''-slide-transition''' -: crossfade|fade. See '''-slide-transition''' '''-menu-slide-total''' -: -; '''-menu-slide-total''' INT -: Use INT number of the slides that were passed in with '''-slides''' -: to make the animated or static slide menu. The length of the menu is -: determined by 1) '''-menu-length''' NUM if given, and by 2) the length -: of the audio from '''-bgaudio'''. For submenu slideshows, it is determined -: by 1) '''-submenu-length''' NUM if given, and by 2) the length of the -: audio from '''-submenu-audio''' FILE(S). -: -; '''-submenu-slide-total''' INT -: This option is the same as '''-menu-slide-total''' except that it is -: for submenu slideshows. -: -; '''-slide-transition''' crossfade|fade [crossfade] -: The type of fade transition between slides in a animated slide menu. Be -: sure the menu length is long enough to support the 1 second transitions -: between the slides. The length is determined by 1) the length of the -: -bgaudio AUDIO 2) the length given with -menu-length NUM. For submenu -: slideshows, it is determined by 1) '''-submenu-length''' NUM if given, and -: by 2) the length of the audio from '''-submenu-audio''' FILE(S). -: -: See '''-menu-slide-total''' , '''-bgaudio''' , '''-menu-length''' , -: '''-submenu-length''', and '''-submenu-audio'''. -: -: The 'crossfade' transition fades from one slide to another. The 'fade' -: transition fades in and out from and to black. If you don't use this -: option, the default is to use a 'crossfade' transition. -: -; '''-slideshow-menu-thumbs''' FILES -: Use the FILES instead of the 1st image in each slideshow as the -: thumb that shows on the menu. This option is for multiple slideshows -: or mixed slideshow/video menus only. -: -; '''-slides-to-bin''' FILES -: FILES will be resized to 640x480 using a 'box' filter - this -: is called 'binning'. It will reduce the 'signal to noise' ratio for the -: image in the animated slide menu. Use this if you get some unwanted -: effects for certain images, such as pixels shifting in what should be a -: static image. See also '''-slides-to-blur''' and '''-slide-border''' -: -; '''-slides-to-blur''' FILES -: FILES will be blurred a small amount - which will help on -: slides that still have noise even after 'binning' with -slides-to-bin. -: The default blur is 0x0.2 - you can increase this with -: -slide-blur ARG. See also '''-slides-to-bin''' and '''-slide-border''' -: -; '''-slide-blur''' VALUE or LIST of VALUES [0x0.2] -: The argument to use for blurring files. It will be passed to -: imagemagick: convert -blur ARG. The format of the arg is {radius}x{sigma} -: and the default is 0x0.2. Using values between 0x0.1 and 0x0.9 is probably -: the best range. Use a single value for all, or a list to have a different -: blur for each file passed with '''-slides-to-blur'''. You must pass in -: '''-files-to-blur''' FILES to use this option. Blurring can help 'noise' -: problems in the video. See also '''-slides-to-bin''' and '''-slide-border''' -: -; '''-slide-border''' WIDTH [100] -: Pad the slides with a border for the animated slide menu. The default -: without using an argument is 100. Using this option can also solve some -: noise/ringing effects if used alone or in conjunction with 'binning' -: ('''-slides-to-bin''') or blurring ('''-slides-to-blur'''). -: -; '''-slide-frame''' WIDTH [12] -: Frame the slides for the animated slideshow menu. The default width -: without using an argument is 12. See also '''-slide-frame-color''' -: -; '''-slide-frame-color''', '''-slide-frame-colour''' -: The color of the slide frame if passing '''-slide-frame'''. The default if -: you don't use this option is a color-safe white: rgb(235,235,235). -: -; '''-showcase-slideshow''' -: If doing multiple slideshows or mixed videos and slideshow(s), then use -: the animated slideshow as a showcase video. It will be composed of slides -: from each slideshow in the menu. The thumb for each slideshow button will -: be static. If you used with a mixed menu of videos and slideshows, then -: the video thumbs WILL be animated, so you may wish to use -static or -: -textmenu with the option in that case. If you want to use the -: **-switched-menus option with a mixed menu leave this option out. -: -; '''-background-slideshow''', '''-bg-slideshow''' -: If doing multiple slideshows or mixed videos and slideshow(s), then use -: the animated slideshow as a background video. See '''-showcase-slideshow''' -: for additional details. -: -; '''-no-confirm-backup''' -: Slideshows are an experimental (but well tested) feature. Todisc is -: unlikely to overwrite your personal files, but you should take precautions -: and backup your images, as you would with any beta software. Todisc -: will prompt you to backup your files normally. If you have already backed -: up your images, use this option to disable the prompt. -: See '''General Options''' -: -; '''-use-dvd-slideshow''' [FILE CONFIG] -: If you pass this option without an argument, tovid will use the -: dvd-slideshow program to create the animated slide menu, assuming you have -: this program installed. The optional argument is the dvd-slideshow -: configuration file - if you don't use this argument tovid will create it -: for you. If you want to use the 'Ken Burns effect' - then the -: configuration file argument is required. Note: the configuration file will -: override many of the above options for slideshows. - -=== Burning the disc === - -; '''-burn''' -: Prompt to burn the DVD directory on completion. -: -; '''-device''' -: Device to use for the burning program [ /dev/dvdrw ] -: -; '''-speed''' -: The speed to use for burning the disc. - -=== Advanced usage === - -==== Options ==== - -; '''-menu-length''' -: The desired animated main menu length in seconds -; '''-submenu-length''' -: The desired submenu length. This will also affect the length of submenu -: audio for static submenus. (Assuming that -submenu-audio was passed in). -: The default is to use 10 seconds of audio for static menus. -; '''-submenu-stroke''' COLOR -: The color for the sub-menu font shadow -; '''-submenu-title-color''', '''-submenu-title-colour''' -: The fill color used for sub-menu title fonts -; '''-submenu-titles''' -: You can supply a list of titles here for sub-menus without the length -: restrictions found in thumb titles. Must equal number of videos -; '''-chapters''' [ NUM | CHAPTER POINTS in HH:MM:SS ] -: The number of chapters for each video (default: 6) OR -: the actual chapter points in HH:MM:SS format. -: Chapter points will be used for generating the submenu thumbs, and for -: seeking with your DVD player. You can pass in just one value that will -: be used for all videos, or supply a list of values (number of chapters) -: or time code strings. -: -: If you just pass an integer for 'number of chapters', then tovid will -: make the chapter points for you by dividing the video length by the number -: you supply. If using the '''-no-menu''' option, the INT passed in will be -: the chapter interval in minutes, rather than the above formula. -: -: If passing HH:MM:SS format you need to pass the string of chapter points for -: each video and each string should have comma separated values. -: Additionally, the first chapter should always start at 00:00:00 as -: dvdauthor will add that if it is not there already. -: -: To get your time codes, you can play your videos in mplayer and press 'o' -: to see them on-screen. I have found these to be very accurate in my short -: tests. For greater frame accuracy you could try loading the file in -: avidemux and find the time codes for the frames you want. -: -: If passing grouped chapters you need to join the chapters from all the -: videos in a group with a '+' separator. If you want to skip creating -: chapters for a video in the group use '0' for its chapters. -: -: Note: chapters for grouped videos should probably be passed in using the -: above HH:MM:SS format. (Arbitrary chapters using just an INT for the # of -: chapters is not guaranteed to work reliably in all cases for grouped videos -: at the moment.) -: -: Example for passing just number of chapters ( 4 videos ): -<pre> - -chapters 5 2 4 8 -</pre> - -: -: Example of passing chapter points ( 4 videos ): -<pre> - -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \ - 00:00:00,00:04:25.623,00:09:12,00:15:51 \ - 00:00:00,00:05:10,00:13:41,00:18:13.033 \ - 00:00:00,00:15:23.342,00:26:42.523 -</pre> - -: -: Example of passing grouped chapters using the '+' separator: -<pre> - -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \ - 00:00:00... etc. -</pre> - -: -; '''-chapter-titles''' LIST -: If you are using submenus, you can pass a list of titles for the -: chapters. Each title must be quoted, and the number of titles given -: must equal the total number of chapters for all videos. In other words -: if you use -chapters 4 6 8 , you must give 18 chapter titles, in the same -: order that the videos were passed in. Note: if you are passing in options -: on the command line to the 'tovid disc' GUI, you must repeat the option -: '''-chapter-titles''' for each video, accompanied by its respective chapter -: titles. (you can also choose to use this syntax for the todisc script.) -: -; '''-chapter-font''' FONT -: Use FONT as the font for submenu chapters. -: -; '''-chapter-fontsize''' SIZE -: Use SIZE as the pointsize for the chapters font. -; '''-chapter-color''' COLOR -: The color for the chapters font. -; '''-chapter-stroke''' COLOR -: The color for the chapters font shadow -: -; '''-seek''' NUM | "NUM1 NUM2 NUM3 . . ." -: Seek to NUM seconds before generating thumbnails (default: 2.0 seconds) -: If a quoted string of values matching the number of videos is used, then -: each video can use a different seek value -: If using switched menus, the '''-seek''' value(s) will be used to generate -: the showcase image that displays on switching to another video choice with -: the up/down arrow keys. -; '''-fast-seek''' -: Use faster seek method for ffmpeg. This is not as accurate as the default -: method, and may produce grey frames. -; '''-frame-safe''' Instead of seeking and then outputting one frame for -: previews and static menus, output 9 frames and choose the largest. Not -: frame accurate (may be as much as 9 frames off), but safer. Choose this -: if you are getting grey frames/thumbnails with some videos. You can also -: use it to try to get the 'best' frame. This option -: has no effect on submenus at present. -; '''-showcase-seek''' NUM -: Seek to NUM seconds before generating thumbnails for showcase video -: (default: 2.0 seconds) -; '''-bgvideo-seek''', '''-bg-video-seek''' NUM -: Seek to NUM seconds before generating images for background video -: (default: 2.0 seconds) -; '''-bgaudio-seek''', **-bg-audio-seek NUM -: Seek to NUM seconds before generating audio for bgaudio -: (default: 2.0 seconds) -; '''-group''' N VIDEO1 VIDEO2 . . . -: Allow grouping videos in dvdauthor.xml, so they will play sequentially as -: a group. The videos passed in after the 'N' will be grouped with the 'Nth' -: video. Example: -: -<pre> - -group 2 2.mpg 3.mpg 4.mpg -</pre> - -: -: will group these 3 videos with the 2nd video given with '''-files''', so that -: they will play sequentially as one title. Only one thumbnail and/or title -: will appear on the menu for the group: it will be made from the 1st video -: in the group. In the above example if you passed: -<pre> - -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg -</pre> - -: then the group will consist of bar.mpg 2.mpg, 3.mpg and 4.mpg, and only the -: title and/or thumbnail for bar.mpg will appear in the menu. You can use -: '''-group''' more than once for multiple groups. Be sure to quote video -: filenames if they contain spaces. - -=== Menu Style === - -; '''-menu-title-geo''' north|south|east|west|center [south] -: The position of the menu title. You may need to use -align as well if -: you don't want your title covering other parts of your menu. See -: '''-align''' -; '''-menu-title-offset''' OFFSET (+X+Y) -: Move menu title by this offset from its N|S|E|W|Center position. You -: may need to use -align as well if you don't want your title covering other -: parts of your menu. See '''-align''' -; '''-button-style''' line|rect|text|text-rect [line] -: The style of button that you will see when you play the DVD. -: "line" style underlines the title, "rect" draws a rectangle around the -: thumb when you select it in the DVD player, "text" highlights the video -: title text, and "text-rect" draws a rectangle around the title -: text. -; '''-title-color''', '''-title-colour''' COLOR -: Color to use for the main menu title. For list of supported colors do: -: '''convert -list''' color. HTML notation may be used: "#ff0000". See: -: [http://www.imagemagick.org/script/color.php] -; '''-title-stroke''' COLOR -: Shadow color for the main menu's title font. Use "none" for transparent -: outline (see title-color). Note: this is not a -stroke in the sense that -: imagemagick uses the term, but a shadow (the font is drawn twice). To get -: a true imagemagick stroke see '''-title-font-deco''' -; '''-title-font-deco''', '''-title-fontdeco''' "IMAGEMAGICK STRING" -: Sets the font decoration method to FONTDECORATION. It is used by the 'convert' -: ImageMagick command to draw the menu text. You can add colored text -: outlines, gradient fills, and many others. See '''Usage notes''' -; '''-titles-stroke''' COLOR -: Shadow color for the thumb or textmenu video titles font. Use "none" for -: transparent outline (see '''-titles-color'''). Note: this is not a -stroke -: in the sense that imagemagick uses the term, but a shadow -: (the font is drawn twice). To get a true imagemagick stroke, -: see '''-titles-font-deco''' -; '''-titles-font-deco''', '''-titles-fontdeco''' "IMAGEMAGICK STRING" -: Sets the font decoration method to FONTDECORATION. It is used by the 'convert' -: ImageMagick command to draw the menu text. You can add colored text -: outlines, gradient fills, and others. See '''Usage notes''' for more info. -; '''-highlight-color''', '''-highlight-colour''' -: Color to use for the menu buttons that your DVD remote uses to navigate. -; '''-select-color''', '''-select-colour''' -: Color to use for the menu buttons that your DVD remote uses to select. -; '''-text-mist''' -: Put a semi-transparent misted background behind the text for the menu's -: title, just slightly larger than the text area. -; '''-text-mist-color''', '''-text-mist-colour''' COLOR -: Color of the mist behind the menu's title (see title-color). -; '''-text-mist-opacity''' -: Opacity of the mist behind the menu's title - see '''-opacity''' -; '''-title-opacity''' -: Opacity of the menu title text -; '''-titles-opacity''' -: Opacity of the text for video titles -; '''-submenu-title-opacity''' -: Opacity of the text for submenu menu titles -; '''-chapter-title-opacity''' -: Opacity of the text for submenu chapter titles -; '''-menu-audio-fade''' -: Number of sec to fade given menu audio in and out (default: 1.0 seconds) -: If you use '''-menu-audio-fade''' 0 then the audio will not be faded. -; '''-submenu-audio-fade''' -: Number of secs to fade sub-menu audio in and out (default: 1.0 seconds). -: See '''-menu-audio-fade''' -; '''-intro''' VIDEO -: Use a introductory video that will play before the main menu. -: At present it must be a DVD compatible video at the correct resolution etc. -: Only 4:3 aspect is supported: 16:9 will give unexpected results. - -==== Style options specific to showcase/textmenu arrangements ==== - -; '''-text-start''' N -: This option is for '''-textmenu''' menus. The titles will start at the Nth -: pixel from the top of the menu ( Y axis ). -; '''-title-gap''' N -: This option is for '''-textmenu''' menus. The gap is the space between -: titles vertically ( Y axis ). -; '''-rotate''' DEGREES -: Rotate the showcase image|video clockwise by DEGREES. -: (default: if used without options, the rotate will be 5 degrees). Note: -: this will not turn a portait image into a landscape image! -; '''-showcase-geo''' GEOMETRY -: The position of the showcase image. ( +X+Y position ) -: For example: '''-showcase-geo''' +300+200 -; '''-wave''' default|GEOMETRY -: Wave effect for showcase image|video. Alters thumbs along a sine wave using -: GEOMETRY. (default: no wave) -: "default" will produce a wave arg of -20x556, which -: produces a gentle wave with a small amount of distortion. -: See: [http://www.imagemagick.org/Usage/distorts/#wave] if you want -: to try other values. -; '''-showcase-shape''' egg|oval|plectrum|arch|spiral|galaxy|flat-tube|normal -: Apply a shaped transparency mask to showcase videos or images. -: Note: if you wish to make your own mask PNGS you can put them in -: $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the -: command line using the filename minus the path and extension. -: No frame is used for shaped thumbs. -; '''-showcase-framestyle''' none|glass -: For -showcase-* style template only -: "none" will use the default frame method, using "convert -frame . . ." -: "glass" will use mplayer to make frames, which gives an interesting -: animated effect to the frames, and can be much faster ( especially if you -: don't use '''-rotate''' or '''-wave''' as thumbs will not need to be processed -: again after mplayer spits them out. Note: you need to be using either -: '''-showcase''' IMAGE or '''-showcase''' VIDEO for this "frame style" to work. -; '''-showcase-frame-size''' PIXELS -: The size of the showcase frame. This value will be used for both width and -: height for the 'thickness' of the frame. This will also set the thickness -: of the raised "frame" of the showcase thumb when you use '''-3d-showcase'''. -: See also '''-thumb-frame-size''' and '''-showcase-frame-color''' -; '''-showcase-frame-color''', '''-showcase-frame-colour''' PIXELS -: The color of the showcase frame. Use hexadecimal or named colors notation. -: Remember to quote! ( '#ffac5f' ). -; '''-3d-showcase''', '''-3dshowcase''' -: This will give an illusion of 3D to the showcase thumb: dynamic lighting on -: rounded thumbs, and a raised effect on rectangular thumbs. Try it ! - -=== Thumbnail Style === - -; '''-user-thumbs''' IMAGE(S) -: Supply your own images for menu buttons, rather than relying on todisc to -: generate them from the video. They must be the same aspect ratio as the -: videos in the titleset (4:3 or 16:9), as todisc will resize them without -: checking and cropping. There must be on image for each thumb that will be -: displayed on the menu (ie. one thumb for each video in a titleset). -; '''-opacity''' [0-100] (default 100) -: Opacity of thumbnail videos as a percentage (no percent sign). -: Anything less than 100(%) is semi-transparent. Not recommended with dark -: backgrounds. -; '''-thumb-blur''', '''-blur''' NUM -: The amount of feather blur to apply to the thumb-shape. The default is 1.0 -: which will more or less keep the shape and produces transparency at the -: edges. Choose float or integer values between 0.1 and 2.0. 3D thumbs are -: set to a tiny blur, so this option doesn't affect the '''-3dthumbs''' option. -; '''-showcase-blur''' NUM -: The amount of 'feather' blur to apply to the showcase image/video. Choose -: values between 0.1 and 2.0. This option has no effect on '''-3d-showcase'''. -: See '''-thumb-blur''' for more info. -; '''-align''' DIRECTION -: This will align thumbs/titles in DIRECTION, which is a compass direction -: as used by imagemagick: ie. north|south|east|west|northeast|northwest etc. -: If '''-align''' south then menu title will align north, unless you manually -: set one or both of '''-menu-title-geo''' or '''-menu-title-offset'''. -: Only '''-align''' north|south|center has any effect on showcase with thumb, -: or with the default montage arrangement of central thumbs. The most -: apparent changes with be with textmenu, though with 2 column arrangements -: only the north* and south* changes will show an effect. -: -: Diagram: -; . northwest north northeast . -; . . -; . west center east . -; . . -; . southwest south souteast . -; '''-thumb-mist''' [COLOR] -: Use a mist behind thumbnails. The optional argument is the color of the -: mist. This option helps with contrast. Be sure to set the font color -: to an appropriate color if using a colored mist, and/or use a bold font. -; '''-titles-color''', '''-titles-colour''' COLOR -: Color to use for the thumb or textmenu titles. If your titles are not -: clear enough or look washed out, try using a '''-titles-stroke''' that -: is the same color as used with '''-titles-color''' (see '''-title-color''') -; '''-showcase-titles-align''' west|east (default: center [centre]) -: The default is to center the text above the thumbnails. This option will -: align the titles either to the left (west) or right (east). Aligning west -: gives more space to the titles. Aligning east also does so, and as well -: will facilitate using \n in your titles to achieve multi line titles. -; '''-tile-3x1''', '''-tile3x1''' -: Use a montage tile of 3x1 instead of the usual 2x2 for 3 videos -: ie. -: -: [movie1] [movie2] [movie3] instead of: -: -: [movie1] [movie2] -: -: [movie3] -: -: This option only comes into play if the number of videos supplied equals 3 -: Otherwise it will be silently ignored. Not used for -showcase-* style. -; '''-tile-4x1''', '''-tile4x1''' -: Same as '''-tile-3x1''' above, except use tile of 4x1. (one row of 4 videos) -; **-thumb-columns 3|4 -: Same as '''-tile-3x1''' and tile-4x1** above, except it accepts either '3' -: (1 row of 3 thumbs), or '4' (one row of 4 thumbs) as an argument. This -: alternative was added to help compact the gui layout. -; '''-rotate-thumbs''' DEGREE LIST ( list of degrees, one for each thumb ) -: Rotate thumbs the given amount in degrees - can be positive or negative. -: There must be one value for each file given with '''-files'''. -: If the values are not the same distance from zero, the thumbs will be of -: different sizes as images are necessarily resized *after* rotating. With -: the default montage template - this will also resize the titles; with the -: showcase template the titles will remain the same size. Example: -: -<pre> - -rotate-thumbs -10 10 -10 10 -10 (for 5 files) -</pre> - -: **Note: this option will not turn a portrait image into a landscape image! - -=== Dvdauthor options === - -; '''-loop''' PAUSE -: Pause in seconds at end of menu. Use "inf" if you wish indefinite pause. -: Note: using "inf" with '''-menu-fade''' will disable the fadeout portion of -: the fade. (default: "inf" for static menu, 10.0 seconds for animated.) -; '''-playall''' -: This option will create a button on the main menu that will allow going -: right to the 1st title and playing all videos in succession before -: returning to the main menu. If doing titlesets you can use this within -: the '''-vmgm''' ... '''-end-vmgm''' options to allow playing ALL titlesets. -: (If you want also to have a playall button in each titleset you could use -: this option between each '''-titleset''' ... '''-end-titleset''' option or put -: it outside of the vmgm and titlset options as a global option. -; '''-videos-are-chapters''' -: A button will be made on the main menu for each video, which you can use as -: a chapter button. Selecting any video will play them all in order -: starting with the selected one. -; '''-chain-videos''' NUM | N1-NN -: Without options this will chain all videos together so they play -: sequentially without returning to the main menu, except for the last, which -: will return. You can also specify which videos you want to behave this way -: by number or by a range. ( ie. '''-chain-videos''' 1 2 4-6 ). -; '''-subtitle-lang''' "lang1 lang2 . . ." -: This allows selectable subtitles in the DVD, assuming you have optional -: subtitles muxed into your videos. Use 2 character language codes. -; '''-audio-channel''' "Video1_track Video2_track Video3_track . . ." -: "VideoN_track" is the track number to use in a multi-track (multi-language) -: mpeg: usually something like '''-audio-channel''' "1 0 1". The 1st track is -: 0, 2nd is 1 . . . etc. If the tracks are 0. English 1.French, then the -: above would make French the audio language on Video1 and Video3, and -: English the audio language on Video2. You can check the mpeg with -: "mplayer -v . . .". -; '''-audio-lang''' LANGUAGE CODES -: Identify the audio tracks on the DVD. These language codes are used for -: each video in the titleset. When you use the audio button on your DVD -: remote the language name is displayed. Example: '''-audio-lang''' en fr -; '''-aspect''' 4:3|16:9 -: This will output a <video aspect WIDTH:HEIGHT /> tag for the dvdauthor -: xml file. It will affect all videos in the titleset. Example: -: -<pre> - -aspect 16:9 -</pre> - -; '''-widescreen''' nopanscan|noletterbox [nopanscan] -: This will output a <video widescreen=nopanscan /> tag (for example) -: for the dvdauthor xml file. It will affect all videos in the titleset. Use -: in conjunction with '''-aspect''' if your dvd player is cropping your videos. -: Example: -: -<pre> - -aspect 16:9 -widescreen -</pre> - -; '''-quick-nav''' -: This option will allow navigation of a menu with more than one titleset by -: using the left and right arrow keys of your DVD remote. When you press -: this key the highlight will go the next or previous title. If you are at -: the end of a titleset the right key will go to the next titleset. If you -: are at the beginning of a titleset, the left key will go to the previous -: titleset. If no next or previous titleset it will cycle to the end or -: beginning of the titlesets. -; '''-outlinewidth''', '''-outline-width''' WIDTH -: For spumux outlinewidth variable. If there is a large gap between words in -: a text button, this option may help. -; '''-video-pause''' PAUSE (single value or list) -: The pause in seconds after playing a video title. This is useful for -: slideshows: the 'slide' will remain on the screen for this length of time. -: If you have grouped videos you should probably not pause the videos that -: have a grouped title after it, but instead see '''-grouped-video-pause'''. -: Note: if you provide a list of values they must be one for each video. -; '''-group-video-pause''' PAUSE (single value or list) -: The pause in seconds after a grouped video plays. If you wish to pause -: after the whole group finishes, then only use a value greater than zero -: for the last video in the group. If providing a list of values they must -: equal the number of grouped videos. - -=== Usage notes === - -The argument given to various *-font options that set the font to use must be -one of the fonts listed by the command 'convert -list type'. Please note that -many of your installed fonts may not be available; if you want to maximize the -number of fonts available to todisc, download and run -[http://www.cit.gu.edu.au/~anthony/anthony.html Anthony Thyssen's] -[http://www.imagemagick.org/Usage/scripts/imagick_type_gen imagick_type_gen] -script and run it like this: -imagick_type_gen > ~/.magick/type.xml. -If that doesn't work, try imagick_type_gen > ~/.magick/type.mgk. - -Or you can specify a ttf font file directly to the *-font options if you don't -want to install fonts to ImageMagick. - -The *-stroke options in todisc are not a stroke in the sense that ImageMagick -uses the term, but rather a font shadow (the text is drawn twice) To get a -truer Imagemagick -stroke try something like: --title-font-deco "-stroke black" (or -titles-font-deco "-stroke black"). The -'''-fontdeco''' option is quite flexible and takes a lot of ImageMagick's -''convert'' options. Please refer to the tovid -[http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus wiki] and Anthony -Thyssen's guide [[http://www.imagemagick.org/Usage]] for further explanation and examples. - -== Command:mpg == - -'''tovid mpg''' converts arbitrary video files into (S)VCD/DVD-compliant -MPEG format, suitable for burning to CD/DVD-R for playback on a -standalone DVD player. - -=== Usage === - -'''tovid mpg''' [''OPTIONS''] '''-in''' ''INFILE'' '''-out''' ''OUTPREFIX'' - -Where ''INFILE'' is any multimedia video file, and ''OUTPREFIX'' is what -you want to call the output file, minus the file extension. ''OPTIONS'' -are additional customizations, described below. - -By default, you will (hopefully) end up with an NTSC DVD-compliant -MPEG-2 video file; if you burn this file to a DVD-R, it should be -playable on most DVD players. - -For example: - -; <tt>tovid mpg -in foo.avi -out foo_encoded</tt> -: Convert 'foo.avi' to NTSC DVD format, saving to 'foo_encoded.mpg'. -: -; <tt>tovid mpg -pal -vcd foo.avi -out foo_encoded</tt> -: Convert 'foo.avi' to PAL VCD format, saving to 'foo_encoded.mpg'. - -=== Basic options === - -; '''-v''', '''-version''' -: Print tovid version number only, then exit. -; '''-quiet''' -: Reduce output to the console. -; '''-fake''' -: Do not actually encode; only print the commands (mplayer, mpeg2enc etc.) -: that would be executed. Useful in debugging; have tovid give you the -: commands, and run them manually. -; '''-ffmpeg''' -: Use ffmpeg for video encoding, instead of mplayer/mpeg2enc. Try this if -: you have any problems with the default encoding method. Using this option, -: encoding will be considerably faster. It can do almost everything that -: mpeg2enc does such as -filters and -subtitles by using a pipe from mplayer -: though using these options will make encoding somewhat slower. The -: exceptions are some special options like -kvcd* -bdvd where you will still -: need to use the default mpeg2enc option. - -==== Television standards ==== - -; '''-ntsc''' -: NTSC format video (USA, Americas) (default) -; '''-ntscfilm''' -: NTSC-film format video -; '''-pal''' -: PAL format video (Europe and others) - -==== Formats ==== - -Standard formats, should be playable in most DVD players: - -; '''-dvd''' -: (720x480 NTSC, 720x576 PAL) DVD-compatible output (default) -; '''-half-dvd''' -: (352x480 NTSC, 352x576 PAL) Half-D1-compatible output -; '''-svcd''' -: (480x480 NTSC, 480x576 PAL) Super VideoCD-compatible output -; '''-dvd-vcd''' -: (352x240 NTSC, 352x288 PAL) VCD-on-DVD output -; '''-vcd''' -: (352x240 NTSC, 352x288 PAL) VideoCD-compatible output - -Non-standard formats, playable in some DVD players: - -; '''-kvcd''' -: (352x240 NTSC, 352x288 PAL) KVCD-enhanced long-playing video CD -; '''-kdvd''' -: (720x480 NTSC, 720x576 PAL) KVCD-enhanced long-playing DVD -; '''-kvcdx3''' -: (528x480 NTSC, 520x576 PAL) KVCDx3 specification -; '''-kvcdx3a''' -: (544x480 NTSC, 544x576 PAL) KVCDx3a specification (slightly wider) -; '''-bdvd''' -: (720x480 NTSC, 720x576 PAL) BVCD-enhanced long-playing DVD - -See [http://kvcd.net/ kvcd.net] for details on the KVCD specification. Please -note that KVCD ("K Video Compression Dynamics") is the name of a compression -scheme that can be applied to any MPEG-1 or MPEG-2 video, and has little to -do with VCD ("Video Compact Disc"), which is the name of a standard video disc -format. - -=== Advanced options === - -==== Aspect ratios ==== - -tovid automatically determines aspect ratio of the input video by playing it in -mplayer. If your video plays with correct aspect in mplayer, you should not -need to override the default tovid behavior. - -If mplayer does not play your video with correct aspect, you may provide an -explicit aspect ratio in one of several ways: - -; '''-full''' -: Same as '''-aspect 4:3''' -; '''-wide''' -: Same as '''-aspect 16:9''' -; '''-panavision''' -: Same as '''-aspect 235:100''' -; '''-aspect''' ''WIDTH''''':'''''HEIGHT'' -: Custom aspect, where ''WIDTH'' and ''HEIGHT'' are integers. - -The above are the intended INPUT aspect ratio. tovid chooses an optimal output -aspect ratio for the selected disc format (VCD, DVD, etc.) and does the -appropriate letterboxing or anamorphic scaling. Use '''-widetv''' to encode -for a widescreen monitor or TV. - -==== Video stream options ==== - -; '''-quality''' ''NUM'' (default 6) -: Desired output quality, on a scale of 1 to 10, with 10 giving the best -: quality at the expense of a larger output file. Default is 6. Output size -: can vary by approximately a factor of 4 (that is, '''-quality 1''' output -: can be 1/4 the size of '''-quality 10''' output). Your results may vary. -: WARNING: With '''-quality 10''', the output bitrate may be too high for -: your hardware DVD player to handle. Stick with 9 or lower unless you -: have phenomenally good eyesight. -: -: At present, this option affects both output bitrate and quantization (but -: may, in the future, affect other quality/size-related attributes). Use -: '''-vbitrate''' if you want to explicitly provide a maximum bitrate. -: -; '''-vbitrate''' ''NUM'' -: Maximum bitrate to use for video (in kbits/sec). Must be within allowable -: limits for the given format. Overrides default values. Ignored for VCD, -: which must be constant bitrate. -: -; '''-interlaced''' -: Do interlaced encoding of the input video (top fields first). Use this -: option if your video is interlaced, and you want to preserve as much -: picture quality as possible. This option is ignored for VCD, which -: doesn't support it. -: -: You can tell your source video is interlaced by playing it, and pausing -: during a scene with horizontal motion; if you see a "comb" effect at the -: edges of objects in the scene, you have interlaced video. Use this option -: to encode it properly. -: -: If you would prefer to have output in progressive format, use -: '''-progressive'''. If you have a DV camera, use '''-interlaced_bf''' since -: DV footage is generally bottom fields first. -: -; '''-interlaced_bf''' -: Do interlaced encoding of the input video (bottom fields first). -: -; '''-deinterlace''', '''-progressive''' -: Convert interlaced source video into progressive output video. Because -: deinterlacing works by averaging fields together, some picture quality is -: invariably lost. Uses an adaptive kernel deinterlacer (kerndeint), or, -: if that's not available, the libavcodec deinterlacer (lavcdeint). -: -; '''-mkvsub''' ''LANG'' (EXPERIMENTAL) -: Attempt to encode an integrated subtitle stream (such as may be found in -: Matroska .mkv files) in the given language code (eng, jpn, etc.) May work -: for other formats. -: -; '''-autosubs''' -: Automatically include subtitle files with the same name as the input video. -: -; '''-subtitles''' ''FILE'' -: Get subtitles from ''FILE'' and encode them into the video. WARNING: This -: hard-codes the subtitles into the video, and you cannot turn them off while -: viewing the video. By default, no subtitles are loaded. If your video is -: already compliant with the chosen output format, it will be re-encoded to -: include the subtitles. This works with both -ffmpeg and the default, -: mpeg2enc. -: -; '''-dvd-subtitles''', '''-dvdsubs''' | ''FILE'' -: Get subtitles from ''FILE(S)'' and add them '''as a subtitle stream''' into the -: video. This allows selectable subtitles on your DVD. You can use more than -: one file for multiple languages. Be sure to use the -subtitle-lang option -: in 'tovid disc' so the name of the language will show up on the DVD instead -: of 'UNKNOWN' or similar -: -; '''-dvdsubs-only''' -: Use this if you have an already complient MPEG and wish to add a subtitle -: stream without re-encoding, using '''-dvdsubs''' , -: -; '''-dvdsubs-fontsize''' ''NUM'' [18] -: The pointsize in pixels for DVD selectable subtitles. To affect this for -: hard-coded subtitles ( '''-subtitles''' ) you will need to pass options to -: the player via '''-mplayeropts''' or '''-mpvopts'''. -: -; '''-type''' {live|animation|bw} -: Optimize video encoding for different kinds of video. Use 'live' (default) -: for live-action video, use 'animation' for cartoons or anime, and 'bw' for -: black-and-white video. This option currently only has an effect with -: KVCD/KSVCD output formats; other formats may support this in the future. -: -; '''-safe''' ''PERCENT'' -: Fit the video within a safe area defined by ''PERCENT''. For example, -: '''-safe 90%''' will scale the video to 90% of the width/height of the output -: resolution, and pad the edges with a black border. Use this if some of the -: picture is cut off when played on your TV. The percent sign is optional. -: -; '''-filters''' {none,denoise,deblock,contrast,all} (default none) -: Apply post-processing filters to enhance the video. If your input video is -: very high quality, use 'none'. If your input video is grainy, use 'denoise'; -: if it looks washed out or faded, use 'contrast'. You can use multiple -: filters separated by commas. To apply all filters, use 'all'. This works -: with both mpeg2enc and -ffmpeg. -: -; '''-fps''' ''RATIO'' -: Force input video to be interpreted as ''RATIO'' frames per second. May be -: necessary for some ASF, MOV, or other videos. ''RATIO'' should be an -: integer ratio such as "24000:1001" (23.976fps), "30000:1001" (29.97fps), or -: "25:1" (25fps). This option is temporary, and may disappear in future -: releases. (Hint: To convert a decimal like 23.976 to an integer ratio, just -: multiply by 1000, i.e. 23976:1000) -: -; '''-crop''' ''WIDTH'':''HEIGHT'':''X'':''Y'' -: Crop a portion of the video ''WIDTH'' by ''HEIGHT'' in size, with the -: top-left corner at ''X'', ''Y''. -: -; '''-widetv''' -: Always encode to 16:9 widescreen (only supported by '''-dvd''', '''-kdvd''', -: '''-bdvd'''), for optimal viewing on a widescreen monitor or TV. - -==== Audio stream options ==== - -; '''-normalize''' -: Analyze the audio stream and then normalize the volume of the audio. -: This is useful if the audio is too quiet or too loud, or you want to -: make volume consistent for a bunch of videos. Similar to running -: normalize without any parameters. The default is -12dB average level -: with 0dB gain. -: -; '''-amplitude''' ''NUM''[dB] -: In addition to analyzing and normalizing, apply the gain to the audio -: such that the 'average' (RMS) sound level is ''NUM''. Valid values -: range 0.0 - 1.0, with 0.0 being silent and 1.0 being full scale. Use -: ''NUM''dB for a decibel gain below full scale (the default without -: -amplitude is -12dB). -: -; '''-abitrate''' ''NUM'' -: Encode audio at ''NUM'' kilobits per second. Reasonable values include -: 128, 224, and 384. The default is 224 kbits/sec, good enough for most -: encodings. The value must be within the allowable range for the chosen disc -: format; Ignored for VCD, which must be 224. -: -; '''-audiotrack''' ''NUM'' -: Encode the given audio track, if the input video has multiple audio tracks. -: ''NUM'' is ''1'' for the first track, ''2'' for the second, etc. You may -: also provide a list of tracks, separated by spaces or commas, for example -: '''-audiotrack 3,1,2'''. Use '''tovid id''' on your source video to determine -: which audio tracks it contains. -: -; '''-downmix''' -: Encode all audio tracks as stereo. This can save space on your DVD if -: your player only does stereo. The default behavior of tovid is to use -: the original number of channels in each track. For aac audio, downmixing -: is not possible: tovid runs a quick 1 frame test to try to downmix the -: input track with the largest number of channels, and if it fails then it -: will revert to the default behavior of using the original channels. - -==== Other options ==== - -; '''-config''' ''FILE'' -: Read configuration from ''FILE'', containing 'tovid' alone on the first -: line, and free-formatted (whitespace-separated) tovid command-line options -: on remaining lines. -: -; '''-force''' -: Force encoding of already-compliant video or audio streams. -: -; '''-overwrite''' -: Overwrite any existing output files (with the same name as the given -: '''-out''' option). -: -; '''-priority''' {low|medium|high} -: Sets the main encoding process to the given priority. With high priority, -: it may take other programs longer to load and respond. With lower priority, -: other programs will be more responsive, but encoding may take 30-40% -: longer. The default is high priority. -: -; '''-discsize''' ''NUM'' -: When encoding, tovid automatically splits the output file into several -: pieces if it exceeds the size of the target media. This option sets the -: desired target DVD/CD-R size to ''NUM'' mebibytes (MiB, 2^20). By default, -: splitting occurs at 700 for CD, 4300 for DVD. Use higher values at your -: own risk. Use 650 or lower if you plan to burn to smaller-capacity CDs. -: Doesn't work with the '''-ffmpeg''' option. -: -; '''-fit''' ''NUM'' -: Fit the output file into ''NUM'' MiB. Rather than using default (or -: specified) video bitrates, tovid will calculate the correct video bitrate -: that will limit the final output size to ''NUM'' MiB. This is different -: than '''-discsize''', which cuts the final file into ''NUM'' MiB pieces. -: '''-fit''' makes sure that the file never exceeds ''NUM'' MiB. This works -: with '''-ffmpeg''', but not with '''-vcd''' since VCDs have a standardized -: constant bitrate. -: -; '''-parallel''' -: Perform ripping, encoding, and multiplexing processes in parallel using -: named pipes. Maximizes CPU utilization and minimizes disk usage. Note that -: this option simply does more tasks simultaneously, in order to make better -: use of available CPU cycles; it's unrelated to multi-CPU processing (which -: is done automatically anyway). Has no effect when '''-ffmpeg''' is used. -: -; '''-update''' ''SECS'' -: Print status updates at intervals of ''SECS'' seconds. This affects how -: regularly the progress-meter is updated. The default is once every five -: seconds. -: -; '''-mpv''' -: Use mpv instead of mplayer. This option is experimental. -: -; '''-mplayeropts''' ''OPTIONS'' -: Append ''OPTIONS'' to the mplayer command run during video encoding. Use -: this if you want to add specific video filters (documented in the mplayer -: manual page). Overriding some options will cause encoding to fail, so use -: this with caution! -: -; '''-mpvopts''' ''OPTIONS'' -: Append ''OPTIONS'' to the mpv command run during video encoding. Use -: this if you want to add specific video filters (documented in the mplayer -: or mpv manual page). Overriding some options will cause encoding to fail, -: so use this with caution! -: -; '''-nofifo''' (EXPERIMENTAL) -: Do not use a FIFO pipe for video encoding. If you are getting "Broken pipe" -: errors with normal encoding, try this option. WARNING: This uses lots of -: disk space (about 2 GB per minute of video). -: -; '''-keepfiles''' -: Keep the intermediate files after encoding. Usually, this means the audio -: and video streams are kept (eg the .ac3 and .m2v files for an NTSC DVD). -: This doesn't work with -parallel because the intermediate files are named -: pipes, and not real files. -: -; '''-slice''' ''START''-''END'' -: Encode a segment from ''START'' to ''END'' (in seconds). Only works with -: -ffmpeg. -: -; '''-from-gui''' -: Put makempg into a fully non-interactive state, suitable for calling from -: a gui. -: -; '''-noask''' -: Don't ask questions when choices need to be made. Assume reasonable -: answers. - -== Command:id == - -'''tovid id''' identifies each multimedia video file in a -list, and reports its compliance with video disc standards such as VCD, -SVCD, and DVD. - -=== Usage === - -'''tovid id''' [''OPTIONS''] ''VIDEO_FILE(s)'' - -For example: - -; <tt>tovid id foo.avi</tt> -; <tt>tovid id -tabluar videos/*.mpg</tt> - -=== Options === - -; '''-terse''' -: Print raw video characteristics, no formatting. Helpful when -: calling from other scripts. -: -; '''-verbose''' -: Print extra information from mplayer, tcprobe, and ffmpeg. -: -; '''-accurate''' -: Do lengthy play-time estimation by scanning through the entire video file. -: Use this if the default behavior is giving you inaccurate play times. -: -; '''-fast''' -: Skip lengthy play-time estimation, and go with what mplayer reports -: as being the video duration. Unlike pre-0.32 versions of tovid, this -: is now the default behavior, and the '''-fast''' option doesn't do anything. -: -; '''-tabular''' -: Display output in a table format for easier comparison. Most useful -: when identifying multiple video files. -: -; '''-keepfiles''' -: Keep temporary directory for debugging. -: -; '''-isformat''' [''pal-dvd''|''ntsc-dvd''] (same syntax for vcd and svcd) -: Check ''VIDEO_FILE'' for compliance with the given disc format. -: If ''VIDEO_FILE'' matches the given format, then '''tovid id''' reports "true" -: and exits successfully. Otherwise, '''tovid id''' reports "false" and exits -: with status 1 (failure). This checks and reports both vcd/svcd/dvd -: and pal/ntsc. -: -; '''-mpv''' -: This option is mainly for testing. If you have only mpv installed instead -: of mplayer, it is used automatically. With this option, you can have BOTH -: installed and choose which one to use. (default: mplayer) - -=== Examples === - -; <tt>tovid id -verbose homevideo.avi</tt> -: Report everything mplayer, ffmpeg, and transcode can determine about -: homevideo.avi. -: -; <tt>tovid id -isformat dvd homevideo.mpg</tt> -: Check to see if homevideo.mpg is compliant with the DVD standard. - -== Command:dvd == - -'''tovid dvd''' takes a DVD directory as generated by tovid with 'tovid disc' or -one of the GUI frontends like 'tovid gui' or 'tovid titlesets' and burns -it to appropriate media. This will also work if the DVD directory is -generated by the dvdauthor backend that tovid also uses. - -Running this program may slow down your other applications, due to intense -disk activity. - -=== Usage === - -'''tovid dvd''' [''OPTIONS''] ''DVD_DIR'' - -For example: - -; <tt>tovid dvd /path/to/DVD/directory</tt> - -=== Options === - -; '''-burn''' -: Burn a DVD file-system in ''DVD_DIR'' (must contain a VIDEO_TS folder). -: This option is currently not necessary as the makedvd script ONLY burns -: now that legacy scripts like makexml have been removed. Left for -: compatibility only. -: -; '''-eject''' -: Eject the DVD tray after burning is complete. By default, the DVD is not -: ejected. -: -; '''-device''' ''DEVICE'' (default /dev/dvdrw) -: Burn the disc image to ''DEVICE'', the Linux device file-system -: name of your DVD-recorder. Common examples might be /dev/dvdrw, -: /dev/scd1, and /dev/hdc. You can also use a bus/id/lun triple -: such as ATAPI:0,1,0 -: -; '''-speed''' ''NUM'' (default 1) -: Burn disc at speed ''NUM''. -: -; '''-label''' ''DISC_LABEL'' -: Uses ''DISC_LABEL'' as the volume ID. This appears as the mount -: name of the disc on some computer platforms. Must be <=32 -: alphanumeric digits without spaces. -: -; '''-quiet''' -: Limit output to essential messages. -: -; '''-noask''' -: Don't ask interactive questions and assume answers that will continue -: execution. - - After burning, the DVD can be previewed by calling: - '''''xine''' dvd:/path/to/output/directory'' - or: - '''''vlc''' /path/to/output/directory'' - -== Command:chapters == - -'''tovid chapters''' will start a GUI using mplayer to set chapter points in a -video. If the video plays through and you want to add more chapters you can -press the play button again, but remember that new chapter points will be -appended (in correct sequential order). It will display the resulting chapter -points, and also output to a terminal (useful for scripts). As well it will -give the option of saving the chapters string to a text file. - -Note that the 'tovid gui' now features a similar widget when you press the -chapters button on the opening page. - -=== Examples === - -; <tt>tovid chapters foo.avi</tt> -: -; <tt>chapters=$(tovid chapters /home/grepper/videos/foo.avi)</tt> - -== CONTACT == - -For further assistance, contact information, forum and IRC links, -please refer to the [http://tovid.wikia.com/ tovid homepage]. - -<!-- wiki code generated by txt2tags 2.6 (http://txt2tags.org) --> -<!-- cmdline: txt2tags -t wiki -\-toc -\-toc-level 2 docs/src/en/tovid.t2t -->
View file
tovid-0.35.0.tar.gz/PKG-INFO -> tovid-0.35.2.tar.gz/PKG-INFO
Changed
@@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: tovid -Version: 0.35.0 +Version: 0.35.2 Summary: A suite of tools for making video DVDs Home-page: http://tovid.wikia.com/ Author: grepper
View file
tovid-0.35.2.tar.gz/docs/scripts
Added
+(directory)
View file
tovid-0.35.2.tar.gz/docs/scripts/txt2tags
Added
@@ -0,0 +1,5987 @@ +#!/usr/bin/env python +# txt2tags - generic text conversion tool ---> READY TO PYTHON 3! +# http://txt2tags.org +# +# Copyright 2001-2010 Aurelio Jargas +# +# License: http://www.gnu.org/licenses/gpl-2.0.txt +# Subversion: http://svn.txt2tags.org +# Bug tracker: http://bugs.txt2tags.org +# +######################################################################## +# +# BORING CODE EXPLANATION AHEAD +# +# Just read it if you wish to understand how the txt2tags code works. +# +######################################################################## +# +# The code that [1] parses the marked text is separated from the +# code that [2] insert the target tags. +# +# [1] made by: def convert() +# [2] made by: class BlockMaster +# +# The structures of the marked text are identified and its contents are +# extracted into a data holder (Python lists and dictionaries). +# +# When parsing the source file, the blocks (para, lists, quote, table) +# are opened with BlockMaster, right when found. Then its contents, +# which spans on several lines, are feeded into a special holder on the +# BlockMaster instance. Just when the block is closed, the target tags +# are inserted for the full block as a whole, in one pass. This way, we +# have a better control on blocks. Much better than the previous line by +# line approach. +# +# In other words, whenever inside a block, the parser *holds* the tag +# insertion process, waiting until the full block is read. That was +# needed primary to close paragraphs for the XHTML target, but +# proved to be a very good adding, improving many other processing. +# +# ------------------------------------------------------------------- +# +# These important classes are all documented: +# CommandLine, SourceDocument, ConfigMaster, ConfigLines. +# +# There is a RAW Config format and all kind of configuration is first +# converted to this format. Then a generic method parses it. +# +# These functions get information about the input file(s) and take +# care of the init processing: +# get_infiles_config(), process_source_file() and convert_this_files() +# +######################################################################## + +#XXX Python coding warning +# Avoid common mistakes: +# - do NOT use newlist=list instead newlist=list[:] +# - do NOT use newdic=dic instead newdic=dic.copy() +# - do NOT use dic[key] instead dic.get(key) +# - do NOT use del dic[key] without has_key() before + +#XXX Smart Image Align don't work if the image is a link +# Can't fix that because the image is expanded together with the +# link, at the linkbank filling moment. Only the image is passed +# to parse_images(), not the full line, so it is always 'middle'. + +#XXX Paragraph separation not valid inside Quote +# Quote will not have <p></p> inside, instead will close and open +# again the <blockquote>. This really sux in CSS, when defining a +# different background color. Still don't know how to fix it. + +#XXX TODO (maybe) +# New mark or macro which expands to an anchor full title. +# It is necessary to parse the full document in this order: +# DONE 1st scan: HEAD: get all settings, including %!includeconf +# DONE 2nd scan: BODY: expand includes & apply %!preproc +# 3rd scan: BODY: read titles and compose TOC info +# 4th scan: BODY: full parsing, expanding [#anchor] 1st +# Steps 2 and 3 can be made together, with no tag adding. +# Two complete body scans will be *slow*, don't know if it worths. +# One solution may be add the titles as postproc rules + + +############################################################################## + +# User config (1=ON, 0=OFF) + +USE_I18N = 1 # use gettext for i18ned messages? (default is 1) +COLOR_DEBUG = 1 # show debug messages in colors? (default is 1) +BG_LIGHT = 0 # your terminal background color is light (default is 0) +HTML_LOWER = 0 # use lowercased HTML tags instead upper? (default is 0) + +############################################################################## + + +# These are all the core Python modules used by txt2tags (KISS!) +import re, os, sys, time, getopt + +# The CSV module is new in Python version 2.3 +try: + import csv +except ImportError: + csv = None + +# Program information +my_url = 'http://txt2tags.org' +my_name = 'txt2tags' +my_email = 'verde@aurelio.net' +my_version = '2.6' + +# i18n - just use if available +if USE_I18N: + try: + import gettext + # If your locale dir is different, change it here + cat = gettext.Catalog('txt2tags',localedir='/usr/share/locale/') + _ = cat.gettext + except: + _ = lambda x:x +else: + _ = lambda x:x + +# FLAGS : the conversion related flags , may be used in %!options +# OPTIONS : the conversion related options, may be used in %!options +# ACTIONS : the other behavior modifiers, valid on command line only +# MACROS : the valid macros with their default values for formatting +# SETTINGS: global miscellaneous settings, valid on RC file only +# NO_TARGET: actions that don't require a target specification +# NO_MULTI_INPUT: actions that don't accept more than one input file +# CONFIG_KEYWORDS: the valid %!key:val keywords +# +# FLAGS and OPTIONS are configs that affect the converted document. +# They usually have also a --no-<option> to turn them OFF. +# +# ACTIONS are needed because when doing multiple input files, strange +# behavior would be found, as use command line interface for the +# first file and gui for the second. There is no --no-<action>. +# --version and --help inside %!options are also odd +# +TARGETS = sorted( 'html xhtml sgml dbk tex lout man mgp wiki gwiki doku pmw moin pm6 txt art adoc creole'.split() ) + +FLAGS = {'headers' :1 , 'enum-title' :0 , 'mask-email' :0 , + 'toc-only' :0 , 'toc' :0 , 'rc' :1 , + 'css-sugar' :0 , 'css-suggar' :0 , 'css-inside' :0 , + 'quiet' :0 , 'slides' :0 } +OPTIONS = {'target' :'', 'toc-level' :3 , 'style' :'', + 'infile' :'', 'outfile' :'', 'encoding' :'', + 'config-file':'', 'split' :0 , 'lang' :'', + 'width' :0 , 'height' :0 , 'art-chars' :'', + 'show-config-value':''} +ACTIONS = {'help' :0 , 'version' :0 , 'gui' :0 , + 'verbose' :0 , 'debug' :0 , 'dump-config':0 , + 'dump-source':0 , 'targets' :0} +MACROS = {'date' : '%Y%m%d', 'infile': '%f', + 'mtime': '%Y%m%d', 'outfile': '%f'} +SETTINGS = {} # for future use +NO_TARGET = ['help', 'version', 'gui', 'toc-only', 'dump-config', 'dump-source', 'targets'] +NO_MULTI_INPUT = ['gui','dump-config','dump-source'] +CONFIG_KEYWORDS = [ + 'target', 'encoding', 'style', 'options', 'preproc','postproc', + 'guicolors'] + +TARGET_NAMES = { + 'html' : _('HTML page'), + 'xhtml' : _('XHTML page'), + 'sgml' : _('SGML document'), + 'dbk' : _('DocBook document'), + 'tex' : _('LaTeX document'), + 'lout' : _('Lout document'), + 'man' : _('UNIX Manual page'), + 'mgp' : _('MagicPoint presentation'), + 'wiki' : _('Wikipedia page'), + 'gwiki' : _('Google Wiki page'), + 'doku' : _('DokuWiki page'), + 'pmw' : _('PmWiki page'), + 'moin' : _('MoinMoin page'), + 'pm6' : _('PageMaker document'), + 'txt' : _('Plain Text'), + 'art' : _('ASCII Art text'), + 'adoc' : _('AsciiDoc document'), + 'creole' : _('Creole 1.0 document') +} + +DEBUG = 0 # do not edit here, please use --debug +VERBOSE = 0 # do not edit here, please use -v, -vv or -vvv +QUIET = 0 # do not edit here, please use --quiet +GUI = 0 # do not edit here, please use --gui +AUTOTOC = 1 # do not edit here, please use --no-toc or %%toc + +DFT_TEXT_WIDTH = 72 # do not edit here, please use --width +DFT_SLIDE_WIDTH = 80 # do not edit here, please use --width +DFT_SLIDE_HEIGHT = 25 # do not edit here, please use --height + +# ASCII Art config +AA_KEYS = 'corner border side bar1 bar2 level2 level3 level4 level5'.split() +AA_VALUES = '+-|-==-^"' # do not edit here, please use --art-chars +AA = dict(zip(AA_KEYS, AA_VALUES)) +AA_COUNT = 0 +AA_TITLE = '' + +RC_RAW = [] +CMDLINE_RAW = [] +CONF = {} +BLOCK = None +TITLE = None +regex = {} +TAGS = {} +rules = {} + +# Gui globals +askopenfilename = None +showinfo = None +showwarning = None +showerror = None + +lang = 'english' +TARGET = '' + +STDIN = STDOUT = '-' +MODULEIN = MODULEOUT = '-module-' +ESCCHAR = '\x00' +SEPARATOR = '\x01' +LISTNAMES = {'-':'list', '+':'numlist', ':':'deflist'} +LINEBREAK = {'default':'\n', 'win':'\r\n', 'mac':'\r'} + +# Platform specific settings +LB = LINEBREAK.get(sys.platform[:3]) or LINEBREAK['default'] + +VERSIONSTR = _("%s version %s <%s>")%(my_name,my_version,my_url) + +USAGE = '\n'.join([ +'', +_("Usage: %s [OPTIONS] [infile.t2t ...]") % my_name, +'', +_(" --targets print a list of all the available targets and exit"), +_(" -t, --target=TYPE set target document type. currently supported:"), + ' %s,' % ', '.join(TARGETS[:9]), + ' %s' % ', '.join(TARGETS[9:]), +_(" -i, --infile=FILE set FILE as the input file name ('-' for STDIN)"), +_(" -o, --outfile=FILE set FILE as the output file name ('-' for STDOUT)"), +_(" --encoding=ENC set target file encoding (utf-8, iso-8859-1, etc)"), +_(" --toc add an automatic Table of Contents to the output"), +_(" --toc-level=N set maximum TOC level (depth) to N"), +_(" --toc-only print the Table of Contents and exit"), +_(" -n, --enum-title enumerate all titles as 1, 1.1, 1.1.1, etc"), +_(" --style=FILE use FILE as the document style (like HTML CSS)"), +_(" --css-sugar insert CSS-friendly tags for HTML/XHTML"), +_(" --css-inside insert CSS file contents inside HTML/XHTML headers"), +_(" -H, --no-headers suppress header and footer from the output"), +_(" --mask-email hide email from spam robots. x@y.z turns <x (a) y z>"), +_(" --slides format output as presentation slides (used by -t art)"), +_(" --width=N set the output's width to N columns (used by -t art)"), +_(" --height=N set the output's height to N rows (used by -t art)"), +_(" -C, --config-file=F read configuration from file F"), +_(" --gui invoke Graphical Tk Interface"), +_(" -q, --quiet quiet mode, suppress all output (except errors)"), +_(" -v, --verbose print informative messages during conversion"), +_(" -h, --help print this help information and exit"), +_(" -V, --version print program version and exit"), +_(" --dump-config print all the configuration found and exit"), +_(" --dump-source print the document source, with includes expanded"), +'', +_("Turn OFF options:"), +" --no-css-inside, --no-css-sugar, --no-dump-config, --no-dump-source,", +" --no-encoding, --no-enum-title, --no-headers, --no-infile,", +" --no-mask-email, --no-outfile, --no-quiet, --no-rc, --no-slides,", +" --no-style, --no-targets, --no-toc, --no-toc-only", +'', +_("Example:"), +" %s -t html --toc %s" % (my_name, _("file.t2t")), +'', +_("By default, converted output is saved to 'infile.<target>'."), +_("Use --outfile to force an output file name."), +_("If input file is '-', reads from STDIN."), +_("If output file is '-', dumps output to STDOUT."), +'', +my_url, +'' +]) + + +############################################################################## + + +# Here is all the target's templates +# You may edit them to fit your needs +# - the %(HEADERn)s strings represent the Header lines +# - the %(STYLE)s string is changed by --style contents +# - the %(ENCODING)s string is changed by --encoding contents +# - if any of the above is empty, the full line is removed +# - use %% to represent a literal % +# +HEADER_TEMPLATE = { + 'art':""" +Fake template to respect the general process. +""", + 'txt': """\ +%(HEADER1)s +%(HEADER2)s +%(HEADER3)s +""", + + 'sgml': """\ +<!doctype linuxdoc system> +<article> +<title>%(HEADER1)s +<author>%(HEADER2)s +<date>%(HEADER3)s +""", + + 'html': """\ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> +<META NAME="generator" CONTENT="http://txt2tags.org"> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=%(ENCODING)s"> +<LINK REL="stylesheet" TYPE="text/css" HREF="%(STYLE)s"> +<TITLE>%(HEADER1)s</TITLE> +</HEAD><BODY BGCOLOR="white" TEXT="black"> +<CENTER> +<H1>%(HEADER1)s</H1> +<FONT SIZE="4"><I>%(HEADER2)s</I></FONT><BR> +<FONT SIZE="4">%(HEADER3)s</FONT> +</CENTER> +""", + + 'htmlcss': """\ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> +<META NAME="generator" CONTENT="http://txt2tags.org"> +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=%(ENCODING)s"> +<LINK REL="stylesheet" TYPE="text/css" HREF="%(STYLE)s"> +<TITLE>%(HEADER1)s</TITLE> +</HEAD> +<BODY> + +<DIV CLASS="header" ID="header"> +<H1>%(HEADER1)s</H1> +<H2>%(HEADER2)s</H2> +<H3>%(HEADER3)s</H3> +</DIV> +""", + + 'xhtml': """\ +<?xml version="1.0" + encoding="%(ENCODING)s" +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>%(HEADER1)s</title> +<meta name="generator" content="http://txt2tags.org" /> +<link rel="stylesheet" type="text/css" href="%(STYLE)s" /> +</head> +<body bgcolor="white" text="black"> +<div align="center"> +<h1>%(HEADER1)s</h1> +<h2>%(HEADER2)s</h2> +<h3>%(HEADER3)s</h3> +</div> +""", + + 'xhtmlcss': """\ +<?xml version="1.0" + encoding="%(ENCODING)s" +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>%(HEADER1)s</title> +<meta name="generator" content="http://txt2tags.org" /> +<link rel="stylesheet" type="text/css" href="%(STYLE)s" /> +</head> +<body> + +<div class="header" id="header"> +<h1>%(HEADER1)s</h1> +<h2>%(HEADER2)s</h2> +<h3>%(HEADER3)s</h3> +</div> +""", + + 'dbk': """\ +<?xml version="1.0" + encoding="%(ENCODING)s" +?> +<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"\ + "docbook/dtd/xml/4.5/docbookx.dtd"> +<article lang="en"> + <articleinfo> + <title>%(HEADER1)s</title> + <authorgroup> + <author><othername>%(HEADER2)s</othername></author> + </authorgroup> + <date>%(HEADER3)s</date> + </articleinfo> +""", + + 'man': """\ +.TH "%(HEADER1)s" 1 "%(HEADER3)s" "%(HEADER2)s" +""", + +# TODO style to <HR> + 'pm6': """\ +<PMTags1.0 win><C-COLORTABLE ("Preto" 1 0 0 0) +><@Normal= + <FONT "Times New Roman"><CCOLOR "Preto"><SIZE 11> + <HORIZONTAL 100><LETTERSPACE 0><CTRACK 127><CSSIZE 70><C+SIZE 58.3> + <C-POSITION 33.3><C+POSITION 33.3><P><CBASELINE 0><CNOBREAK 0><CLEADING -0.05> + <GGRID 0><GLEFT 7.2><GRIGHT 0><GFIRST 0><G+BEFORE 7.2><G+AFTER 0> + <GALIGNMENT "justify"><GMETHOD "proportional"><G& "ENGLISH"> + <GPAIRS 12><G%% 120><GKNEXT 0><GKWIDOW 0><GKORPHAN 0><GTABS $> + <GHYPHENATION 2 34 0><GWORDSPACE 75 100 150><GSPACE -5 0 25> +><@Bullet=<@-PARENT "Normal"><FONT "Abadi MT Condensed Light"> + <GLEFT 14.4><G+BEFORE 2.15><G%% 110><GTABS(25.2 l "")> +><@PreFormat=<@-PARENT "Normal"><FONT "Lucida Console"><SIZE 8><CTRACK 0> + <GLEFT 0><G+BEFORE 0><GALIGNMENT "left"><GWORDSPACE 100 100 100><GSPACE 0 0 0> +><@Title1=<@-PARENT "Normal"><FONT "Arial"><SIZE 14><B> + <GCONTENTS><GLEFT 0><G+BEFORE 0><GALIGNMENT "left"> +><@Title2=<@-PARENT "Title1"><SIZE 12><G+BEFORE 3.6> +><@Title3=<@-PARENT "Title1"><SIZE 10><GLEFT 7.2><G+BEFORE 7.2> +><@Title4=<@-PARENT "Title3"> +><@Title5=<@-PARENT "Title3"> +><@Quote=<@-PARENT "Normal"><SIZE 10><I>> + +%(HEADER1)s +%(HEADER2)s +%(HEADER3)s +""", + + 'mgp': """\ +#!/usr/X11R6/bin/mgp -t 90 +%%deffont "normal" xfont "utopia-medium-r", charset "iso8859-1" +%%deffont "normal-i" xfont "utopia-medium-i", charset "iso8859-1" +%%deffont "normal-b" xfont "utopia-bold-r" , charset "iso8859-1" +%%deffont "normal-bi" xfont "utopia-bold-i" , charset "iso8859-1" +%%deffont "mono" xfont "courier-medium-r", charset "iso8859-1" +%%default 1 size 5 +%%default 2 size 8, fore "yellow", font "normal-b", center +%%default 3 size 5, fore "white", font "normal", left, prefix " " +%%tab 1 size 4, vgap 30, prefix " ", icon arc "red" 40, leftfill +%%tab 2 prefix " ", icon arc "orange" 40, leftfill +%%tab 3 prefix " ", icon arc "brown" 40, leftfill +%%tab 4 prefix " ", icon arc "darkmagenta" 40, leftfill +%%tab 5 prefix " ", icon arc "magenta" 40, leftfill +%%%%------------------------- end of headers ----------------------------- +%%page + + + + + +%%size 10, center, fore "yellow" +%(HEADER1)s + +%%font "normal-i", size 6, fore "white", center +%(HEADER2)s + +%%font "mono", size 7, center +%(HEADER3)s +""", + + 'moin': """\ +'''%(HEADER1)s''' + +''%(HEADER2)s'' + +%(HEADER3)s +""", + + 'gwiki': """\ +*%(HEADER1)s* + +%(HEADER2)s + +_%(HEADER3)s_ +""", + + 'adoc': """\ += %(HEADER1)s +%(HEADER2)s +%(HEADER3)s +""", + + 'doku': """\ +===== %(HEADER1)s ===== + +**//%(HEADER2)s//** + +//%(HEADER3)s// +""", + + 'pmw': """\ +(:Title %(HEADER1)s:) + +(:Description %(HEADER2)s:) + +(:Summary %(HEADER3)s:) +""", + + 'wiki': """\ +'''%(HEADER1)s''' + +%(HEADER2)s + +''%(HEADER3)s'' +""", + + 'tex': \ +r"""\documentclass{article} +\usepackage{graphicx} +\usepackage{paralist} %% needed for compact lists +\usepackage[normalem]{ulem} %% needed by strike +\usepackage[urlcolor=blue,colorlinks=true]{hyperref} +\usepackage[%(ENCODING)s]{inputenc} %% char encoding +\usepackage{%(STYLE)s} %% user defined + +\title{%(HEADER1)s} +\author{%(HEADER2)s} +\begin{document} +\date{%(HEADER3)s} +\maketitle +\clearpage +""", + + 'lout': """\ +@SysInclude { doc } +@Document + @InitialFont { Times Base 12p } # Times, Courier, Helvetica, ... + @PageOrientation { Portrait } # Portrait, Landscape + @ColumnNumber { 1 } # Number of columns (2, 3, ...) + @PageHeaders { Simple } # None, Simple, Titles, NoTitles + @InitialLanguage { English } # German, French, Portuguese, ... + @OptimizePages { Yes } # Yes/No smart page break feature +// +@Text @Begin +@Display @Heading { %(HEADER1)s } +@Display @I { %(HEADER2)s } +@Display { %(HEADER3)s } +#@NP # Break page after Headers +""", + 'creole': """\ +%(HEADER1)s +%(HEADER2)s +%(HEADER3)s +""" +# @SysInclude { tbl } # Tables support +# setup: @MakeContents { Yes } # show TOC +# setup: @SectionGap # break page at each section +} + + +############################################################################## + + +def getTags(config): + "Returns all the known tags for the specified target" + + keys = """ + title1 numtitle1 + title2 numtitle2 + title3 numtitle3 + title4 numtitle4 + title5 numtitle5 + title1Open title1Close + title2Open title2Close + title3Open title3Close + title4Open title4Close + title5Open title5Close + blocktitle1Open blocktitle1Close + blocktitle2Open blocktitle2Close + blocktitle3Open blocktitle3Close + + paragraphOpen paragraphClose + blockVerbOpen blockVerbClose + blockQuoteOpen blockQuoteClose blockQuoteLine + blockCommentOpen blockCommentClose + + fontMonoOpen fontMonoClose + fontBoldOpen fontBoldClose + fontItalicOpen fontItalicClose + fontUnderlineOpen fontUnderlineClose + fontStrikeOpen fontStrikeClose + + listOpen listClose + listOpenCompact listCloseCompact + listItemOpen listItemClose listItemLine + numlistOpen numlistClose + numlistOpenCompact numlistCloseCompact + numlistItemOpen numlistItemClose numlistItemLine + deflistOpen deflistClose + deflistOpenCompact deflistCloseCompact + deflistItem1Open deflistItem1Close + deflistItem2Open deflistItem2Close deflistItem2LinePrefix + + bar1 bar2 + url urlMark + email emailMark + img imgAlignLeft imgAlignRight imgAlignCenter + _imgAlignLeft _imgAlignRight _imgAlignCenter + + tableOpen tableClose + _tableBorder _tableAlignLeft _tableAlignCenter + tableRowOpen tableRowClose tableRowSep + tableTitleRowOpen tableTitleRowClose + tableCellOpen tableCellClose tableCellSep + tableTitleCellOpen tableTitleCellClose tableTitleCellSep + _tableColAlignLeft _tableColAlignRight _tableColAlignCenter + _tableCellAlignLeft _tableCellAlignRight _tableCellAlignCenter + _tableCellColSpan tableColAlignSep + _tableCellMulticolOpen + _tableCellMulticolClose + + bodyOpen bodyClose + cssOpen cssClose + tocOpen tocClose TOC + anchor + comment + pageBreak + EOD + """.split() + + # TIP: \a represents the current text inside the mark + # TIP: ~A~, ~B~ and ~C~ are expanded to other tags parts + + alltags = { + + 'art': { + 'title1' : '\a' , + 'title2' : '\a' , + 'title3' : '\a' , + 'title4' : '\a' , + 'title5' : '\a' , + 'blockQuoteLine' : '\t' , + 'listItemOpen' : '- ' , + 'numlistItemOpen' : '\a. ' , + 'bar1' : aa_line(AA['bar1'], config['width']), + 'bar2' : aa_line(AA['bar2'], config['width']), + 'url' : '\a' , + 'urlMark' : '\a (\a)' , + 'email' : '\a' , + 'emailMark' : '\a (\a)' , + 'img' : '[\a]' , + }, + + 'txt': { + 'title1' : ' \a' , + 'title2' : '\t\a' , + 'title3' : '\t\t\a' , + 'title4' : '\t\t\t\a' , + 'title5' : '\t\t\t\t\a', + 'blockQuoteLine' : '\t' , + 'listItemOpen' : '- ' , + 'numlistItemOpen' : '\a. ' , + 'bar1' : '\a' , + 'url' : '\a' , + 'urlMark' : '\a (\a)' , + 'email' : '\a' , + 'emailMark' : '\a (\a)' , + 'img' : '[\a]' , + }, + + 'html': { + 'paragraphOpen' : '<P>' , + 'paragraphClose' : '</P>' , + 'title1' : '~A~<H1>\a</H1>' , + 'title2' : '~A~<H2>\a</H2>' , + 'title3' : '~A~<H3>\a</H3>' , + 'title4' : '~A~<H4>\a</H4>' , + 'title5' : '~A~<H5>\a</H5>' , + 'anchor' : '<A NAME="\a"></A>\n', + 'blockVerbOpen' : '<PRE>' , + 'blockVerbClose' : '</PRE>' , + 'blockQuoteOpen' : '<BLOCKQUOTE>' , + 'blockQuoteClose' : '</BLOCKQUOTE>' , + 'fontMonoOpen' : '<CODE>' , + 'fontMonoClose' : '</CODE>' , + 'fontBoldOpen' : '<B>' , + 'fontBoldClose' : '</B>' , + 'fontItalicOpen' : '<I>' , + 'fontItalicClose' : '</I>' , + 'fontUnderlineOpen' : '<U>' , + 'fontUnderlineClose' : '</U>' , + 'fontStrikeOpen' : '<S>' , + 'fontStrikeClose' : '</S>' , + 'listOpen' : '<UL>' , + 'listClose' : '</UL>' , + 'listItemOpen' : '<LI>' , + 'numlistOpen' : '<OL>' , + 'numlistClose' : '</OL>' , + 'numlistItemOpen' : '<LI>' , + 'deflistOpen' : '<DL>' , + 'deflistClose' : '</DL>' , + 'deflistItem1Open' : '<DT>' , + 'deflistItem1Close' : '</DT>' , + 'deflistItem2Open' : '<DD>' , + 'bar1' : '<HR NOSHADE SIZE=1>' , + 'bar2' : '<HR NOSHADE SIZE=5>' , + 'url' : '<A HREF="\a">\a</A>' , + 'urlMark' : '<A HREF="\a">\a</A>' , + 'email' : '<A HREF="mailto:\a">\a</A>' , + 'emailMark' : '<A HREF="mailto:\a">\a</A>' , + 'img' : '<IMG~A~ SRC="\a" BORDER="0" ALT="">', + '_imgAlignLeft' : ' ALIGN="left"' , + '_imgAlignCenter' : ' ALIGN="middle"', + '_imgAlignRight' : ' ALIGN="right"' , + 'tableOpen' : '<TABLE~A~~B~ CELLPADDING="4">', + 'tableClose' : '</TABLE>' , + 'tableRowOpen' : '<TR>' , + 'tableRowClose' : '</TR>' , + 'tableCellOpen' : '<TD~A~~S~>' , + 'tableCellClose' : '</TD>' , + 'tableTitleCellOpen' : '<TH~S~>' , + 'tableTitleCellClose' : '</TH>' , + '_tableBorder' : ' BORDER="1"' , + '_tableAlignCenter' : ' ALIGN="center"', + '_tableCellAlignRight' : ' ALIGN="right"' , + '_tableCellAlignCenter': ' ALIGN="center"', + '_tableCellColSpan' : ' COLSPAN="\a"' , + 'cssOpen' : '<STYLE TYPE="text/css">', + 'cssClose' : '</STYLE>' , + 'comment' : '<!-- \a -->' , + 'EOD' : '</BODY></HTML>' + }, + + #TIP xhtml inherits all HTML definitions (lowercased) + #TIP http://www.w3.org/TR/xhtml1/#guidelines + #TIP http://www.htmlref.com/samples/Chapt17/17_08.htm + 'xhtml': { + 'listItemClose' : '</li>' , + 'numlistItemClose' : '</li>' , + 'deflistItem2Close' : '</dd>' , + 'bar1' : '<hr class="light" />', + 'bar2' : '<hr class="heavy" />', + 'anchor' : '<a id="\a" name="\a"></a>\n', + 'img' : '<img~A~ src="\a" border="0" alt=""/>', + }, + + 'sgml': { + 'paragraphOpen' : '<p>' , + 'title1' : '<sect>\a~A~<p>' , + 'title2' : '<sect1>\a~A~<p>' , + 'title3' : '<sect2>\a~A~<p>' , + 'title4' : '<sect3>\a~A~<p>' , + 'title5' : '<sect4>\a~A~<p>' , + 'anchor' : '<label id="\a">' , + 'blockVerbOpen' : '<tscreen><verb>' , + 'blockVerbClose' : '</verb></tscreen>' , + 'blockQuoteOpen' : '<quote>' , + 'blockQuoteClose' : '</quote>' , + 'fontMonoOpen' : '<tt>' , + 'fontMonoClose' : '</tt>' , + 'fontBoldOpen' : '<bf>' , + 'fontBoldClose' : '</bf>' , + 'fontItalicOpen' : '<em>' , + 'fontItalicClose' : '</em>' , + 'fontUnderlineOpen' : '<bf><em>' , + 'fontUnderlineClose' : '</em></bf>' , + 'listOpen' : '<itemize>' , + 'listClose' : '</itemize>' , + 'listItemOpen' : '<item>' , + 'numlistOpen' : '<enum>' , + 'numlistClose' : '</enum>' , + 'numlistItemOpen' : '<item>' , + 'deflistOpen' : '<descrip>' , + 'deflistClose' : '</descrip>' , + 'deflistItem1Open' : '<tag>' , + 'deflistItem1Close' : '</tag>' , + 'bar1' : '<!-- \a -->' , + 'url' : '<htmlurl url="\a" name="\a">' , + 'urlMark' : '<htmlurl url="\a" name="\a">' , + 'email' : '<htmlurl url="mailto:\a" name="\a">' , + 'emailMark' : '<htmlurl url="mailto:\a" name="\a">' , + 'img' : '<figure><ph vspace=""><img src="\a"></figure>', + 'tableOpen' : '<table><tabular ca="~C~">' , + 'tableClose' : '</tabular></table>' , + 'tableRowSep' : '<rowsep>' , + 'tableCellSep' : '<colsep>' , + '_tableColAlignLeft' : 'l' , + '_tableColAlignRight' : 'r' , + '_tableColAlignCenter' : 'c' , + 'comment' : '<!-- \a -->' , + 'TOC' : '<toc>' , + 'EOD' : '</article>' + }, + + 'dbk': { + 'paragraphOpen' : '<para>' , + 'paragraphClose' : '</para>' , + 'title1Open' : '~A~<sect1><title>\a</title>' , + 'title1Close' : '</sect1>' , + 'title2Open' : '~A~ <sect2><title>\a</title>' , + 'title2Close' : ' </sect2>' , + 'title3Open' : '~A~ <sect3><title>\a</title>' , + 'title3Close' : ' </sect3>' , + 'title4Open' : '~A~ <sect4><title>\a</title>' , + 'title4Close' : ' </sect4>' , + 'title5Open' : '~A~ <sect5><title>\a</title>', + 'title5Close' : ' </sect5>' , + 'anchor' : '<anchor id="\a"/>\n' , + 'blockVerbOpen' : '<programlisting>' , + 'blockVerbClose' : '</programlisting>' , + 'blockQuoteOpen' : '<blockquote><para>' , + 'blockQuoteClose' : '</para></blockquote>' , + 'fontMonoOpen' : '<code>' , + 'fontMonoClose' : '</code>' , + 'fontBoldOpen' : '<emphasis role="bold">' , + 'fontBoldClose' : '</emphasis>' , + 'fontItalicOpen' : '<emphasis>' , + 'fontItalicClose' : '</emphasis>' , + 'fontUnderlineOpen' : '<emphasis role="underline">' , + 'fontUnderlineClose' : '</emphasis>' , + # 'fontStrikeOpen' : '<emphasis role="strikethrough">' , # Don't know + # 'fontStrikeClose' : '</emphasis>' , + 'listOpen' : '<itemizedlist>' , + 'listClose' : '</itemizedlist>' , + 'listItemOpen' : '<listitem><para>' , + 'listItemClose' : '</para></listitem>' , + 'numlistOpen' : '<orderedlist numeration="arabic">' , + 'numlistClose' : '</orderedlist>' , + 'numlistItemOpen' : '<listitem><para>' , + 'numlistItemClose' : '</para></listitem>' , + 'deflistOpen' : '<variablelist>' , + 'deflistClose' : '</variablelist>' , + 'deflistItem1Open' : '<varlistentry><term>' , + 'deflistItem1Close' : '</term>' , + 'deflistItem2Open' : '<listitem><para>' , + 'deflistItem2Close' : '</para></listitem></varlistentry>' , + # 'bar1' : '<>' , # Don't know + # 'bar2' : '<>' , # Don't know + 'url' : '<ulink url="\a">\a</ulink>' , + 'urlMark' : '<ulink url="\a">\a</ulink>' , + 'email' : '<email>\a</email>' , + 'emailMark' : '<email>\a</email>' , + 'img' : '<mediaobject><imageobject><imagedata fileref="\a"/></imageobject></mediaobject>', + # '_imgAlignLeft' : '' , # Don't know + # '_imgAlignCenter' : '' , # Don't know + # '_imgAlignRight' : '' , # Don't know + # 'tableOpen' : '<informaltable><tgroup cols=""><tbody>', # Don't work, need to know number of cols + # 'tableClose' : '</tbody></tgroup></informaltable>' , + # 'tableRowOpen' : '<row>' , + # 'tableRowClose' : '</row>' , + # 'tableCellOpen' : '<entry>' , + # 'tableCellClose' : '</entry>' , + # 'tableTitleRowOpen' : '<thead>' , + # 'tableTitleRowClose' : '</thead>' , + # '_tableBorder' : ' frame="all"' , + # '_tableAlignCenter' : ' align="center"' , + # '_tableCellAlignRight' : ' align="right"' , + # '_tableCellAlignCenter': ' align="center"' , + # '_tableCellColSpan' : ' COLSPAN="\a"' , + 'TOC' : '<index/>' , + 'comment' : '<!-- \a -->' , + 'EOD' : '</article>' + }, + + 'tex': { + 'title1' : '~A~\section*{\a}' , + 'title2' : '~A~\\subsection*{\a}' , + 'title3' : '~A~\\subsubsection*{\a}', + # title 4/5: DIRTY: para+BF+\\+\n + 'title4' : '~A~\\paragraph{}\\textbf{\a}\\\\\n', + 'title5' : '~A~\\paragraph{}\\textbf{\a}\\\\\n', + 'numtitle1' : '\n~A~\section{\a}' , + 'numtitle2' : '~A~\\subsection{\a}' , + 'numtitle3' : '~A~\\subsubsection{\a}' , + 'anchor' : '\\hypertarget{\a}{}\n' , + 'blockVerbOpen' : '\\begin{verbatim}' , + 'blockVerbClose' : '\\end{verbatim}' , + 'blockQuoteOpen' : '\\begin{quotation}' , + 'blockQuoteClose' : '\\end{quotation}' , + 'fontMonoOpen' : '\\texttt{' , + 'fontMonoClose' : '}' , + 'fontBoldOpen' : '\\textbf{' , + 'fontBoldClose' : '}' , + 'fontItalicOpen' : '\\textit{' , + 'fontItalicClose' : '}' , + 'fontUnderlineOpen' : '\\underline{' , + 'fontUnderlineClose' : '}' , + 'fontStrikeOpen' : '\\sout{' , + 'fontStrikeClose' : '}' , + 'listOpen' : '\\begin{itemize}' , + 'listClose' : '\\end{itemize}' , + 'listOpenCompact' : '\\begin{compactitem}', + 'listCloseCompact' : '\\end{compactitem}' , + 'listItemOpen' : '\\item ' , + 'numlistOpen' : '\\begin{enumerate}' , + 'numlistClose' : '\\end{enumerate}' , + 'numlistOpenCompact' : '\\begin{compactenum}', + 'numlistCloseCompact' : '\\end{compactenum}' , + 'numlistItemOpen' : '\\item ' , + 'deflistOpen' : '\\begin{description}', + 'deflistClose' : '\\end{description}' , + 'deflistOpenCompact' : '\\begin{compactdesc}', + 'deflistCloseCompact' : '\\end{compactdesc}' , + 'deflistItem1Open' : '\\item[' , + 'deflistItem1Close' : ']' , + 'bar1' : '\\hrulefill{}' , + 'bar2' : '\\rule{\linewidth}{1mm}', + 'url' : '\\htmladdnormallink{\a}{\a}', + 'urlMark' : '\\htmladdnormallink{\a}{\a}', + 'email' : '\\htmladdnormallink{\a}{mailto:\a}', + 'emailMark' : '\\htmladdnormallink{\a}{mailto:\a}', + 'img' : '\\includegraphics{\a}', + 'tableOpen' : '\\begin{center}\\begin{tabular}{|~C~|}', + 'tableClose' : '\\end{tabular}\\end{center}', + 'tableRowOpen' : '\\hline ' , + 'tableRowClose' : ' \\\\' , + 'tableCellSep' : ' & ' , + '_tableColAlignLeft' : 'l' , + '_tableColAlignRight' : 'r' , + '_tableColAlignCenter' : 'c' , + '_tableCellAlignLeft' : 'l' , + '_tableCellAlignRight' : 'r' , + '_tableCellAlignCenter': 'c' , + '_tableCellColSpan' : '\a' , + '_tableCellMulticolOpen' : '\\multicolumn{\a}{|~C~|}{', + '_tableCellMulticolClose' : '}', + 'tableColAlignSep' : '|' , + 'comment' : '% \a' , + 'TOC' : '\\tableofcontents', + 'pageBreak' : '\\clearpage', + 'EOD' : '\\end{document}' + }, + + 'lout': { + 'paragraphOpen' : '@LP' , + 'blockTitle1Open' : '@BeginSections' , + 'blockTitle1Close' : '@EndSections' , + 'blockTitle2Open' : ' @BeginSubSections' , + 'blockTitle2Close' : ' @EndSubSections' , + 'blockTitle3Open' : ' @BeginSubSubSections' , + 'blockTitle3Close' : ' @EndSubSubSections' , + 'title1Open' : '~A~@Section @Title { \a } @Begin', + 'title1Close' : '@End @Section' , + 'title2Open' : '~A~ @SubSection @Title { \a } @Begin', + 'title2Close' : ' @End @SubSection' , + 'title3Open' : '~A~ @SubSubSection @Title { \a } @Begin', + 'title3Close' : ' @End @SubSubSection' , + 'title4Open' : '~A~@LP @LeftDisplay @B { \a }', + 'title5Open' : '~A~@LP @LeftDisplay @B { \a }', + 'anchor' : '@Tag { \a }\n' , + 'blockVerbOpen' : '@LP @ID @F @RawVerbatim @Begin', + 'blockVerbClose' : '@End @RawVerbatim' , + 'blockQuoteOpen' : '@QD {' , + 'blockQuoteClose' : '}' , + # enclosed inside {} to deal with joined**words** + 'fontMonoOpen' : '{@F {' , + 'fontMonoClose' : '}}' , + 'fontBoldOpen' : '{@B {' , + 'fontBoldClose' : '}}' , + 'fontItalicOpen' : '{@II {' , + 'fontItalicClose' : '}}' , + 'fontUnderlineOpen' : '{@Underline{' , + 'fontUnderlineClose' : '}}' , + # the full form is more readable, but could be BL EL LI NL TL DTI + 'listOpen' : '@BulletList' , + 'listClose' : '@EndList' , + 'listItemOpen' : '@ListItem{' , + 'listItemClose' : '}' , + 'numlistOpen' : '@NumberedList' , + 'numlistClose' : '@EndList' , + 'numlistItemOpen' : '@ListItem{' , + 'numlistItemClose' : '}' , + 'deflistOpen' : '@TaggedList' , + 'deflistClose' : '@EndList' , + 'deflistItem1Open' : '@DropTagItem {' , + 'deflistItem1Close' : '}' , + 'deflistItem2Open' : '{' , + 'deflistItem2Close' : '}' , + 'bar1' : '@DP @FullWidthRule' , + 'url' : '{blue @Colour { \a }}' , + 'urlMark' : '\a ({blue @Colour { \a }})' , + 'email' : '{blue @Colour { \a }}' , + 'emailMark' : '\a ({blue Colour{ \a }})' , + 'img' : '~A~@IncludeGraphic { \a }' , # eps only! + '_imgAlignLeft' : '@LeftDisplay ' , + '_imgAlignRight' : '@RightDisplay ' , + '_imgAlignCenter' : '@CentredDisplay ' , + # lout tables are *way* complicated, no support for now + #'tableOpen' : '~A~@Tbl~B~\naformat{ @Cell A | @Cell B } {', + #'tableClose' : '}' , + #'tableRowOpen' : '@Rowa\n' , + #'tableTitleRowOpen' : '@HeaderRowa' , + #'tableCenterAlign' : '@CentredDisplay ' , + #'tableCellOpen' : '\a {' , # A, B, ... + #'tableCellClose' : '}' , + #'_tableBorder' : '\nrule {yes}' , + 'comment' : '# \a' , + # @MakeContents must be on the config file + 'TOC' : '@DP @ContentsGoesHere @DP', + 'pageBreak' : '@NP' , + 'EOD' : '@End @Text' + }, + + # http://moinmo.in/SyntaxReference + 'moin': { + 'title1' : '= \a =' , + 'title2' : '== \a ==' , + 'title3' : '=== \a ===' , + 'title4' : '==== \a ====' , + 'title5' : '===== \a =====', + 'blockVerbOpen' : '{{{' , + 'blockVerbClose' : '}}}' , + 'blockQuoteLine' : ' ' , + 'fontMonoOpen' : '{{{' , + 'fontMonoClose' : '}}}' , + 'fontBoldOpen' : "'''" , + 'fontBoldClose' : "'''" , + 'fontItalicOpen' : "''" , + 'fontItalicClose' : "''" , + 'fontUnderlineOpen' : '__' , + 'fontUnderlineClose' : '__' , + 'fontStrikeOpen' : '--(' , + 'fontStrikeClose' : ')--' , + 'listItemOpen' : ' * ' , + 'numlistItemOpen' : ' \a. ' , + 'deflistItem1Open' : ' ' , + 'deflistItem1Close' : '::' , + 'deflistItem2LinePrefix': ' :: ' , + 'bar1' : '----' , + 'bar2' : '--------' , + 'url' : '[\a]' , + 'urlMark' : '[\a \a]' , + 'email' : '[\a]' , + 'emailMark' : '[\a \a]' , + 'img' : '[\a]' , + 'tableRowOpen' : '||' , + 'tableCellOpen' : '~A~' , + 'tableCellClose' : '||' , + 'tableTitleCellClose' : '||' , + '_tableCellAlignRight' : '<)>' , + '_tableCellAlignCenter' : '<:>' , + 'comment' : '/* \a */' , + 'TOC' : '[[TableOfContents]]' + }, + + # http://code.google.com/p/support/wiki/WikiSyntax + 'gwiki': { + 'title1' : '= \a =' , + 'title2' : '== \a ==' , + 'title3' : '=== \a ===' , + 'title4' : '==== \a ====' , + 'title5' : '===== \a =====', + 'blockVerbOpen' : '{{{' , + 'blockVerbClose' : '}}}' , + 'blockQuoteLine' : ' ' , + 'fontMonoOpen' : '{{{' , + 'fontMonoClose' : '}}}' , + 'fontBoldOpen' : '*' , + 'fontBoldClose' : '*' , + 'fontItalicOpen' : '_' , # underline == italic + 'fontItalicClose' : '_' , + 'fontStrikeOpen' : '~~' , + 'fontStrikeClose' : '~~' , + 'listItemOpen' : ' * ' , + 'numlistItemOpen' : ' # ' , + 'url' : '\a' , + 'urlMark' : '[\a \a]' , + 'email' : 'mailto:\a' , + 'emailMark' : '[mailto:\a \a]', + 'img' : '[\a]' , + 'tableRowOpen' : '|| ' , + 'tableRowClose' : ' ||' , + 'tableCellSep' : ' || ' , + }, + + # http://powerman.name/doc/asciidoc + 'adoc': { + 'title1' : '== \a' , + 'title2' : '=== \a' , + 'title3' : '==== \a' , + 'title4' : '===== \a' , + 'title5' : '===== \a' , + 'blockVerbOpen' : '----' , + 'blockVerbClose' : '----' , + 'fontMonoOpen' : '+' , + 'fontMonoClose' : '+' , + 'fontBoldOpen' : '*' , + 'fontBoldClose' : '*' , + 'fontItalicOpen' : '_' , + 'fontItalicClose' : '_' , + 'listItemOpen' : '- ' , + 'listItemLine' : '\t' , + 'numlistItemOpen' : '. ' , + 'url' : '\a' , + 'urlMark' : '\a[\a]' , + 'email' : 'mailto:\a' , + 'emailMark' : 'mailto:\a[\a]' , + 'img' : 'image::\a[]' , + }, + + # http://wiki.splitbrain.org/wiki:syntax + # Hint: <br> is \\ $ + # Hint: You can add footnotes ((This is a footnote)) + 'doku': { + 'title1' : '===== \a =====', + 'title2' : '==== \a ====' , + 'title3' : '=== \a ===' , + 'title4' : '== \a ==' , + 'title5' : '= \a =' , + # DokuWiki uses ' ' identation to mark verb blocks (see indentverbblock) + 'blockQuoteLine' : '>' , + 'fontMonoOpen' : "''" , + 'fontMonoClose' : "''" , + 'fontBoldOpen' : "**" , + 'fontBoldClose' : "**" , + 'fontItalicOpen' : "//" , + 'fontItalicClose' : "//" , + 'fontUnderlineOpen' : "__" , + 'fontUnderlineClose' : "__" , + 'fontStrikeOpen' : '<del>' , + 'fontStrikeClose' : '</del>' , + 'listItemOpen' : ' * ' , + 'numlistItemOpen' : ' - ' , + 'bar1' : '----' , + 'url' : '[[\a]]' , + 'urlMark' : '[[\a|\a]]' , + 'email' : '[[\a]]' , + 'emailMark' : '[[\a|\a]]' , + 'img' : '{{\a}}' , + 'imgAlignLeft' : '{{\a }}' , + 'imgAlignRight' : '{{ \a}}' , + 'imgAlignCenter' : '{{ \a }}' , + 'tableTitleRowOpen' : '^ ' , + 'tableTitleRowClose' : ' ^' , + 'tableTitleCellSep' : ' ^ ' , + 'tableRowOpen' : '| ' , + 'tableRowClose' : ' |' , + 'tableCellSep' : ' | ' , + # DokuWiki has no attributes. The content must be aligned! + # '_tableCellAlignRight' : '<)>' , # ?? + # '_tableCellAlignCenter': '<:>' , # ?? + # DokuWiki colspan is the same as txt2tags' with multiple ||| + # 'comment' : '## \a' , # ?? + # TOC is automatic + }, + + # http://www.pmwiki.org/wiki/PmWiki/TextFormattingRules + 'pmw': { + 'title1' : '~A~! \a ' , + 'title2' : '~A~!! \a ' , + 'title3' : '~A~!!! \a ' , + 'title4' : '~A~!!!! \a ' , + 'title5' : '~A~!!!!! \a ' , + 'blockQuoteOpen' : '->' , + 'blockQuoteClose' : '\n' , + # In-text font + 'fontLargeOpen' : "[+" , + 'fontLargeClose' : "+]" , + 'fontLargerOpen' : "[++" , + 'fontLargerClose' : "++]" , + 'fontSmallOpen' : "[-" , + 'fontSmallClose' : "-]" , + 'fontLargerOpen' : "[--" , + 'fontLargerClose' : "--]" , + 'fontMonoOpen' : "@@" , + 'fontMonoClose' : "@@" , + 'fontBoldOpen' : "'''" , + 'fontBoldClose' : "'''" , + 'fontItalicOpen' : "''" , + 'fontItalicClose' : "''" , + 'fontUnderlineOpen' : "{+" , + 'fontUnderlineClose' : "+}" , + 'fontStrikeOpen' : '{-' , + 'fontStrikeClose' : '-}' , + # Lists + 'listItemLine' : '*' , + 'numlistItemLine' : '#' , + 'deflistItem1Open' : ': ' , + 'deflistItem1Close' : ':' , + 'deflistItem2LineOpen' : '::' , + 'deflistItem2LineClose' : ':' , + # Verbatim block + 'blockVerbOpen' : '[@' , + 'blockVerbClose' : '@]' , + 'bar1' : '----' , + # URL, email and anchor + 'url' : '\a' , + 'urlMark' : '[[\a -> \a]]' , + 'email' : '\a' , + 'emailMark' : '[[\a -> mailto:\a]]', + 'anchor' : '[[#\a]]\n' , + # Image markup + 'img' : '\a' , + #'imgAlignLeft' : '{{\a }}' , + #'imgAlignRight' : '{{ \a}}' , + #'imgAlignCenter' : '{{ \a }}' , + # Table attributes + 'tableTitleRowOpen' : '||! ' , + 'tableTitleRowClose' : '||' , + 'tableTitleCellSep' : ' ||!' , + 'tableRowOpen' : '||' , + 'tableRowClose' : '||' , + 'tableCellSep' : ' ||' , + }, + + # http://en.wikipedia.org/wiki/Help:Editing + 'wiki': { + 'title1' : '== \a ==' , + 'title2' : '=== \a ===' , + 'title3' : '==== \a ====' , + 'title4' : '===== \a =====' , + 'title5' : '====== \a ======', + 'blockVerbOpen' : '<pre>' , + 'blockVerbClose' : '</pre>' , + 'blockQuoteOpen' : '<blockquote>' , + 'blockQuoteClose' : '</blockquote>' , + 'fontMonoOpen' : '<tt>' , + 'fontMonoClose' : '</tt>' , + 'fontBoldOpen' : "'''" , + 'fontBoldClose' : "'''" , + 'fontItalicOpen' : "''" , + 'fontItalicClose' : "''" , + 'fontUnderlineOpen' : '<u>' , + 'fontUnderlineClose' : '</u>' , + 'fontStrikeOpen' : '<s>' , + 'fontStrikeClose' : '</s>' , + #XXX Mixed lists not working: *#* list inside numlist inside list + 'listItemLine' : '*' , + 'numlistItemLine' : '#' , + 'deflistItem1Open' : '; ' , + 'deflistItem2LinePrefix': ': ' , + 'bar1' : '----' , + 'url' : '[\a]' , + 'urlMark' : '[\a \a]' , + 'email' : 'mailto:\a' , + 'emailMark' : '[mailto:\a \a]' , + # [[Image:foo.png|right|Optional alt/caption text]] (right, left, center, none) + 'img' : '[[Image:\a~A~]]' , + '_imgAlignLeft' : '|left' , + '_imgAlignCenter' : '|center' , + '_imgAlignRight' : '|right' , + # {| border="1" cellspacing="0" cellpadding="4" align="center" + 'tableOpen' : '{|~A~~B~ cellpadding="4"', + 'tableClose' : '|}' , + 'tableRowOpen' : '|-\n| ' , + 'tableTitleRowOpen' : '|-\n! ' , + 'tableCellSep' : ' || ' , + 'tableTitleCellSep' : ' !! ' , + '_tableBorder' : ' border="1"' , + '_tableAlignCenter' : ' align="center"' , + 'comment' : '<!-- \a -->' , + 'TOC' : '__TOC__' , + }, + + # http://www.inference.phy.cam.ac.uk/mackay/mgp/SYNTAX + # http://en.wikipedia.org/wiki/MagicPoint + 'mgp': { + 'paragraphOpen' : '%font "normal", size 5' , + 'title1' : '%page\n\n\a\n' , + 'title2' : '%page\n\n\a\n' , + 'title3' : '%page\n\n\a\n' , + 'title4' : '%page\n\n\a\n' , + 'title5' : '%page\n\n\a\n' , + 'blockVerbOpen' : '%font "mono"' , + 'blockVerbClose' : '%font "normal"' , + 'blockQuoteOpen' : '%prefix " "' , + 'blockQuoteClose' : '%prefix " "' , + 'fontMonoOpen' : '\n%cont, font "mono"\n' , + 'fontMonoClose' : '\n%cont, font "normal"\n' , + 'fontBoldOpen' : '\n%cont, font "normal-b"\n' , + 'fontBoldClose' : '\n%cont, font "normal"\n' , + 'fontItalicOpen' : '\n%cont, font "normal-i"\n' , + 'fontItalicClose' : '\n%cont, font "normal"\n' , + 'fontUnderlineOpen' : '\n%cont, fore "cyan"\n' , + 'fontUnderlineClose' : '\n%cont, fore "white"\n' , + 'listItemLine' : '\t' , + 'numlistItemLine' : '\t' , + 'numlistItemOpen' : '\a. ' , + 'deflistItem1Open' : '\t\n%cont, font "normal-b"\n', + 'deflistItem1Close' : '\n%cont, font "normal"\n' , + 'bar1' : '%bar "white" 5' , + 'bar2' : '%pause' , + 'url' : '\n%cont, fore "cyan"\n\a' +\ + '\n%cont, fore "white"\n' , + 'urlMark' : '\a \n%cont, fore "cyan"\n\a'+\ + '\n%cont, fore "white"\n' , + 'email' : '\n%cont, fore "cyan"\n\a' +\ + '\n%cont, fore "white"\n' , + 'emailMark' : '\a \n%cont, fore "cyan"\n\a'+\ + '\n%cont, fore "white"\n' , + 'img' : '~A~\n%newimage "\a"\n%left\n', + '_imgAlignLeft' : '\n%left' , + '_imgAlignRight' : '\n%right' , + '_imgAlignCenter' : '\n%center' , + 'comment' : '%% \a' , + 'pageBreak' : '%page\n\n\n' , + 'EOD' : '%%EOD' + }, + + # man groff_man ; man 7 groff + 'man': { + 'paragraphOpen' : '.P' , + 'title1' : '.SH \a' , + 'title2' : '.SS \a' , + 'title3' : '.SS \a' , + 'title4' : '.SS \a' , + 'title5' : '.SS \a' , + 'blockVerbOpen' : '.nf' , + 'blockVerbClose' : '.fi\n' , + 'blockQuoteOpen' : '.RS' , + 'blockQuoteClose' : '.RE' , + 'fontBoldOpen' : '\\fB' , + 'fontBoldClose' : '\\fR' , + 'fontItalicOpen' : '\\fI' , + 'fontItalicClose' : '\\fR' , + 'listOpen' : '.RS' , + 'listItemOpen' : '.IP \(bu 3\n', + 'listClose' : '.RE' , + 'numlistOpen' : '.RS' , + 'numlistItemOpen' : '.IP \a. 3\n', + 'numlistClose' : '.RE' , + 'deflistItem1Open' : '.TP\n' , + 'bar1' : '\n\n' , + 'url' : '\a' , + 'urlMark' : '\a (\a)', + 'email' : '\a' , + 'emailMark' : '\a (\a)', + 'img' : '\a' , + 'tableOpen' : '.TS\n~A~~B~tab(^); ~C~.', + 'tableClose' : '.TE' , + 'tableRowOpen' : ' ' , + 'tableCellSep' : '^' , + '_tableAlignCenter' : 'center, ', + '_tableBorder' : 'allbox, ', + '_tableColAlignLeft' : 'l' , + '_tableColAlignRight' : 'r' , + '_tableColAlignCenter' : 'c' , + 'comment' : '.\\" \a' + }, + + 'pm6': { + 'paragraphOpen' : '<@Normal:>' , + 'title1' : '<@Title1:>\a', + 'title2' : '<@Title2:>\a', + 'title3' : '<@Title3:>\a', + 'title4' : '<@Title4:>\a', + 'title5' : '<@Title5:>\a', + 'blockVerbOpen' : '<@PreFormat:>' , + 'blockQuoteLine' : '<@Quote:>' , + 'fontMonoOpen' : '<FONT "Lucida Console"><SIZE 9>' , + 'fontMonoClose' : '<SIZE$><FONT$>', + 'fontBoldOpen' : '<B>' , + 'fontBoldClose' : '<P>' , + 'fontItalicOpen' : '<I>' , + 'fontItalicClose' : '<P>' , + 'fontUnderlineOpen' : '<U>' , + 'fontUnderlineClose' : '<P>' , + 'listOpen' : '<@Bullet:>' , + 'listItemOpen' : '*\t' , # \x95 == ~U -> changed to "*" + 'numlistOpen' : '<@Bullet:>' , + 'numlistItemOpen' : '*\t' , + 'bar1' : '\a' , + 'url' : '<U>\a<P>' , # underline + 'urlMark' : '\a <U>\a<P>' , + 'email' : '\a' , + 'emailMark' : '\a \a' , + 'img' : '\a' + }, + # http://www.wikicreole.org/wiki/AllMarkup + 'creole': { + 'title1' : '= \a =' , + 'title2' : '== \a ==' , + 'title3' : '=== \a ===' , + 'title4' : '==== \a ====' , + 'title5' : '===== \a =====', + 'blockVerbOpen' : '{{{' , + 'blockVerbClose' : '}}}' , + 'blockQuoteLine' : ' ' , + # 'fontMonoOpen' : '##' , # planned for 2.0, + # 'fontMonoClose' : '##' , # meanwhile we disable it + 'fontBoldOpen' : '**' , + 'fontBoldClose' : '**' , + 'fontItalicOpen' : '//' , + 'fontItalicClose' : '//' , + 'fontUnderlineOpen' : '//' , # no underline in 1.0, planned for 2.0, + 'fontUnderlineClose' : '//' , # meanwhile we can use italic (emphasized) + # 'fontStrikeOpen' : '--' , # planned for 2.0, + # 'fontStrikeClose' : '--' , # meanwhile we disable it + 'listItemLine' : '*' , + 'numlistItemLine' : '#' , + 'deflistItem2LinePrefix': ':' , + 'bar1' : '----' , + 'url' : '[[\a]]' , + 'urlMark' : '[[\a|\a]]' , + 'img' : '{{\a}}' , + 'tableTitleRowOpen' : '|= ' , + 'tableTitleRowClose' : '|' , + 'tableTitleCellSep' : ' |= ' , + 'tableRowOpen' : '| ' , + 'tableRowClose' : ' |' , + 'tableCellSep' : ' | ' , + # TODO: placeholder (mark for unknown syntax) + # if possible: http://www.wikicreole.org/wiki/Placeholder + } + } + + # Exceptions for --css-sugar + if config['css-sugar'] and config['target'] in ('html','xhtml'): + # Change just HTML because XHTML inherits it + htmltags = alltags['html'] + # Table with no cellpadding + htmltags['tableOpen'] = htmltags['tableOpen'].replace(' CELLPADDING="4"', '') + # DIVs + htmltags['tocOpen' ] = '<DIV CLASS="toc">' + htmltags['tocClose'] = '</DIV>' + htmltags['bodyOpen'] = '<DIV CLASS="body" ID="body">' + htmltags['bodyClose']= '</DIV>' + + # Make the HTML -> XHTML inheritance + xhtml = alltags['html'].copy() + for key in xhtml.keys(): xhtml[key] = xhtml[key].lower() + # Some like HTML tags as lowercase, some don't... (headers out) + if HTML_LOWER: alltags['html'] = xhtml.copy() + xhtml.update(alltags['xhtml']) + alltags['xhtml'] = xhtml.copy() + + # Compose the target tags dictionary + tags = {} + target_tags = alltags[config['target']].copy() + + for key in keys: tags[key] = '' # create empty keys + for key in target_tags.keys(): + tags[key] = maskEscapeChar(target_tags[key]) # populate + + # Map strong line to pagebreak + if rules['mapbar2pagebreak'] and tags['pageBreak']: + tags['bar2'] = tags['pageBreak'] + + # Map strong line to separator if not defined + if not tags['bar2'] and tags['bar1']: + tags['bar2'] = tags['bar1'] + + return tags + + +############################################################################## + + +def getRules(config): + "Returns all the target-specific syntax rules" + + ret = {} + allrules = [ + + # target rules (ON/OFF) + 'linkable', # target supports external links + 'tableable', # target supports tables + 'imglinkable', # target supports images as links + 'imgalignable', # target supports image alignment + 'imgasdefterm', # target supports image as definition term + 'autonumberlist', # target supports numbered lists natively + 'autonumbertitle', # target supports numbered titles natively + 'stylable', # target supports external style files + 'parainsidelist', # lists items supports paragraph + 'compactlist', # separate enclosing tags for compact lists + 'spacedlistitem', # lists support blank lines between items + 'listnotnested', # lists cannot be nested + 'quotenotnested', # quotes cannot be nested + 'verbblocknotescaped', # don't escape specials in verb block + 'verbblockfinalescape', # do final escapes in verb block + 'escapeurl', # escape special in link URL + 'labelbeforelink', # label comes before the link on the tag + 'onelinepara', # dump paragraph as a single long line + 'tabletitlerowinbold', # manually bold any cell on table titles + 'tablecellstrip', # strip extra spaces from each table cell + 'tablecellspannable', # the table cells can have span attribute + 'tablecellmulticol', # separate open+close tags for multicol cells + 'barinsidequote', # bars are allowed inside quote blocks + 'finalescapetitle', # perform final escapes on title lines + 'autotocnewpagebefore', # break page before automatic TOC + 'autotocnewpageafter', # break page after automatic TOC + 'autotocwithbars', # automatic TOC surrounded by bars + 'mapbar2pagebreak', # map the strong bar to a page break + 'titleblocks', # titles must be on open/close section blocks + + # Target code beautify (ON/OFF) + 'indentverbblock', # add leading spaces to verb block lines + 'breaktablecell', # break lines after any table cell + 'breaktablelineopen', # break line after opening table line + 'notbreaklistopen', # don't break line after opening a new list + 'keepquoteindent', # don't remove the leading TABs on quotes + 'keeplistindent', # don't remove the leading spaces on lists + 'blankendautotoc', # append a blank line at the auto TOC end + 'tagnotindentable', # tags must be placed at the line beginning + 'spacedlistitemopen', # append a space after the list item open tag + 'spacednumlistitemopen',# append a space after the numlist item open tag + 'deflisttextstrip', # strip the contents of the deflist text + 'blanksaroundpara', # put a blank line before and after paragraphs + 'blanksaroundverb', # put a blank line before and after verb blocks + 'blanksaroundquote', # put a blank line before and after quotes + 'blanksaroundlist', # put a blank line before and after lists + 'blanksaroundnumlist', # put a blank line before and after numlists + 'blanksarounddeflist', # put a blank line before and after deflists + 'blanksaroundtable', # put a blank line before and after tables + 'blanksaroundbar', # put a blank line before and after bars + 'blanksaroundtitle', # put a blank line before and after titles + 'blanksaroundnumtitle', # put a blank line before and after numtitles + + # Value settings + 'listmaxdepth', # maximum depth for lists + 'quotemaxdepth', # maximum depth for quotes + 'tablecellaligntype', # type of table cell align: cell, column + ] + + rules_bank = { + 'txt': { + 'indentverbblock':1, + 'spacedlistitem':1, + 'parainsidelist':1, + 'keeplistindent':1, + 'barinsidequote':1, + 'autotocwithbars':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'art': { + #TIP art inherits all TXT rules + }, + 'html': { + 'indentverbblock':1, + 'linkable':1, + 'stylable':1, + 'escapeurl':1, + 'imglinkable':1, + 'imgalignable':1, + 'imgasdefterm':1, + 'autonumberlist':1, + 'spacedlistitem':1, + 'parainsidelist':1, + 'tableable':1, + 'tablecellstrip':1, + 'breaktablecell':1, + 'breaktablelineopen':1, + 'keeplistindent':1, + 'keepquoteindent':1, + 'barinsidequote':1, + 'autotocwithbars':1, + 'tablecellspannable':1, + 'tablecellaligntype':'cell', + + # 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'xhtml': { + #TIP xhtml inherits all HTML rules + }, + 'sgml': { + 'linkable':1, + 'escapeurl':1, + 'autonumberlist':1, + 'spacedlistitem':1, + 'tableable':1, + 'tablecellstrip':1, + 'blankendautotoc':1, + 'quotenotnested':1, + 'keeplistindent':1, + 'keepquoteindent':1, + 'barinsidequote':1, + 'finalescapetitle':1, + 'tablecellaligntype':'column', + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'dbk': { + 'linkable':1, + 'tableable':0, # activate when table tags are ready + 'imglinkable':1, + 'imgalignable':1, + 'imgasdefterm':1, + 'autonumberlist':1, + 'autonumbertitle':1, + 'parainsidelist':1, + 'spacedlistitem':1, + 'titleblocks':1, + }, + 'mgp': { + 'tagnotindentable':1, + 'spacedlistitem':1, + 'imgalignable':1, + 'autotocnewpagebefore':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + # 'blanksaroundtitle':1, + # 'blanksaroundnumtitle':1, + }, + 'tex': { + 'stylable':1, + 'escapeurl':1, + 'autonumberlist':1, + 'autonumbertitle':1, + 'spacedlistitem':1, + 'compactlist':1, + 'parainsidelist':1, + 'tableable':1, + 'tablecellstrip':1, + 'tabletitlerowinbold':1, + 'verbblocknotescaped':1, + 'keeplistindent':1, + 'listmaxdepth':4, # deflist is 6 + 'quotemaxdepth':6, + 'barinsidequote':1, + 'finalescapetitle':1, + 'autotocnewpageafter':1, + 'mapbar2pagebreak':1, + 'tablecellaligntype':'column', + 'tablecellmulticol':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'lout': { + 'keepquoteindent':1, + 'deflisttextstrip':1, + 'escapeurl':1, + 'verbblocknotescaped':1, + 'imgalignable':1, + 'mapbar2pagebreak':1, + 'titleblocks':1, + 'autonumberlist':1, + 'parainsidelist':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'moin': { + 'spacedlistitem':1, + 'linkable':1, + 'keeplistindent':1, + 'tableable':1, + 'barinsidequote':1, + 'tabletitlerowinbold':1, + 'tablecellstrip':1, + 'autotocwithbars':1, + 'tablecellaligntype':'cell', + 'deflisttextstrip':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + # 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'gwiki': { + 'spacedlistitem':1, + 'linkable':1, + 'keeplistindent':1, + 'tableable':1, + 'tabletitlerowinbold':1, + 'tablecellstrip':1, + 'autonumberlist':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + # 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'adoc': { + 'spacedlistitem':1, + 'linkable':1, + 'keeplistindent':1, + 'autonumberlist':1, + 'autonumbertitle':1, + 'listnotnested':1, + 'blanksaroundpara':1, + 'blanksaroundverb':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'doku': { + 'indentverbblock':1, # DokuWiki uses ' ' to mark verb blocks + 'spacedlistitem':1, + 'linkable':1, + 'keeplistindent':1, + 'tableable':1, + 'barinsidequote':1, + 'tablecellstrip':1, + 'autotocwithbars':1, + 'autonumberlist':1, + 'imgalignable':1, + 'tablecellaligntype':'cell', + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'pmw': { + 'indentverbblock':1, + 'spacedlistitem':1, + 'linkable':1, + 'labelbeforelink':1, + # 'keeplistindent':1, + 'tableable':1, + 'barinsidequote':1, + 'tablecellstrip':1, + 'autotocwithbars':1, + 'autonumberlist':1, + 'spacedlistitemopen':1, + 'spacednumlistitemopen':1, + 'imgalignable':1, + 'tabletitlerowinbold':1, + 'tablecellaligntype':'cell', + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'wiki': { + 'linkable':1, + 'tableable':1, + 'tablecellstrip':1, + 'autotocwithbars':1, + 'spacedlistitemopen':1, + 'spacednumlistitemopen':1, + 'deflisttextstrip':1, + 'autonumberlist':1, + 'imgalignable':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'man': { + 'spacedlistitem':1, + 'tagnotindentable':1, + 'tableable':1, + 'tablecellaligntype':'column', + 'tabletitlerowinbold':1, + 'tablecellstrip':1, + 'barinsidequote':1, + 'parainsidelist':0, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + # 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'pm6': { + 'keeplistindent':1, + 'verbblockfinalescape':1, + #TODO add support for these + # maybe set a JOINNEXT char and do it on addLineBreaks() + 'notbreaklistopen':1, + 'barinsidequote':1, + 'autotocwithbars':1, + 'onelinepara':1, + + 'blanksaroundpara':1, + 'blanksaroundverb':1, + # 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + # 'blanksaroundtable':1, + # 'blanksaroundbar':1, + 'blanksaroundtitle':1, + 'blanksaroundnumtitle':1, + }, + 'creole': { + 'linkable':1, + 'tableable':1, + 'imglinkable':1, + 'tablecellstrip':1, + 'autotocwithbars':1, + 'spacedlistitemopen':1, + 'spacednumlistitemopen':1, + 'deflisttextstrip':1, + 'verbblocknotescaped':1, + 'blanksaroundpara':1, + 'blanksaroundverb':1, + 'blanksaroundquote':1, + 'blanksaroundlist':1, + 'blanksaroundnumlist':1, + 'blanksarounddeflist':1, + 'blanksaroundtable':1, + 'blanksaroundbar':1, + 'blanksaroundtitle':1, + }, + } + + # Exceptions for --css-sugar + if config['css-sugar'] and config['target'] in ('html','xhtml'): + rules_bank['html']['indentverbblock'] = 0 + rules_bank['html']['autotocwithbars'] = 0 + + # Get the target specific rules + if config['target'] == 'xhtml': + myrules = rules_bank['html'].copy() # inheritance + myrules.update(rules_bank['xhtml']) # get XHTML specific + elif config['target'] == 'art': + myrules = rules_bank['txt'].copy() # inheritance + if config['slides']: + myrules['blanksaroundtitle'] = 0 + myrules['blanksaroundnumtitle'] = 0 + else: + myrules = rules_bank[config['target']].copy() + + # Populate return dictionary + for key in allrules: ret[key] = 0 # reset all + ret.update(myrules) # get rules + + return ret + + +############################################################################## + + +def getRegexes(): + "Returns all the regexes used to find the t2t marks" + + bank = { + 'blockVerbOpen': + re.compile(r'^```\s*$'), + 'blockVerbClose': + re.compile(r'^```\s*$'), + 'blockRawOpen': + re.compile(r'^"""\s*$'), + 'blockRawClose': + re.compile(r'^"""\s*$'), + 'blockTaggedOpen': + re.compile(r"^'''\s*$"), + 'blockTaggedClose': + re.compile(r"^'''\s*$"), + 'blockCommentOpen': + re.compile(r'^%%%\s*$'), + 'blockCommentClose': + re.compile(r'^%%%\s*$'), + 'quote': + re.compile(r'^\t+'), + '1lineVerb': + re.compile(r'^``` (?=.)'), + '1lineRaw': + re.compile(r'^""" (?=.)'), + '1lineTagged': + re.compile(r"^''' (?=.)"), + # mono, raw, bold, italic, underline: + # - marks must be glued with the contents, no boundary spaces + # - they are greedy, so in ****bold****, turns to <b>**bold**</b> + 'fontMono': + re.compile( r'``([^\s](|.*?[^\s])`*)``'), + 'raw': + re.compile( r'""([^\s](|.*?[^\s])"*)""'), + 'tagged': + re.compile( r"''([^\s](|.*?[^\s])'*)''"), + 'fontBold': + re.compile(r'\*\*([^\s](|.*?[^\s])\**)\*\*'), + 'fontItalic': + re.compile( r'//([^\s](|.*?[^\s])/*)//'), + 'fontUnderline': + re.compile( r'__([^\s](|.*?[^\s])_*)__'), + 'fontStrike': + re.compile( r'--([^\s](|.*?[^\s])-*)--'), + 'list': + re.compile(r'^( *)(-) (?=[^ ])'), + 'numlist': + re.compile(r'^( *)(\+) (?=[^ ])'), + 'deflist': + re.compile(r'^( *)(:) (.*)$'), + 'listclose': + re.compile(r'^( *)([-+:])\s*$'), + 'bar': + re.compile(r'^(\s*)([_=-]{20,})\s*$'), + 'table': + re.compile(r'^ *\|\|? '), + 'blankline': + re.compile(r'^\s*$'), + 'comment': + re.compile(r'^%'), + + # Auxiliary tag regexes + '_imgAlign' : re.compile(r'~A~', re.I), + '_tableAlign' : re.compile(r'~A~', re.I), + '_anchor' : re.compile(r'~A~', re.I), + '_tableBorder' : re.compile(r'~B~', re.I), + '_tableColAlign' : re.compile(r'~C~', re.I), + '_tableCellColSpan': re.compile(r'~S~', re.I), + '_tableCellAlign' : re.compile(r'~A~', re.I), + } + + # Special char to place data on TAGs contents (\a == bell) + bank['x'] = re.compile('\a') + + # %%macroname [ (formatting) ] + bank['macros'] = re.compile(r'%%%%(?P<name>%s)\b(\((?P<fmt>.*?)\))?' % ( + '|'.join(MACROS.keys())), re.I) + + # %%TOC special macro for TOC positioning + bank['toc'] = re.compile(r'^ *%%toc\s*$', re.I) + + # Almost complicated title regexes ;) + titskel = r'^ *(?P<id>%s)(?P<txt>%s)\1(\[(?P<label>[\w-]*)\])?\s*$' + bank[ 'title'] = re.compile(titskel%('[=]{1,5}','[^=](|.*[^=])')) + bank['numtitle'] = re.compile(titskel%('[+]{1,5}','[^+](|.*[^+])')) + + ### Complicated regexes begin here ;) + # + # Textual descriptions on --help's style: [...] is optional, | is OR + + + ### First, some auxiliary variables + # + + # [image.EXT] + patt_img = r'\[([\w_,.+%$#@!?+~/-]+\.(png|jpe?g|gif|eps|bmp))\]' + + # Link things + # http://www.gbiv.com/protocols/uri/rfc/rfc3986.html + # pchar: A-Za-z._~- / %FF / !$&'()*+,;= / :@ + # Recomended order: scheme://user:pass@domain/path?query=foo#anchor + # Also works : scheme://user:pass@domain/path#anchor?query=foo + # TODO form: !'(): + urlskel = { + 'proto' : r'(https?|ftp|news|telnet|gopher|wais)://', + 'guess' : r'(www[23]?|ftp)\.', # w/out proto, try to guess + 'login' : r'A-Za-z0-9_.-', # for ftp://login@domain.com + 'pass' : r'[^ @]*', # for ftp://login:pass@dom.com + 'chars' : r'A-Za-z0-9%._/~:,=$@&+-', # %20(space), :80(port), D&D + 'anchor': r'A-Za-z0-9%._-', # %nn(encoded) + 'form' : r'A-Za-z0-9/%&=+:;.,$@*_-', # .,@*_-(as is) + 'punct' : r'.,;:!?' + } + + # username [ :password ] @ + patt_url_login = r'([%s]+(:%s)?@)?'%(urlskel['login'],urlskel['pass']) + + # [ http:// ] [ username:password@ ] domain.com [ / ] + # [ #anchor | ?form=data ] + retxt_url = r'\b(%s%s|%s)[%s]+\b/*(\?[%s]+)?(#[%s]*)?'%( + urlskel['proto'],patt_url_login, urlskel['guess'], + urlskel['chars'],urlskel['form'],urlskel['anchor']) + + # filename | [ filename ] #anchor + retxt_url_local = r'[%s]+|[%s]*(#[%s]*)'%( + urlskel['chars'],urlskel['chars'],urlskel['anchor']) + + # user@domain [ ?form=data ] + patt_email = r'\b[%s]+@([A-Za-z0-9_-]+\.)+[A-Za-z]{2,4}\b(\?[%s]+)?'%( + urlskel['login'],urlskel['form']) + + # Saving for future use + bank['_urlskel'] = urlskel + + ### And now the real regexes + # + + bank['email'] = re.compile(patt_email,re.I) + + # email | url + bank['link'] = re.compile(r'%s|%s'%(retxt_url,patt_email), re.I) + + # \[ label | imagetag url | email | filename \] + bank['linkmark'] = re.compile( + r'\[(?P<label>%s|[^]]+) (?P<link>%s|%s|%s)\]'%( + patt_img, retxt_url, patt_email, retxt_url_local), + re.L+re.I) + + # Image + bank['img'] = re.compile(patt_img, re.L+re.I) + + # Special things + bank['special'] = re.compile(r'^%!\s*') + return bank +### END OF regex nightmares + +################# functions for the ASCII Art backend ######################## + +def aa_line(char, length): + return char * length + +def aa_box(txt, length): + len_txt = len(txt) + nspace = int((length - len_txt - 4) / 2) + line_box = " " * nspace + AA['corner'] + AA['border'] * (len_txt + 2) + AA['corner'] + # <----- nspace " " -----> "+" <----- len_txt+2 "-" -----> "+" + # +-------------------------------+ + # | all theeeeeeeeeeeeeeeeee text | + # <----- nspace " " -----> "| " <--------- txt ---------> " |" + line_txt = " " * nspace + AA['side'] + ' ' + txt + ' ' + AA['side'] + return [line_box, line_txt, line_box] + +def aa_header(header_data, length, n, end): + header = [aa_line(AA['bar2'], length)] + header.extend(['']*int(n)) #n must be int! + for h in 'HEADER1', 'HEADER2', 'HEADER3': + if header_data[h]: + header.extend(aa_box(header_data[h], length)) + header.extend(['']*int(n)) #Again, n must be int!! + header.extend(['']*end) + header.append(aa_line(AA['bar2'], length)) + return header + +def aa_slide(title, length): + res = [aa_line(AA['bar2'], length)] + res.append('') + res.append(title.center(length)) + res.append('') + res.append(aa_line(AA['bar2'], length)) + return res + +def aa_table(table): + data = [row[2:-2].split(' | ') for row in table] + n = max([len(line) for line in data]) + data = [line + (n - len(line)) * [''] for line in data] + tab = [] + for i in range(n): + tab.append([line[i] for line in data]) + length = [max([len(el) for el in line]) for line in tab] + res = "+" + for i in range(n): + res = res + (length[i] + 2) * "-" + '+' + ret = [] + for line in data: + aff = "|" + ret.append(res) + for j,el in enumerate(line): + aff = aff + " " + el + (length[j] - len(el) + 1) * " " + "|" + ret.append(aff) + ret.append(res) + return ret + +############################################################################## + +class error(Exception): + pass +def echo(msg): # for quick debug + print('\033[32;1m%s\033[m'%msg) +def Quit(msg=''): + if msg: print(msg) + sys.exit(0) +def Error(msg): + msg = _("%s: Error: ")%my_name + msg + raise error(msg) +def getTraceback(): + try: + from traceback import format_exception + etype, value, tb = sys.exc_info() + return ''.join(format_exception(etype, value, tb)) + except: pass +def getUnknownErrorMessage(): + msg = '%s\n%s (%s):\n\n%s'%( + _('Sorry! Txt2tags aborted by an unknown error.'), + _('Please send the following Error Traceback to the author'), + my_email, getTraceback()) + return msg +def Message(msg,level): + if level <= VERBOSE and not QUIET: + prefix = '-'*5 + print("%s %s"%(prefix*level, msg)) +def Debug(msg,id_=0,linenr=None): + "Show debug messages, categorized (colored or not)" + if QUIET or not DEBUG: return + if int(id_) not in range(8): id_ = 0 + # 0:black 1:red 2:green 3:yellow 4:blue 5:pink 6:cyan 7:white ;1:light + ids = ['INI','CFG','SRC','BLK','HLD','GUI','OUT','DET'] + colors_bgdark = ['7;1','1;1','3;1','6;1','4;1','5;1','2;1','7;1'] + colors_bglight = ['0' ,'1' ,'3' ,'6' ,'4' ,'5' ,'2' ,'0' ] + if linenr is not None: msg = "LINE %04d: %s"%(linenr,msg) + if COLOR_DEBUG: + if BG_LIGHT: color = colors_bglight[id_] + else : color = colors_bgdark[id_] + msg = '\033[3%sm%s\033[m'%(color,msg) + print("++ %s: %s"%(ids[id_],msg)) + +def Readfile(file_path, remove_linebreaks=0, ignore_error=0): + data = [] + if file_path == '-': + try: + data = sys.stdin.readlines() + except: + if not ignore_error: + Error(_('You must feed me with data on STDIN!')) + else: + try: + f = open(file_path) + data = f.readlines() + f.close() + except: + if not ignore_error: + Error(_("Cannot read file:") + ' ' + file_path) + if remove_linebreaks: + data = [re.sub('[\n\r]+$', '', x) for x in data] + Message(_("File read (%d lines): %s") % (len(data), file_path), 2) + return data + +def Savefile(file_path, contents): + try: + f = open(file_path, 'w') + except: + Error(_("Cannot open file for writing:") + ' ' + file_path) + if isinstance(contents, type([])): + doit = f.writelines + else: + doit = f.write + doit(contents) + f.close() + +def showdic(dic): + for k in dic.keys(): print("%15s : %s" % (k,dic[k])) +def dotted_spaces(txt=''): + return txt.replace(' ', '.') + +# TIP: win env vars http://www.winnetmag.com/Article/ArticleID/23873/23873.html +def get_rc_path(): + "Return the full path for the users' RC file" + # Try to get the path from an env var. if yes, we're done + user_defined = os.environ.get('T2TCONFIG') + if user_defined: return user_defined + # Env var not found, so perform automatic path composing + # Set default filename according system platform + rc_names = {'default':'.txt2tagsrc', 'win':'_t2trc'} + rc_file = rc_names.get(sys.platform[:3]) or rc_names['default'] + # The file must be on the user directory, but where is this dir? + rc_dir_search = ['HOME', 'HOMEPATH'] + for var in rc_dir_search: + rc_dir = os.environ.get(var) + if rc_dir: break + # rc dir found, now we must join dir+file to compose the full path + if rc_dir: + # Compose path and return it if the file exists + rc_path = os.path.join(rc_dir, rc_file) + # On windows, prefix with the drive (%homedrive%: 2k/XP/NT) + if sys.platform.startswith('win'): + rc_drive = os.environ.get('HOMEDRIVE') + rc_path = os.path.join(rc_drive,rc_path) + return rc_path + # Sorry, not found + return '' + + + +############################################################################## + +class CommandLine: + """ + Command Line class - Masters command line + + This class checks and extract data from the provided command line. + The --long options and flags are taken from the global OPTIONS, + FLAGS and ACTIONS dictionaries. The short options are registered + here, and also their equivalence to the long ones. + + _compose_short_opts() -> str + _compose_long_opts() -> list + Compose the valid short and long options list, on the + 'getopt' format. + + parse() -> (opts, args) + Call getopt to check and parse the command line. + It expects to receive the command line as a list, and + without the program name (sys.argv[1:]). + + get_raw_config() -> [RAW config] + Scans command line and convert the data to the RAW config + format. See ConfigMaster class to the RAW format description. + Optional 'ignore' and 'filter_' arguments are used to filter + in or out specified keys. + + compose_cmdline(dict) -> [Command line] + Compose a command line list from an already parsed config + dictionary, generated from RAW by ConfigMaster(). Use + this to compose an optimal command line for a group of + options. + + The get_raw_config() calls parse(), so the typical use of this + class is: + + raw = CommandLine().get_raw_config(sys.argv[1:]) + """ + def __init__(self): + self.all_options = list(OPTIONS.keys()) + self.all_flags = list(FLAGS.keys()) + self.all_actions = list(ACTIONS.keys()) + + # short:long options equivalence + self.short_long = { + 'C':'config-file', + 'h':'help', + 'H':'no-headers', + 'i':'infile', + 'n':'enum-title', + 'o':'outfile', + 'q':'quiet', + 't':'target', + 'v':'verbose', + 'V':'version', + } + + # Compose valid short and long options data for getopt + self.short_opts = self._compose_short_opts() + self.long_opts = self._compose_long_opts() + + def _compose_short_opts(self): + "Returns a string like 'hVt:o' with all short options/flags" + ret = [] + for opt in self.short_long.keys(): + long_ = self.short_long[opt] + if long_ in self.all_options: # is flag or option? + opt = opt+':' # option: have param + ret.append(opt) + #Debug('Valid SHORT options: %s'%ret) + return ''.join(ret) + + def _compose_long_opts(self): + "Returns a list with all the valid long options/flags" + ret = [x+'=' for x in self.all_options] # add = + ret.extend(self.all_flags) # flag ON + ret.extend(self.all_actions) # actions + ret.extend(['no-'+x for x in self.all_flags]) # add no-* + ret.extend(['no-style','no-encoding']) # turn OFF + ret.extend(['no-outfile','no-infile']) # turn OFF + ret.extend(['no-dump-config', 'no-dump-source']) # turn OFF + ret.extend(['no-targets']) # turn OFF + #Debug('Valid LONG options: %s'%ret) + return ret + + def _tokenize(self, cmd_string=''): + "Convert a command line string to a list" + #TODO protect quotes contents -- Don't use it, pass cmdline as list + return cmd_string.split() + + def parse(self, cmdline=[]): + "Check/Parse a command line list TIP: no program name!" + # Get the valid options + short, long_ = self.short_opts, self.long_opts + # Parse it! + try: + opts, args = getopt.getopt(cmdline, short, long_) + except getopt.error as errmsg: + Error(_("%s (try --help)")%errmsg) + return (opts, args) + + def get_raw_config(self, cmdline=[], ignore=[], filter_=[], relative=0): + "Returns the options/arguments found as RAW config" + + if not cmdline: return [] + ret = [] + + # We need lists, not strings (such as from %!options) + if type(cmdline) in (type(''), type('')): + cmdline = self._tokenize(cmdline) + + # Extract name/value pair of all configs, check for invalid names + options, arguments = self.parse(cmdline[:]) + + # Some cleanup on the raw config + for name, value in options: + + # Remove leading - and -- + name = re.sub('^--?', '', name) + + # Fix old misspelled --suGGar, --no-suGGar + name = name.replace('suggar', 'sugar') + + # Translate short option to long + if len(name) == 1: + name = self.short_long[name] + + # Outfile exception: path relative to PWD + if name == 'outfile' and relative and value not in [STDOUT, MODULEOUT]: + value = os.path.abspath(value) + + # -C, --config-file inclusion, path relative to PWD + if name == 'config-file': + ret.extend(ConfigLines().include_config_file(value)) + continue + + # Save this config + ret.append(['all', name, value]) + + # All configuration was read and saved + + # Get infile, if any + while arguments: + infile = arguments.pop(0) + ret.append(['all', 'infile', infile]) + + # Apply 'ignore' and 'filter_' rules (filter_ is stronger) + if (ignore or filter_): + filtered = [] + for target, name, value in ret: + if (filter_ and name in filter_) or \ + (ignore and name not in ignore): + filtered.append([target, name, value]) + ret = filtered[:] + + # Add the original command line string as 'realcmdline' + ret.append( ['all', 'realcmdline', cmdline] ) + + return ret + + def compose_cmdline(self, conf={}, no_check=0): + "compose a full (and diet) command line from CONF dict" + if not conf: return [] + args = [] + dft_options = OPTIONS.copy() + cfg = conf.copy() + valid_opts = self.all_options + self.all_flags + use_short = {'no-headers':'H', 'enum-title':'n'} + # Remove useless options + if not no_check and cfg.get('toc-only'): + if 'no-headers' in cfg: + del cfg['no-headers'] + if 'outfile' in cfg: + del cfg['outfile'] # defaults to STDOUT + if cfg.get('target') == 'txt': + del cfg['target'] # already default + args.append('--toc-only') # must be the first + del cfg['toc-only'] + # Add target type + if 'target' in cfg: + args.append('-t '+cfg['target']) + del cfg['target'] + # Add other options + for key in cfg.keys(): + if key not in valid_opts: continue # may be a %!setting + if key == 'outfile' or key == 'infile': continue # later + val = cfg[key] + if not val: continue + # Default values are useless on cmdline + if val == dft_options.get(key): continue + # -short format + if key in use_short.keys(): + args.append('-'+use_short[key]) + continue + # --long format + if key in self.all_flags: # add --option + args.append('--'+key) + else: # add --option=value + args.append('--%s=%s'%(key,val)) + # The outfile using -o + if 'outfile' in cfg and \ + cfg['outfile'] != dft_options.get('outfile'): + args.append('-o '+cfg['outfile']) + # Place input file(s) always at the end + if 'infile' in cfg: + args.append(' '.join(cfg['infile'])) + # Return as a nice list + Debug("Diet command line: %s"%' '.join(args), 1) + return args + +############################################################################## + +class SourceDocument: + """ + SourceDocument class - scan document structure, extract data + + It knows about full files. It reads a file and identify all + the areas beginning (Head,Conf,Body). With this info it can + extract each area contents. + Note: the original line break is removed. + + DATA: + self.arearef - Save Head, Conf, Body init line number + self.areas - Store the area names which are not empty + self.buffer - The full file contents (with NO \\r, \\n) + + METHODS: + get() - Access the contents of an Area. Example: + config = SourceDocument(file).get('conf') + + split() - Get all the document Areas at once. Example: + head, conf, body = SourceDocument(file).split() + + RULES: + * The document parts are sequential: Head, Conf and Body. + * One ends when the next begins. + * The Conf Area is optional, so a document can have just + Head and Body Areas. + + These are the Areas limits: + - Head Area: the first three lines + - Body Area: from the first valid text line to the end + - Conf Area: the comments between Head and Body Areas + + Exception: If the first line is blank, this means no + header info, so the Head Area is just the first line. + """ + def __init__(self, filename='', contents=[]): + self.areas = ['head','conf','body'] + self.arearef = [] + self.areas_fancy = '' + self.filename = filename + self.buffer = [] + if filename: + self.scan_file(filename) + elif contents: + self.scan(contents) + + def split(self): + "Returns all document parts, splitted into lists." + return self.get('head'), self.get('conf'), self.get('body') + + def get(self, areaname): + "Returns head|conf|body contents from self.buffer" + # Sanity + if areaname not in self.areas: return [] + if not self.buffer : return [] + # Go get it + bufini = 1 + bufend = len(self.buffer) + if areaname == 'head': + ini = bufini + end = self.arearef[1] or self.arearef[2] or bufend + elif areaname == 'conf': + ini = self.arearef[1] + end = self.arearef[2] or bufend + elif areaname == 'body': + ini = self.arearef[2] + end = bufend + else: + Error("Unknown Area name '%s'"%areaname) + lines = self.buffer[ini:end] + # Make sure head will always have 3 lines + while areaname == 'head' and len(lines) < 3: + lines.append('') + return lines + + def scan_file(self, filename): + Debug("source file: %s"%filename) + Message(_("Loading source document"),1) + buf = Readfile(filename, remove_linebreaks=1) + self.scan(buf) + + def scan(self, lines): + "Run through source file and identify head/conf/body areas" + buf = lines + if len(buf) == 0: + Error(_('The input file is empty: %s')%self.filename) + cfg_parser = ConfigLines().parse_line + buf.insert(0, '') # text start at pos 1 + ref = [1,4,0] + if not buf[1].strip(): # no header + ref[0] = 0 ; ref[1] = 2 + rgx = getRegexes() + on_comment_block = 0 + for i in range(ref[1],len(buf)): # find body init: + # Handle comment blocks inside config area + if not on_comment_block \ + and rgx['blockCommentOpen'].search(buf[i]): + on_comment_block = 1 + continue + if on_comment_block \ + and rgx['blockCommentOpen'].search(buf[i]): + on_comment_block = 0 + continue + if on_comment_block: continue + + if buf[i].strip() and ( # ... not blank and + buf[i][0] != '%' or # ... not comment or + rgx['macros'].match(buf[i]) or # ... %%macro + rgx['toc'].match(buf[i]) or # ... %%toc + cfg_parser(buf[i],'include')[1] or # ... %!include + cfg_parser(buf[i],'csv')[1] # ... %!csv + ): + ref[2] = i ; break + if ref[1] == ref[2]: ref[1] = 0 # no conf area + for i in 0,1,2: # del !existent + if ref[i] >= len(buf): ref[i] = 0 # title-only + if not ref[i]: self.areas[i] = '' + Debug('Head,Conf,Body start line: %s'%ref) + self.arearef = ref # save results + self.buffer = buf + # Fancyness sample: head conf body (1 4 8) + self.areas_fancy = "%s (%s)"%( + ' '.join(self.areas), + ' '.join(map(str, [x or '' for x in ref]))) + Message(_("Areas found: %s")%self.areas_fancy, 2) + + def get_raw_config(self): + "Handy method to get the CONF area RAW config (if any)" + if not self.areas.count('conf'): return [] + Message(_("Scanning source document CONF area"),1) + raw = ConfigLines( + file_=self.filename, lines=self.get('conf'), + first_line=self.arearef[1]).get_raw_config() + Debug("document raw config: %s"%raw, 1) + return raw + +############################################################################## + +class ConfigMaster: + """ + ConfigMaster class - the configuration wizard + + This class is the configuration master. It knows how to handle + the RAW and PARSED config format. It also performs the sanity + checking for a given configuration. + + DATA: + self.raw - Stores the config on the RAW format + self.parsed - Stores the config on the PARSED format + self.defaults - Stores the default values for all keys + self.off - Stores the OFF values for all keys + self.multi - List of keys which can have multiple values + self.numeric - List of keys which value must be a number + self.incremental - List of keys which are incremental + + RAW FORMAT: + The RAW format is a list of lists, being each mother list item + a full configuration entry. Any entry is a 3 item list, on + the following format: [ TARGET, KEY, VALUE ] + Being a list, the order is preserved, so it's easy to use + different kinds of configs, as CONF area and command line, + respecting the precedence. + The special target 'all' is used when no specific target was + defined on the original config. + + PARSED FORMAT: + The PARSED format is a dictionary, with all the 'key : value' + found by reading the RAW config. The self.target contents + matters, so this dictionary only contains the target's + config. The configs of other targets are ignored. + + The CommandLine and ConfigLines classes have the get_raw_config() + method which convert the configuration found to the RAW format. + Just feed it to parse() and get a brand-new ready-to-use config + dictionary. Example: + + >>> raw = CommandLine().get_raw_config(['-n', '-H']) + >>> print raw + [['all', 'enum-title', ''], ['all', 'no-headers', '']] + >>> parsed = ConfigMaster(raw).parse() + >>> print parsed + {'enum-title': 1, 'headers': 0} + """ + def __init__(self, raw=[], target=''): + self.raw = raw + self.target = target + self.parsed = {} + self.dft_options = OPTIONS.copy() + self.dft_flags = FLAGS.copy() + self.dft_actions = ACTIONS.copy() + self.dft_settings = SETTINGS.copy() + self.defaults = self._get_defaults() + self.off = self._get_off() + self.incremental = ['verbose'] + self.numeric = ['toc-level', 'split', 'width', 'height'] + self.multi = ['infile', 'preproc', 'postproc', 'options', 'style'] + + def _get_defaults(self): + "Get the default values for all config/options/flags" + empty = {} + for kw in CONFIG_KEYWORDS: empty[kw] = '' + empty.update(self.dft_options) + empty.update(self.dft_flags) + empty.update(self.dft_actions) + empty.update(self.dft_settings) + empty['realcmdline'] = '' # internal use only + empty['sourcefile'] = '' # internal use only + return empty + + def _get_off(self): + "Turns OFF all the config/options/flags" + off = {} + for key in self.defaults.keys(): + kind = type(self.defaults[key]) + if isinstance(0, kind): + off[key] = 0 + elif isinstance('', kind): + off[key] = '' + elif isinstance([], kind): + off[key] = [] + else: + Error('ConfigMaster: %s: Unknown type' % key) + return off + + def _check_target(self): + "Checks if the target is already defined. If not, do it" + if not self.target: + self.target = self.find_value('target') + + def get_target_raw(self): + "Returns the raw config for self.target or 'all'" + ret = [] + self._check_target() + for entry in self.raw: + if entry[0] == self.target or entry[0] == 'all': + ret.append(entry) + return ret + + def add(self, key, val): + "Adds the key:value pair to the config dictionary (if needed)" + # %!options + if key == 'options': + ignoreme = list(self.dft_actions.keys()) + ['target'] + ignoreme.remove('dump-config') + ignoreme.remove('dump-source') + ignoreme.remove('targets') + raw_opts = CommandLine().get_raw_config( + val, ignore=ignoreme) + for target, key, val in raw_opts: + self.add(key, val) + return + # The no- prefix turns OFF this key + if key.startswith('no-'): + key = key[3:] # remove prefix + val = self.off.get(key) # turn key OFF + # Is this key valid? + if key not in self.defaults.keys(): + Debug('Bogus Config %s:%s'%(key,val),1) + return + # Is this value the default one? + if val == self.defaults.get(key): + # If default value, remove previous key:val + if key in self.parsed: + del self.parsed[key] + # Nothing more to do + return + # Flags ON comes empty. we'll add the 1 value now + if val == '' and ( + key in self.dft_flags.keys() or + key in self.dft_actions.keys()): + val = 1 + # Multi value or single? + if key in self.multi: + # First one? start new list + if key not in self.parsed: + self.parsed[key] = [] + self.parsed[key].append(val) + # Incremental value? so let's add it + elif key in self.incremental: + self.parsed[key] = (self.parsed.get(key) or 0) + val + else: + self.parsed[key] = val + fancykey = dotted_spaces("%12s"%key) + Message(_("Added config %s : %s")%(fancykey,val),3) + + def get_outfile_name(self, config={}): + "Dirname is the same for {in,out}file" + infile, outfile = config['sourcefile'], config['outfile'] + if outfile and outfile not in (STDOUT, MODULEOUT) \ + and not os.path.isabs(outfile): + outfile = os.path.join(os.path.dirname(infile), outfile) + if infile == STDIN and not outfile: outfile = STDOUT + if infile == MODULEIN and not outfile: outfile = MODULEOUT + if not outfile and (infile and config.get('target')): + basename = re.sub('\.(txt|t2t)$','',infile) + outfile = "%s.%s"%(basename, config['target']) + Debug(" infile: '%s'"%infile , 1) + Debug("outfile: '%s'"%outfile, 1) + return outfile + + def sanity(self, config, gui=0): + "Basic config sanity checking" + global AA + if not config: return {} + target = config.get('target') + # Some actions don't require target specification + if not target: + for action in NO_TARGET: + if config.get(action): + target = 'txt' + break + # On GUI, some checking are skipped + if not gui: + # We *need* a target + if not target: + Error(_('No target specified (try --help)') + '\n\n' + + _('Please inform a target using the -t option or the %!target command.') + '\n' + + _('Example:') + ' %s -t html %s' % (my_name, _('file.t2t')) + '\n\n' + + _("Run 'txt2tags --targets' to see all the available targets.")) + # And of course, an infile also + # TODO#1: It seems that this checking is never reached + if not config.get('infile'): + Error(_('Missing input file (try --help)')) + # Is the target valid? + if not TARGETS.count(target): + Error(_("Invalid target '%s'") % target + '\n\n' + + _("Run 'txt2tags --targets' to see all the available targets.")) + # Ensure all keys are present + empty = self.defaults.copy() ; empty.update(config) + config = empty.copy() + # Check integers options + for key in config.keys(): + if key in self.numeric: + try: + config[key] = int(config[key]) + except ValueError: + Error(_('--%s value must be a number') % key) + # Check split level value + if config['split'] not in (0,1,2): + Error(_('Option --split must be 0, 1 or 2')) + # Slides needs width and height + if config['slides'] and target == 'art': + if not config['width']: + config['width'] = DFT_SLIDE_WIDTH + if not config['height']: + config['height'] = DFT_SLIDE_HEIGHT + # ASCII Art needs a width + if target == 'art' and not config['width']: + config['width'] = DFT_TEXT_WIDTH + # Check/set user ASCII Art formatting characters + if config['art-chars']: + if len(config['art-chars']) != len(AA_VALUES): + Error(_("--art-chars: Expected %i chars, got %i") % ( + len(AA_VALUES), len(config['art-chars']))) + else: + AA = dict(zip(AA_KEYS, config['art-chars'])) + # --toc-only is stronger than others + if config['toc-only']: + config['headers'] = 0 + config['toc'] = 0 + config['split'] = 0 + config['gui'] = 0 + config['outfile'] = config['outfile'] or STDOUT + # Splitting is disable for now (future: HTML only, no STDOUT) + config['split'] = 0 + # Restore target + config['target'] = target + # Set output file name + config['outfile'] = self.get_outfile_name(config) + # Checking suicide + if config['sourcefile'] == config['outfile'] and \ + config['outfile'] not in [STDOUT,MODULEOUT] and not gui: + Error(_("Input and Output files are the same: %s") % config['outfile']) + return config + + def parse(self): + "Returns the parsed config for the current target" + raw = self.get_target_raw() + for target, key, value in raw: + self.add(key, value) + Message(_("Added the following keys: %s") % ', '.join(self.parsed.keys()), 2) + return self.parsed.copy() + + def find_value(self, key='', target=''): + "Scans ALL raw config to find the desired key" + ret = [] + # Scan and save all values found + for targ, k, val in self.raw: + if k == key and (targ == target or targ == 'all'): + ret.append(val) + if not ret: return '' + # If not multi value, return only the last found + if key in self.multi: return ret + else : return ret[-1] + +######################################################################## + +class ConfigLines: + """ + ConfigLines class - the config file data extractor + + This class reads and parse the config lines on the %!key:val + format, converting it to RAW config. It deals with user + config file (RC file), source document CONF area and + %!includeconf directives. + + Call it passing a file name or feed the desired config lines. + Then just call the get_raw_config() method and wait to + receive the full config data on the RAW format. This method + also follows the possible %!includeconf directives found on + the config lines. Example: + + raw = ConfigLines(file=".txt2tagsrc").get_raw_config() + + The parse_line() method is also useful to be used alone, + to identify and tokenize a single config line. For example, + to get the %!include command components, on the source + document BODY: + + target, key, value = ConfigLines().parse_line(body_line) + """ + def __init__(self, file_='', lines=[], first_line=1): + self.file = file_ or 'NOFILE' + self.lines = lines + self.first_line = first_line + + def load_lines(self): + "Make sure we've loaded the file contents into buffer" + if not self.lines and not self.file: + Error("ConfigLines: No file or lines provided") + if not self.lines: + self.lines = self.read_config_file(self.file) + + def read_config_file(self, filename=''): + "Read a Config File contents, aborting on invalid line" + if not filename: return [] + errormsg = _("Invalid CONFIG line on %s")+"\n%03d:%s" + lines = Readfile(filename, remove_linebreaks=1) + # Sanity: try to find invalid config lines + for i in range(len(lines)): + line = lines[i].rstrip() + if not line: continue # empty + if line[0] != '%': Error(errormsg%(filename,i+1,line)) + return lines + + def include_config_file(self, file_=''): + "Perform the %!includeconf action, returning RAW config" + if not file_: return [] + # Current dir relative to the current file (self.file) + current_dir = os.path.dirname(self.file) + file_ = os.path.join(current_dir, file_) + # Read and parse included config file contents + lines = self.read_config_file(file_) + return ConfigLines(file_=file_, lines=lines).get_raw_config() + + def get_raw_config(self): + "Scan buffer and extract all config as RAW (including includes)" + ret = [] + self.load_lines() + first = self.first_line + for i in range(len(self.lines)): + line = self.lines[i] + Message(_("Processing line %03d: %s")%(first+i,line),2) + target, key, val = self.parse_line(line) + if not key: continue # no config on this line + if key == 'includeconf': + err = _('A file cannot include itself (loop!)') + if val == self.file: + Error("%s: %%!includeconf: %s" % (err, self.file)) + more_raw = self.include_config_file(val) + ret.extend(more_raw) + Message(_("Finished Config file inclusion: %s") % val, 2) + else: + ret.append([target, key, val]) + Message(_("Added %s")%key,3) + return ret + + def parse_line(self, line='', keyname='', target=''): + "Detects %!key:val config lines and extract data from it" + empty = ['', '', ''] + if not line: return empty + no_target = ['target', 'includeconf'] + re_name = keyname or '[a-z]+' + re_target = target or '[a-z]*' + # XXX TODO <value>\S.+? requires TWO chars, breaks %!include:a + cfgregex = re.compile(""" + ^%%!\s* # leading id with opt spaces + (?P<name>%s)\s* # config name + (\((?P<target>%s)\))? # optional target spec inside () + \s*:\s* # key:value delimiter with opt spaces + (?P<value>\S.+?) # config value + \s*$ # rstrip() spaces and hit EOL + """%(re_name, re_target), re.I+re.VERBOSE) + prepostregex = re.compile(""" + # ---[ PATTERN ]--- + ^( "([^"]*)" # "double quoted" or + | '([^']*)' # 'single quoted' or + | ([^\s]+) # single_word + ) + \s+ # separated by spaces + + # ---[ REPLACE ]--- + ( "([^"]*)" # "double quoted" or + | '([^']*)' # 'single quoted' or + | (.*) # anything + ) + \s*$ + """, re.VERBOSE) + guicolors = re.compile("^([^\s]+\s+){3}[^\s]+") # 4 tokens + + # Give me a match or get out + match = cfgregex.match(line) + if not match: return empty + + # Save information about this config + name = (match.group('name') or '').lower() + target = (match.group('target') or 'all').lower() + value = match.group('value') + + # %!keyword(target) not allowed for these + if name in no_target and match.group('target'): + Error( + _("You can't use (target) with %s") % ('%!' + name) + + "\n%s" % line) + + # Force no_target keywords to be valid for all targets + if name in no_target: + target = 'all' + + # Special config for GUI colors + if name == 'guicolors': + valmatch = guicolors.search(value) + if not valmatch: return empty + value = re.split('\s+', value) + + # Special config with two quoted values (%!preproc: "foo" 'bar') + if name == 'preproc' or name == 'postproc': + valmatch = prepostregex.search(value) + if not valmatch: return empty + getval = valmatch.group + patt = getval(2) or getval(3) or getval(4) or '' + repl = getval(6) or getval(7) or getval(8) or '' + value = (patt, repl) + return [target, name, value] + +############################################################################## + +class MaskMaster: + "(Un)Protect important structures from escaping and formatting" + def __init__(self): + self.linkmask = 'vvvLINKvvv' + self.monomask = 'vvvMONOvvv' + self.macromask = 'vvvMACROvvv' + self.rawmask = 'vvvRAWvvv' + self.taggedmask= 'vvvTAGGEDvvv' + self.tocmask = 'vvvTOCvvv' + self.macroman = MacroMaster() + self.reset() + + def reset(self): + self.linkbank = [] + self.monobank = [] + self.macrobank = [] + self.rawbank = [] + self.taggedbank = [] + + def mask(self, line=''): + global AUTOTOC + + # The verbatim, raw and tagged inline marks are mutually exclusive. + # This means that one can't appear inside the other. + # If found, the inner marks must be ignored. + # Example: ``foo ""bar"" ''baz''`` + # In HTML: <code>foo ""bar"" ''baz''</code> + # + # The trick here is to protect the mark who appears first on the line. + # The three regexes are tried and the one with the lowest index wins. + # If none is found (else), we get out of the loop. + # + while True: + + # Try to match the line for the three marks + # Note: 'z' > 999999 + # + t = r = v = 1000000 #Python 3 doesn't allow comparison between str and int! + try: t = regex['tagged'].search(line).start() + except: pass + try: r = regex['raw'].search(line).start() + except: pass + try: v = regex['fontMono'].search(line).start() + except: pass + + # Protect tagged text + if t >= 0 and t < r and t < v: + txt = regex['tagged'].search(line).group(1) + self.taggedbank.append(txt) + line = regex['tagged'].sub(self.taggedmask,line,1) + + # Protect raw text + elif r >= 0 and r < t and r < v: + txt = regex['raw'].search(line).group(1) + txt = doEscape(TARGET,txt) + self.rawbank.append(txt) + line = regex['raw'].sub(self.rawmask,line,1) + + # Protect verbatim text + elif v >= 0 and v < t and v < r: + txt = regex['fontMono'].search(line).group(1) + txt = doEscape(TARGET,txt) + self.monobank.append(txt) + line = regex['fontMono'].sub(self.monomask,line,1) + else: + break + + # Protect macros + while regex['macros'].search(line): + txt = regex['macros'].search(line).group() + self.macrobank.append(txt) + line = regex['macros'].sub(self.macromask,line,1) + + # Protect TOC location + while regex['toc'].search(line): + line = regex['toc'].sub(self.tocmask,line) + AUTOTOC = 0 + + # Protect URLs and emails + while regex['linkmark'].search(line) or \ + regex['link' ].search(line): + + # Try to match plain or named links + match_link = regex['link'].search(line) + match_named = regex['linkmark'].search(line) + + # Define the current match + if match_link and match_named: + # Both types found, which is the first? + m = match_link + if match_named.start() < match_link.start(): + m = match_named + else: + # Just one type found, we're fine + m = match_link or match_named + + # Extract link data and apply mask + if m == match_link: # plain link + link = m.group() + label = '' + link_re = regex['link'] + else: # named link + link = m.group('link') + label = m.group('label').rstrip() + link_re = regex['linkmark'] + line = link_re.sub(self.linkmask,line,1) + + # Save link data to the link bank + self.linkbank.append((label, link)) + return line + + def undo(self, line): + + # url & email + for label,url in self.linkbank: + link = get_tagged_link(label, url) + line = line.replace(self.linkmask, link, 1) + + # Expand macros + for macro in self.macrobank: + macro = self.macroman.expand(macro) + line = line.replace(self.macromask, macro, 1) + + # Expand verb + for mono in self.monobank: + open_,close = TAGS['fontMonoOpen'],TAGS['fontMonoClose'] + line = line.replace(self.monomask, open_+mono+close, 1) + + # Expand raw + for raw in self.rawbank: + line = line.replace(self.rawmask, raw, 1) + + # Expand tagged + for tagged in self.taggedbank: + line = line.replace(self.taggedmask, tagged, 1) + + return line + + +############################################################################## + + +class TitleMaster: + "Title things" + def __init__(self): + self.count = ['',0,0,0,0,0] + self.toc = [] + self.level = 0 + self.kind = '' + self.txt = '' + self.label = '' + self.tag = '' + self.tag_hold = [] + self.last_level = 0 + self.count_id = '' + self.user_labels = {} + self.anchor_count = 0 + self.anchor_prefix = 'toc' + + def _open_close_blocks(self): + "Open new title blocks, closing the previous (if any)" + if not rules['titleblocks']: return + tag = '' + last = self.last_level + curr = self.level + + # Same level, just close the previous + if curr == last: + tag = TAGS.get('title%dClose'%last) + if tag: self.tag_hold.append(tag) + + # Section -> subsection, more depth + while curr > last: + last += 1 + + # Open the new block of subsections + tag = TAGS.get('blockTitle%dOpen'%last) + if tag: self.tag_hold.append(tag) + + # Jump from title1 to title3 or more + # Fill the gap with an empty section + if curr - last > 0: + tag = TAGS.get('title%dOpen'%last) + tag = regex['x'].sub('', tag) # del \a + if tag: self.tag_hold.append(tag) + + # Section <- subsection, less depth + while curr < last: + # Close the current opened subsection + tag = TAGS.get('title%dClose'%last) + if tag: self.tag_hold.append(tag) + + # Close the current opened block of subsections + tag = TAGS.get('blockTitle%dClose'%last) + if tag: self.tag_hold.append(tag) + + last -= 1 + + # Close the previous section of the same level + # The subsections were under it + if curr == last: + tag = TAGS.get('title%dClose'%last) + if tag: self.tag_hold.append(tag) + + def add(self, line): + "Parses a new title line." + if not line: return + self._set_prop(line) + self._open_close_blocks() + self._set_count_id() + self._set_label() + self._save_toc_info() + + def close_all(self): + "Closes all opened title blocks" + ret = [] + ret.extend(self.tag_hold) + while self.level: + tag = TAGS.get('title%dClose'%self.level) + if tag: ret.append(tag) + tag = TAGS.get('blockTitle%dClose'%self.level) + if tag: ret.append(tag) + self.level -= 1 + return ret + + def _save_toc_info(self): + "Save TOC info, used by self.dump_marked_toc()" + self.toc.append((self.level, self.count_id, self.txt, self.label)) + + def _set_prop(self, line=''): + "Extract info from original line and set data holders." + # Detect title type (numbered or not) + id_ = line.lstrip()[0] + if id_ == '=': kind = 'title' + elif id_ == '+': kind = 'numtitle' + else: Error("Unknown Title ID '%s'"%id_) + # Extract line info + match = regex[kind].search(line) + level = len(match.group('id')) + txt = match.group('txt').strip() + label = match.group('label') + # Parse info & save + if CONF['enum-title']: kind = 'numtitle' # force + if rules['titleblocks']: + self.tag = TAGS.get('%s%dOpen'%(kind,level)) or \ + TAGS.get('title%dOpen'%level) + else: + self.tag = TAGS.get(kind+repr(level)) or \ + TAGS.get('title'+repr(level)) + self.last_level = self.level + self.kind = kind + self.level = level + self.txt = txt + self.label = label + + def _set_count_id(self): + "Compose and save the title count identifier (if needed)." + count_id = '' + if self.kind == 'numtitle' and not rules['autonumbertitle']: + # Manually increase title count + self.count[self.level] += 1 + # Reset sublevels count (if any) + max_levels = len(self.count) + if self.level < max_levels-1: + for i in range(self.level+1, max_levels): + self.count[i] = 0 + # Compose count id from hierarchy + for i in range(self.level): + count_id= "%s%d."%(count_id, self.count[i+1]) + self.count_id = count_id + + def _set_label(self): + "Compose and save title label, used by anchors." + # Remove invalid chars from label set by user + self.label = re.sub('[^A-Za-z0-9_-]', '', self.label or '') + # Generate name as 15 first :alnum: chars + #TODO how to translate safely accented chars to plain? + #self.label = re.sub('[^A-Za-z0-9]', '', self.txt)[:15] + # 'tocN' label - sequential count, ignoring 'toc-level' + #self.label = self.anchor_prefix + str(len(self.toc)+1) + + def _get_tagged_anchor(self): + "Return anchor if user defined a label, or TOC is on." + ret = '' + label = self.label + if CONF['toc'] and self.level <= CONF['toc-level']: + # This count is needed bcos self.toc stores all + # titles, regardless of the 'toc-level' setting, + # so we can't use self.toc length to number anchors + self.anchor_count += 1 + # Autonumber label (if needed) + label = label or '%s%s' % (self.anchor_prefix, self.anchor_count) + if label and TAGS['anchor']: + ret = regex['x'].sub(label,TAGS['anchor']) + return ret + + def _get_full_title_text(self): + "Returns the full title contents, already escaped." + ret = self.txt + # Insert count_id (if any) before text + if self.count_id: + ret = '%s %s'%(self.count_id, ret) + # Escape specials + ret = doEscape(TARGET, ret) + # Same targets needs final escapes on title lines + # It's here because there is a 'continue' after title + if rules['finalescapetitle']: + ret = doFinalEscape(TARGET, ret) + return ret + + def get(self): + "Returns the tagged title as a list." + global AA_TITLE + ret = [] + + # Maybe some anchoring before? + anchor = self._get_tagged_anchor() + self.tag = regex['_anchor'].sub(anchor, self.tag) + + ### Compose & escape title text (TOC uses unescaped) + full_title = self._get_full_title_text() + + # Close previous section area + ret.extend(self.tag_hold) + self.tag_hold = [] + + tagged = regex['x'].sub(full_title, self.tag) + + # Adds "underline" on TXT target + if TARGET == 'txt': + if BLOCK.count > 1: ret.append('') # blank line before + ret.append(tagged) + #Can't be used on Python 3 because every string is unicode unless declared as b'non-unicode string. Array of bytes' + #It doesn't support 'decode' + # + # Get the right letter count for UTF + #if CONF['encoding'].lower() == 'utf-8': + # i = len(full_title.decode('utf-8')) + #else: + i = len(full_title) + ret.append(regex['x'].sub('='*i, self.tag)) + elif TARGET == 'art' and self.level == 1: + if CONF['slides'] : + AA_TITLE = tagged + else : + if BLOCK.count > 1: ret.append('') # blank line before + ret.extend(aa_box(tagged, CONF['width'])) + elif TARGET == 'art': + level = 'level'+str(self.level) + if BLOCK.count > 1: ret.append('') # blank line before + ret.append(tagged) + ret.append(AA[level] * len(full_title)) + else: + ret.append(tagged) + return ret + + def dump_marked_toc(self, max_level=99): + "Dumps all toc itens as a valid t2t-marked list" + ret = [] + toc_count = 1 + for level, count_id, txt, label in self.toc: + if level > max_level: continue # ignore + indent = ' '*level + id_txt = ('%s %s'%(count_id, txt)).lstrip() + label = label or self.anchor_prefix+repr(toc_count) + toc_count += 1 + + # TOC will have crosslinks to anchors + if TAGS['anchor']: + if CONF['enum-title'] and level == 1: + # 1. [Foo #anchor] is more readable than [1. Foo #anchor] in level 1. + # This is a stoled idea from Windows .CHM help files. + tocitem = '%s+ [""%s"" #%s]' % (indent, txt, label) + else: + tocitem = '%s- [""%s"" #%s]' % (indent, id_txt, label) + + # TOC will be plain text (no links) + else: + if TARGET in ['txt', 'man', 'art']: + # For these, the list is not necessary, just dump the text + tocitem = '%s""%s""' % (indent, id_txt) + else: + tocitem = '%s- ""%s""' % (indent, id_txt) + ret.append(tocitem) + return ret + + +############################################################################## + +#TODO check all this table mess +# It uses parse_row properties for table lines +# BLOCK.table() replaces the cells by the parsed content +class TableMaster: + def __init__(self, line=''): + self.rows = [] + self.border = 0 + self.align = 'Left' + self.cellalign = [] + self.colalign = [] + self.cellspan = [] + if line: + prop = self.parse_row(line) + self.border = prop['border'] + self.align = prop['align'] + self.cellalign = prop['cellalign'] + self.cellspan = prop['cellspan'] + self.colalign = self._get_col_align() + + def _get_col_align(self): + colalign = [] + for cell in range(0,len(self.cellalign)): + align = self.cellalign[cell] + span = self.cellspan[cell] + colalign.extend([align] * span) + return colalign + + def _get_open_tag(self): + topen = TAGS['tableOpen'] + tborder = TAGS['_tableBorder'] + talign = TAGS['_tableAlign'+self.align] + calignsep = TAGS['tableColAlignSep'] + calign = '' + + # The first line defines if table has border or not + if not self.border: tborder = '' + # Set the columns alignment + if rules['tablecellaligntype'] == 'column': + calign = [TAGS['_tableColAlign%s'%x] for x in self.colalign] + calign = calignsep.join(calign) + # Align full table, set border and Column align (if any) + topen = regex['_tableAlign' ].sub(talign , topen) + topen = regex['_tableBorder' ].sub(tborder, topen) + topen = regex['_tableColAlign'].sub(calign , topen) + # Tex table spec, border or not: {|l|c|r|} , {lcr} + if calignsep and not self.border: + # Remove cell align separator + topen = topen.replace(calignsep, '') + return topen + + def _get_cell_align(self, cells): + ret = [] + for cell in cells: + align = 'Left' + if cell.strip(): + if cell[0] == ' ' and cell[-1] == ' ': + align = 'Center' + elif cell[0] == ' ': + align = 'Right' + ret.append(align) + return ret + + def _get_cell_span(self, cells): + ret = [] + for cell in cells: + span = 1 + m = re.search('\a(\|+)$', cell) + if m: span = len(m.group(1))+1 + ret.append(span) + return ret + + def _tag_cells(self, rowdata): + row = [] + cells = rowdata['cells'] + open_ = TAGS['tableCellOpen'] + close = TAGS['tableCellClose'] + sep = TAGS['tableCellSep'] + calign = [TAGS['_tableCellAlign'+x] for x in rowdata['cellalign']] + calignsep = TAGS['tableColAlignSep'] + ncolumns = len(self.colalign) + + # Populate the span and multicol open tags + cspan = [] + multicol = [] + colindex = 0 + for cellindex in range(0,len(rowdata['cellspan'])): + + span = rowdata['cellspan'][cellindex] + align = rowdata['cellalign'][cellindex] + + if span > 1: + cspan.append(regex['x'].sub( + str(span), TAGS['_tableCellColSpan'])) + + mcopen = regex['x'].sub(str(span), TAGS['_tableCellMulticolOpen']) + multicol.append(mcopen) + else: + cspan.append('') + + if colindex < ncolumns and align != self.colalign[colindex]: + mcopen = regex['x'].sub('1', TAGS['_tableCellMulticolOpen']) + multicol.append(mcopen) + else: + multicol.append('') + + if not self.border: + multicol[-1] = multicol[-1].replace(calignsep, '') + + colindex += span + + # Maybe is it a title row? + if rowdata['title']: + open_ = TAGS['tableTitleCellOpen'] or open_ + close = TAGS['tableTitleCellClose'] or close + sep = TAGS['tableTitleCellSep'] or sep + + # Should we break the line on *each* table cell? + if rules['breaktablecell']: close = close+'\n' + + # Cells pre processing + if rules['tablecellstrip']: + cells = [x.strip() for x in cells] + if rowdata['title'] and rules['tabletitlerowinbold']: + cells = [enclose_me('fontBold',x) for x in cells] + + # Add cell BEGIN/END tags + for cell in cells: + copen = open_ + cclose = close + # Make sure we will pop from some filled lists + # Fixes empty line bug '| |' + this_align = this_span = this_mcopen = '' + if calign: this_align = calign.pop(0) + if cspan : this_span = cspan.pop(0) + if multicol: this_mcopen = multicol.pop(0) + + # Insert cell align into open tag (if cell is alignable) + if rules['tablecellaligntype'] == 'cell': + copen = regex['_tableCellAlign'].sub( + this_align, copen) + + # Insert cell span into open tag (if cell is spannable) + if rules['tablecellspannable']: + copen = regex['_tableCellColSpan'].sub( + this_span, copen) + + # Use multicol tags instead (if multicol supported, and if + # cell has a span or is aligned differently to column) + if rules['tablecellmulticol']: + if this_mcopen: + copen = regex['_tableColAlign'].sub(this_align, this_mcopen) + cclose = TAGS['_tableCellMulticolClose'] + + row.append(copen + cell + cclose) + + # Maybe there are cell separators? + return sep.join(row) + + def add_row(self, cells): + self.rows.append(cells) + + def parse_row(self, line): + # Default table properties + ret = { + 'border':0, 'title':0, 'align':'Left', + 'cells':[], 'cellalign':[], 'cellspan':[] + } + # Detect table align (and remove spaces mark) + if line[0] == ' ': ret['align'] = 'Center' + line = line.lstrip() + # Detect title mark + if line[1] == '|': ret['title'] = 1 + # Detect border mark and normalize the EOL + m = re.search(' (\|+) *$', line) + if m: line = line+' ' ; ret['border'] = 1 + else: line = line+' | ' + # Delete table mark + line = regex['table'].sub('', line) + # Detect colspan | foo | bar baz ||| + line = re.sub(' (\|+)\| ', '\a\\1 | ', line) + # Split cells (the last is fake) + ret['cells'] = line.split(' | ')[:-1] + # Find cells span + ret['cellspan'] = self._get_cell_span(ret['cells']) + # Remove span ID + ret['cells'] = [re.sub('\a\|+$','',x) for x in ret['cells']] + # Find cells align + ret['cellalign'] = self._get_cell_align(ret['cells']) + # Hooray! + Debug('Table Prop: %s' % ret, 7) + return ret + + def dump(self): + open_ = self._get_open_tag() + rows = self.rows + close = TAGS['tableClose'] + + rowopen = TAGS['tableRowOpen'] + rowclose = TAGS['tableRowClose'] + rowsep = TAGS['tableRowSep'] + titrowopen = TAGS['tableTitleRowOpen'] or rowopen + titrowclose = TAGS['tableTitleRowClose'] or rowclose + + if rules['breaktablelineopen']: + rowopen = rowopen + '\n' + titrowopen = titrowopen + '\n' + + # Tex gotchas + if TARGET == 'tex': + if not self.border: + rowopen = titrowopen = '' + else: + close = rowopen + close + + # Now we tag all the table cells on each row + #tagged_cells = map(lambda x: self._tag_cells(x), rows) #!py15 + tagged_cells = [] + for cell in rows: tagged_cells.append(self._tag_cells(cell)) + + # Add row separator tags between lines + tagged_rows = [] + if rowsep: + #!py15 + #tagged_rows = map(lambda x:x+rowsep, tagged_cells) + for cell in tagged_cells: + tagged_rows.append(cell+rowsep) + # Remove last rowsep, because the table is over + tagged_rows[-1] = tagged_rows[-1].replace(rowsep, '') + # Add row BEGIN/END tags for each line + else: + for rowdata in rows: + if rowdata['title']: + o,c = titrowopen, titrowclose + else: + o,c = rowopen, rowclose + row = tagged_cells.pop(0) + tagged_rows.append(o + row + c) + + # Join the pieces together + fulltable = [] + if open_: fulltable.append(open_) + fulltable.extend(tagged_rows) + if close: fulltable.append(close) + + return fulltable + + +############################################################################## + + +class BlockMaster: + "TIP: use blockin/out to add/del holders" + def __init__(self): + self.BLK = [] + self.HLD = [] + self.PRP = [] + self.depth = 0 + self.count = 0 + self.last = '' + self.tableparser = None + self.contains = { + 'para' :['comment','raw','tagged'], + 'verb' :[], + 'table' :['comment'], + 'raw' :[], + 'tagged' :[], + 'comment' :[], + 'quote' :['quote','comment','raw','tagged'], + 'list' :['list','numlist','deflist','para','verb','comment','raw','tagged'], + 'numlist' :['list','numlist','deflist','para','verb','comment','raw','tagged'], + 'deflist' :['list','numlist','deflist','para','verb','comment','raw','tagged'], + 'bar' :[], + 'title' :[], + 'numtitle':[], + } + self.allblocks = list(self.contains.keys()) + + # If one is found inside another, ignore the marks + self.exclusive = ['comment','verb','raw','tagged'] + + # May we include bars inside quotes? + if rules['barinsidequote']: + self.contains['quote'].append('bar') + + def block(self): + if not self.BLK: return '' + return self.BLK[-1] + + def isblock(self, name=''): + return self.block() == name + + def prop(self, key): + if not self.PRP: return '' + return self.PRP[-1].get(key) or '' + + def propset(self, key, val): + self.PRP[-1][key] = val + #Debug('BLOCK prop ++: %s->%s'%(key,repr(val)), 1) + #Debug('BLOCK props: %s'%(repr(self.PRP)), 1) + + def hold(self): + if not self.HLD: return [] + return self.HLD[-1] + + def holdadd(self, line): + if self.block().endswith('list'): line = [line] + self.HLD[-1].append(line) + Debug('HOLD add: %s'%repr(line), 4) + Debug('FULL HOLD: %s'%self.HLD, 4) + + def holdaddsub(self, line): + self.HLD[-1][-1].append(line) + Debug('HOLD addsub: %s'%repr(line), 4) + Debug('FULL HOLD: %s'%self.HLD, 4) + + def holdextend(self, lines): + if self.block().endswith('list'): lines = [lines] + self.HLD[-1].extend(lines) + Debug('HOLD extend: %s'%repr(lines), 4) + Debug('FULL HOLD: %s'%self.HLD, 4) + + def blockin(self, block): + ret = [] + if block not in self.allblocks: + Error("Invalid block '%s'"%block) + + # First, let's close other possible open blocks + while self.block() and block not in self.contains[self.block()]: + ret.extend(self.blockout()) + + # Now we can gladly add this new one + self.BLK.append(block) + self.HLD.append([]) + self.PRP.append({}) + self.count += 1 + if block == 'table': self.tableparser = TableMaster() + # Deeper and deeper + self.depth = len(self.BLK) + Debug('block ++ (%s): %s' % (block,self.BLK), 3) + return ret + + def blockout(self): + global AA_COUNT + + if not self.BLK: Error('No block to pop') + blockname = self.BLK.pop() + result = getattr(self, blockname)() + parsed = self.HLD.pop() + self.PRP.pop() + self.depth = len(self.BLK) + if blockname == 'table': del self.tableparser + + # Inserting a nested block into mother + if self.block(): + if blockname != 'comment': # ignore comment blocks + if self.block().endswith('list'): + self.HLD[-1][-1].append(result) + else: + self.HLD[-1].append(result) + # Reset now. Mother block will have it all + result = [] + + Debug('block -- (%s): %s' % (blockname,self.BLK), 3) + Debug('RELEASED (%s): %s' % (blockname,parsed), 3) + + # Save this top level block name (produced output) + # The next block will use it + if result: + self.last = blockname + Debug('BLOCK: %s'%result, 6) + + # ASCII Art processing + if TARGET == 'art' and CONF['slides'] and not CONF['toc-only'] and not CONF.get('art-no-title'): + n = (CONF['height'] - 1) - (AA_COUNT % (CONF['height'] - 1) + 1) + if n < len(result) and not (TITLE.level == 1 and blockname in ["title", "numtitle"]): + result = ([''] * n) + [aa_line(AA['bar1'], CONF['width'])] + aa_slide(AA_TITLE, CONF['width']) + [''] + result + if blockname in ["title", "numtitle"] and TITLE.level == 1: + aa_title = aa_slide(AA_TITLE, CONF['width']) + [''] + if AA_COUNT: + aa_title = ([''] * n) + [aa_line(AA['bar2'], CONF['width'])] + aa_title + result = aa_title + result + AA_COUNT += len(result) + + return result + + def _last_escapes(self, line): + return doFinalEscape(TARGET, line) + + def _get_escaped_hold(self): + ret = [] + for line in self.hold(): + linetype = type(line) + if isinstance('', linetype): + ret.append(self._last_escapes(line)) + elif isinstance([], linetype): + ret.extend(line) + else: + Error("BlockMaster: Unknown HOLD item type: %s" % linetype) + return ret + + def _remove_twoblanks(self, lastitem): + if len(lastitem) > 1 and lastitem[-2:] == ['','']: + return lastitem[:-2] + return lastitem + + def _should_add_blank_line(self, where, blockname): + "Validates the blanksaround* rules" + + # Nestable blocks: only mother blocks (level 1) are spaced + if blockname.endswith('list') and self.depth > 1: + return False + + # The blank line after the block is always added + if where == 'after' \ + and rules['blanksaround'+blockname]: + return True + + # # No blank before if it's the first block of the body + # elif where == 'before' \ + # and BLOCK.count == 1: + # return False + + # # No blank before if it's the first block of this level (nested) + # elif where == 'before' \ + # and self.count == 1: + # return False + + # The blank line before the block is only added if + # the previous block haven't added a blank line + # (to avoid consecutive blanks) + elif where == 'before' \ + and rules['blanksaround'+blockname] \ + and not rules.get('blanksaround'+self.last): + return True + + # Nested quotes are handled here, + # because the mother quote isn't closed yet + elif where == 'before' \ + and blockname == 'quote' \ + and rules['blanksaround'+blockname] \ + and self.depth > 1: + return True + + return False + + def comment(self): + return '' + + def raw(self): + lines = self.hold() + return [doEscape(TARGET, x) for x in lines] + + def tagged(self): + return self.hold() + + def para(self): + result = [] + open_ = TAGS['paragraphOpen'] + close = TAGS['paragraphClose'] + lines = self._get_escaped_hold() + + # Blank line before? + if self._should_add_blank_line('before', 'para'): result.append('') + + # Open tag + if open_: result.append(open_) + + # Pagemaker likes a paragraph as a single long line + if rules['onelinepara']: + result.append(' '.join(lines)) + # Others are normal :) + else: + result.extend(lines) + + # Close tag + if close: result.append(close) + + # Blank line after? + if self._should_add_blank_line('after', 'para'): result.append('') + + # Very very very very very very very very very UGLY fix + # Needed because <center> can't appear inside <p> + try: + if len(lines) == 1 and \ + TARGET in ('html', 'xhtml') and \ + re.match('^\s*<center>.*</center>\s*$', lines[0]): + result = [lines[0]] + except: pass + + return result + + def verb(self): + "Verbatim lines are not masked, so there's no need to unmask" + result = [] + open_ = TAGS['blockVerbOpen'] + close = TAGS['blockVerbClose'] + + # Blank line before? + if self._should_add_blank_line('before', 'verb'): result.append('') + + # Open tag + if open_: result.append(open_) + + # Get contents + for line in self.hold(): + if self.prop('mapped') == 'table': + line = MacroMaster().expand(line) + if not rules['verbblocknotescaped']: + line = doEscape(TARGET,line) + if rules['indentverbblock']: + line = ' '+line + if rules['verbblockfinalescape']: + line = doFinalEscape(TARGET, line) + result.append(line) + + # Close tag + if close: result.append(close) + + # Blank line after? + if self._should_add_blank_line('after', 'verb'): result.append('') + + return result + + def numtitle(self): return self.title('numtitle') + def title(self, name='title'): + result = [] + + # Blank line before? + if self._should_add_blank_line('before', name): result.append('') + + # Get contents + result.extend(TITLE.get()) + + # Blank line after? + if self._should_add_blank_line('after', name): result.append('') + + return result + + def table(self): + result = [] + + # Blank line before? + if self._should_add_blank_line('before', 'table'): result.append('') + + # Rewrite all table cells by the unmasked and escaped data + lines = self._get_escaped_hold() + for i in range(len(lines)): + cells = lines[i].split(SEPARATOR) + self.tableparser.rows[i]['cells'] = cells + result.extend(self.tableparser.dump()) + + # Blank line after? + if self._should_add_blank_line('after', 'table'): result.append('') + + return result + + def quote(self): + result = [] + open_ = TAGS['blockQuoteOpen'] # block based + close = TAGS['blockQuoteClose'] + qline = TAGS['blockQuoteLine'] # line based + indent = tagindent = '\t'*self.depth + + # Apply rules + if rules['tagnotindentable']: tagindent = '' + if not rules['keepquoteindent']: indent = '' + + # Blank line before? + if self._should_add_blank_line('before', 'quote'): result.append('') + + # Open tag + if open_: result.append(tagindent+open_) + + # Get contents + for item in self.hold(): + if isinstance(item, type([])): + result.extend(item) # subquotes + else: + item = regex['quote'].sub('', item) # del TABs + item = self._last_escapes(item) + item = qline*self.depth + item + result.append(indent+item) # quote line + + # Close tag + if close: result.append(tagindent+close) + + # Blank line after? + if self._should_add_blank_line('after', 'quote'): result.append('') + + return result + + def bar(self): + result = [] + bar_tag = '' + + # Blank line before? + if self._should_add_blank_line('before', 'bar'): result.append('') + + # Get the original bar chars + bar_chars = self.hold()[0].strip() + + # Set bar type + if bar_chars.startswith('='): bar_tag = TAGS['bar2'] + else : bar_tag = TAGS['bar1'] + + # To avoid comment tag confusion like <!-- ------ --> (sgml) + if TAGS['comment'].count('--'): + bar_chars = bar_chars.replace('--', '__') + + # Get the bar tag (may contain \a) + result.append(regex['x'].sub(bar_chars, bar_tag)) + + # Blank line after? + if self._should_add_blank_line('after', 'bar'): result.append('') + + return result + + def deflist(self): return self.list('deflist') + def numlist(self): return self.list('numlist') + def list(self, name='list'): + result = [] + items = self.hold() + indent = self.prop('indent') + tagindent = indent + listline = TAGS.get(name+'ItemLine') + itemcount = 0 + + if name == 'deflist': + itemopen = TAGS[name+'Item1Open'] + itemclose = TAGS[name+'Item2Close'] + itemsep = TAGS[name+'Item1Close']+\ + TAGS[name+'Item2Open'] + else: + itemopen = TAGS[name+'ItemOpen'] + itemclose = TAGS[name+'ItemClose'] + itemsep = '' + + # Apply rules + if rules['tagnotindentable']: tagindent = '' + if not rules['keeplistindent']: indent = tagindent = '' + + # ItemLine: number of leading chars identifies list depth + if listline: + itemopen = listline*self.depth + itemopen + + # Adds trailing space on opening tags + if (name == 'list' and rules['spacedlistitemopen']) or \ + (name == 'numlist' and rules['spacednumlistitemopen']): + itemopen = itemopen + ' ' + + # Remove two-blanks from list ending mark, to avoid <p> + items[-1] = self._remove_twoblanks(items[-1]) + + # Blank line before? + if self._should_add_blank_line('before', name): result.append('') + + # Tag each list item (multiline items), store in listbody + itemopenorig = itemopen + listbody = [] + widelist = 0 + for item in items: + + # Add "manual" item count for noautonum targets + itemcount += 1 + if name == 'numlist' and not rules['autonumberlist']: + n = str(itemcount) + itemopen = regex['x'].sub(n, itemopenorig) + del n + + # Tag it + item[0] = self._last_escapes(item[0]) + if name == 'deflist': + z,term,rest = item[0].split(SEPARATOR, 2) + item[0] = rest + if not item[0]: del item[0] # to avoid <p> + listbody.append(tagindent+itemopen+term+itemsep) + else: + fullitem = tagindent+itemopen + listbody.append(item[0].replace(SEPARATOR, fullitem)) + del item[0] + + # Process next lines for this item (if any) + for line in item: + if isinstance(line, type([])): # sublist inside + listbody.extend(line) + else: + line = self._last_escapes(line) + + # Blank lines turns to <p> + if not line and rules['parainsidelist']: + line = indent + TAGS['paragraphOpen'] + TAGS['paragraphClose'] + line = line.rstrip() + widelist = 1 + + # Some targets don't like identation here (wiki) + if not rules['keeplistindent'] or (name == 'deflist' and rules['deflisttextstrip']): + line = line.lstrip() + + # Maybe we have a line prefix to add? (wiki) + if name == 'deflist' and TAGS['deflistItem2LinePrefix']: + line = TAGS['deflistItem2LinePrefix'] + line + + listbody.append(line) + + # Close item (if needed) + if itemclose: listbody.append(tagindent+itemclose) + + if not widelist and rules['compactlist']: + listopen = TAGS.get(name+'OpenCompact') + listclose = TAGS.get(name+'CloseCompact') + else: + listopen = TAGS.get(name+'Open') + listclose = TAGS.get(name+'Close') + + # Open list (not nestable lists are only opened at mother) + if listopen and not \ + (rules['listnotnested'] and BLOCK.depth != 1): + result.append(tagindent+listopen) + + result.extend(listbody) + + # Close list (not nestable lists are only closed at mother) + if listclose and not \ + (rules['listnotnested'] and self.depth != 1): + result.append(tagindent+listclose) + + # Blank line after? + if self._should_add_blank_line('after', name): result.append('') + + return result + + +############################################################################## + + +class MacroMaster: + def __init__(self, config={}): + self.name = '' + self.config = config or CONF + self.infile = self.config['sourcefile'] + self.outfile = self.config['outfile'] + self.currdate = time.localtime(time.time()) + self.rgx = regex.get('macros') or getRegexes()['macros'] + self.fileinfo = { 'infile': None, 'outfile': None } + self.dft_fmt = MACROS + + def walk_file_format(self, fmt): + "Walks the %%{in/out}file format string, expanding the % flags" + i = 0; ret = '' # counter/hold + while i < len(fmt): # char by char + c = fmt[i]; i += 1 + if c == '%': # hot char! + if i == len(fmt): # % at the end + ret = ret + c + break + c = fmt[i]; i += 1 # read next + ret = ret + self.expand_file_flag(c) + else: + ret = ret +c # common char + return ret + + def expand_file_flag(self, flag): + "%f: filename %F: filename (w/o extension)" + "%d: dirname %D: dirname (only parent dir)" + "%p: file path %e: extension" + info = self.fileinfo[self.name] # get dict + if flag == '%': x = '%' # %% -> % + elif flag == 'f': x = info['name'] + elif flag == 'F': x = re.sub('\.[^.]*$','',info['name']) + elif flag == 'd': x = info['dir'] + elif flag == 'D': x = os.path.split(info['dir'])[-1] + elif flag == 'p': x = info['path'] + elif flag == 'e': x = re.search('.(\.([^.]+))?$', info['name']).group(2) or '' + #TODO simpler way for %e ? + else : x = '%'+flag # false alarm + return x + + def set_file_info(self, macroname): + if self.fileinfo.get(macroname): return # already done + file_ = getattr(self, self.name) # self.infile + if file_ == STDOUT or file_ == MODULEOUT: + dir_ = '' + path = name = file_ + else: + path = os.path.abspath(file_) + dir_ = os.path.dirname(path) + name = os.path.basename(path) + self.fileinfo[macroname] = {'path':path,'dir':dir_,'name':name} + + def expand(self, line=''): + "Expand all macros found on the line" + while self.rgx.search(line): + m = self.rgx.search(line) + name = self.name = m.group('name').lower() + fmt = m.group('fmt') or self.dft_fmt.get(name) + if name == 'date': + txt = time.strftime(fmt,self.currdate) + elif name == 'mtime': + if self.infile in (STDIN, MODULEIN): + fdate = self.currdate + else: + mtime = os.path.getmtime(self.infile) + fdate = time.localtime(mtime) + txt = time.strftime(fmt,fdate) + elif name == 'infile' or name == 'outfile': + self.set_file_info(name) + txt = self.walk_file_format(fmt) + else: + Error("Unknown macro name '%s'"%name) + line = self.rgx.sub(txt,line,1) + return line + + +############################################################################## + + +def listTargets(): + """list all available targets""" + targets = sorted(TARGETS) + for target in targets: + print("%s\t%s" % (target, TARGET_NAMES.get(target))) + +def dumpConfig(source_raw, parsed_config): + onoff = {1:_('ON'), 0:_('OFF')} + data = [ + (_('RC file') , RC_RAW ), + (_('source document'), source_raw ), + (_('command line') , CMDLINE_RAW) + ] + # First show all RAW data found + for label, cfg in data: + print(_('RAW config for %s')%label) + for target,key,val in cfg: + target = '(%s)'%target + key = dotted_spaces("%-14s"%key) + val = val or _('ON') + print(' %-8s %s: %s'%(target,key,val)) + print() + # Then the parsed results of all of them + print(_('Full PARSED config')) + for key in sorted( parsed_config.keys() ): + val = parsed_config[key] + # Filters are the last + if key == 'preproc' or key == 'postproc': + continue + # Flag beautifier + if key in FLAGS.keys() or key in ACTIONS.keys(): + val = onoff.get(val) or val + # List beautifier + if isinstance(val, type([])): + if key == 'options': sep = ' ' + else : sep = ', ' + val = sep.join(val) + print("%25s: %s"%(dotted_spaces("%-14s"%key),val)) + print() + print(_('Active filters')) + for filter_ in ['preproc', 'postproc']: + for rule in parsed_config.get(filter_) or []: + print("%25s: %s -> %s" % ( + dotted_spaces("%-14s"%filter_), rule[0], rule[1])) + + +def get_file_body(file_): + "Returns all the document BODY lines" + return process_source_file(file_, noconf=1)[1][2] + + +def finish_him(outlist, config): + "Writing output to screen or file" + outfile = config['outfile'] + outlist = unmaskEscapeChar(outlist) + outlist = expandLineBreaks(outlist) + + # Apply PostProc filters + if config['postproc']: + filters = compile_filters(config['postproc'], + _('Invalid PostProc filter regex')) + postoutlist = [] + errmsg = _('Invalid PostProc filter replacement') + for line in outlist: + for rgx,repl in filters: + try: line = rgx.sub(repl, line) + except: Error("%s: '%s'"%(errmsg, repl)) + postoutlist.append(line) + outlist = postoutlist[:] + + if outfile == MODULEOUT: + return outlist + elif outfile == STDOUT: + if GUI: + return outlist, config + else: + for line in outlist: print(line) + else: + Savefile(outfile, addLineBreaks(outlist)) + if not GUI and not QUIET: + print(_('%s wrote %s')%(my_name,outfile)) + + if config['split']: + if not QUIET: print("--- html...") + sgml2html = 'sgml2html -s %s -l %s %s' % ( + config['split'], config['lang'] or lang, outfile) + if not QUIET: print("Running system command:", sgml2html) + os.system(sgml2html) + + +def toc_inside_body(body, toc, config): + ret = [] + if AUTOTOC: return body # nothing to expand + toc_mark = MaskMaster().tocmask + # Expand toc mark with TOC contents + for line in body: + if line.count(toc_mark): # toc mark found + if config['toc']: + ret.extend(toc) # include if --toc + else: + pass # or remove %%toc line + else: + ret.append(line) # common line + return ret + +def toc_tagger(toc, config): + "Returns the tagged TOC, as a single tag or a tagged list" + ret = [] + # Convert the TOC list (t2t-marked) to the target's list format + if config['toc-only'] or (config['toc'] and not TAGS['TOC']): + fakeconf = config.copy() + fakeconf['headers'] = 0 + fakeconf['toc-only'] = 0 + fakeconf['mask-email'] = 0 + fakeconf['preproc'] = [] + fakeconf['postproc'] = [] + fakeconf['css-sugar'] = 0 + fakeconf['art-no-title'] = 1 # needed for --toc and --slides together, avoids slide title before TOC + ret,foo = convert(toc, fakeconf) + set_global_config(config) # restore config + # Our TOC list is not needed, the target already knows how to do a TOC + elif config['toc'] and TAGS['TOC']: + ret = [TAGS['TOC']] + return ret + +def toc_formatter(toc, config): + "Formats TOC for automatic placement between headers and body" + + if config['toc-only']: return toc # no formatting needed + if not config['toc'] : return [] # TOC disabled + ret = toc + + # Art: An automatic "Table of Contents" header is added to the TOC slide + if config['target'] == 'art' and config['slides']: + n = (config['height'] - 1) - (len(toc) + 6) % (config['height'] - 1) + toc = aa_slide(_("Table of Contents"), config['width']) + toc + ([''] * n) + toc.append(aa_line(AA['bar2'], config['width'])) + return toc + + # TOC open/close tags (if any) + if TAGS['tocOpen' ]: ret.insert(0, TAGS['tocOpen']) + if TAGS['tocClose']: ret.append(TAGS['tocClose']) + + # Autotoc specific formatting + if AUTOTOC: + if rules['autotocwithbars']: # TOC between bars + para = TAGS['paragraphOpen']+TAGS['paragraphClose'] + bar = regex['x'].sub('-' * DFT_TEXT_WIDTH, TAGS['bar1']) + tocbar = [para, bar, para] + if config['target'] == 'art' and config['headers']: + # exception: header already printed a bar + ret = [para] + ret + tocbar + else: + ret = tocbar + ret + tocbar + if rules['blankendautotoc']: # blank line after TOC + ret.append('') + if rules['autotocnewpagebefore']: # page break before TOC + ret.insert(0,TAGS['pageBreak']) + if rules['autotocnewpageafter']: # page break after TOC + ret.append(TAGS['pageBreak']) + return ret + + +def doHeader(headers, config): + if not config['headers']: return [] + if not headers: headers = ['','',''] + target = config['target'] + if target not in HEADER_TEMPLATE: + Error("doHeader: Unknown target '%s'"%target) + + if target in ('html','xhtml') and config.get('css-sugar'): + template = HEADER_TEMPLATE[target+'css'].split('\n') + else: + template = HEADER_TEMPLATE[target].split('\n') + + head_data = {'STYLE':[], 'ENCODING':''} + for key in head_data.keys(): + val = config.get(key.lower()) + # Remove .sty extension from each style filename (freaking tex) + # XXX Can't handle --style foo.sty,bar.sty + if target == 'tex' and key == 'STYLE': + val = [re.sub('(?i)\.sty$','',x) for x in val] + if key == 'ENCODING': + val = get_encoding_string(val, target) + head_data[key] = val + # Parse header contents + for i in 0,1,2: + # Expand macros + contents = MacroMaster(config=config).expand(headers[i]) + # Escapes - on tex, just do it if any \tag{} present + if target != 'tex' or \ + (target == 'tex' and re.search(r'\\\w+{', contents)): + contents = doEscape(target, contents) + if target == 'lout': + contents = doFinalEscape(target, contents) + + head_data['HEADER%d'%(i+1)] = contents + + # css-inside removes STYLE line + #XXX In tex, this also removes the modules call (%!style:amsfonts) + if target in ('html','xhtml') and config.get('css-inside') and \ + config.get('style'): + head_data['STYLE'] = [] + + Debug("Header Data: %s"%head_data, 1) + + # ASCII Art does not use a header template, aa_header() formats the header + if target == 'art': + n_h = len([v for v in head_data if v.startswith("HEADER") and head_data[v]]) + if not n_h : + return [] + if config['slides']: + x = config['height'] - 3 - (n_h * 3) + n = x / (n_h + 1) + end = x % (n_h + 1) + template = aa_header(head_data, config['width'], n, end) + else: + template = [''] + aa_header(head_data, config['width'], 2, 0) + # Header done, let's get out + return template + + # Scan for empty dictionary keys + # If found, scan template lines for that key reference + # If found, remove the reference + # If there isn't any other key reference on the same line, remove it + #TODO loop by template line > key + for key in head_data.keys(): + if head_data.get(key): continue + for line in template: + if line.count('%%(%s)s'%key): + sline = line.replace('%%(%s)s'%key, '') + if not re.search(r'%\([A-Z0-9]+\)s', sline): + template.remove(line) + # Style is a multiple tag. + # - If none or just one, use default template + # - If two or more, insert extra lines in a loop (and remove original) + styles = head_data['STYLE'] + if len(styles) == 1: + head_data['STYLE'] = styles[0] + elif len(styles) > 1: + style_mark = '%(STYLE)s' + for i in range(len(template)): + if template[i].count(style_mark): + while styles: + template.insert(i+1, template[i].replace(style_mark, styles.pop())) + del template[i] + break + # Populate template with data (dict expansion) + template = '\n'.join(template) % head_data + + # Adding CSS contents into template (for --css-inside) + # This code sux. Dirty++ + if target in ('html','xhtml') and config.get('css-inside') and \ + config.get('style'): + set_global_config(config) # usually on convert(), needed here + for i in range(len(config['style'])): + cssfile = config['style'][i] + if not os.path.isabs(cssfile): + infile = config.get('sourcefile') + cssfile = os.path.join( + os.path.dirname(infile), cssfile) + try: + contents = Readfile(cssfile, 1) + css = "\n%s\n%s\n%s\n%s\n" % ( + doCommentLine("Included %s" % cssfile), + TAGS['cssOpen'], + '\n'.join(contents), + TAGS['cssClose']) + # Style now is content, needs escaping (tex) + #css = maskEscapeChar(css) + except: + errmsg = "CSS include failed for %s" % cssfile + css = "\n%s\n" % (doCommentLine(errmsg)) + # Insert this CSS file contents on the template + template = re.sub('(?i)(</HEAD>)', css+r'\1', template) + # template = re.sub(r'(?i)(\\begin{document})', + # css+'\n'+r'\1', template) # tex + + # The last blank line to keep everything separated + template = re.sub('(?i)(</HEAD>)', '\n'+r'\1', template) + + return template.split('\n') + +def doCommentLine(txt): + # The -- string ends a (h|sg|xht)ml comment :( + txt = maskEscapeChar(txt) + if TAGS['comment'].count('--') and txt.count('--'): + txt = re.sub('-(?=-)', r'-\\', txt) + + if TAGS['comment']: + return regex['x'].sub(txt, TAGS['comment']) + return '' + +def doFooter(config): + ret = [] + + # No footer. The --no-headers option hides header AND footer + if not config['headers']: + return [] + + # Only add blank line before footer if last block doesn't added by itself + if not rules.get('blanksaround'+BLOCK.last): + ret.append('') + + # Add txt2tags info at footer, if target supports comments + if TAGS['comment']: + + # Not using TARGET_NAMES because it's i18n'ed. + # It's best to always present this info in english. + target = config['target'] + if config['target'] == 'tex': + target = 'LaTeX2e' + + t2t_version = '%s code generated by %s %s (%s)' % (target, my_name, my_version, my_url) + cmdline = 'cmdline: %s %s' % (my_name, ' '.join(config['realcmdline'])) + + ret.append(doCommentLine(t2t_version)) + ret.append(doCommentLine(cmdline)) + + # Maybe we have a specific tag to close the document? + if TAGS['EOD']: + ret.append(TAGS['EOD']) + + return ret + +def doEscape(target,txt): + "Target-specific special escapes. Apply *before* insert any tag." + tmpmask = 'vvvvThisEscapingSuxvvvv' + if target in ('html','sgml','xhtml','dbk'): + txt = re.sub('&','&',txt) + txt = re.sub('<','<',txt) + txt = re.sub('>','>',txt) + if target == 'sgml': + txt = re.sub('\xff','ÿ',txt) # "+y + elif target == 'pm6': + txt = re.sub('<','<\#60>',txt) + elif target == 'mgp': + txt = re.sub('^%',' %',txt) # add leading blank to avoid parse + elif target == 'man': + txt = re.sub("^([.'])", '\\&\\1',txt) # command ID + txt = txt.replace(ESCCHAR, ESCCHAR+'e') # \e + elif target == 'lout': + # TIP: / moved to FinalEscape to avoid //italic// + # TIP: these are also converted by lout: ... --- -- + txt = txt.replace(ESCCHAR, tmpmask) # \ + txt = txt.replace('"', '"%s""'%ESCCHAR) # "\"" + txt = re.sub('([|&{}@#^~])', '"\\1"', txt) # "@" + txt = txt.replace(tmpmask, '"%s"'%(ESCCHAR*2)) # "\\" + elif target == 'tex': + # Mark literal \ to be changed to $\backslash$ later + txt = txt.replace(ESCCHAR, tmpmask) + txt = re.sub('([#$&%{}])', ESCCHAR+r'\1' , txt) # \% + txt = re.sub('([~^])' , ESCCHAR+r'\1{}', txt) # \~{} + txt = re.sub('([<|>])' , r'$\1$', txt) # $>$ + txt = txt.replace(tmpmask, maskEscapeChar(r'$\backslash$')) + # TIP the _ is escaped at the end + return txt + +# TODO man: where - really needs to be escaped? +def doFinalEscape(target, txt): + "Last escapes of each line" + if target == 'pm6' : txt = txt.replace(ESCCHAR+'<', r'<\#92><') + elif target == 'man' : txt = txt.replace('-', r'\-') + elif target == 'sgml': txt = txt.replace('[', '[') + elif target == 'lout': txt = txt.replace('/', '"/"') + elif target == 'tex' : + txt = txt.replace('_', r'\_') + txt = txt.replace('vvvvTexUndervvvv', '_') # shame! + return txt + +def EscapeCharHandler(action, data): + "Mask/Unmask the Escape Char on the given string" + if not data.strip(): return data + if action not in ('mask','unmask'): + Error("EscapeCharHandler: Invalid action '%s'"%action) + if action == 'mask': return data.replace('\\', ESCCHAR) + else: return data.replace(ESCCHAR, '\\') + +def maskEscapeChar(data): + "Replace any Escape Char \ with a text mask (Input: str or list)" + if isinstance(data, type([])): + return [EscapeCharHandler('mask', x) for x in data] + return EscapeCharHandler('mask',data) + +def unmaskEscapeChar(data): + "Undo the Escape char \ masking (Input: str or list)" + if isinstance(data, type([])): + return [EscapeCharHandler('unmask', x) for x in data] + return EscapeCharHandler('unmask',data) + +def addLineBreaks(mylist): + "use LB to respect sys.platform" + ret = [] + for line in mylist: + line = line.replace('\n', LB) # embedded \n's + ret.append(line+LB) # add final line break + return ret + +# Convert ['foo\nbar'] to ['foo', 'bar'] +def expandLineBreaks(mylist): + ret = [] + for line in mylist: + ret.extend(line.split('\n')) + return ret + +def compile_filters(filters, errmsg='Filter'): + if filters: + for i in range(len(filters)): + patt,repl = filters[i] + try: rgx = re.compile(patt) + except: Error("%s: '%s'"%(errmsg, patt)) + filters[i] = (rgx,repl) + return filters + +def enclose_me(tagname, txt): + return TAGS.get(tagname+'Open') + txt + TAGS.get(tagname+'Close') + +def beautify_me(name, line): + "where name is: bold, italic, underline or strike" + + # Exception: Doesn't parse an horizontal bar as strike + if name == 'strike' and regex['bar'].search(line): return line + + name = 'font%s' % name.capitalize() + open_ = TAGS['%sOpen'%name] + close = TAGS['%sClose'%name] + txt = r'%s\1%s'%(open_, close) + line = regex[name].sub(txt,line) + return line + +def get_tagged_link(label, url): + ret = '' + target = CONF['target'] + image_re = regex['img'] + + # Set link type + if regex['email'].match(url): + linktype = 'email' + else: + linktype = 'url'; + + # Escape specials from TEXT parts + label = doEscape(target,label) + + # Escape specials from link URL + if not rules['linkable'] or rules['escapeurl']: + url = doEscape(target, url) + + # Adding protocol to guessed link + guessurl = '' + if linktype == 'url' and \ + re.match('(?i)'+regex['_urlskel']['guess'], url): + if url[0] in 'Ww': guessurl = 'http://' +url + else : guessurl = 'ftp://' +url + + # Not link aware targets -> protocol is useless + if not rules['linkable']: guessurl = '' + + # Simple link (not guessed) + if not label and not guessurl: + if CONF['mask-email'] and linktype == 'email': + # Do the email mask feature (no TAGs, just text) + url = url.replace('@', ' (a) ') + url = url.replace('.', ' ') + url = "<%s>" % url + if rules['linkable']: url = doEscape(target, url) + ret = url + else: + # Just add link data to tag + tag = TAGS[linktype] + ret = regex['x'].sub(url,tag) + + # Named link or guessed simple link + else: + # Adjusts for guessed link + if not label: label = url # no protocol + if guessurl : url = guessurl # with protocol + + # Image inside link! + if image_re.match(label): + if rules['imglinkable']: # get image tag + label = parse_images(label) + else: # img@link !supported + label = "(%s)"%image_re.match(label).group(1) + + # Putting data on the right appearance order + if rules['labelbeforelink'] or not rules['linkable']: + urlorder = [label, url] # label before link + else: + urlorder = [url, label] # link before label + + # Add link data to tag (replace \a's) + ret = TAGS["%sMark"%linktype] + for data in urlorder: + ret = regex['x'].sub(data,ret,1) + + return ret + + +def parse_deflist_term(line): + "Extract and parse definition list term contents" + img_re = regex['img'] + term = regex['deflist'].search(line).group(3) + + # Mask image inside term as (image.jpg), where not supported + if not rules['imgasdefterm'] and img_re.search(term): + while img_re.search(term): + imgfile = img_re.search(term).group(1) + term = img_re.sub('(%s)'%imgfile, term, 1) + + #TODO tex: escape ] on term. \], \rbrack{} and \verb!]! don't work :( + return term + + +def get_image_align(line): + "Return the image (first found) align for the given line" + + # First clear marks that can mess align detection + line = re.sub(SEPARATOR+'$', '', line) # remove deflist sep + line = re.sub('^'+SEPARATOR, '', line) # remove list sep + line = re.sub('^[\t]+' , '', line) # remove quote mark + + # Get image position on the line + m = regex['img'].search(line) + ini = m.start() ; head = 0 + end = m.end() ; tail = len(line) + + # The align detection algorithm + if ini == head and end != tail: align = 'left' # ^img + text$ + elif ini != head and end == tail: align = 'right' # ^text + img$ + else : align = 'center' # default align + + # Some special cases + if BLOCK.isblock('table'): align = 'center' # ignore when table +# if TARGET == 'mgp' and align == 'center': align = 'center' + + return align + + +# Reference: http://www.iana.org/assignments/character-sets +# http://www.drclue.net/F1.cgi/HTML/META/META.html +def get_encoding_string(enc, target): + if not enc: return '' + # Target specific translation table + translate = { + 'tex': { + # missing: ansinew , applemac , cp437 , cp437de , cp865 + 'utf-8' : 'utf8', + 'us-ascii' : 'ascii', + 'windows-1250': 'cp1250', + 'windows-1252': 'cp1252', + 'ibm850' : 'cp850', + 'ibm852' : 'cp852', + 'iso-8859-1' : 'latin1', + 'iso-8859-2' : 'latin2', + 'iso-8859-3' : 'latin3', + 'iso-8859-4' : 'latin4', + 'iso-8859-5' : 'latin5', + 'iso-8859-9' : 'latin9', + 'koi8-r' : 'koi8-r' + } + } + # Normalization + enc = re.sub('(?i)(us[-_]?)?ascii|us|ibm367','us-ascii' , enc) + enc = re.sub('(?i)(ibm|cp)?85([02])' ,'ibm85\\2' , enc) + enc = re.sub('(?i)(iso[_-]?)?8859[_-]?' ,'iso-8859-' , enc) + enc = re.sub('iso-8859-($|[^1-9]).*' ,'iso-8859-1', enc) + # Apply translation table + try: enc = translate[target][enc.lower()] + except: pass + return enc + + +############################################################################## +##MerryChristmas,IdontwanttofighttonightwithyouImissyourbodyandIneedyourlove## +############################################################################## + + +def process_source_file(file_='', noconf=0, contents=[]): + """ + Find and Join all the configuration available for a source file. + No sanity checking is done on this step. + It also extracts the source document parts into separate holders. + + The config scan order is: + 1. The user configuration file (i.e. $HOME/.txt2tagsrc) + 2. The source document's CONF area + 3. The command line options + + The return data is a tuple of two items: + 1. The parsed config dictionary + 2. The document's parts, as a (head, conf, body) tuple + + All the conversion process will be based on the data and + configuration returned by this function. + The source files is read on this step only. + """ + if contents: + source = SourceDocument(contents=contents) + else: + source = SourceDocument(file_) + head, conf, body = source.split() + Message(_("Source document contents stored"),2) + if not noconf: + # Read document config + source_raw = source.get_raw_config() + # Join all the config directives found, then parse it + full_raw = RC_RAW + source_raw + CMDLINE_RAW + Message(_("Parsing and saving all config found (%03d items)") % (len(full_raw)), 1) + full_parsed = ConfigMaster(full_raw).parse() + # Add manually the filename to the conf dic + if contents: + full_parsed['sourcefile'] = MODULEIN + full_parsed['infile'] = MODULEIN + full_parsed['outfile'] = MODULEOUT + else: + full_parsed['sourcefile'] = file_ + # Maybe should we dump the config found? + if full_parsed.get('dump-config'): + dumpConfig(source_raw, full_parsed) + Quit() + # The user just want to know a single config value (hidden feature) + #TODO pick a better name than --show-config-value + elif full_parsed.get('show-config-value'): + config_value = full_parsed.get(full_parsed['show-config-value']) + if config_value: + if isinstance(config_value, type([])): + print('\n'.join(config_value)) + else: + print(config_value) + Quit() + # Okay, all done + Debug("FULL config for this file: %s"%full_parsed, 1) + else: + full_parsed = {} + return full_parsed, (head,conf,body) + +def get_infiles_config(infiles): + """ + Find and Join into a single list, all configuration available + for each input file. This function is supposed to be the very + first one to be called, before any processing. + """ + return list(map(process_source_file, infiles)) + +def convert_this_files(configs): + global CONF + for myconf,doc in configs: # multifile support + target_head = [] + target_toc = [] + target_body = [] + target_foot = [] + source_head, source_conf, source_body = doc + myconf = ConfigMaster().sanity(myconf) + # Compose the target file Headers + #TODO escape line before? + #TODO see exceptions by tex and mgp + Message(_("Composing target Headers"),1) + target_head = doHeader(source_head, myconf) + # Parse the full marked body into tagged target + first_body_line = (len(source_head) or 1)+ len(source_conf) + 1 + Message(_("Composing target Body"),1) + target_body, marked_toc = convert(source_body, myconf, firstlinenr=first_body_line) + # If dump-source, we're done + if myconf['dump-source']: + for line in source_head+source_conf+target_body: + print(line) + return + + # Close the last slide + if myconf['slides'] and not myconf['toc-only'] and myconf['target'] == 'art': + n = (myconf['height'] - 1) - (AA_COUNT % (myconf['height'] - 1) + 1) + target_body = target_body + ([''] * n) + [aa_line(AA['bar2'], myconf['width'])] + + # Compose the target file Footer + Message(_("Composing target Footer"),1) + target_foot = doFooter(myconf) + + # Make TOC (if needed) + Message(_("Composing target TOC"),1) + tagged_toc = toc_tagger(marked_toc, myconf) + target_toc = toc_formatter(tagged_toc, myconf) + target_body = toc_inside_body(target_body, target_toc, myconf) + if not AUTOTOC and not myconf['toc-only']: target_toc = [] + # Finally, we have our document + outlist = target_head + target_toc + target_body + target_foot + # If on GUI, abort before finish_him + # If module, return finish_him as list + # Else, write results to file or STDOUT + if GUI: + return outlist, myconf + elif myconf.get('outfile') == MODULEOUT: + return finish_him(outlist, myconf), myconf + else: + Message(_("Saving results to the output file"),1) + finish_him(outlist, myconf) + + +def parse_images(line): + "Tag all images found" + while regex['img'].search(line) and TAGS['img'] != '[\a]': + txt = regex['img'].search(line).group(1) + tag = TAGS['img'] + + # If target supports image alignment, here we go + if rules['imgalignable']: + + align = get_image_align(line) # right + align_name = align.capitalize() # Right + + # The align is a full tag, or part of the image tag (~A~) + if TAGS['imgAlign'+align_name]: + tag = TAGS['imgAlign'+align_name] + else: + align_tag = TAGS['_imgAlign'+align_name] + tag = regex['_imgAlign'].sub(align_tag, tag, 1) + + # Dirty fix to allow centered solo images + if align == 'center' and TARGET in ('html','xhtml'): + rest = regex['img'].sub('',line,1) + if re.match('^\s+$', rest): + tag = "<center>%s</center>" %tag + + if TARGET == 'tex': + tag = re.sub(r'\\b',r'\\\\b',tag) + txt = txt.replace('_', 'vvvvTexUndervvvv') + + # Ugly hack to avoid infinite loop when target's image tag contains [] + tag = tag.replace('[', 'vvvvEscapeSquareBracketvvvv') + + line = regex['img'].sub(tag,line,1) + line = regex['x'].sub(txt,line,1) + return line.replace('vvvvEscapeSquareBracketvvvv','[') + + +def add_inline_tags(line): + # Beautifiers + for beauti in ('bold', 'italic', 'underline', 'strike'): + if regex['font%s'%beauti.capitalize()].search(line): + line = beautify_me(beauti, line) + + line = parse_images(line) + return line + + +def get_include_contents(file_, path=''): + "Parses %!include: value and extract file contents" + ids = {'`':'verb', '"':'raw', "'":'tagged' } + id_ = 't2t' + # Set include type and remove identifier marks + mark = file_[0] + if mark in ids.keys(): + if file_[:2] == file_[-2:] == mark*2: + id_ = ids[mark] # set type + file_ = file_[2:-2] # remove marks + # Handle remote dir execution + filepath = os.path.join(path, file_) + # Read included file contents + lines = Readfile(filepath, remove_linebreaks=1) + # Default txt2tags marked text, just BODY matters + if id_ == 't2t': + lines = get_file_body(filepath) + #TODO fix images relative path if file has a path, ie.: chapter1/index.t2t (wait until tree parsing) + #TODO for the images path fix, also respect outfile path, if different from infile (wait until tree parsing) + lines.insert(0, '%%INCLUDED(%s) starts here: %s'%(id_,file_)) + # This appears when included hit EOF with verbatim area open + #lines.append('%%INCLUDED(%s) ends here: %s'%(id_,file_)) + return id_, lines + + +def set_global_config(config): + global CONF, TAGS, regex, rules, TARGET + CONF = config + rules = getRules(CONF) + TAGS = getTags(CONF) + regex = getRegexes() + TARGET = config['target'] # save for buggy functions that need global + + +def convert(bodylines, config, firstlinenr=1): + global BLOCK, TITLE + + set_global_config(config) + + target = config['target'] + BLOCK = BlockMaster() + MASK = MaskMaster() + TITLE = TitleMaster() + + ret = [] + dump_source = [] + f_lastwasblank = 0 + + # Compiling all PreProc regexes + pre_filter = compile_filters( + CONF['preproc'], _('Invalid PreProc filter regex')) + + # Let's mark it up! + linenr = firstlinenr-1 + lineref = 0 + while lineref < len(bodylines): + # Defaults + MASK.reset() + results_box = '' + + untouchedline = bodylines[lineref] + dump_source.append(untouchedline) + + line = re.sub('[\n\r]+$','',untouchedline) # del line break + + # Apply PreProc filters + if pre_filter: + errmsg = _('Invalid PreProc filter replacement') + for rgx,repl in pre_filter: + try: line = rgx.sub(repl, line) + except: Error("%s: '%s'"%(errmsg, repl)) + + line = maskEscapeChar(line) # protect \ char + linenr += 1 + lineref += 1 + + Debug(repr(line), 2, linenr) # heavy debug: show each line + + #------------------[ Comment Block ]------------------------ + + # We're already on a comment block + if BLOCK.block() == 'comment': + + # Closing comment + if regex['blockCommentClose'].search(line): + ret.extend(BLOCK.blockout() or []) + continue + + # Normal comment-inside line. Ignore it. + continue + + # Detecting comment block init + if regex['blockCommentOpen'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('comment')) + continue + + #-------------------------[ Tagged Text ]---------------------- + + # We're already on a tagged block + if BLOCK.block() == 'tagged': + + # Closing tagged + if regex['blockTaggedClose'].search(line): + ret.extend(BLOCK.blockout()) + continue + + # Normal tagged-inside line + BLOCK.holdadd(line) + continue + + # Detecting tagged block init + if regex['blockTaggedOpen'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('tagged')) + continue + + # One line tagged text + if regex['1lineTagged'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('tagged')) + line = regex['1lineTagged'].sub('',line) + BLOCK.holdadd(line) + ret.extend(BLOCK.blockout()) + continue + + #-------------------------[ Raw Text ]---------------------- + + # We're already on a raw block + if BLOCK.block() == 'raw': + + # Closing raw + if regex['blockRawClose'].search(line): + ret.extend(BLOCK.blockout()) + continue + + # Normal raw-inside line + BLOCK.holdadd(line) + continue + + # Detecting raw block init + if regex['blockRawOpen'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('raw')) + continue + + # One line raw text + if regex['1lineRaw'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('raw')) + line = regex['1lineRaw'].sub('',line) + BLOCK.holdadd(line) + ret.extend(BLOCK.blockout()) + continue + + #------------------------[ Verbatim ]---------------------- + + #TIP We'll never support beautifiers inside verbatim + + # Closing table mapped to verb + if BLOCK.block() == 'verb' \ + and BLOCK.prop('mapped') == 'table' \ + and not regex['table'].search(line): + ret.extend(BLOCK.blockout()) + + # We're already on a verb block + if BLOCK.block() == 'verb': + + # Closing verb + if regex['blockVerbClose'].search(line): + ret.extend(BLOCK.blockout()) + continue + + # Normal verb-inside line + BLOCK.holdadd(line) + continue + + # Detecting verb block init + if regex['blockVerbOpen'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('verb')) + f_lastwasblank = 0 + continue + + # One line verb-formatted text + if regex['1lineVerb'].search(line) \ + and BLOCK.block() not in BLOCK.exclusive: + ret.extend(BLOCK.blockin('verb')) + line = regex['1lineVerb'].sub('',line) + BLOCK.holdadd(line) + ret.extend(BLOCK.blockout()) + f_lastwasblank = 0 + continue + + # Tables are mapped to verb when target is not table-aware + if not rules['tableable'] and regex['table'].search(line): + if not BLOCK.isblock('verb'): + ret.extend(BLOCK.blockin('verb')) + BLOCK.propset('mapped', 'table') + BLOCK.holdadd(line) + continue + + #---------------------[ blank lines ]----------------------- + + if regex['blankline'].search(line): + + # Close open paragraph + if BLOCK.isblock('para'): + ret.extend(BLOCK.blockout()) + f_lastwasblank = 1 + continue + + # Close all open tables + if BLOCK.isblock('table'): + ret.extend(BLOCK.blockout()) + f_lastwasblank = 1 + continue + + # Close all open quotes + while BLOCK.isblock('quote'): + ret.extend(BLOCK.blockout()) + + # Closing all open lists + if f_lastwasblank: # 2nd consecutive blank + if BLOCK.block().endswith('list'): + BLOCK.holdaddsub('') # helps parser + while BLOCK.depth: # closes list (if any) + ret.extend(BLOCK.blockout()) + continue # ignore consecutive blanks + + # Paragraph (if any) is wanted inside lists also + if BLOCK.block().endswith('list'): + BLOCK.holdaddsub('') + + f_lastwasblank = 1 + continue + + + #---------------------[ special ]--------------------------- + + if regex['special'].search(line): + + targ, key, val = ConfigLines().parse_line(line, None, target) + + if key: + Debug("Found config '%s', value '%s'" % (key, val), 1, linenr) + else: + Debug('Bogus Special Line', 1, linenr) + + # %!include command + if key == 'include': + + incpath = os.path.dirname(CONF['sourcefile']) + incfile = val + err = _('A file cannot include itself (loop!)') + if CONF['sourcefile'] == incfile: + Error("%s: %s"%(err,incfile)) + inctype, inclines = get_include_contents(incfile, incpath) + + # Verb, raw and tagged are easy + if inctype != 't2t': + ret.extend(BLOCK.blockin(inctype)) + BLOCK.holdextend(inclines) + ret.extend(BLOCK.blockout()) + else: + # Insert include lines into body + #TODO include maxdepth limit + bodylines = bodylines[:lineref] + inclines + bodylines[lineref:] + #TODO fix path if include@include + # Remove %!include call + if CONF['dump-source']: + dump_source.pop() + + # This line is done, go to next + continue + + # %!csv command + elif key == 'csv': + + if not csv: + Error("Python module 'csv' not found, but needed for %!csv") + + table = [] + filename = val + reader = csv.reader(Readfile(filename)) + + # Convert each CSV line to a txt2tags' table line + # foo,bar,baz -> | foo | bar | baz | + try: + for row in reader: + table.append('| %s |' % ' | '.join(row)) + except csv.Error as e: + Error('CSV: file %s: %s' % (filename, e)) + + # Parse and convert the new table + # Note: cell contents is raw, no t2t marks are parsed + if rules['tableable']: + ret.extend(BLOCK.blockin('table')) + if table: + BLOCK.tableparser.__init__(table[0]) + for row in table: + tablerow = TableMaster().parse_row(row) + BLOCK.tableparser.add_row(tablerow) + + # Very ugly, but necessary for escapes + line = SEPARATOR.join(tablerow['cells']) + BLOCK.holdadd(doEscape(target, line)) + ret.extend(BLOCK.blockout()) + + # Tables are mapped to verb when target is not table-aware + else: + if target == 'art' and table: + table = aa_table(table) + ret.extend(BLOCK.blockin('verb')) + BLOCK.propset('mapped', 'table') + for row in table: + BLOCK.holdadd(row) + ret.extend(BLOCK.blockout()) + + # This line is done, go to next + continue + + #---------------------[ dump-source ]----------------------- + + # We don't need to go any further + if CONF['dump-source']: + continue + + #---------------------[ Comments ]-------------------------- + + # Just skip them (if not macro) + if regex['comment'].search(line) and not \ + regex['macros'].match(line) and not \ + regex['toc'].match(line): + continue + + #---------------------[ Triggers ]-------------------------- + + # Valid line, reset blank status + f_lastwasblank = 0 + + # Any NOT quote line closes all open quotes + if BLOCK.isblock('quote') and not regex['quote'].search(line): + while BLOCK.isblock('quote'): + ret.extend(BLOCK.blockout()) + + # Any NOT table line closes an open table + if BLOCK.isblock('table') and not regex['table'].search(line): + ret.extend(BLOCK.blockout()) + + + #---------------------[ Horizontal Bar ]-------------------- + + if regex['bar'].search(line): + + # Bars inside quotes are handled on the Quote processing + # Otherwise we parse the bars right here + # + if not (BLOCK.isblock('quote') or regex['quote'].search(line)) \ + or (BLOCK.isblock('quote') and not rules['barinsidequote']): + + # Close all the opened blocks + ret.extend(BLOCK.blockin('bar')) + + # Extract the bar chars (- or =) + m = regex['bar'].search(line) + bar_chars = m.group(2) + + # Process and dump the tagged bar + BLOCK.holdadd(bar_chars) + ret.extend(BLOCK.blockout()) + Debug("BAR: %s"%line, 6) + + # We're done, nothing more to process + continue + + + #---------------------[ Title ]----------------------------- + + if (regex['title'].search(line) or regex['numtitle'].search(line)) \ + and not BLOCK.block().endswith('list'): + + if regex['title'].search(line): + name = 'title' + else: + name = 'numtitle' + + # Close all the opened blocks + ret.extend(BLOCK.blockin(name)) + + # Process title + TITLE.add(line) + ret.extend(BLOCK.blockout()) + + # We're done, nothing more to process + continue + + #---------------------[ %%toc ]----------------------- + + # %%toc line closes paragraph + if BLOCK.block() == 'para' and regex['toc'].search(line): + ret.extend(BLOCK.blockout()) + + #---------------------[ apply masks ]----------------------- + + line = MASK.mask(line) + + #XXX from here, only block-inside lines will pass + + #---------------------[ Quote ]----------------------------- + + if regex['quote'].search(line): + + # Store number of leading TABS + quotedepth = len(regex['quote'].search(line).group(0)) + + # SGML doesn't support nested quotes + if rules['quotenotnested']: quotedepth = 1 + + # Don't cross depth limit + maxdepth = rules['quotemaxdepth'] + if maxdepth and quotedepth > maxdepth: + quotedepth = maxdepth + + # New quote + if not BLOCK.isblock('quote'): + ret.extend(BLOCK.blockin('quote')) + + # New subquotes + while BLOCK.depth < quotedepth: + BLOCK.blockin('quote') + + # Closing quotes + while quotedepth < BLOCK.depth: + ret.extend(BLOCK.blockout()) + + # Bar inside quote + if regex['bar'].search(line) and rules['barinsidequote']: + tempBlock = BlockMaster() + tagged_bar = [] + tagged_bar.extend(tempBlock.blockin('bar')) + tempBlock.holdadd(line) + tagged_bar.extend(tempBlock.blockout()) + BLOCK.holdextend(tagged_bar) + continue + + #---------------------[ Lists ]----------------------------- + + # An empty item also closes the current list + if BLOCK.block().endswith('list'): + m = regex['listclose'].match(line) + if m: + listindent = m.group(1) + listtype = m.group(2) + currlisttype = BLOCK.prop('type') + currlistindent = BLOCK.prop('indent') + if listindent == currlistindent and \ + listtype == currlisttype: + ret.extend(BLOCK.blockout()) + continue + + if regex['list'].search(line) or \ + regex['numlist'].search(line) or \ + regex['deflist'].search(line): + + listindent = BLOCK.prop('indent') + listids = ''.join(LISTNAMES.keys()) + m = re.match('^( *)([%s]) '%listids, line) + listitemindent = m.group(1) + listtype = m.group(2) + listname = LISTNAMES[listtype] + results_box = BLOCK.holdadd + + # Del list ID (and separate term from definition) + if listname == 'deflist': + term = parse_deflist_term(line) + line = regex['deflist'].sub( + SEPARATOR+term+SEPARATOR,line) + else: + line = regex[listname].sub(SEPARATOR,line) + + # Don't cross depth limit + maxdepth = rules['listmaxdepth'] + if maxdepth and BLOCK.depth == maxdepth: + if len(listitemindent) > len(listindent): + listitemindent = listindent + + # List bumping (same indent, diff mark) + # Close the currently open list to clear the mess + if BLOCK.block().endswith('list') \ + and listname != BLOCK.block() \ + and len(listitemindent) == len(listindent): + ret.extend(BLOCK.blockout()) + listindent = BLOCK.prop('indent') + + # Open mother list or sublist + if not BLOCK.block().endswith('list') or \ + len(listitemindent) > len(listindent): + ret.extend(BLOCK.blockin(listname)) + BLOCK.propset('indent',listitemindent) + BLOCK.propset('type',listtype) + + # Closing sublists + while len(listitemindent) < len(BLOCK.prop('indent')): + ret.extend(BLOCK.blockout()) + + # O-oh, sublist before list ("\n\n - foo\n- foo") + # Fix: close sublist (as mother), open another list + if not BLOCK.block().endswith('list'): + ret.extend(BLOCK.blockin(listname)) + BLOCK.propset('indent',listitemindent) + BLOCK.propset('type',listtype) + + #---------------------[ Table ]----------------------------- + + #TODO escape undesired format inside table + #TODO add pm6 target + if regex['table'].search(line): + + if not BLOCK.isblock('table'): # first table line! + ret.extend(BLOCK.blockin('table')) + BLOCK.tableparser.__init__(line) + + tablerow = TableMaster().parse_row(line) + BLOCK.tableparser.add_row(tablerow) # save config + + # Maintain line to unmask and inlines + # XXX Bug: | **bo | ld** | turns **bo\x01ld** and gets converted :( + # TODO isolate unmask+inlines parsing to use here + line = SEPARATOR.join(tablerow['cells']) + + #---------------------[ Paragraph ]------------------------- + + if not BLOCK.block() and \ + not line.count(MASK.tocmask): # new para! + ret.extend(BLOCK.blockin('para')) + + + ############################################################ + ############################################################ + ############################################################ + + + #---------------------[ Final Parses ]---------------------- + + # The target-specific special char escapes for body lines + line = doEscape(target,line) + + line = add_inline_tags(line) + line = MASK.undo(line) + + + #---------------------[ Hold or Return? ]------------------- + + ### Now we must choose where to put the parsed line + # + if not results_box: + # List item extra lines + if BLOCK.block().endswith('list'): + results_box = BLOCK.holdaddsub + # Other blocks + elif BLOCK.block(): + results_box = BLOCK.holdadd + # No blocks + else: + line = doFinalEscape(target, line) + results_box = ret.append + + results_box(line) + + # EOF: close any open para/verb/lists/table/quotes + Debug('EOF',7) + while BLOCK.block(): + ret.extend(BLOCK.blockout()) + + # Maybe close some opened title area? + if rules['titleblocks']: + ret.extend(TITLE.close_all()) + + # Maybe a major tag to enclose body? (like DIV for CSS) + if TAGS['bodyOpen' ]: ret.insert(0, TAGS['bodyOpen']) + if TAGS['bodyClose']: ret.append(TAGS['bodyClose']) + + if CONF['toc-only']: ret = [] + marked_toc = TITLE.dump_marked_toc(CONF['toc-level']) + + # If dump-source, all parsing is ignored + if CONF['dump-source']: ret = dump_source[:] + + return ret, marked_toc + + + +############################################################################## +################################### GUI ###################################### +############################################################################## +# +# Tk help: http://python.org/topics/tkinter/ +# Tuto: http://ibiblio.org/obp/py4fun/gui/tkPhone.html +# /usr/lib/python*/lib-tk/Tkinter.py +# +# grid table : row=0, column=0, columnspan=2, rowspan=2 +# grid align : sticky='n,s,e,w' (North, South, East, West) +# pack place : side='top,bottom,right,left' +# pack fill : fill='x,y,both,none', expand=1 +# pack align : anchor='n,s,e,w' (North, South, East, West) +# padding : padx=10, pady=10, ipadx=10, ipady=10 (internal) +# checkbox : offvalue is return if the _user_ deselected the box +# label align: justify=left,right,center + +def load_GUI_resources(): + "Load all extra modules and methods used by GUI" + global askopenfilename, showinfo, showwarning, showerror, tkinter + from tkinter.filedialog import askopenfilename + from tkinter.messagebox import showinfo,showwarning,showerror + import tkinter + +class Gui: + "Graphical Tk Interface" + def __init__(self, conf={}): + self.root = tkinter.Tk() # mother window, come to butthead + self.root.title(my_name) # window title bar text + self.window = self.root # variable "focus" for inclusion + self.row = 0 # row count for grid() + + self.action_length = 150 # left column length (pixel) + self.frame_margin = 10 # frame margin size (pixel) + self.frame_border = 6 # frame border size (pixel) + + # The default Gui colors, can be changed by %!guicolors + self.dft_gui_colors = ['#6c6','white','#cf9','#030'] + self.gui_colors = [] + self.bg1 = self.fg1 = self.bg2 = self.fg2 = '' + + # On Tk, vars need to be set/get using setvar()/get() + self.infile = self.setvar('') + self.target = self.setvar('') + self.target_name = self.setvar('') + + # The checks appearance order + self.checks = [ + 'headers', 'enum-title', 'toc', 'mask-email', 'toc-only', 'stdout' + ] + + # Creating variables for all checks + for check in self.checks: + setattr(self, 'f_'+check, self.setvar('')) + + # Load RC config + self.conf = {} + if conf: self.load_config(conf) + + def load_config(self, conf): + self.conf = conf + self.gui_colors = conf.get('guicolors') or self.dft_gui_colors + self.bg1, self.fg1, self.bg2, self.fg2 = self.gui_colors + self.root.config(bd=15,bg=self.bg1) + + ### Config as dic for python 1.5 compat (**opts don't work :( ) + def entry(self, **opts): return tkinter.Entry(self.window, opts) + def label(self, txt='', bg=None, **opts): + opts.update({'text':txt,'bg':bg or self.bg1}) + return tkinter.Label(self.window, opts) + def button(self,name,cmd,**opts): + opts.update({'text':name,'command':cmd}) + return tkinter.Button(self.window, opts) + def check(self,name,checked=0,**opts): + bg, fg = self.bg2, self.fg2 + opts.update({ + 'text':name, + 'onvalue':1, + 'offvalue':0, + 'activeforeground':fg, + 'activebackground':bg, + 'highlightbackground':bg, + 'fg':fg, + 'bg':bg, + 'anchor':'w' + }) + chk = tkinter.Checkbutton(self.window, opts) + if checked: chk.select() + chk.grid(columnspan=2, sticky='w', padx=0) + def menu(self,sel,items): + return tkinter.OptionMenu(*(self.window,sel)+tuple(items)) + + # Handy auxiliary functions + def action(self, txt): + self.label( + txt, + fg=self.fg1, + bg=self.bg1, + wraplength=self.action_length).grid(column=0,row=self.row) + def frame_open(self): + self.window = tkinter.Frame( + self.root, + bg=self.bg2, + borderwidth=self.frame_border) + def frame_close(self): + self.window.grid( + column=1, + row=self.row, + sticky='w', + padx=self.frame_margin) + self.window = self.root + self.label('').grid() + self.row += 2 # update row count + def target_name2key(self): + name = self.target_name.get() + target = [x for x in TARGETS if TARGET_NAMES[x] == name] + try : key = target[0] + except: key = '' + self.target = self.setvar(key) + def target_key2name(self): + key = self.target.get() + name = TARGET_NAMES.get(key) or key + self.target_name = self.setvar(name) + + def exit(self): self.root.destroy() + def setvar(self, val): z = tkinter.StringVar() ; z.set(val) ; return z + + def askfile(self): + ftypes= [(_('txt2tags files'), ('*.t2t','*.txt')), (_('All files'),'*')] + newfile = askopenfilename(filetypes=ftypes) + if newfile: + self.infile.set(newfile) + newconf = process_source_file(newfile)[0] + newconf = ConfigMaster().sanity(newconf, gui=1) + # Restate all checkboxes after file selection + #TODO how to make a refresh without killing it? + self.root.destroy() + self.__init__(newconf) + self.mainwindow() + + def scrollwindow(self, txt='no text!', title=''): + # Create components + win = tkinter.Toplevel() ; win.title(title) + frame = tkinter.Frame(win) + scroll = tkinter.Scrollbar(frame) + text = tkinter.Text(frame,yscrollcommand=scroll.set) + button = tkinter.Button(win) + # Config + text.insert(tkinter.END, '\n'.join(txt)) + scroll.config(command=text.yview) + button.config(text=_('Close'), command=win.destroy) + button.focus_set() + # Packing + text.pack(side='left', fill='both', expand=1) + scroll.pack(side='right', fill='y') + frame.pack(fill='both', expand=1) + button.pack(ipadx=30) + + def runprogram(self): + global CMDLINE_RAW + # Prepare + self.target_name2key() + infile, target = self.infile.get(), self.target.get() + # Sanity + if not target: + showwarning(my_name,_("You must select a target type!")) + return + if not infile: + showwarning(my_name,_("You must provide the source file location!")) + return + # Compose cmdline + guiflags = [] + real_cmdline_conf = ConfigMaster(CMDLINE_RAW).parse() + if 'infile' in real_cmdline_conf: + del real_cmdline_conf['infile'] + if 'target' in real_cmdline_conf: + del real_cmdline_conf['target'] + real_cmdline = CommandLine().compose_cmdline(real_cmdline_conf) + default_outfile = ConfigMaster().get_outfile_name( + {'sourcefile':infile, 'outfile':'', 'target':target}) + for opt in self.checks: + val = int(getattr(self, 'f_%s'%opt).get() or "0") + if opt == 'stdout': opt = 'outfile' + on_config = self.conf.get(opt) or 0 + on_cmdline = real_cmdline_conf.get(opt) or 0 + if opt == 'outfile': + if on_config == STDOUT: on_config = 1 + else: on_config = 0 + if on_cmdline == STDOUT: on_cmdline = 1 + else: on_cmdline = 0 + if val != on_config or ( + val == on_config == on_cmdline and + opt in real_cmdline_conf): + if val: + # Was not set, but user selected on GUI + Debug("user turned ON: %s"%opt) + if opt == 'outfile': opt = '-o-' + else: opt = '--%s'%opt + else: + # Was set, but user deselected on GUI + Debug("user turned OFF: %s"%opt) + if opt == 'outfile': + opt = "-o%s"%default_outfile + else: opt = '--no-%s'%opt + guiflags.append(opt) + cmdline = [my_name, '-t', target] + real_cmdline + guiflags + [infile] + Debug('Gui/Tk cmdline: %s' % cmdline, 5) + # Run! + cmdline_raw_orig = CMDLINE_RAW + try: + # Fake the GUI cmdline as the real one, and parse file + CMDLINE_RAW = CommandLine().get_raw_config(cmdline[1:]) + data = process_source_file(infile) + # On GUI, convert_* returns the data, not finish_him() + outlist, config = convert_this_files([data]) + # On GUI and STDOUT, finish_him() returns the data + result = finish_him(outlist, config) + # Show outlist in s a nice new window + if result: + outlist, config = result + title = _('%s: %s converted to %s') % ( + my_name, + os.path.basename(infile), + config['target'].upper()) + self.scrollwindow(outlist, title) + # Show the "file saved" message + else: + msg = "%s\n\n %s\n%s\n\n %s\n%s"%( + _('Conversion done!'), + _('FROM:'), infile, + _('TO:'), config['outfile']) + showinfo(my_name, msg) + except error: # common error (windowed), not quit + pass + except: # fatal error (windowed and printed) + errormsg = getUnknownErrorMessage() + print(errormsg) + showerror(_('%s FATAL ERROR!')%my_name,errormsg) + self.exit() + CMDLINE_RAW = cmdline_raw_orig + + def mainwindow(self): + self.infile.set(self.conf.get('sourcefile') or '') + self.target.set(self.conf.get('target') or _('-- select one --')) + outfile = self.conf.get('outfile') + if outfile == STDOUT: # map -o- + self.conf['stdout'] = 1 + if self.conf.get('headers') == None: + self.conf['headers'] = 1 # map default + + action1 = _("Enter the source file location:") + action2 = _("Choose the target document type:") + action3 = _("Some options you may check:") + action4 = _("Some extra options:") + checks_txt = { + 'headers' : _("Include headers on output"), + 'enum-title': _("Number titles (1, 1.1, 1.1.1, etc)"), + 'toc' : _("Do TOC also (Table of Contents)"), + 'mask-email': _("Hide e-mails from SPAM robots"), + + 'toc-only' : _("Just do TOC, nothing more"), + 'stdout' : _("Dump to screen (Don't save target file)") + } + targets_menu = [TARGET_NAMES[x] for x in TARGETS] + + # Header + self.label("%s %s"%(my_name.upper(), my_version), + bg=self.bg2, fg=self.fg2).grid(columnspan=2, ipadx=10) + self.label(_("ONE source, MULTI targets")+'\n%s\n'%my_url, + bg=self.bg1, fg=self.fg1).grid(columnspan=2) + self.row = 2 + # Choose input file + self.action(action1) ; self.frame_open() + e_infile = self.entry(textvariable=self.infile,width=25) + e_infile.grid(row=self.row, column=0, sticky='e') + if not self.infile.get(): e_infile.focus_set() + self.button(_("Browse"), self.askfile).grid( + row=self.row, column=1, sticky='w', padx=10) + # Show outfile name, style and encoding (if any) + txt = '' + if outfile: + txt = outfile + if outfile == STDOUT: txt = _('<screen>') + l_output = self.label(_('Output: ')+txt, fg=self.fg2, bg=self.bg2) + l_output.grid(columnspan=2, sticky='w') + for setting in ['style','encoding']: + if self.conf.get(setting): + name = setting.capitalize() + val = self.conf[setting] + self.label('%s: %s'%(name, val), + fg=self.fg2, bg=self.bg2).grid( + columnspan=2, sticky='w') + # Choose target + self.frame_close() ; self.action(action2) + self.frame_open() + self.target_key2name() + self.menu(self.target_name, targets_menu).grid( + columnspan=2, sticky='w') + # Options checkboxes label + self.frame_close() ; self.action(action3) + self.frame_open() + # Compose options check boxes, example: + # self.check(checks_txt['toc'],1,variable=self.f_toc) + for check in self.checks: + # Extra options label + if check == 'toc-only': + self.frame_close() ; self.action(action4) + self.frame_open() + txt = checks_txt[check] + var = getattr(self, 'f_'+check) + checked = self.conf.get(check) + self.check(txt,checked,variable=var) + self.frame_close() + # Spacer and buttons + self.label('').grid() ; self.row += 1 + b_quit = self.button(_("Quit"), self.exit) + b_quit.grid(row=self.row, column=0, sticky='w', padx=30) + b_conv = self.button(_("Convert!"), self.runprogram) + b_conv.grid(row=self.row, column=1, sticky='e', padx=30) + if self.target.get() and self.infile.get(): + b_conv.focus_set() + + # As documentation told me + if sys.platform.startswith('win'): + self.root.iconify() + self.root.update() + self.root.deiconify() + + self.root.mainloop() + + +############################################################################## +############################################################################## + +def exec_command_line(user_cmdline=[]): + global CMDLINE_RAW, RC_RAW, DEBUG, VERBOSE, QUIET, GUI, Error + + # Extract command line data + cmdline_data = user_cmdline or sys.argv[1:] + CMDLINE_RAW = CommandLine().get_raw_config(cmdline_data, relative=1) + cmdline_parsed = ConfigMaster(CMDLINE_RAW).parse() + DEBUG = cmdline_parsed.get('debug' ) or 0 + VERBOSE = cmdline_parsed.get('verbose') or 0 + QUIET = cmdline_parsed.get('quiet' ) or 0 + GUI = cmdline_parsed.get('gui' ) or 0 + infiles = cmdline_parsed.get('infile' ) or [] + + Message(_("Txt2tags %s processing begins")%my_version,1) + + # The easy ones + if cmdline_parsed.get('help' ): Quit(USAGE) + if cmdline_parsed.get('version'): Quit(VERSIONSTR) + if cmdline_parsed.get('targets'): + listTargets() + Quit() + + # Multifile haters + if len(infiles) > 1: + errmsg=_("Option --%s can't be used with multiple input files") + for option in NO_MULTI_INPUT: + if cmdline_parsed.get(option): + Error(errmsg%option) + + Debug("system platform: %s"%sys.platform) + Debug("python version: %s"%(sys.version.split('(')[0])) + Debug("line break char: %s"%repr(LB)) + Debug("command line: %s"%sys.argv) + Debug("command line raw config: %s"%CMDLINE_RAW,1) + + # Extract RC file config + if cmdline_parsed.get('rc') == 0: + Message(_("Ignoring user configuration file"),1) + else: + rc_file = get_rc_path() + if os.path.isfile(rc_file): + Message(_("Loading user configuration file"),1) + RC_RAW = ConfigLines(file_=rc_file).get_raw_config() + + Debug("rc file: %s"%rc_file) + Debug("rc file raw config: %s"%RC_RAW,1) + + # Get all infiles config (if any) + infiles_config = get_infiles_config(infiles) + + # Is GUI available? + # Try to load and start GUI interface for --gui + if GUI: + try: + load_GUI_resources() + Debug("GUI resources OK (Tk module is installed)") + winbox = Gui() + Debug("GUI display OK") + GUI = 1 + except: + Debug("GUI Error: no Tk module or no DISPLAY") + GUI = 0 + + # User forced --gui, but it's not available + if cmdline_parsed.get('gui') and not GUI: + print(getTraceback()); print() + Error( + "Sorry, I can't run my Graphical Interface - GUI\n" + "- Check if Python Tcl/Tk module is installed (Tkinter)\n" + "- Make sure you are in a graphical environment (like X)") + + # Okay, we will use GUI + if GUI: + Message(_("We are on GUI interface"),1) + + # Redefine Error function to raise exception instead sys.exit() + def Error(msg): + showerror(_('txt2tags ERROR!'), msg) + raise error + + # If no input file, get RC+cmdline config, else full config + if not infiles: + gui_conf = ConfigMaster(RC_RAW+CMDLINE_RAW).parse() + else: + try : gui_conf = infiles_config[0][0] + except: gui_conf = {} + + # Sanity is needed to set outfile and other things + gui_conf = ConfigMaster().sanity(gui_conf, gui=1) + Debug("GUI config: %s"%gui_conf,5) + + # Insert config and populate the nice window! + winbox.load_config(gui_conf) + winbox.mainwindow() + + # Console mode rocks forever! + else: + Message(_("We are on Command Line interface"),1) + + # Called with no arguments, show error + # TODO#1: this checking should be only in ConfigMaster.sanity() + if not infiles: + Error(_('Missing input file (try --help)') + '\n\n' + + _('Please inform an input file (.t2t) at the end of the command.') + '\n' + + _('Example:') + ' %s -t html %s' % (my_name, _('file.t2t'))) + + convert_this_files(infiles_config) + + Message(_("Txt2tags finished successfully"),1) + +if __name__ == '__main__': + try: + exec_command_line() + except error as msg: + sys.stderr.write("%s\n"%msg) + sys.stderr.flush() + sys.exit(1) + except SystemExit: + pass + except: + sys.stderr.write(getUnknownErrorMessage()) + sys.stderr.flush() + sys.exit(1) + Quit() + +# The End.
View file
tovid-0.35.0.tar.gz/libtovid/metagui/gui.py -> tovid-0.35.2.tar.gz/libtovid/metagui/gui.py
Changed
@@ -95,7 +95,9 @@ """ text = self.stdin_text.get() # Write the entered text to the command's stdin pipe - self.command.proc.stdin.write(text + '\n') + #self.command.proc.stdin.write(text + '\n') + # python 3 compatibility + self.command.proc.stdin.write(bytearray(text + "\n", "ascii")) self.command.proc.stdin.flush() # Show what was typed in the log window self.write(text)
View file
tovid-0.35.0.tar.gz/setup.py -> tovid-0.35.2.tar.gz/setup.py
Changed
@@ -44,7 +44,7 @@ # Current SVN version number #_tovid_version = svn_version() # Official release number -_tovid_version = '0.35.0' +_tovid_version = '0.35.2' import os @@ -148,11 +148,18 @@ def run(self): """Build the tovid manual page. """ + # For python 3 txt2tags needs an unofficial script + import sys + if (sys.version_info > (3, 0)): + txt2tags = 'docs/scripts/txt2tags' + else: + txt2tags = 'txt2tags' + # Build only if target does not exist, or if source is newer than target mod = os.path.getmtime if not os.path.exists(self.target) or (mod(self.source) > mod(self.target)): print("Rebuilding tovid manual page") - command = 'txt2tags -t man -i "%s" -o "%s"' % (self.source, self.target) + command = '%s -t man -i "%s" -o "%s"' % (txt2tags, self.source, self.target) os.system(command) else: print("Manual page already built, not building again")
View file
tovid-0.35.0.tar.gz/src/idvid -> tovid-0.35.2.tar.gz/src/idvid
Changed
@@ -455,11 +455,11 @@ if $USE_NAVLOG; then if egrep -qi 'mpeg$|mpg$|vob$' <<< "${INFILE##*.}"; then ID_VIDEO_FRAMES=$(awk 'END{print NR}' "$NAV_LOG" ) - V_DUR=$(bc <<< "$ID_VIDEO_FRAMES / $ID_VIDEO_FPS") + V_DUR=$( ${bC} <<< "$ID_VIDEO_FRAMES / $ID_VIDEO_FPS") V_DURATION=${V_DUR%%.*} # final value is integer ( seconds ) else V_DURATION=$(awk '($2==1) { field = $NF }; END{ print field/1000 }' "$NAV_LOG") - ID_VIDEO_FRAMES=$(bc <<< "$V_DURATION * $ID_VIDEO_FPS") + ID_VIDEO_FRAMES=$( ${bC} <<< "$V_DURATION * $ID_VIDEO_FPS") ID_VIDEO_FRAMES=${ID_VIDEO_FRAMES%%.*} # final value is in seconds V_DURATION=${V_DURATION%%.*} # integer @@ -531,7 +531,7 @@ # infer bitrate from file size and duration v_size=$(( $(du -m "$INFILE" | awk '{ print $1 }') * 8192 )) if (( ${V_DURATION%.*} )); then - ID_VIDEO_BITRATE=$(bc -l <<< "$v_size / $V_DURATION") + ID_VIDEO_BITRATE=$( ${bC} -l <<< "$v_size / $V_DURATION") ID_VIDEO_BITRATE=$(( v_size / V_DURATION ))000 #echo -e "Probed video bitrate not available, infering from file size and duration\n" fi @@ -545,7 +545,7 @@ if test_is_number $vid_frames && ((vid_frames)); then (( $ID_VIDEO_FRAMES == 0 )) && ID_VIDEO_FRAMES=$vid_frames elif (( ${V_DURATION%.*} )) && (( ${ID_VIDEO_FPS/./} )); then - VIDEO_FRAMES=$(bc -l <<< "$V_DURATION * $ID_VIDEO_FPS") + VIDEO_FRAMES=$( ${bC} -l <<< "$V_DURATION * $ID_VIDEO_FPS") if (( $ID_VIDEO_FRAMES == 0 )); then ID_VIDEO_FRAMES=${VIDEO_FRAMES%.*} #echo -e "Probed frame count not available, infering from duration and framerate\n" @@ -622,7 +622,7 @@ echo "V_ASPECT_WIDTH=$V_ASPECT_WIDTH" echo "ID_VIDEO_FRAMES=$ID_VIDEO_FRAMES" elif $TABULAR; then - FILE_SIZE=$(du -Dh "$INFILE" | awk '{print $1}') + FILE_SIZE=$(du -Hh "$INFILE" | awk '{print $1}') echo "$INFILE||$FILE_SIZE||${ID_VIDEO_WIDTH}x${ID_VIDEO_HEIGHT}||$ID_VIDEO_FPS||$ID_VIDEO_BITRATE||$ID_AUDIO_BITRATE" >> "$TABLE" else echo $SEPARATOR
View file
tovid-0.35.0.tar.gz/src/makedvd -> tovid-0.35.2.tar.gz/src/makedvd
Changed
@@ -142,7 +142,7 @@ else DISC_CAPACITY=0 fi - DISC_CAPACITY=$(echo "$DISC_CAPACITY / 1024 / 1024" | bc) + DISC_CAPACITY=$(echo "$DISC_CAPACITY / 1024 / 1024" | ${bC} ) # Define usable DVDs HAVE_DVD_RW=$(verify "$DISC_TYPE" set "DVD-RW DVD+RW") @@ -308,12 +308,13 @@ DISC_SUM=0 while test $i -le $NUM_VOBS; do VOB=$(echo "$VOB_LIST" | awk -F ':' '{ print $'$i' }') - VOB_SIZE=$(du -D -B M "$VOB" | awk -F ' ' '{print $1}' | tr -d M) + VOB_SIZE=$(du -H -m "$VOB" | awk '{print $1}') DISC_SUM=$(expr $VOB_SIZE \+ $DISC_SUM) i=$(expr $i \+ 1) done OUTDIR=$(readlink -f "$OUT_DIR") - AVAIL_SPACE=$(df -B M -P "${OUTDIR%/*}" | awk 'NR != 1 {print $4;}' | tr -d M) + AVAIL_SPACE=$(df -P "$OUT_DIR" | awk 'NR==1 {sub("-blocks", "", $2); blocksize=$2} \ + NR!=1 {print int($4/1024*blocksize/1024)}') if test $DISC_SUM -gt $AVAIL_SPACE; then echo $SEPARATOR
View file
tovid-0.35.0.tar.gz/src/makempg -> tovid-0.35.2.tar.gz/src/makempg
Changed
@@ -336,7 +336,7 @@ # based on original file size $SLICE && VIDEO_DURATION=$CLIP_LENGTH || VIDEO_DURATION=$V_DURATION if test "$VIDEO_DURATION" = "0"; then - CUR_SIZE=$(du -Dck "$IN_FILE" | awk 'END{print $1}') + CUR_SIZE=$(du -Hck "$IN_FILE" | awk 'END{print $1}') NEED_SPACE=$(expr $CUR_SIZE \* 2) # Estimate space based as kbps * duration else @@ -757,13 +757,13 @@ test -n "$AVG_BITRATE" && AVG_BITRATE=$(expr $AVG_BITRATE \/ 1000) test -n "$PEAK_BITRATE" && PEAK_BITRATE=$(expr $PEAK_BITRATE \/ 1000) KB_PER_MIN=$(expr $FINAL_SIZE \* 60 \/ $V_DURATION \+ 1) - ENC_TIME_RATIO=$(echo "scale = 2; $SCRIPT_TOT_TIME / $V_DURATION" | bc) + ENC_TIME_RATIO=$(echo "scale = 2; $SCRIPT_TOT_TIME / $V_DURATION" | ${bC} ) if $USE_FFMPEG; then BACKEND="$FFmpeg" else BACKEND="mpeg2enc" fi - + [[ $CPU_SPEED ]] && MHZ=MHz || MHZ= # Final statistics string (pretty-printed) FINAL_STATS_PRETTY=`cat << EOF ---------------------------------------- @@ -775,7 +775,7 @@ Target bitrate: $VID_BITRATE kbits/sec Average bitrate: $AVG_BITRATE kbits/sec Peak bitrate: $PEAK_BITRATE kbits/sec - Took $HHMMSS to encode on $CPU_MODEL $CPU_SPEED mhz + Took $HHMMSS to encode on $CPU_MODEL $CPU_SPEED $MHZ ----------------------------------------- EOF` @@ -1116,13 +1116,13 @@ ((${CLIP_SEEK%.*} > 0)) && [[ -z $ASYNC ]] && ASYNC1="-async 1" if [[ "$CLIP_ENDTIME" ]]; then [[ "$CLIP_ENDTIME" = *:* ]] && CLIP_ENDTIME=$(unformat_time $CLIP_ENDTIME) - CLIP_LENGTH=$(echo "$CLIP_ENDTIME - $CLIP_SEEK" | bc) + CLIP_LENGTH=$(echo "$CLIP_ENDTIME - $CLIP_SEEK" | ${bC} ) [[ ${CLIP_LENGTH%.*} -eq 0 ]] && CLIP_LENGTH=1 FF_LENGTH="-t $CLIP_LENGTH" fi CLIP_SEEK="-ss $CLIP_SEEK" fi -# FRAMES=$(echo "scale = 2; $ID_VIDEO_FPS * $CLIP_ENDTIME" | bc) +# FRAMES=$(echo "scale = 2; $ID_VIDEO_FPS * $CLIP_ENDTIME" | ${bC} ) # MP_FRAMES="-frames ${FRAMES%.*}" @@ -1133,7 +1133,7 @@ yecho "Probing video for information. This may take several minutes..." # Get an MD5sum of the input file for statistics - IN_FILE_MD5=$(md5sum "$IN_FILE" | awk '{print $1}') + IN_FILE_MD5=$($md5sum "$IN_FILE" | awk '{print $1}') # Assume nothing is compliant unless idvid says so # (these will be overridden by idvid for compliant A/V) @@ -1257,7 +1257,7 @@ # When the audio is already compliant and the bitrate is known we # can calculate a more accurate size. if $AUDIO_OK && test "$ID_AUDIO_BITRATE" != "0"; then - AUD_BITRATE=$(echo "scale = 0; $ID_AUDIO_BITRATE / 1000" | bc) + AUD_BITRATE=$(echo "scale = 0; $ID_AUDIO_BITRATE / 1000" | ${bC} ) fi AUDIO_SIZE=$(bc_math "$AUD_BITRATE * $LENGTH / (8 *1024)") VIDEO_SIZE=$(bc_math "$AUD_VID_SIZE - $AUDIO_SIZE") @@ -1665,7 +1665,7 @@ errors=$( $FFmpeg -i "$IN_FILE" -t 1 \ -vf scale=w=720:h=352,pad=width=720:height=480:x=0:y=64,setdar=16/9 \ -f null -y /dev/null 2>&1) -if grep -qE "Error.*\(width\|height\|setdar\|w=\|h=\)" <<< "$errors"; then +if grep -qE "Error.*(width|height|setdar|w=|h=)" <<< "$errors"; then ff_legacy=1 fi @@ -2190,8 +2190,8 @@ # ****************************************************************************** if ! $FAKE; then - AUDIO_SIZE=$(du -c -b "$AUDIO_STREAM" | awk 'END{print $1}') - VIDEO_SIZE=$(du -c -b "$VIDEO_STREAM" | awk 'END{print $1}') + AUDIO_SIZE=$(ls -lnR "$AUDIO_STREAM" | awk 'END{print $5}') + VIDEO_SIZE=$(ls -lnR "$VIDEO_STREAM" | awk 'END{print $5}') # Total size of streams so far (in MBytes) STREAM_SIZE=$(expr \( $AUDIO_SIZE \+ $VIDEO_SIZE \) \/ 1000000) # If it exceeds disc size, add '%d' field to allow mplex to split output
View file
tovid-0.35.0.tar.gz/src/todisc -> tovid-0.35.2.tar.gz/src/todisc
Changed
@@ -80,7 +80,6 @@ # check if symlink in /tmp exists and use time stamped link if so WORK_DIR="/tmp/todisc-work" - LOG_FILE=$(readlink -f todisc.log) OUT_DIRECTORY="" TV_STANDARD=ntsc @@ -332,6 +331,7 @@ # Usage: continue_in [SECONDS] continue_in() { + local count LAST yecho "" (($1)) && LAST=$1 || LAST=5 for ((i=LAST; i>=0; i--)); do @@ -456,19 +456,19 @@ # last 2 args are optional: defaults 'video' and the whole stream. stream_length() { - local end="" + local end="" local stream_type=video local ff_opts="-an -vcodec copy" [[ -n $2 ]] && stream_type=$2 [[ -n $3 ]] && end="-t $3" - sed_var="{s/^.*time= *\([^ ]*\).*/\1/p}" + sed_var="{s/^.*time= *\([^ ]*\).*/\1/p;}" stream_name=$stream_type if [[ $stream_type = 'audio' ]]; then ff_opts="-vn -acodec copy" # workaround for avconv which is broken atm wrt getting m2v framerate right # overload stream_type to have another meaning, elif [[ $stream_type = 'm2v' ]]; then - sed_var="{s/^.*frame= *\([^ ]*\).*/\1/p}" + sed_var="{s/^.*frame= *\([^ ]*\).*/\1/p;}" stream_name=video fi print2log "Using $FFmpeg to get accurate $stream_name length of $1" @@ -598,9 +598,11 @@ # usage: bc_math "expression" [int] bc_math() { + local val=$1 + #val=${val//$'\n'/} OLC_ALL=$LC_ALL LC_ALL=C - bc_out=$(bc <<< "scale=3;$1" 2>/dev/null) + bc_out=$( ${bC} <<< "scale=3;$val" 2>/dev/null) if [[ -n $2 && $2 = "int" ]]; then echo ${bc_out%.*} else @@ -967,7 +969,7 @@ video_type=$3 yecho "" yecho "$VIDEO_IN is not compliant - re-encoding \ - $(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) + $( ${bC} <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) second slice to DVD compliant file" yecho "This is not strictly necessary and will reduce quality, but it may" yecho "help with sync problems if using the same file for audio and video." @@ -984,7 +986,7 @@ yecho "Converting files to $TGT_CAPS format with 'makempg'" continue_in 5 makempg $NO_ASK -in "$VIDEO_IN" \ - -slice 0-$(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) \ + -slice 0-$( ${bC} <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) \ -${TV_STANDARD} -${TARGET} -in "$VIDEO_IN" \ -out "${VIDEO_IN}.enc" "${TOVID_OPTS[@]}" # See if output file exists @@ -1039,7 +1041,7 @@ done else for len in ${GROUP_VIDEO_LENGTHS[@]}; do - adjusted_length=$( bc <<< "scale=3; $len + $remainder" 2>/dev/null) + adjusted_length=$( ${bC} <<< "scale=3; $len + $remainder" 2>/dev/null) num_chapters=$( bc_math "$adjusted_length / $chapter_length" int ) if (( num_chapters > 0)); then chapt_len_array=( $( for ((t=0; t<num_chapters; t++)); do @@ -1050,7 +1052,7 @@ chapter_points=$( running_total <<< ${chapt_len_array[@]} ) # remove trailing space chapter_points=$(sed 's/[ \t]*$//' <<< $chapter_points) - remainder=$( bc <<< "$adjusted_length % $chapter_length" \ + remainder=$( ${bC} <<< "$adjusted_length % $chapter_length" \ 2>/dev/null) (( ${nochapt[index]} )) && local group_chapters[x++]=0 || local group_chapters[x++]=$chapter_points @@ -1353,7 +1355,7 @@ MENUTITLES=( "${menutitles[@]}" ) # some vars for vmgm menu, depending on presence of -static or -quick-nav # how many titlesets do we have ? - for i in "$@"; do [[ $i == -end-titleset ]] && ((count++)); done + for i in "$@"; do [[ $i == -end-titleset ]] && ((tscount++)); done VMGM_PAUSE=$PAUSE_TIME grep -q -- -static <<< "${VMGM_OPTS[@]}" && VMGM_PAUSE="inf" for i in ${!VMGM_OPTS[@]}; do @@ -1422,7 +1424,7 @@ fi) $(if $QUICK_NAV; then echo -e " <button name=\"ActionLeft\">" - echo -e " g5=${ALLTITLES[count-1]}; g3=$count; button=1024;" + echo -e " g5=${ALLTITLES[tscount-1]}; g3=$tscount; button=1024;" echo -e " jump vmgm menu entry title;</button>" echo -e " <button name=\"ActionRight\">" echo -e " g5=1; g3=1; button=1024;" @@ -1485,7 +1487,7 @@ done unset vmgmtitles get_menu_titles "${VMGM_OPTS[@]}" - if [[ -n ${VMGM_OPTS[@]} ]] && ((${#vmgmtitles[@]} != count)); then + if [[ -n ${VMGM_OPTS[@]} ]] && ((${#vmgmtitles[@]} != tscount)); then usage_error "Number of titleset titles must equal the number of titlesets. ( -vmgm ... -titles 'Title 1' 'Title 2' -end-vmgm )" fi @@ -1499,14 +1501,14 @@ yecho "One title for each titleset you are making." yecho "Any other appropriate todisc options for the vmgm menu \ can be specified as well." - if [[ ${#MENUTITLES[@]} -eq $count ]]; then + if [[ ${#MENUTITLES[@]} -eq $tscount ]]; then yecho "Since -menu-title was supplied for each titleset: \ these titleset titles will be used:" for t in "${MENUTITLES[@]}"; do echo "\"$t\""; done VMGM_OPTS=(-titles "${MENUTITLES[@]}") else VMGM_OPTS[0]="-titles" - for ((menu=1; menu<=count; menu++)); do + for ((menu=1; menu<=tscount; menu++)); do VMGM_OPTS[menu]="Titleset $menu" done fi @@ -1517,7 +1519,7 @@ else unset vmgmtitles get_menu_titles "${VMGM_OPTS[@]}" - if ((${#vmgmtitles[@]} != 0)) && ((${#vmgmtitles[@]} != count)); then + if ((${#vmgmtitles[@]} != 0)) && ((${#vmgmtitles[@]} != tscount)); then usage_error "Number of titleset titles must equal the number of titlesets." fi @@ -1546,7 +1548,7 @@ shift done titleset_cmd=( todisc -titleset-mode -basedir "$WORK_DIR" \ - -title_count "$num_titles" -tset_num ${count}-${tset} \ + -title_count "$num_titles" -tset_num ${tscount}-${tset} \ "${GEN_OPTS[@]}" $NO_CONFIRM_BACKUP "${TITLESET_OPTS[@]}" \ $vmgm_playall ) yecho @@ -1659,14 +1661,14 @@ clr1="$colr1" fi - mk_rtn_cmd=(convert -size 100x80 xc:none \ + mk_rtn_cmd=(convert +antialias -size 100x80 xc:none \ -strokewidth 1 -stroke "$colr2" -fill "$clr1" \ -draw 'rectangle 0,0 70,62' \ -fill "$colr2" -stroke none \ -draw "polyline 40,10 40,50 10,30 40,10" \ -draw "polyline 60,10 60,50 30,30 60,10" \ -fill "$colr2" -draw "rectangle 6,10 10,50" \ - -resize 30% -trim +repage +antialias "$outbutton") + -resize 30% -trim +repage "$outbutton") print2log "Running ${mk_rtn_cmd[@]}" "${mk_rtn_cmd[@]}" mogrify -channel A -threshold 50% "$outbutton" @@ -1698,6 +1700,7 @@ play_btn_dim=$(get_image_dim "$outbutton") play_btn_width=$(awk -Fx '{print $1}' <<< $play_btn_dim ) play_btn_height=$(awk -Fx '{print $2}' <<< $play_btn_dim ) + mogrify -channel A -threshold 50% "$outbutton" } check_menufile() @@ -2115,16 +2118,16 @@ index=$2 outppm="$WORK_DIR/animenu/$(printf %06d%s $index .ppm)" if [[ $fade_type = "crossfade" ]]; then - value=$(bc -l <<< "scale=2; ($fade_slide + 1) * $fade_incr") >&2 + value=$( ${bC} -l <<< "scale=2; ($fade_slide + 1) * $fade_incr") >&2 fade_cmd=(composite -blend $value -depth 8 "$overlay_ppm" \ "$base_ppm" "$outppm") elif [[ $fade_type = "fadein" ]]; then - value=$(bc -l <<< "scale=2; $fade_slide * $fade_incr") >&2 + value=$( ${bC} -l <<< "scale=2; $fade_slide * $fade_incr") >&2 fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \ -blend ${value}% "$outppm") elif [[ $fade_type = "fadeout" ]]; then - value=$(bc -l <<< "scale=2;100 - (($fade_slide + 1) * $fade_incr)") >&2 - (( $(bc <<< "$value < 0") == 1 )) && value=0 + value=$( ${bC} -l <<< "scale=2;100 - (($fade_slide + 1) * $fade_incr)") >&2 + (( $( ${bC} <<< "$value < 0") == 1 )) && value=0 fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \ -blend ${value}% "$outppm") fi @@ -3558,8 +3561,7 @@ # check for multiple cpus if -jobs not passed already #TODO always wait for either 1 or 2 processes - no need for if block later if [[ -z $JOBS ]]; then - proc_cnt=$(grep ^processor /proc/cpuinfo |awk 'END{print $NF+1}') - max_procs=$proc_cnt + max_procs=$cpu_count # cpu_count is sourced from tovid-init fi if $BURN; then @@ -3683,7 +3685,13 @@ # Make sure -out was provided and it is valid if test -n "$OUT_DIRECTORY"; then + # for BSD readlink + if [[ ! -d "$OUT_DIRECTORY" ]]; then + mkdir "$OUT_DIRECTORY" || usage_error "Can not make $OUT_DIRECTORY" + bsdoutdir=1 + fi OUT_DIR=$(readlink -f "$OUT_DIRECTORY") + ((bsdoutdir)) && rmdir "$OUT_DIRECTORY" if [[ ! -d ${OUT_DIR%/*} ]]; then OUT_PATH=$(readlink -m "$OUT_DIRECTORY") usage_error "The -out path ${OUT_PATH%/*}/ does not exist" @@ -5014,7 +5022,7 @@ SHORTFILE=: else FRAME_CK=$(stream_length "${IN_FILES[i]}" video 90) - [[ $(bc -l <<< "$FRAME_CK < 2") -eq 1 ]] && SHORTFILE=: + [[ $( ${bC} -l <<< "$FRAME_CK < 2") -eq 1 ]] && SHORTFILE=: fi if $SHORTFILE; then ! $USER_SEEK_VAL && SEEK_VAL[i]=0 @@ -7258,7 +7266,7 @@ BG_AUDIOLENGTH=$(stream_length "$BG_AUDIO" audio) # make sure user isn't trying to get a longer menu than the audio allows - if [[ $(bc <<< "${MENU_LEN[MENU_NUM-1]} \ + if [[ $( ${bC} <<< "${MENU_LEN[MENU_NUM-1]} \ > $BG_AUDIOLENGTH" 2>/dev/null) -eq 1 ]]; then MENU_AUDIOLEN=$BG_AUDIOLENGTH fi @@ -7278,10 +7286,10 @@ TT=1 # a constant value atm $SLIDE_FADE && MIX_SLIDE_LEN=$(bc_math "$MIX_SLIDE_LEN - $TT") - if [[ $(bc -l <<< "$MIX_SLIDE_LEN == 0") -eq 1 ]]; then + if [[ $( ${bC} -l <<< "$MIX_SLIDE_LEN == 0") -eq 1 ]]; then # use 2 frames for each still so MIX_SLIDE_LEN is not 0 - MIX_SLIDE_LEN=$(bc -l <<< "scale=3; 2 / $FRAME_RATE") - elif [[ $(bc -l <<< "$MIX_SLIDE_LEN < 0") -eq 1 ]]; then + MIX_SLIDE_LEN=$( ${bC} -l <<< "scale=3; 2 / $FRAME_RATE") + elif [[ $( ${bC} -l <<< "$MIX_SLIDE_LEN < 0") -eq 1 ]]; then runtime_error "The menu length is not long enough for an animated menu. For slideshows where -bgaudio FILE is supplied, this is determined by: 1. -menu-length argument if supplied @@ -7389,12 +7397,12 @@ if [[ $EFFECT = "fade" ]]; then [[ $TV_STANDARD = "ntsc" ]] && fade_frames=15 || fade_frames=12 - fade_incr=$(bc -l <<< "scale=2; 100 / $fade_frames") >&2 + fade_incr=$( ${bC} -l <<< "scale=2; 100 / $fade_frames") >&2 convert -size ${CAROUSEL_SIZE}! xc:'#101010' -depth 8 \ "$WORK_DIR/black.ppm" elif [[ $EFFECT = "crossfade" ]]; then [[ $TV_STANDARD = "ntsc" ]] && fade_frames=30 || fade_frames=25 - fade_incr=$(bc -l <<< "scale=2; 100 / $fade_frames") >&2 + fade_incr=$( ${bC} -l <<< "scale=2; 100 / $fade_frames") >&2 fi TOYUV_FADE_CMD=(ppmtoy4m -v 0 -n $fade_frames -A $PIXEL_AR -F $YUV_FR -I p \ @@ -7622,7 +7630,7 @@ fi # add -force to makevcd if short file # wait for input on short files (slides) unless -video-pause passed - if [[ $(bc -l <<< "${VID_LEN[i]} < 1") -eq 1 ]]; then + if [[ $( ${bC} -l <<< "${VID_LEN[i]} < 1") -eq 1 ]]; then [[ -z ${VPAUSE[i]} ]] && VPAUSE[i]="inf" # 1 chapter per short file, (altered below if group short file) ! $USER_CHAPTERS && CHAPTERS[i]=1 # each 'slide' is a chapter @@ -7648,7 +7656,7 @@ GROUP_VID_LENGTHS[i]="${GROUP_VID_LENGTHS[i]} \ ${GROUP_VID_LEN[t]}" # if short file, assume it is a slideshow, and use pause="inf" - if [[ $(bc -l <<< "${GROUP_VID_LEN[t]} < 1") -eq 1 ]]; then + if [[ $( ${bC} -l <<< "${GROUP_VID_LEN[t]} < 1") -eq 1 ]]; then # but only if -group-video-pause was not passed [[ -z ${GRP_VPAUSE[i]} ]] && GRP_VPAUSE[i]="inf" ! $USER_CHAPTERS && CHAPTERS[i]=0 # each slide's a chapter @@ -7683,7 +7691,7 @@ let vid=MENU_NUM-1 SHOWCASE_SEEK_VAL=${SEEK_VAL[vid]} # use silence if a short file ( probably a slide ) and no background audio - if [[ -z $BG_AUDIO && $( bc -l <<< "${VID_LEN[vid]} < 1") -eq 1 ]]; then + if [[ -z $BG_AUDIO && $( ${bC} -l <<< "${VID_LEN[vid]} < 1") -eq 1 ]]; then BG_AUDIO="none" fi # if no audio is detected in the video @@ -7706,11 +7714,11 @@ ! $USER_BG_AUDIO_SEEK && BG_AUDIO_SEEK=0 # make sure MENU_AUDIOLEN value isn't longer than the video # FIXME if video shorter than menu length adjust MENU_LEN - [[ $( bc -l <<< "$MENU_AUDIOLEN > ${VID_LEN[vid]}") -eq 1 ]] \ + [[ $( ${bC} -l <<< "$MENU_AUDIOLEN > ${VID_LEN[vid]}") -eq 1 ]] \ && MENU_AUDIOLEN=${VID_LEN[vid]} # MENU_LEN can't be longer than the audio length # don't use fade unless the video is long enough to support it - [[ $(bc -l <<< "${VID_LEN[vid]} < (($FADE * 2) + 2)") \ + [[ $( ${bC} -l <<< "${VID_LEN[vid]} < (($FADE * 2) + 2)") \ -eq 1 ]] && AUDIO_FADE=false else # same seek value as video unless user passes -bgaudio-seek @@ -8687,7 +8695,7 @@ fi fi # SM_LOOPS is the # of frames for static menus - SM_LOOPS[i]=$( bc \ + SM_LOOPS[i]=$( ${bC} \ <<< "${SUBMENU_AUDIOLEN[i]} * $FRAME_RATE" 2>/dev/null) SM_LOOPS[i]=${SM_LOOPS[i]%.*} done @@ -9629,7 +9637,7 @@ if $STATIC; then # we have a value for MENU_AUDIOLEN AND BG_AUDIO if [[ -n "$BG_AUDIO" && "$BG_AUDIO" != "none" ]] && ! $MENU_FADE; then - LOOPS=$( bc <<< "$MENU_AUDIOLEN * $FRAME_RATE" 2>/dev/null) + LOOPS=$( ${bC} <<< "$MENU_AUDIOLEN * $FRAME_RATE" 2>/dev/null) LOOPS=${LOOPS%.*} # switched menu: no bg audio or video and not menu fade elif $SWITCHED && [[ -z $BG_VIDEO && -z $BG_AUDIO ]] && ! $MENU_FADE; then
View file
tovid-0.35.0.tar.gz/src/todisc-fade-routine -> tovid-0.35.2.tar.gz/src/todisc-fade-routine
Changed
@@ -211,14 +211,14 @@ init_gamma_array () { -bc -l <<BC_EOF +${bC} -l <<BC_EOF pi=4*a(1); start_frame=0 # Get values from standard in # Format: -# echo "29.97\n 300\n 10\n .1\n 5\n .05\n .1\n" | bc -l +# echo "29.97\n 300\n 10\n .1\n 5\n .05\n .1\n" | ${bC} -l frame_rate=$FRAME_RATE; end_frame=$ANIMENU_ENDFRAME; average=$1;
View file
tovid-0.35.0.tar.gz/src/tovid-init -> tovid-0.35.2.tar.gz/src/tovid-init
Changed
@@ -45,7 +45,7 @@ #set -u # Suite version -TOVID_VERSION="0.35.0" +TOVID_VERSION="0.35.2" # String used to separate blocks of output SEPARATOR="=========================================================" @@ -55,6 +55,7 @@ TOVID_FORUMS="http://groups.google.com/group/tovid-users" TOVID_ISSUES="https://github.com/tovid-suite/tovid/issues" + # ****************************************************************************** # ****************************************************************************** # @@ -190,7 +191,7 @@ HMS_SECS=$(awk -F ':' '{print $3}' <<< $1) # allow integer to be passed, if so it will be echoed unchanged if [[ $1 = *:* ]]; then - TOT_SECONDS=$(bc <<< "($HMS_HOURS * 3600) + ($HMS_MINS * 60) + $HMS_SECS") + TOT_SECONDS=$( ${bC} <<< "($HMS_HOURS * 3600) + ($HMS_MINS * 60) + $HMS_SECS") else TOT_SECONDS=$1 fi @@ -281,7 +282,7 @@ # Wait for input file to appear # After a 30-second timeout, exit gracefully CUR_TIME=30 - while test $CUR_TIME -gt 0; do + while test $CUR_TIME -gt 0; do sleep 3 # If file exists, wait a few more seconds, then break out if test -e "$FOP_OUTFILE"; then @@ -304,7 +305,8 @@ # File size in bytes FOP_LAST_SIZE=0 - FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}') + # BSD compatibiity, yes I know parsing ls is bad + FOP_CUR_SIZE=$(ls -lnR "$FOP_OUTFILE" | awk 'END{print $5}') # Keep looping until outfile stops getting bigger while test "$FOP_CUR_SIZE" -gt "$FOP_LAST_SIZE"; do @@ -323,11 +325,11 @@ "$ANIM_STR" "$FOP_MSG" "$FOP_CUR_MB" "$FOP_BASENAME_NAME" # Doze a bit to let the file size increase - # (SLEEP_TIME defaults to 1s if unset) - sleep ${SLEEP_TIME-"1"} + # freebsd couldn't handle ${SLEEP_TIME-1} so leave at 1s + sleep 1 FOP_LAST_SIZE=$FOP_CUR_SIZE - FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}') + FOP_CUR_SIZE=$(ls -lnR "$FOP_OUTFILE" | awk 'END{print $5}') done $QUIET && printf "\n" || printf "\n\n" } @@ -398,7 +400,7 @@ bc_math() # usage: bc_math "expression" [int] { - bc_out=$(bc <<< "scale=3;$1" 2>/dev/null) + bc_out=$( ${bC} <<< "scale=3;$1" 2>/dev/null) if [[ -n $2 && $2 = "int" ]]; then echo ${bc_out%.*} else @@ -455,6 +457,25 @@ printf "\n" } +# BSD's readlink behaves differently than GNU's. Use python instead +# This is just a replacement for readlink -f which is used in our scripts, +# though it could be adapted for other options easily enough. +if [[ $(uname -s) =~ BSD ]]; then + readlink () + { + local args out parent_dir; + args=(); + for arg in "$@"; do + case "$arg" in + -[a-zA-Z0-9]) ;; + *) args+=($arg) ;; + esac; + done; + out="\"${args[*]}\""; + python -c "import os.path; print os.path.realpath($out)" + } +fi + # ****************************************************************************** # # @@ -476,15 +497,28 @@ /proc/cpuinfo | head -n 1 | sed 's/^ *//g') CPU_SPEED=$(awk 'BEGIN { IGNORECASE = 1 } /MHz/ { print $4 }' /proc/cpuinfo | head -n 1) # Test for multiple CPUs. If they are available, try to use them. - if test $(grep "^processor" /proc/cpuinfo | wc -l) -ge "2"; then - MULTIPLE_CPUS=: - else - MULTIPLE_CPUS=false - fi + cpu_count=$(grep "^processor" /proc/cpuinfo | wc -l) + ((cpu_count > 1)) && MULTIPLE_CPUS=: || MULTIPLE_CPUS=false elif test "$KERNEL" = "Darwin"; then - : + (( $(sysctl -n hw.ncpu) > 1 )) && MULTIPLE_CPUS=: || MULTIPLE_CPUS=false +elif [[ $KERNEL =~ BSD ]]; then + cpu_count=$(sysctl hw.ncpu | awk '{print $2}') + ((cpu_count > 1)) && MULTIPLE_CPUS=: + CPU_MODEL=$(sysctl hw.model |sed 's/.*: \(.*\)@/\1/') + CPU_SPEED='' fi +# use gnubc on bsd systems (found in /usr/local) +# bsd uses md5, which needs -r to print hash in 1st column +if [[ $KERNEL =~ 'BSD' ]]; then + bC=/usr/local/bin/bc + md5=md5 + md5sum="md5 -r" +else + bC=$(which bc) + md5=md5sum + md5sum=md5sum +fi # ****************************************************************************** # Find multiple version kludge @@ -558,10 +592,19 @@ [[ $TOVID_OUTPUT_DIR ]] && OUTPUT_DIR="$TOVID_WORKING_DIR" [[ $TOVID_FFMPEG_CMD ]] && TOVID_FFMPEG="$TOVID_FFMPEG_CMD" # FFmpeg and FFprobe are vars used for ffmpeg by scripts needing ffmpeg/avconv -# if avconv is installed, use that unless env var set -hash avconv 2>/dev/null && TOVID_FFMPEG=${TOVID_FFMPEG:-avconv} -hash avprobe 2>/dev/null && TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe} +# if ffmpeg is installed, use that unless env var set +if hash ffmpeg 2>/dev/null; then + TOVID_FFMPEG=${TOVID_FFMPEG:-ffmpeg} +elif hash avconv 2>/dev/null; then + TOVID_FFMPEG=${TOVID_FFMPEG:-avconv} +fi +if hash ffprobe 2>/dev/null; then + TOVID_FFPROBE=${TOVID_FFPROBE:=ffprobe} +elif hash ffprobe 2>/dev/null; then + TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe} +fi # finally, default to ffmpeg if non of the above override it +# this will cause the assert_dep to recommend installing ffmpeg FFmpeg=${TOVID_FFMPEG:=ffmpeg} [[ $FFmpeg =~ ffmpeg ]] && TOVID_FFPROBE=ffprobe [[ $FFmpeg =~ avconv ]] && TOVID_FFPROBE=avprobe @@ -593,7 +636,7 @@ # ************************************************************************* # Required Dependencies # ************************************************************************* - core="grep sed md5sum mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv" + core="grep sed $md5 mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv" # ************************************************************************* # Optional Dependencies @@ -633,7 +676,7 @@ # Quit and complain if ANY core dependency is missing. assert_dep "$core" "You are missing CORE tovid dependencies!" # ffmpeg is also a part of core deps, but is taken care of here - ffmpeg_alts="Use either ffmpeg (ffmpeg.org) or avconv (libav.org)." + ffmpeg_alts="Use ffmpeg from ffmpeg.org (recommended), or avconv from libav.org." ffmpeg_pref="Set choice in ${USER_PREFS}. As in: TOVID_FFMPEG=ffmpeg" assert_dep $FFmpeg "You are missing $FFmpeg ! $ffmpeg_alts ${ffmpeg_pref}."
View file
tovid-0.35.0.tar.gz/src/tovid-init.in -> tovid-0.35.2.tar.gz/src/tovid-init.in
Changed
@@ -55,6 +55,7 @@ TOVID_FORUMS="http://groups.google.com/group/tovid-users" TOVID_ISSUES="https://github.com/tovid-suite/tovid/issues" + # ****************************************************************************** # ****************************************************************************** # @@ -190,7 +191,7 @@ HMS_SECS=$(awk -F ':' '{print $3}' <<< $1) # allow integer to be passed, if so it will be echoed unchanged if [[ $1 = *:* ]]; then - TOT_SECONDS=$(bc <<< "($HMS_HOURS * 3600) + ($HMS_MINS * 60) + $HMS_SECS") + TOT_SECONDS=$( ${bC} <<< "($HMS_HOURS * 3600) + ($HMS_MINS * 60) + $HMS_SECS") else TOT_SECONDS=$1 fi @@ -281,7 +282,7 @@ # Wait for input file to appear # After a 30-second timeout, exit gracefully CUR_TIME=30 - while test $CUR_TIME -gt 0; do + while test $CUR_TIME -gt 0; do sleep 3 # If file exists, wait a few more seconds, then break out if test -e "$FOP_OUTFILE"; then @@ -304,7 +305,8 @@ # File size in bytes FOP_LAST_SIZE=0 - FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}') + # BSD compatibiity, yes I know parsing ls is bad + FOP_CUR_SIZE=$(ls -lnR "$FOP_OUTFILE" | awk 'END{print $5}') # Keep looping until outfile stops getting bigger while test "$FOP_CUR_SIZE" -gt "$FOP_LAST_SIZE"; do @@ -323,11 +325,11 @@ "$ANIM_STR" "$FOP_MSG" "$FOP_CUR_MB" "$FOP_BASENAME_NAME" # Doze a bit to let the file size increase - # (SLEEP_TIME defaults to 1s if unset) - sleep ${SLEEP_TIME-"1"} + # freebsd couldn't handle ${SLEEP_TIME-1} so leave at 1s + sleep 1 FOP_LAST_SIZE=$FOP_CUR_SIZE - FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}') + FOP_CUR_SIZE=$(ls -lnR "$FOP_OUTFILE" | awk 'END{print $5}') done $QUIET && printf "\n" || printf "\n\n" } @@ -398,7 +400,7 @@ bc_math() # usage: bc_math "expression" [int] { - bc_out=$(bc <<< "scale=3;$1" 2>/dev/null) + bc_out=$( ${bC} <<< "scale=3;$1" 2>/dev/null) if [[ -n $2 && $2 = "int" ]]; then echo ${bc_out%.*} else @@ -455,6 +457,25 @@ printf "\n" } +# BSD's readlink behaves differently than GNU's. Use python instead +# This is just a replacement for readlink -f which is used in our scripts, +# though it could be adapted for other options easily enough. +if [[ $(uname -s) =~ BSD ]]; then + readlink () + { + local args out parent_dir; + args=(); + for arg in "$@"; do + case "$arg" in + -[a-zA-Z0-9]) ;; + *) args+=($arg) ;; + esac; + done; + out="\"${args[*]}\""; + python -c "import os.path; print os.path.realpath($out)" + } +fi + # ****************************************************************************** # # @@ -476,15 +497,28 @@ /proc/cpuinfo | head -n 1 | sed 's/^ *//g') CPU_SPEED=$(awk 'BEGIN { IGNORECASE = 1 } /MHz/ { print $4 }' /proc/cpuinfo | head -n 1) # Test for multiple CPUs. If they are available, try to use them. - if test $(grep "^processor" /proc/cpuinfo | wc -l) -ge "2"; then - MULTIPLE_CPUS=: - else - MULTIPLE_CPUS=false - fi + cpu_count=$(grep "^processor" /proc/cpuinfo | wc -l) + ((cpu_count > 1)) && MULTIPLE_CPUS=: || MULTIPLE_CPUS=false elif test "$KERNEL" = "Darwin"; then - : + (( $(sysctl -n hw.ncpu) > 1 )) && MULTIPLE_CPUS=: || MULTIPLE_CPUS=false +elif [[ $KERNEL =~ BSD ]]; then + cpu_count=$(sysctl hw.ncpu | awk '{print $2}') + ((cpu_count > 1)) && MULTIPLE_CPUS=: + CPU_MODEL=$(sysctl hw.model |sed 's/.*: \(.*\)@/\1/') + CPU_SPEED='' fi +# use gnubc on bsd systems (found in /usr/local) +# bsd uses md5, which needs -r to print hash in 1st column +if [[ $KERNEL =~ 'BSD' ]]; then + bC=/usr/local/bin/bc + md5=md5 + md5sum="md5 -r" +else + bC=$(which bc) + md5=md5sum + md5sum=md5sum +fi # ****************************************************************************** # Find multiple version kludge @@ -558,10 +592,19 @@ [[ $TOVID_OUTPUT_DIR ]] && OUTPUT_DIR="$TOVID_WORKING_DIR" [[ $TOVID_FFMPEG_CMD ]] && TOVID_FFMPEG="$TOVID_FFMPEG_CMD" # FFmpeg and FFprobe are vars used for ffmpeg by scripts needing ffmpeg/avconv -# if avconv is installed, use that unless env var set -hash avconv 2>/dev/null && TOVID_FFMPEG=${TOVID_FFMPEG:-avconv} -hash avprobe 2>/dev/null && TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe} +# if ffmpeg is installed, use that unless env var set +if hash ffmpeg 2>/dev/null; then + TOVID_FFMPEG=${TOVID_FFMPEG:-ffmpeg} +elif hash avconv 2>/dev/null; then + TOVID_FFMPEG=${TOVID_FFMPEG:-avconv} +fi +if hash ffprobe 2>/dev/null; then + TOVID_FFPROBE=${TOVID_FFPROBE:=ffprobe} +elif hash ffprobe 2>/dev/null; then + TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe} +fi # finally, default to ffmpeg if non of the above override it +# this will cause the assert_dep to recommend installing ffmpeg FFmpeg=${TOVID_FFMPEG:=ffmpeg} [[ $FFmpeg =~ ffmpeg ]] && TOVID_FFPROBE=ffprobe [[ $FFmpeg =~ avconv ]] && TOVID_FFPROBE=avprobe @@ -593,7 +636,7 @@ # ************************************************************************* # Required Dependencies # ************************************************************************* - core="grep sed md5sum mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv" + core="grep sed $md5 mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv" # ************************************************************************* # Optional Dependencies @@ -633,7 +676,7 @@ # Quit and complain if ANY core dependency is missing. assert_dep "$core" "You are missing CORE tovid dependencies!" # ffmpeg is also a part of core deps, but is taken care of here - ffmpeg_alts="Use either ffmpeg (ffmpeg.org) or avconv (libav.org)." + ffmpeg_alts="Use ffmpeg from ffmpeg.org (recommended), or avconv from libav.org." ffmpeg_pref="Set choice in ${USER_PREFS}. As in: TOVID_FFMPEG=ffmpeg" assert_dep $FFmpeg "You are missing $FFmpeg ! $ffmpeg_alts ${ffmpeg_pref}."
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.